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}