[英]What's the instruction for '&&' in LLVM IR?
我想寫一個 LLVM 通行證來減少 LLVM IR 中的&&
,但我在 IR 中找不到它的具體說明。 例如,
#include <iostream>
int main(){
bool a = true;
bool b = false;
bool c = a && b;
return 0;
}
我得到了IR,
define dso_local i32 @main() #4 {
%1 = alloca i32, align 4
%2 = alloca i8, align 1
%3 = alloca i8, align 1
%4 = alloca i8, align 1
store i32 0, i32* %1, align 4
store i8 1, i8* %2, align 1
store i8 0, i8* %3, align 1
%5 = load i8, i8* %2, align 1
%6 = trunc i8 %5 to i1
br i1 %6, label %7, label %10
7: ; preds = %0
%8 = load i8, i8* %3, align 1
%9 = trunc i8 %8 to i1
br label %10
10: ; preds = %7, %0
%11 = phi i1 [ false, %0 ], [ %9, %7 ]
%12 = zext i1 %11 to i8
store i8 %12, i8* %4, align 1
ret i32 0
}
但我試過這個,
#include <iostream>
int main(){
int a = 10;
int b = 10;
int c;
c = a && b;
return 0;
}
我明白了
define dso_local i32 @main() #4 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 10, i32* %2, align 4
store i32 10, i32* %3, align 4
%5 = load i32, i32* %2, align 4
%6 = icmp ne i32 %5, 0
br i1 %6, label %7, label %10
7: ; preds = %0
%8 = load i32, i32* %3, align 4
%9 = icmp ne i32 %8, 0
br label %10
10: ; preds = %7, %0
%11 = phi i1 [ false, %0 ], [ %9, %7 ]
%12 = zext i1 %11 to i32
store i32 %12, i32* %4, align 4
ret i32 0
}
我在 ubuntu 中使用 LLVM 10。 我將不勝感激任何答案或建議。
沒有專門對應於&&
運算符的 LLVM 指令。 根據表達式和優化設置,它可以並且將以不同的方式進行翻譯。
當您啟用優化時,操作數沒有副作用(並且評估成本不高)並且無法優化整個表達式, clang
通常會將兩個操作數都轉換為i1
並對它們應用邏輯and
運算符。
當優化被禁用或操作數有副作用時,通常會使用分支指令進行翻譯。 您發布的兩個示例就是這種情況。
注意expr1 && expr2
在語義上等價於expr1? expr2: false
expr1? expr2: false
並且您通常會為兩者獲得相同的 LLVM 代碼。
如果你對治療expr1? expr2: false
expr1? expr2: false
和其他等效代碼(例如使用if
語句)與&&
相同,您可以嘗試檢測它們創建的分支模式。 如果您需要您的通行證在優化后也適用,您還必須至少檢測轉換為 i1 and
ing 的模式。
如果您只希望您的轉換適用於&&
而沒有別的,您根本無法在 LLVM 級別進行。 您需要在 Clang 級別進行 AST 轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.