gpt4 book ai didi

c++ - LLVM 优化器不能处理简单的情况?

转载 作者:可可西里 更新时间:2023-11-01 18:36:43 25 4
gpt4 key购买 nike

我写了一个如下所示的.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;
}

然后我用-O3选项通过clang编译这段代码,输出的.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;
scanf( "%d", &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, 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" }

尽管这段代码更容易分析(总是采用分支),但 LLVM 优化器不会去除无意义的 forloop

如果我是优化器,我想生成这样的优化代码

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
}

谁能告诉我为什么优化器不能分析更简单的代码?

最佳答案

我已经使用 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++ - LLVM 优化器不能处理简单的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36976980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com