-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[InstCombine] Preserve profile branch weights when folding logical booleans #161293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[InstCombine] Preserve profile branch weights when folding logical booleans #161293
Conversation
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-ir Author: Alan Zhao (alanzhao1) ChangesLogical booleans in LLVM are represented by select statements - e.g. the statement
is represented as
When LLVM folds two of the same logical booleans into a logical boolean and a bitwise boolean (e.g. Tracking issue: #147390 Patch is 25.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161293.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 783f8f6d2478c..041a4ce112275 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -1722,16 +1722,19 @@ class IRBuilderBase {
return Insert(BinOp, Name);
}
- Value *CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name = "") {
+ Value *CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name = "",
+ Instruction *MDFrom = nullptr) {
assert(Cond2->getType()->isIntOrIntVectorTy(1));
return CreateSelect(Cond1, Cond2,
- ConstantInt::getNullValue(Cond2->getType()), Name);
+ ConstantInt::getNullValue(Cond2->getType()), Name,
+ MDFrom);
}
- Value *CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name = "") {
+ Value *CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name = "",
+ Instruction *MDFrom = nullptr) {
assert(Cond2->getType()->isIntOrIntVectorTy(1));
return CreateSelect(Cond1, ConstantInt::getAllOnesValue(Cond2->getType()),
- Cond2, Name);
+ Cond2, Name, MDFrom);
}
Value *CreateLogicalOp(Instruction::BinaryOps Opc, Value *Cond1, Value *Cond2,
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index b6b3a95f35c76..459c7e02254fe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -50,6 +50,7 @@
using namespace llvm;
using namespace PatternMatch;
+extern cl::opt<bool> ProfcheckDisableMetadataFixes;
/// Replace a select operand based on an equality comparison with the identity
/// constant of a binop.
@@ -3369,7 +3370,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
impliesPoisonOrCond(FalseVal, B, /*Expected=*/false)) {
// (A || B) || C --> A || (B | C)
return replaceInstUsesWith(
- SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal)));
+ SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal), "",
+ ProfcheckDisableMetadataFixes
+ ? nullptr
+ : cast<SelectInst>(CondVal)));
}
// (A && B) || (C && B) --> (A || C) && B
@@ -3411,7 +3415,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
impliesPoisonOrCond(TrueVal, B, /*Expected=*/true)) {
// (A && B) && C --> A && (B & C)
return replaceInstUsesWith(
- SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal)));
+ SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal), "",
+ ProfcheckDisableMetadataFixes
+ ? nullptr
+ : cast<SelectInst>(CondVal)));
}
// (A || B) && (C || B) --> (A && C) || B
diff --git a/llvm/test/Transforms/InstCombine/select-safe-bool-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-bool-transforms.ll
index 9de9150f62ed4..4ac61f65862b1 100644
--- a/llvm/test/Transforms/InstCombine/select-safe-bool-transforms.ll
+++ b/llvm/test/Transforms/InstCombine/select-safe-bool-transforms.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; TODO: All of these should be optimized to less than or equal to a single
@@ -7,502 +7,512 @@
; --- (A op B) op' A / (B op A) op' A ---
; (A land B) land A
-define i1 @land_land_left1(i1 %A, i1 %B) {
+define i1 @land_land_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_land_left1(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1:![0-9]+]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %A, i1 %B, i1 false
- %res = select i1 %c, i1 %A, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
-define i1 @land_land_left2(i1 %A, i1 %B) {
+define i1 @land_land_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_land_left2(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false, !prof [[PROF2:![0-9]+]]
; CHECK-NEXT: ret i1 [[RES]]
;
- %c = select i1 %B, i1 %A, i1 false
- %res = select i1 %c, i1 %A, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
; (A land B) band A
-define i1 @land_band_left1(i1 %A, i1 %B) {
+define i1 @land_band_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_band_left1(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %A, i1 %B, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
%res = and i1 %c, %A
ret i1 %res
}
-define i1 @land_band_left2(i1 %A, i1 %B) {
+define i1 @land_band_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_band_left2(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
+; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false, !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %B, i1 %A, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
%res = and i1 %c, %A
ret i1 %res
}
; (A land B) lor A
-define i1 @land_lor_left1(i1 %A, i1 %B) {
+define i1 @land_lor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_lor_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 %B, i1 false
- %res = select i1 %c, i1 true, i1 %A
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
-define i1 @land_lor_left2(i1 %A, i1 %B) {
+define i1 @land_lor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_lor_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 %A, i1 false
- %res = select i1 %c, i1 true, i1 %A
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
; (A land B) bor A
-define i1 @land_bor_left1(i1 %A, i1 %B) {
+define i1 @land_bor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_bor_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 %B, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
%res = or i1 %c, %A
ret i1 %res
}
-define i1 @land_bor_left2(i1 %A, i1 %B) {
+define i1 @land_bor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_bor_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 %A, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
%res = or i1 %c, %A
ret i1 %res
}
; (A band B) land A
-define i1 @band_land_left1(i1 %A, i1 %B) {
+define i1 @band_land_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_land_left1(
; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = and i1 %A, %B
- %res = select i1 %c, i1 %A, i1 false
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
-define i1 @band_land_left2(i1 %A, i1 %B) {
+define i1 @band_land_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_land_left2(
; CHECK-NEXT: [[C:%.*]] = and i1 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = and i1 %B, %A
- %res = select i1 %c, i1 %A, i1 false
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
; (A band B) lor A
-define i1 @band_lor_left1(i1 %A, i1 %B) {
+define i1 @band_lor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_lor_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = and i1 %A, %B
- %res = select i1 %c, i1 true, i1 %A
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
-define i1 @band_lor_left2(i1 %A, i1 %B) {
+define i1 @band_lor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_lor_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = and i1 %B, %A
- %res = select i1 %c, i1 true, i1 %A
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
; (A lor B) land A
-define i1 @lor_land_left1(i1 %A, i1 %B) {
+define i1 @lor_land_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_land_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 true, i1 %B
- %res = select i1 %c, i1 %A, i1 false
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
-define i1 @lor_land_left2(i1 %A, i1 %B) {
+define i1 @lor_land_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_land_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 true, i1 %A
- %res = select i1 %c, i1 %A, i1 false
+ %c = select i1 %B, i1 true, i1 %A, !prof !3
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
; (A lor B) band A
-define i1 @lor_band_left1(i1 %A, i1 %B) {
+define i1 @lor_band_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_band_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 true, i1 %B
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
%res = and i1 %c, %A
ret i1 %res
}
-define i1 @lor_band_left2(i1 %A, i1 %B) {
+define i1 @lor_band_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_band_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 true, i1 %A
+ %c = select i1 %B, i1 true, i1 %A, !prof !3
%res = and i1 %c, %A
ret i1 %res
}
; (A lor B) lor A
-define i1 @lor_lor_left1(i1 %A, i1 %B) {
+define i1 @lor_lor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_lor_left1(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
+; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]], !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %A, i1 true, i1 %B
- %res = select i1 %c, i1 true, i1 %A
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
-define i1 @lor_lor_left2(i1 %A, i1 %B) {
+define i1 @lor_lor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_lor_left2(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]], !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[RES]]
;
- %c = select i1 %B, i1 true, i1 %A
- %res = select i1 %c, i1 true, i1 %A
+ %c = select i1 %B, i1 true, i1 %A, !prof !3
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
; (A lor B) bor A
-define i1 @lor_bor_left1(i1 %A, i1 %B) {
+define i1 @lor_bor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_bor_left1(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
+; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]], !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %A, i1 true, i1 %B
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
%res = or i1 %c, %A
ret i1 %res
}
-define i1 @lor_bor_left2(i1 %A, i1 %B) {
+define i1 @lor_bor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_bor_left2(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
+; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]], !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %B, i1 true, i1 %A
+ %c = select i1 %B, i1 true, i1 %A, !prof !3
%res = or i1 %c, %A
ret i1 %res
}
; (A bor B) land A
-define i1 @bor_land_left1(i1 %A, i1 %B) {
+define i1 @bor_land_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @bor_land_left1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = or i1 %A, %B
- %res = select i1 %c, i1 %A, i1 false
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
-define i1 @bor_land_left2(i1 %A, i1 %B) {
+define i1 @bor_land_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @bor_land_left2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = or i1 %B, %A
- %res = select i1 %c, i1 %A, i1 false
+ %res = select i1 %c, i1 %A, i1 false, !prof !2
ret i1 %res
}
; (A bor B) lor A
-define i1 @bor_lor_left1(i1 %A, i1 %B) {
+define i1 @bor_lor_left1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @bor_lor_left1(
; CHECK-NEXT: [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = or i1 %A, %B
- %res = select i1 %c, i1 true, i1 %A
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
-define i1 @bor_lor_left2(i1 %A, i1 %B) {
+define i1 @bor_lor_left2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @bor_lor_left2(
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = or i1 %B, %A
- %res = select i1 %c, i1 true, i1 %A
+ %res = select i1 %c, i1 true, i1 %A, !prof !2
ret i1 %res
}
; --- A op (A op' B) / A op (B op' A) ---
; A land (A land B)
-define i1 @land_land_right1(i1 %A, i1 %B) {
+define i1 @land_land_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_land_right1(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[RES]]
;
- %c = select i1 %A, i1 %B, i1 false
- %res = select i1 %A, i1 %c, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
-define i1 @land_land_right2(i1 %A, i1 %B) {
+define i1 @land_land_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_land_right2(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[RES]]
;
- %c = select i1 %B, i1 %A, i1 false
- %res = select i1 %A, i1 %c, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
; A band (A land B)
-define i1 @land_band_right1(i1 %A, i1 %B) {
+define i1 @land_band_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_band_right1(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %A, i1 %B, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
%res = and i1 %A, %c
ret i1 %res
}
-define i1 @land_band_right2(i1 %A, i1 %B) {
+define i1 @land_band_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_band_right2(
-; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
+; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false, !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[C]]
;
- %c = select i1 %B, i1 %A, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
%res = and i1 %A, %c
ret i1 %res
}
; A lor (A land B)
-define i1 @land_lor_right1(i1 %A, i1 %B) {
+define i1 @land_lor_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_lor_right1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 %B, i1 false
- %res = select i1 %A, i1 true, i1 %c
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
+ %res = select i1 %A, i1 true, i1 %c, !prof !1
ret i1 %res
}
-define i1 @land_lor_right2(i1 %A, i1 %B) {
+define i1 @land_lor_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_lor_right2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 %A, i1 false
- %res = select i1 %A, i1 true, i1 %c
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
+ %res = select i1 %A, i1 true, i1 %c, !prof !1
ret i1 %res
}
-define <2 x i1> @land_lor_right1_vec(<2 x i1> %A, <2 x i1> %B) {
+define <2 x i1> @land_lor_right1_vec(<2 x i1> %A, <2 x i1> %B) !prof !0 {
; CHECK-LABEL: @land_lor_right1_vec(
; CHECK-NEXT: ret <2 x i1> [[A:%.*]]
;
- %c = select <2 x i1> %A, <2 x i1> %B, <2 x i1> zeroinitializer
- %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c
+ %c = select <2 x i1> %A, <2 x i1> %B, <2 x i1> zeroinitializer, !prof !1
+ %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c, !prof !1
ret <2 x i1> %res
}
-define <2 x i1> @land_lor_right2_vec(<2 x i1> %A, <2 x i1> %B) {
+define <2 x i1> @land_lor_right2_vec(<2 x i1> %A, <2 x i1> %B) !prof !0 {
; CHECK-LABEL: @land_lor_right2_vec(
; CHECK-NEXT: ret <2 x i1> [[A:%.*]]
;
- %c = select <2 x i1> %B, <2 x i1> %A, <2 x i1> zeroinitializer
- %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c
+ %c = select <2 x i1> %B, <2 x i1> %A, <2 x i1> zeroinitializer, !prof !3
+ %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c, !prof !1
ret <2 x i1> %res
}
; A bor (A land B)
-define i1 @land_bor_right1(i1 %A, i1 %B) {
+define i1 @land_bor_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_bor_right1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 %B, i1 false
+ %c = select i1 %A, i1 %B, i1 false, !prof !1
%res = or i1 %A, %c
ret i1 %res
}
-define i1 @land_bor_right2(i1 %A, i1 %B) {
+define i1 @land_bor_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @land_bor_right2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 %A, i1 false
+ %c = select i1 %B, i1 %A, i1 false, !prof !3
%res = or i1 %A, %c
ret i1 %res
}
; A land (A band B)
-define i1 @band_land_right1(i1 %A, i1 %B) {
+define i1 @band_land_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_land_right1(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[RES]]
;
%c = and i1 %A, %B
- %res = select i1 %A, i1 %c, i1 false
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
-define i1 @band_land_right2(i1 %A, i1 %B) {
+define i1 @band_land_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_land_right2(
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[RES]]
;
%c = and i1 %B, %A
- %res = select i1 %A, i1 %c, i1 false
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
; A lor (A band B)
-define i1 @band_lor_right1(i1 %A, i1 %B) {
+define i1 @band_lor_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_lor_right1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = and i1 %A, %B
- %res = select i1 %A, i1 true, i1 %c
+ %res = select i1 %A, i1 true, i1 %c, !prof !1
ret i1 %res
}
-define i1 @band_lor_right2(i1 %A, i1 %B) {
+define i1 @band_lor_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @band_lor_right2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
%c = and i1 %B, %A
- %res = select i1 %A, i1 true, i1 %c
+ %res = select i1 %A, i1 true, i1 %c, !prof !1
ret i1 %res
}
; A land (A lor B)
-define i1 @lor_land_right1(i1 %A, i1 %B) {
+define i1 @lor_land_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_land_right1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 true, i1 %B
- %res = select i1 %A, i1 %c, i1 false
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
-define i1 @lor_land_right2(i1 %A, i1 %B) {
+define i1 @lor_land_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_land_right2(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %B, i1 true, i1 %A
- %res = select i1 %A, i1 %c, i1 false
+ %c = select i1 %B, i1 true, i1 %A, !prof !3
+ %res = select i1 %A, i1 %c, i1 false, !prof !1
ret i1 %res
}
; A band (A lor B)
-define i1 @lor_band_right1(i1 %A, i1 %B) {
+define i1 @lor_band_right1(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_band_right1(
; CHECK-NEXT: ret i1 [[A:%.*]]
;
- %c = select i1 %A, i1 true, i1 %B
+ %c = select i1 %A, i1 true, i1 %B, !prof !1
%res = and i1 %A, %c
ret i1 %res
}
-define i1 @lor_band_right2(i1 %A, i1 %B) {
+define i1 @lor_band_right2(i1 %A, i1 %B) !prof !0 {
; CHECK-LABEL: @lor_band_right2(
; CHECK-N...
[truncated]
|
Nit: in your commit message, is it (A && B && C -> A && (B && C)), correct? (B && C not B & C) |
It is supposed to be one ampersand ( llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp Lines 3412 to 3414 in 18136c2
|
llvm/test/Transforms/InstCombine/select-safe-bool-transforms.ll
Outdated
Show resolved
Hide resolved
…oleans Logical booleans in LLVM are represented by select statements - e.g. the statement ``` A && B ``` is represented as ``` select i1 %A, i1 %B, i1 false ``` When LLVM folds two of the same logical booleans into a logical boolean and a bitwise boolean (e.g. `A && B && C` -> `A && (B & C)`), the first logical boolean is a select statement that retains the original condition from the first logical boolean of the original statement. This means that the new select statement has the branch weights as the original select statement. Tracking issue: llvm#147390
3456186
to
b87743c
Compare
Logical booleans in LLVM are represented by select statements - e.g. the statement
is represented as
When LLVM folds two of the same logical booleans into a logical boolean and a bitwise boolean (e.g.
A && B && C
->A && (B & C)
), the first logical boolean is a select statement that retains the original condition from the first logical boolean of the original statement. This means that the new select statement has the branch weights as the original select statement.Tracking issue: #147390