LLVM optimizer cannot handle a simple case?

I wrote a .cpp file shown below

int main() { int a, b; scanf( "%d", &b ); for ( int i = 0 ; i < 1000 ; i++ ) { a = 0; if ( b > 10 ) a = 3; } return a; } 

then I compiled this code using clang with the -O3 option, the output .ll file is

 define i32 @main() #0 { entry: %b = alloca i32, align 4 %call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b) %0 = load i32* %b, align 4, !tbaa !1 %cmp1 = icmp sgt i32 %0, 10 %. = select i1 %cmp1, i32 3, i32 0 ret i32 %. } attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 

This conclusion is good. The LLVM optimizer stripped the meaningless forloop from the code, and then assigned three or zero to return the value directly.

Now I will try another case, for example

 int main() { int a, b; scanf( "%d", &b ); for ( int i = 0 ; i < 1000 ; i++ ) { a = 0; if ( true ) // I modified here only a = 3; } return a; } 

and the output file

 define i32 @main() #0 { entry: %b = alloca i32, align 4 %call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b) br label %for.cond for.cond: ; preds = %for.cond, %entry %a.0 = phi i32 [ 0, %entry ], [ 3, %for.cond ] %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ] %inc = add nsw i32 %i.0, 1 %exitcond = icmp eq i32 %inc, 1001 br i1 %exitcond, label %for.end, label %for.cond for.end: ; preds = %for.cond ret i32 %a.0 } attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 

Although this code is easier to parse (the branch is always taken), the LLVM optimizer does not skip meaningless forloop

If I were an optimizer, I would like to create this optimized code, for example

 define i32 @main() #0 { entry: %b = alloca i32, align 4 %call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b) ret i32 3 } 

Can someone tell me why the optimizer cannot parse simpler code?

+7
c ++ optimization llvm
source share
1 answer

I checked your code snippet with llvm 3.9 and it generates:

 define i32 @main() #0 { %1 = alloca i32, align 4 %2 = bitcast i32* %1 to i8* call void @llvm.lifetime.start(i64 4, i8* %2) #3 %3 = call i32 (i8*, ...) @scanf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32* nonnull %1) call void @llvm.lifetime.end(i64 4, i8* %2) #3 ret i32 3 } 

As MikeMB hinted, I think this is a bug in the optimizer, which is now fixed. What was your version of llvm ?

+5
source share

All Articles