Hi Everyone,
I need some help in understanding why the IndVarSimplify
step is performing a seemingly invalid optimization only when it is dealing with constant propagated values of the this
pointer.
The following are the IRs generated before and after the IndVarSimplify
step.
- Without constant propagation turned on ie.
ptr %this
is used.
Before:
define linkonce_odr dso_local void @jumbledName(ptr nonnull align 32 dereferenceable(97) %this, ptr nonnull align 2 dereferenceable(16) %taps) unnamed_addr addrspace(1) #0 comdat align 2 !dbg !6131 { entry: tail call addrspace(1) void @llvm.dbg.value(metadata ptr %this, metadata !6133, metadata !DIExpression()), !dbg !6136 tail call addrspace(1) void @llvm.dbg.value(metadata ptr %taps, metadata !6135, metadata !DIExpression()), !dbg !6136 %varName= getelementptr inbounds %"className.1", ptr %this, i32 0, i32 0 call addrspace(1) void @llvm.memset.p0.i64(ptr align 32 %varName, i8 0, i64 32, i1 false), !dbg !6137 %varName2 = getelementptr inbounds %"className.1", ptr %this, i32 0, i32 1 %arrayinit.begin2 = getelementptr inbounds [4 x i16], ptr %varName2, i32 0, i32 0, !dbg !6138 %call = call signext addrspace(1) i16 @callToSomething() #28, !dbg !6139 store i16 %call, ptr %arrayinit.begin2, align 2, !dbg !6138, !tbaa !6120 %arrayinit.start = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 1, !dbg !6138 %arrayinit.end = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 4, !dbg !6138 br label %arrayinit.body, !dbg !6138 arrayinit.body: ; preds = %arrayinit.body, %entry %arrayinit.cur = phi ptr [ %arrayinit.start, %entry ], [ %arrayinit.next, %arrayinit.body ], !dbg !6138 store i16 0, ptr %arrayinit.cur, align 2, !dbg !6138, !tbaa !6120 %arrayinit.next = getelementptr inbounds i16, ptr %arrayinit.cur, i32 1, !dbg !6138 %arrayinit.done = icmp eq ptr %arrayinit.next, %arrayinit.end, !dbg !6138 br i1 %arrayinit.done, label %arrayinit.end3, label %arrayinit.body, !dbg !6138
After:
define linkonce_odr dso_local void @jumbledName(ptr nonnull align 32 dereferenceable(97) %this, ptr nonnull align 2 dereferenceable(16) %taps) unnamed_addr addrspace(1) #0 comdat align 2 !dbg !6137 { entry: tail call addrspace(1) void @llvm.dbg.value(metadata ptr %this, metadata !6139, metadata !DIExpression()), !dbg !6142 tail call addrspace(1) void @llvm.dbg.value(metadata ptr %taps, metadata !6141, metadata !DIExpression()), !dbg !6142 %varName = getelementptr inbounds %"className.1", ptr %this, i32 0, i32 0 call addrspace(1) void @llvm.memset.p0.i64(ptr align 32 %varName, i8 0, i64 32, i1 false), !dbg !6143 %varName2 = getelementptr inbounds %"className.1", ptr %this, i32 0, i32 1 %arrayinit.begin2 = getelementptr inbounds [4 x i16], ptr %varName2 , i32 0, i32 0, !dbg !6144 %call = call signext addrspace(1) i16 @callToSomething() #27, !dbg !6145 store i16 %call, ptr %arrayinit.begin2, align 2, !dbg !6144, !tbaa !6126 %arrayinit.start = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 1, !dbg !6144 %arrayinit.end = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 4, !dbg !6144 br label %arrayinit.body, !dbg !6144 arrayinit.body: ; preds = %arrayinit.body, %entry %arrayinit.cur = phi ptr [ %arrayinit.start, %entry ], [ %arrayinit.next, %arrayinit.body ], !dbg !6144 store i16 0, ptr %arrayinit.cur, align 2, !dbg !6144, !tbaa !6126 %arrayinit.next = getelementptr inbounds i16, ptr %arrayinit.cur, i32 1, !dbg !6144 %arrayinit.done = icmp eq ptr %arrayinit.next, %arrayinit.end, !dbg !6144 br i1 %arrayinit.done, label %arrayinit.end3, label %arrayinit.body, !dbg !6144
- With the constant propagation turned on. ie. %this is replaced with
@i15
Before:
define linkonce_odr dso_local void @funcName(ptr nonnull align 32 dereferenceable(97) %this, ptr nonnull align 2 dereferenceable(24) %taps) unnamed_addr addrspace(1) #0 comdat align 2 !dbg !6250 { entry: tail call addrspace(1) void @llvm.dbg.value(metadata ptr @i15, metadata !6252, metadata !DIExpression()), !dbg !6255 tail call addrspace(1) void @llvm.dbg.value(metadata ptr %taps, metadata !6254, metadata !DIExpression()), !dbg !6255 %var1 = getelementptr inbounds %"class.1", ptr @i15, i32 0, i32 0 call addrspace(1) void @llvm.memset.p0.i64(ptr align 32 %var1, i8 0, i64 32, i1 false), !dbg !6256 %var2 = getelementptr inbounds %"class.1", ptr @i15, i32 0, i32 1 %arrayinit.begin2 = getelementptr inbounds [4 x i16], ptr %var2, i32 0, i32 0, !dbg !6257 %call = call signext addrspace(1) i16 @f1() #28, !dbg !6258 store i16 %call, ptr %arrayinit.begin2, align 2, !dbg !6257, !tbaa !6120 %arrayinit.start = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 1, !dbg !6257 %arrayinit.end = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 4, !dbg !6257 br label %arrayinit.body, !dbg !6257 arrayinit.body: ; preds = %arrayinit.body, %entry %arrayinit.cur = phi ptr [ %arrayinit.start, %entry ], [ %arrayinit.next, %arrayinit.body ], !dbg !6257 store i16 0, ptr %arrayinit.cur, align 2, !dbg !6257, !tbaa !6120 %arrayinit.next = getelementptr inbounds i16, ptr %arrayinit.cur, i32 1, !dbg !6257 %arrayinit.done = icmp eq ptr %arrayinit.next, %arrayinit.end, !dbg !6257 br i1 %arrayinit.done, label %arrayinit.end3, label %arrayinit.body, !dbg !6257
After:
define linkonce_odr dso_local void @funcName(ptr nonnull align 32 dereferenceable(97) %this, ptr nonnull align 2 dereferenceable(24) %taps) unnamed_addr addrspace(1) #0 comdat align 2 !dbg !6256 { entry: tail call addrspace(1) void @llvm.dbg.value(metadata ptr @i15, metadata !6258, metadata !DIExpression()), !dbg !6261 tail call addrspace(1) void @llvm.dbg.value(metadata ptr %taps, metadata !6260, metadata !DIExpression()), !dbg !6261 %var1 = getelementptr inbounds %"class.1", ptr @i15, i32 0, i32 0 call addrspace(1) void @llvm.memset.p0.i64(ptr align 32 %var1 , i8 0, i64 32, i1 false), !dbg !6262 %var2 = getelementptr inbounds %"class.1", ptr @i15, i32 0, i32 1 %arrayinit.begin2 = getelementptr inbounds [4 x i16], ptr %var2 , i32 0, i32 0, !dbg !6263 %call = call signext addrspace(1) i16 @f1() #27, !dbg !6264 store i16 %call, ptr %arrayinit.begin2, align 2, !dbg !6263, !tbaa !6126 %arrayinit.start = getelementptr inbounds i16, ptr %arrayinit.begin2, i32 1, !dbg !6263 br label %arrayinit.body, !dbg !6263 arrayinit.body: ; preds = %arrayinit.body, %entry %arrayinit.cur = phi ptr [ %arrayinit.start, %entry ], [ %arrayinit.next, %arrayinit.body ], !dbg !6263 store i16 0, ptr %arrayinit.cur, align 2, !dbg !6263, !tbaa !6126 %arrayinit.next = getelementptr inbounds i16, ptr %arrayinit.cur, i32 1, !dbg !6263 br label %arrayinit.body, !dbg !6263
I have confirmed the constant propagation step of replacing this with @i15 is correct. The function is called just once and the objects are unique.
I see that the IndVarSimplify
step ends up creating an infinite loop in this case which is incorrect.
This is with LLVM 18.0.
Any advice on how to debug this further or notes on if this is a known LLVM bug would be helpful.
Thanks in advance!