Skip to content

Commit de59d22

Browse files
committed
[InstCombine] Support logical ops in foldAndOrOfICmpEqZeroAndICmp()
If the and/or is logical and one of the operands only occurs on the RHS, we need to freeze it: https://alive2.llvm.org/ce/z/vuMuE_
1 parent 004a70a commit de59d22

File tree

2 files changed

+22
-19
lines changed

2 files changed

+22
-19
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,8 +2584,9 @@ Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
25842584

25852585
// (icmp eq X, 0) | (icmp ult Other, X) -> (icmp ule Other, X-1)
25862586
// (icmp ne X, 0) & (icmp uge Other, X) -> (icmp ugt Other, X-1)
2587-
Value *foldAndOrOfICmpEqZeroAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
2588-
IRBuilderBase &Builder) {
2587+
static Value *foldAndOrOfICmpEqZeroAndICmp(ICmpInst *LHS, ICmpInst *RHS,
2588+
bool IsAnd, bool IsLogical,
2589+
IRBuilderBase &Builder) {
25892590
ICmpInst::Predicate LPred =
25902591
IsAnd ? LHS->getInversePredicate() : LHS->getPredicate();
25912592
ICmpInst::Predicate RPred =
@@ -2604,6 +2605,8 @@ Value *foldAndOrOfICmpEqZeroAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
26042605
else
26052606
return nullptr;
26062607

2608+
if (IsLogical)
2609+
Other = Builder.CreateFreeze(Other);
26072610
return Builder.CreateICmp(
26082611
IsAnd ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_UGE,
26092612
Builder.CreateAdd(LHS0, Constant::getAllOnesValue(LHS0->getType())),
@@ -2652,14 +2655,14 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
26522655
if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, IsAnd, IsLogical, Builder))
26532656
return V;
26542657

2655-
// TODO: One of these directions is fine with logical and/or, the other could
2656-
// be supported by inserting freeze.
2657-
if (!IsLogical) {
2658-
if (Value *V = foldAndOrOfICmpEqZeroAndICmp(LHS, RHS, IsAnd, Builder))
2659-
return V;
2660-
if (Value *V = foldAndOrOfICmpEqZeroAndICmp(RHS, LHS, IsAnd, Builder))
2661-
return V;
2662-
}
2658+
if (Value *V =
2659+
foldAndOrOfICmpEqZeroAndICmp(LHS, RHS, IsAnd, IsLogical, Builder))
2660+
return V;
2661+
// We can treat logical like bitwise here, because both operands are used on
2662+
// the LHS, and as such poison from both will propagate.
2663+
if (Value *V = foldAndOrOfICmpEqZeroAndICmp(RHS, LHS, IsAnd,
2664+
/*IsLogical*/ false, Builder))
2665+
return V;
26632666

26642667
// TODO: Verify whether this is safe for logical and/or.
26652668
if (!IsLogical) {

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,9 +2172,9 @@ define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
21722172

21732173
define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
21742174
; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2175-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[B:%.*]], 0
2176-
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[A:%.*]], [[B]]
2177-
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2175+
; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2176+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2177+
; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], [[TMP1]]
21782178
; CHECK-NEXT: ret i1 [[TMP3]]
21792179
;
21802180
%1 = icmp eq i64 %b, 0
@@ -2306,9 +2306,9 @@ define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(i64 %a, i64 %b) {
23062306

23072307
define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(i64 %a, i64 %b) {
23082308
; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(
2309-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2310-
; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i64 [[B]], [[A:%.*]]
2311-
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 [[TMP2]], i1 false
2309+
; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2310+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2311+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
23122312
; CHECK-NEXT: ret i1 [[TMP3]]
23132313
;
23142314
%1 = icmp ne i64 %b, 0
@@ -2418,9 +2418,9 @@ define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(i64 %a, i64 %b, i64 %c) {
24182418

24192419
define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(i64 %a, i64 %b) {
24202420
; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_logical(
2421-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2422-
; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2423-
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 [[TMP2]], i1 false
2421+
; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2422+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2423+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
24242424
; CHECK-NEXT: ret i1 [[TMP3]]
24252425
;
24262426
%1 = icmp ne i64 %b, 0

0 commit comments

Comments
 (0)