Strange behavior in binding.parse_assembly

I have a python str irstr that is a valid LLVM IR module with a struct type definition. When I use m=binding.parse_assembly(irstr)multiple times, then print(str(m)), the struct type name changes like %struct.PgHdr.0, %struct.PgHdr.1, %struct.PgHdr.2 … However, function names and global pointer names don’t change like that.

I wonder if that is a bug or a feature.

You may try that using the IR string.

; ModuleID = '<stdin>'
source_filename = "/home/dxic/llvmtest/llvm-test-suite/SingleSource/Regression/C/gcc-c-torture/execute/pr33870.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.PgHdr = type { i32, ptr, ptr, ptr, ptr, ptr, i8, i16, ptr, ptr, i32 }

; Function Attrs: noinline nounwind uwtable
define dso_local ptr @sort_pagelist(ptr noundef %pIn) local_unnamed_addr #0 {
entry:
  %result.i72 = alloca %struct.PgHdr, align 8
  %result.i45 = alloca %struct.PgHdr, align 8
  %result.i = alloca %struct.PgHdr, align 8
  %a = alloca [25 x ptr], align 16
  call void @llvm.lifetime.start.p0(i64 200, ptr nonnull %a) #3
  call void @llvm.memset.p0.i64(ptr noundef nonnull align 16 dereferenceable(200) %a, i8 0, i64 200, i1 false)
  br label %while.cond

while.cond:                                       ; preds = %if.end16, %entry
  %pIn.addr.0 = phi ptr [ %pIn, %entry ], [ %0, %if.end16 ]
  %tobool.not = icmp eq ptr %pIn.addr.0, null
  br i1 %tobool.not, label %while.end, label %while.body

while.body:                                       ; preds = %while.cond
  %pDirty = getelementptr inbounds nuw i8, ptr %pIn.addr.0, i64 56
  %0 = load ptr, ptr %pDirty, align 8, !tbaa !5
  store ptr null, ptr %pDirty, align 8, !tbaa !5
  br label %for.cond

for.cond:                                         ; preds = %merge_pagelist.exit.thread, %while.body
  %p.0 = phi ptr [ %pIn.addr.0, %while.body ], [ %9, %merge_pagelist.exit.thread ]
  %i.0 = phi i32 [ 0, %while.body ], [ %inc, %merge_pagelist.exit.thread ]
  %cmp = icmp samesign ult i32 %i.0, 24
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  %idxprom = zext nneg i32 %i.0 to i64
  %arrayidx = getelementptr inbounds nuw [25 x ptr], ptr %a, i64 0, i64 %idxprom
  %1 = load ptr, ptr %arrayidx, align 8, !tbaa !13
  %cmp2 = icmp eq ptr %1, null
  br i1 %cmp2, label %for.end.thread, label %if.else

for.end.thread:                                   ; preds = %for.body
  %arrayidx.lcssa = phi ptr [ %arrayidx, %for.body ]
  %p.0.lcssa2 = phi ptr [ %p.0, %for.body ]
  store ptr %p.0.lcssa2, ptr %arrayidx.lcssa, align 8, !tbaa !13
  br label %if.end16

if.else:                                          ; preds = %for.body
  call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %result.i) #3
  %tobool135.i.not = icmp eq ptr %p.0, null
  br i1 %tobool135.i.not, label %merge_pagelist.exit.thread, label %while.body.i.preheader

while.body.i.preheader:                           ; preds = %if.else
  br label %while.body.i

while.body.i:                                     ; preds = %while.body.i.preheader, %if.end.i
  %pTail.038.i = phi ptr [ %pTail.1.i, %if.end.i ], [ %result.i, %while.body.i.preheader ]
  %pB.addr.037.i = phi ptr [ %pB.addr.1.i, %if.end.i ], [ %p.0, %while.body.i.preheader ]
  %pA.addr.036.i = phi ptr [ %pA.addr.1.i, %if.end.i ], [ %1, %while.body.i.preheader ]
  %2 = load i32, ptr %pA.addr.036.i, align 8, !tbaa !14
  %3 = load i32, ptr %pB.addr.037.i, align 8, !tbaa !14
  %cmp.i = icmp ult i32 %2, %3
  %pDirty.i = getelementptr inbounds nuw i8, ptr %pTail.038.i, i64 56
  br i1 %cmp.i, label %if.then.i, label %if.else.i

if.then.i:                                        ; preds = %while.body.i
  store ptr %pA.addr.036.i, ptr %pDirty.i, align 8, !tbaa !5
  %pDirty3.i = getelementptr inbounds nuw i8, ptr %pA.addr.036.i, i64 56
  %4 = load ptr, ptr %pDirty3.i, align 8, !tbaa !5
  %5 = freeze ptr %4
  br label %if.end.i

if.else.i:                                        ; preds = %while.body.i
  store ptr %pB.addr.037.i, ptr %pDirty.i, align 8, !tbaa !5
  %pDirty5.i = getelementptr inbounds nuw i8, ptr %pB.addr.037.i, i64 56
  %6 = load ptr, ptr %pDirty5.i, align 8, !tbaa !5
  br label %if.end.i

if.end.i:                                         ; preds = %if.else.i, %if.then.i
  %pA.addr.1.i = phi ptr [ %5, %if.then.i ], [ %pA.addr.036.i, %if.else.i ]
  %pB.addr.1.i = phi ptr [ %pB.addr.037.i, %if.then.i ], [ %6, %if.else.i ]
  %pTail.1.i = phi ptr [ %pA.addr.036.i, %if.then.i ], [ %pB.addr.037.i, %if.else.i ]
  %tobool.i = icmp ne ptr %pA.addr.1.i, null
  %tobool1.i = icmp ne ptr %pB.addr.1.i, null
  %7 = select i1 %tobool.i, i1 %tobool1.i, i1 false
  br i1 %7, label %while.body.i, label %merge_pagelist.exit, !llvm.loop !15

merge_pagelist.exit:                              ; preds = %if.end.i
  %pA.addr.1.i.lcssa = phi ptr [ %pA.addr.1.i, %if.end.i ]
  %pB.addr.1.i.lcssa = phi ptr [ %pB.addr.1.i, %if.end.i ]
  %pTail.1.i.lcssa = phi ptr [ %pTail.1.i, %if.end.i ]
  %tobool.i.lcssa = phi i1 [ %tobool.i, %if.end.i ]
  %spec.select = select i1 %tobool.i.lcssa, ptr %pA.addr.1.i.lcssa, ptr %pB.addr.1.i.lcssa
  br label %merge_pagelist.exit.thread

merge_pagelist.exit.thread:                       ; preds = %merge_pagelist.exit, %if.else
  %result.i.pn = phi ptr [ %pTail.1.i.lcssa, %merge_pagelist.exit ], [ %result.i, %if.else ]
  %8 = phi ptr [ %spec.select, %merge_pagelist.exit ], [ %1, %if.else ]
  %pDirty8.i106 = getelementptr inbounds nuw i8, ptr %result.i.pn, i64 56
  store ptr %8, ptr %pDirty8.i106, align 8, !tbaa !5
  %pDirty17.i = getelementptr inbounds nuw i8, ptr %result.i, i64 56
  %9 = load ptr, ptr %pDirty17.i, align 8, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %result.i) #3
  store ptr null, ptr %arrayidx, align 8, !tbaa !13
  %inc = add nuw nsw i32 %i.0, 1
  br label %for.cond, !llvm.loop !17

for.end:                                          ; preds = %for.cond
  %p.0.lcssa = phi ptr [ %p.0, %for.cond ]
  %i.0.lcssa = phi i32 [ %i.0, %for.cond ]
  %cmp9 = icmp eq i32 %i.0.lcssa, 24
  br i1 %cmp9, label %if.then10, label %if.end16

if.then10:                                        ; preds = %for.end
  %arrayidx12 = getelementptr inbounds nuw i8, ptr %a, i64 192
  %10 = load ptr, ptr %arrayidx12, align 8, !tbaa !13
  call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %result.i45) #3
  %tobool34.i46 = icmp ne ptr %10, null
  %tobool135.i47 = icmp ne ptr %p.0.lcssa, null
  %11 = and i1 %tobool135.i47, %tobool34.i46
  br i1 %11, label %while.body.i55.preheader, label %merge_pagelist.exit71

while.body.i55.preheader:                         ; preds = %if.then10
  br label %while.body.i55

while.body.i55:                                   ; preds = %while.body.i55.preheader, %if.end.i63
  %pTail.038.i56 = phi ptr [ %pTail.1.i66, %if.end.i63 ], [ %result.i45, %while.body.i55.preheader ]
  %pB.addr.037.i57 = phi ptr [ %pB.addr.1.i65, %if.end.i63 ], [ %p.0.lcssa, %while.body.i55.preheader ]
  %pA.addr.036.i58 = phi ptr [ %pA.addr.1.i64, %if.end.i63 ], [ %10, %while.body.i55.preheader ]
  %12 = load i32, ptr %pA.addr.036.i58, align 8, !tbaa !14
  %13 = load i32, ptr %pB.addr.037.i57, align 8, !tbaa !14
  %cmp.i59 = icmp ult i32 %12, %13
  %pDirty.i60 = getelementptr inbounds nuw i8, ptr %pTail.038.i56, i64 56
  br i1 %cmp.i59, label %if.then.i69, label %if.else.i61

if.then.i69:                                      ; preds = %while.body.i55
  store ptr %pA.addr.036.i58, ptr %pDirty.i60, align 8, !tbaa !5
  %pDirty3.i70 = getelementptr inbounds nuw i8, ptr %pA.addr.036.i58, i64 56
  %14 = load ptr, ptr %pDirty3.i70, align 8, !tbaa !5
  br label %if.end.i63

if.else.i61:                                      ; preds = %while.body.i55
  store ptr %pB.addr.037.i57, ptr %pDirty.i60, align 8, !tbaa !5
  %pDirty5.i62 = getelementptr inbounds nuw i8, ptr %pB.addr.037.i57, i64 56
  %15 = load ptr, ptr %pDirty5.i62, align 8, !tbaa !5
  br label %if.end.i63

if.end.i63:                                       ; preds = %if.else.i61, %if.then.i69
  %pA.addr.1.i64 = phi ptr [ %14, %if.then.i69 ], [ %pA.addr.036.i58, %if.else.i61 ]
  %pB.addr.1.i65 = phi ptr [ %pB.addr.037.i57, %if.then.i69 ], [ %15, %if.else.i61 ]
  %pTail.1.i66 = phi ptr [ %pA.addr.036.i58, %if.then.i69 ], [ %pB.addr.037.i57, %if.else.i61 ]
  %tobool.i67 = icmp ne ptr %pA.addr.1.i64, null
  %tobool1.i68 = icmp ne ptr %pB.addr.1.i65, null
  %16 = select i1 %tobool.i67, i1 %tobool1.i68, i1 false
  br i1 %16, label %while.body.i55, label %merge_pagelist.exit71.loopexit, !llvm.loop !15

merge_pagelist.exit71.loopexit:                   ; preds = %if.end.i63
  %pA.addr.1.i64.lcssa = phi ptr [ %pA.addr.1.i64, %if.end.i63 ]
  %pB.addr.1.i65.lcssa = phi ptr [ %pB.addr.1.i65, %if.end.i63 ]
  %pTail.1.i66.lcssa = phi ptr [ %pTail.1.i66, %if.end.i63 ]
  %tobool.i67.lcssa = phi i1 [ %tobool.i67, %if.end.i63 ]
  br label %merge_pagelist.exit71

merge_pagelist.exit71:                            ; preds = %merge_pagelist.exit71.loopexit, %if.then10
  %pA.addr.0.lcssa.i48 = phi ptr [ %10, %if.then10 ], [ %pA.addr.1.i64.lcssa, %merge_pagelist.exit71.loopexit ]
  %pTail.0.lcssa.i49 = phi ptr [ %result.i45, %if.then10 ], [ %pTail.1.i66.lcssa, %merge_pagelist.exit71.loopexit ]
  %tobool.lcssa.i50 = phi i1 [ %tobool34.i46, %if.then10 ], [ %tobool.i67.lcssa, %merge_pagelist.exit71.loopexit ]
  %tobool1.lcssa.i51 = phi ptr [ %p.0.lcssa, %if.then10 ], [ %pB.addr.1.i65.lcssa, %merge_pagelist.exit71.loopexit ]
  %pDirty8.i52 = getelementptr inbounds nuw i8, ptr %pTail.0.lcssa.i49, i64 56
  %pB.addr.0.lcssa.sink.i53 = select i1 %tobool.lcssa.i50, ptr %pA.addr.0.lcssa.i48, ptr %tobool1.lcssa.i51
  store ptr %pB.addr.0.lcssa.sink.i53, ptr %pDirty8.i52, align 8, !tbaa !5
  %pDirty17.i54 = getelementptr inbounds nuw i8, ptr %result.i45, i64 56
  %17 = load ptr, ptr %pDirty17.i54, align 8, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %result.i45) #3
  store ptr %17, ptr %arrayidx12, align 8, !tbaa !13
  br label %if.end16

if.end16:                                         ; preds = %merge_pagelist.exit71, %for.end, %for.end.thread
  br label %while.cond, !llvm.loop !18

while.end:                                        ; preds = %while.cond
  %18 = load ptr, ptr %a, align 16, !tbaa !13
  br label %for.cond18

for.cond18:                                       ; preds = %merge_pagelist.exit98, %while.end
  %p.1 = phi ptr [ %18, %while.end ], [ %26, %merge_pagelist.exit98 ]
  %i.1 = phi i32 [ 1, %while.end ], [ %inc25, %merge_pagelist.exit98 ]
  %cmp19 = icmp samesign ult i32 %i.1, 25
  br i1 %cmp19, label %for.body20, label %for.end26

for.body20:                                       ; preds = %for.cond18
  %idxprom21 = zext nneg i32 %i.1 to i64
  %arrayidx22 = getelementptr inbounds nuw [25 x ptr], ptr %a, i64 0, i64 %idxprom21
  %19 = load ptr, ptr %arrayidx22, align 8, !tbaa !13
  call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %result.i72) #3
  %tobool34.i73 = icmp ne ptr %p.1, null
  %tobool135.i74 = icmp ne ptr %19, null
  %20 = and i1 %tobool34.i73, %tobool135.i74
  br i1 %20, label %while.body.i82.preheader, label %merge_pagelist.exit98

while.body.i82.preheader:                         ; preds = %for.body20
  br label %while.body.i82

while.body.i82:                                   ; preds = %while.body.i82.preheader, %if.end.i90
  %pTail.038.i83 = phi ptr [ %pTail.1.i93, %if.end.i90 ], [ %result.i72, %while.body.i82.preheader ]
  %pB.addr.037.i84 = phi ptr [ %pB.addr.1.i92, %if.end.i90 ], [ %19, %while.body.i82.preheader ]
  %pA.addr.036.i85 = phi ptr [ %pA.addr.1.i91, %if.end.i90 ], [ %p.1, %while.body.i82.preheader ]
  %21 = load i32, ptr %pA.addr.036.i85, align 8, !tbaa !14
  %22 = load i32, ptr %pB.addr.037.i84, align 8, !tbaa !14
  %cmp.i86 = icmp ult i32 %21, %22
  %pDirty.i87 = getelementptr inbounds nuw i8, ptr %pTail.038.i83, i64 56
  br i1 %cmp.i86, label %if.then.i96, label %if.else.i88

if.then.i96:                                      ; preds = %while.body.i82
  store ptr %pA.addr.036.i85, ptr %pDirty.i87, align 8, !tbaa !5
  %pDirty3.i97 = getelementptr inbounds nuw i8, ptr %pA.addr.036.i85, i64 56
  %23 = load ptr, ptr %pDirty3.i97, align 8, !tbaa !5
  br label %if.end.i90

if.else.i88:                                      ; preds = %while.body.i82
  store ptr %pB.addr.037.i84, ptr %pDirty.i87, align 8, !tbaa !5
  %pDirty5.i89 = getelementptr inbounds nuw i8, ptr %pB.addr.037.i84, i64 56
  %24 = load ptr, ptr %pDirty5.i89, align 8, !tbaa !5
  br label %if.end.i90

if.end.i90:                                       ; preds = %if.else.i88, %if.then.i96
  %pA.addr.1.i91 = phi ptr [ %23, %if.then.i96 ], [ %pA.addr.036.i85, %if.else.i88 ]
  %pB.addr.1.i92 = phi ptr [ %pB.addr.037.i84, %if.then.i96 ], [ %24, %if.else.i88 ]
  %pTail.1.i93 = phi ptr [ %pA.addr.036.i85, %if.then.i96 ], [ %pB.addr.037.i84, %if.else.i88 ]
  %tobool.i94 = icmp ne ptr %pA.addr.1.i91, null
  %tobool1.i95 = icmp ne ptr %pB.addr.1.i92, null
  %25 = select i1 %tobool.i94, i1 %tobool1.i95, i1 false
  br i1 %25, label %while.body.i82, label %merge_pagelist.exit98.loopexit, !llvm.loop !15

merge_pagelist.exit98.loopexit:                   ; preds = %if.end.i90
  %pA.addr.1.i91.lcssa = phi ptr [ %pA.addr.1.i91, %if.end.i90 ]
  %pB.addr.1.i92.lcssa = phi ptr [ %pB.addr.1.i92, %if.end.i90 ]
  %pTail.1.i93.lcssa = phi ptr [ %pTail.1.i93, %if.end.i90 ]
  %tobool.i94.lcssa = phi i1 [ %tobool.i94, %if.end.i90 ]
  br label %merge_pagelist.exit98

merge_pagelist.exit98:                            ; preds = %merge_pagelist.exit98.loopexit, %for.body20
  %pA.addr.0.lcssa.i75 = phi ptr [ %p.1, %for.body20 ], [ %pA.addr.1.i91.lcssa, %merge_pagelist.exit98.loopexit ]
  %pTail.0.lcssa.i76 = phi ptr [ %result.i72, %for.body20 ], [ %pTail.1.i93.lcssa, %merge_pagelist.exit98.loopexit ]
  %tobool.lcssa.i77 = phi i1 [ %tobool34.i73, %for.body20 ], [ %tobool.i94.lcssa, %merge_pagelist.exit98.loopexit ]
  %tobool1.lcssa.i78 = phi ptr [ %19, %for.body20 ], [ %pB.addr.1.i92.lcssa, %merge_pagelist.exit98.loopexit ]
  %pDirty8.i79 = getelementptr inbounds nuw i8, ptr %pTail.0.lcssa.i76, i64 56
  %pB.addr.0.lcssa.sink.i80 = select i1 %tobool.lcssa.i77, ptr %pA.addr.0.lcssa.i75, ptr %tobool1.lcssa.i78
  store ptr %pB.addr.0.lcssa.sink.i80, ptr %pDirty8.i79, align 8, !tbaa !5
  %pDirty17.i81 = getelementptr inbounds nuw i8, ptr %result.i72, i64 56
  %26 = load ptr, ptr %pDirty17.i81, align 8, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %result.i72) #3
  %inc25 = add nuw nsw i32 %i.1, 1
  br label %for.cond18, !llvm.loop !19

for.end26:                                        ; preds = %for.cond18
  %p.1.lcssa = phi ptr [ %p.1, %for.cond18 ]
  call void @llvm.lifetime.end.p0(i64 200, ptr nonnull %a) #3
  ret ptr %p.1.lcssa
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1

attributes #0 = { noinline nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #3 = { nounwind }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 20.1.8 (https://github.com/llvm/llvm-project.git 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)"}
!5 = !{!6, !10, i64 56}
!6 = !{!"PgHdr", !7, i64 0, !10, i64 8, !10, i64 16, !10, i64 24, !10, i64 32, !10, i64 40, !8, i64 48, !12, i64 50, !10, i64 56, !10, i64 64, !7, i64 72}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!"p1 _ZTS5PgHdr", !11, i64 0}
!11 = !{!"any pointer", !8, i64 0}
!12 = !{!"short", !8, i64 0}
!13 = !{!10, !10, i64 0}
!14 = !{!6, !7, i64 0}
!15 = distinct !{!15, !16}
!16 = !{!"llvm.loop.mustprogress"}
!17 = distinct !{!17, !16}
!18 = distinct !{!18, !16}
!19 = distinct !{!19, !16}