c – LLVM优化器无法处理简单的情况?

前端之家收集整理的这篇文章主要介绍了c – LLVM优化器无法处理简单的情况?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我写了一个如下所示的.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版本是什么?

猜你在找的C&C++相关文章