I am studying the Transform/Scalar/LICM.cpp pass, and wrote a simple test program to validate. void testLICM(void){ int i,N=100; int data; for(i=0;i<N;i++){ data = 1; printf("i: %d\n",i); } printf("data: %d\n", data); } I expect the "data=1" will be moved out of loop (either hoist or sink). However, to my surprise, that statement remains within the loop after -licm. This is the licm produced IR: define void @testLICM() nounwind { entry: %i = alloca i32 ; <i32*> [#uses=3] %N = alloca i32 ; <i32*> [#uses=2] %data = alloca i32 ; <i32*> [#uses=2] %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !0), !dbg !7 call void @llvm.dbg.declare(metadata !{i32* %N}, metadata !8), !dbg !7 call void @llvm.dbg.declare(metadata !{i32* %data}, metadata !9), !dbg !7 store i32 100, i32* %N, align 4, !dbg !10 store i32 0, i32* %i, align 4, !dbg !11 %0 = load i32* %N, align 4, !dbg !11 ; <i32> [#uses=1] %i.promoted = load i32* %i ; <i32> [#uses=1] br label %bb1, !dbg !11 bb: ; preds = %bb1 store i32 1, i32* %data, align 4, !dbg !12 %1 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 %i.tmp.0) nounwind, !dbg !13 ; <i32> [#uses=0] %2 = add nsw i32 %i.tmp.0, 1, !dbg !11 ; <i32> [#uses=1] br label %bb1, !dbg !11 bb1: ; preds = %bb, %entry %i.tmp.0 = phi i32 [ %i.promoted, %entry ], [ %2, %bb ] ; <i32> [#uses=4] %3 = icmp slt i32 %i.tmp.0, %0, !dbg !11 ; <i1> [#uses=1] br i1 %3, label %bb, label %bb2, !dbg !11 bb2: ; preds = %bb1 store i32 %i.tmp.0, i32* %i %4 = load i32* %data, align 4, !dbg !14 ; <i32> [#uses=1] %5 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 %4) nounwind, !dbg !14 ; <i32> [#uses=0] br label %return, !dbg !15 return: ; preds = %bb2 ret void, !dbg !15 } I ran the program with licm only option through opt: opt -licm < test.bc > test.licm.bc Is this a bug, or am I running it in a wrong way? Thank you Chuck -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100814/587f9899/attachment.html>
I don't think licm looks at loads/stores to allocas -- these are usually handled by mem2reg which happens much earlier (if you run your example with -mem2reg you'll see it already deleted the store). In fact, licm sinks the stores by converting them to stores to allocas first and running mem2reg on that. If you change your example to void testLICM(int* restrict p) { int i,N=100; for(i=0;i<N;i++){ *p = 1; printf("i: %d\n",i); } printf("data: %d\n", *p); } and run opt with -mem2reg -loop-rotate -licm you can see the store being sunk. Eugene On Sun, Aug 15, 2010 at 3:47 AM, Chuck Zhao <czhao at eecg.toronto.edu> wrote:> I am studying the Transform/Scalar/LICM.cpp pass, and wrote a simple test > program to validate. > > void testLICM(void){ > int i,N=100; > int data; > for(i=0;i<N;i++){ > data = 1; > printf("i: %d\n",i); > } > printf("data: %d\n", data); > } > > > I expect the "data=1" will be moved out of loop (either hoist or sink). > However, to my surprise, that statement remains within the loop after -licm. > > This is the licm produced IR: > > define void @testLICM() nounwind { > entry: > %i = alloca i32 ; <i32*> [#uses=3] > %N = alloca i32 ; <i32*> [#uses=2] > %data = alloca i32 ; <i32*> [#uses=2] > %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] > call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !0), !dbg !7 > call void @llvm.dbg.declare(metadata !{i32* %N}, metadata !8), !dbg !7 > call void @llvm.dbg.declare(metadata !{i32* %data}, metadata !9), !dbg !7 > store i32 100, i32* %N, align 4, !dbg !10 > store i32 0, i32* %i, align 4, !dbg !11 > %0 = load i32* %N, align 4, !dbg !11 ; <i32> [#uses=1] > %i.promoted = load i32* %i ; <i32> [#uses=1] > br label %bb1, !dbg !11 > > bb: ; preds = %bb1 > store i32 1, i32* %data, align 4, !dbg !12 > %1 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([7 x > i8]* @.str, i32 0, i32 0), i32 %i.tmp.0) nounwind, !dbg !13 ; <i32> > [#uses=0] > %2 = add nsw i32 %i.tmp.0, 1, !dbg !11 ; <i32> [#uses=1] > br label %bb1, !dbg !11 > > bb1: ; preds = %bb, %entry > %i.tmp.0 = phi i32 [ %i.promoted, %entry ], [ %2, %bb ] ; <i32> [#uses=4] > %3 = icmp slt i32 %i.tmp.0, %0, !dbg !11 ; <i1> [#uses=1] > br i1 %3, label %bb, label %bb2, !dbg !11 > > bb2: ; preds = %bb1 > store i32 %i.tmp.0, i32* %i > %4 = load i32* %data, align 4, !dbg !14 ; <i32> [#uses=1] > %5 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([10 > x i8]* @.str1, i32 0, i32 0), i32 %4) nounwind, !dbg !14 ; <i32> [#uses=0] > br label %return, !dbg !15 > > return: ; preds = %bb2 > ret void, !dbg !15 > } > > > I ran the program with licm only option through opt: > opt -licm < test.bc > test.licm.bc > > > Is this a bug, or am I running it in a wrong way? > > Thank you > > Chuck > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >
Thank you very much, Eugene, This explains it nicely. Chuck On 8/15/2010 10:36 AM, Eugene Toder wrote:> I don't think licm looks at loads/stores to allocas -- these are > usually handled by mem2reg which happens much earlier (if you run your > example with -mem2reg you'll see it already deleted the store). In > fact, licm sinks the stores by converting them to stores to allocas > first and running mem2reg on that. > > If you change your example to > > void testLICM(int* restrict p) > { > int i,N=100; > for(i=0;i<N;i++){ > *p = 1; > printf("i: %d\n",i); > } > printf("data: %d\n", *p); > } > > and run opt with -mem2reg -loop-rotate -licm you can see the store being sunk. > > Eugene > > On Sun, Aug 15, 2010 at 3:47 AM, Chuck Zhao<czhao at eecg.toronto.edu> wrote: >> I am studying the Transform/Scalar/LICM.cpp pass, and wrote a simple test >> program to validate. >> >> void testLICM(void){ >> int i,N=100; >> int data; >> for(i=0;i<N;i++){ >> data = 1; >> printf("i: %d\n",i); >> } >> printf("data: %d\n", data); >> } >> >> >> I expect the "data=1" will be moved out of loop (either hoist or sink). >> However, to my surprise, that statement remains within the loop after -licm. >> >> This is the licm produced IR: >> >> define void @testLICM() nounwind { >> entry: >> %i = alloca i32 ;<i32*> [#uses=3] >> %N = alloca i32 ;<i32*> [#uses=2] >> %data = alloca i32 ;<i32*> [#uses=2] >> %"alloca point" = bitcast i32 0 to i32 ;<i32> [#uses=0] >> call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !0), !dbg !7 >> call void @llvm.dbg.declare(metadata !{i32* %N}, metadata !8), !dbg !7 >> call void @llvm.dbg.declare(metadata !{i32* %data}, metadata !9), !dbg !7 >> store i32 100, i32* %N, align 4, !dbg !10 >> store i32 0, i32* %i, align 4, !dbg !11 >> %0 = load i32* %N, align 4, !dbg !11 ;<i32> [#uses=1] >> %i.promoted = load i32* %i ;<i32> [#uses=1] >> br label %bb1, !dbg !11 >> >> bb: ; preds = %bb1 >> store i32 1, i32* %data, align 4, !dbg !12 >> %1 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([7 x >> i8]* @.str, i32 0, i32 0), i32 %i.tmp.0) nounwind, !dbg !13 ;<i32> >> [#uses=0] >> %2 = add nsw i32 %i.tmp.0, 1, !dbg !11 ;<i32> [#uses=1] >> br label %bb1, !dbg !11 >> >> bb1: ; preds = %bb, %entry >> %i.tmp.0 = phi i32 [ %i.promoted, %entry ], [ %2, %bb ] ;<i32> [#uses=4] >> %3 = icmp slt i32 %i.tmp.0, %0, !dbg !11 ;<i1> [#uses=1] >> br i1 %3, label %bb, label %bb2, !dbg !11 >> >> bb2: ; preds = %bb1 >> store i32 %i.tmp.0, i32* %i >> %4 = load i32* %data, align 4, !dbg !14 ;<i32> [#uses=1] >> %5 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([10 >> x i8]* @.str1, i32 0, i32 0), i32 %4) nounwind, !dbg !14 ;<i32> [#uses=0] >> br label %return, !dbg !15 >> >> return: ; preds = %bb2 >> ret void, !dbg !15 >> } >> >> >> I ran the program with licm only option through opt: >> opt -licm< test.bc> test.licm.bc >> >> >> Is this a bug, or am I running it in a wrong way? >> >> Thank you >> >> Chuck >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >>
Seemingly Similar Threads
- [LLVMdev] a LICM bug (in LLVM-2.7)?
- [LLVMdev] Fwd: Updating PHI for Instruction Domination?
- [LLVMdev] Updating PHI for Instruction Domination?
- [LLVMdev] Updating PHI for Instruction Domination?
- [LLVMdev] RFC: Indexing of structs vs arrays in getelementpointer