2016-05-02 25 views
7

我寫了下面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 
} 

任何人都可以告訴我爲什麼優化器無法分析更簡單的代碼嗎?

+0

聽起來像是我的優化器bug – MikeMB

+0

什麼版本是什麼平臺? – xaxxon

+0

我不是裝配神,但是這對我來說很好(顏色很好)https://godbolt.org/g/qxf6jR - 我在網站上瀏覽了每一個版本的鏗鏘聲,並且無法重現它任何一位。 – xaxxon

回答

5

我測試過您的代碼段與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版本是什麼?

+0

https://godbolt.org/g/qxf6jR - 顏色編碼對於像我這樣的人來說明顯是明顯的 – xaxxon

+0

3.4和3.8,它們都有相同的結果。根據您的測試,我認爲這個bug在3.9中得到修復,但我沒有更新我的LLVM。感謝您的測試:) – hwliu