我寫了下面LLVM優化器無法處理簡單的情況?
int main() {
int a, b;
scanf("%d", &b);
for (int i = 0 ; i < 1000 ; i++) {
a = 0;
if (b > 10)
a = 3;
}
return a;
}
所示的.cpp文件,然後我用-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;
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
}
任何人都可以告訴我爲什麼優化器無法分析更簡單的代碼嗎?
聽起來像是我的優化器bug – MikeMB
什麼版本是什麼平臺? – xaxxon
我不是裝配神,但是這對我來說很好(顏色很好)https://godbolt.org/g/qxf6jR - 我在網站上瀏覽了每一個版本的鏗鏘聲,並且無法重現它任何一位。 – xaxxon