我写了一个如下所示的.cpp文件
int main() { int a,b; scanf( "%d",&b ); for ( int i = 0 ; i < 1000 ; i++ ) { a = 0; if ( b > 10 ) a = 3; } return a; }
然后我通过clang -O3选项编译这段代码,输出.ll文件是
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" }
这个输出很好. LLVM优化器从代码中剥离了无意义的forloop,然后分配了三个或零直接返回值.
现在我尝试另一种情况
int main() { int a,&b ); for ( int i = 0 ; i < 1000 ; i++ ) { a = 0; if ( true ) // I modified here only a = 3; } return a; }
define i32 @main() #0 { entry: %b = alloca i32,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,[ %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" }
即使这个代码更容易分析(总是采用分支),LLVM优化器也不会剥离无意义的forloop
define i32 @main() #0 { entry: %b = alloca i32,i32* %b) ret i32 3 }
任何人都可以告诉我为什么优化器无法分析更简单的代码?
解决方法
我用llvm 3.9测试了你的代码片段并生成:
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 }
正如MikeMB所暗示的,我猜这是优化器中的一个错误,现在已经修复了.你的llvm版本是什么?