Skip to content

Commit 01d8e1c

Browse files
committed
[ValueTracking] Handle non-canonical operand order in isImpliedCondICmps
We don't always have canonical order here, so do it manually. Closes #85575
1 parent 31775e1 commit 01d8e1c

File tree

5 files changed

+46
-60
lines changed

5 files changed

+46
-60
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8471,26 +8471,12 @@ isImpliedCondOperands(CmpInst::Predicate Pred, const Value *ALHS,
84718471
}
84728472
}
84738473

8474-
/// Return true if the operands of two compares (expanded as "L0 pred L1" and
8475-
/// "R0 pred R1") match. IsSwappedOps is true when the operands match, but are
8476-
/// swapped.
8477-
static bool areMatchingOperands(const Value *L0, const Value *L1, const Value *R0,
8478-
const Value *R1, bool &AreSwappedOps) {
8479-
bool AreMatchingOps = (L0 == R0 && L1 == R1);
8480-
AreSwappedOps = (L0 == R1 && L1 == R0);
8481-
return AreMatchingOps || AreSwappedOps;
8482-
}
8483-
84848474
/// Return true if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is true.
84858475
/// Return false if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is false.
84868476
/// Otherwise, return std::nullopt if we can't infer anything.
84878477
static std::optional<bool>
84888478
isImpliedCondMatchingOperands(CmpInst::Predicate LPred,
8489-
CmpInst::Predicate RPred, bool AreSwappedOps) {
8490-
// Canonicalize the predicate as if the operands were not commuted.
8491-
if (AreSwappedOps)
8492-
RPred = ICmpInst::getSwappedPredicate(RPred);
8493-
8479+
CmpInst::Predicate RPred) {
84948480
if (CmpInst::isImpliedTrueByMatchingCmp(LPred, RPred))
84958481
return true;
84968482
if (CmpInst::isImpliedFalseByMatchingCmp(LPred, RPred))
@@ -8532,39 +8518,42 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
85328518
CmpInst::Predicate LPred =
85338519
LHSIsTrue ? LHS->getPredicate() : LHS->getInversePredicate();
85348520

8521+
// We can have non-canonical operands, so try to normalize any common operand
8522+
// to L0/R0.
8523+
if (L0 == R1) {
8524+
std::swap(R0, R1);
8525+
RPred = ICmpInst::getSwappedPredicate(RPred);
8526+
}
8527+
if (R0 == L1) {
8528+
std::swap(L0, L1);
8529+
LPred = ICmpInst::getSwappedPredicate(LPred);
8530+
}
8531+
if (L1 == R1) {
8532+
// If we have L0 == R0 and L1 == R1, then make L1/R1 the constants.
8533+
if (L0 != R0 || match(L0, m_ImmConstant())) {
8534+
std::swap(L0, L1);
8535+
LPred = ICmpInst::getSwappedPredicate(LPred);
8536+
std::swap(R0, R1);
8537+
RPred = ICmpInst::getSwappedPredicate(RPred);
8538+
}
8539+
}
8540+
85358541
// Can we infer anything when the 0-operands match and the 1-operands are
85368542
// constants (not necessarily matching)?
85378543
const APInt *LC, *RC;
85388544
if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)))
85398545
return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
85408546

85418547
// Can we infer anything when the two compares have matching operands?
8542-
bool AreSwappedOps;
8543-
if (areMatchingOperands(L0, L1, R0, R1, AreSwappedOps))
8544-
return isImpliedCondMatchingOperands(LPred, RPred, AreSwappedOps);
8548+
if (L0 == R0 && L1 == R1)
8549+
return isImpliedCondMatchingOperands(LPred, RPred);
85458550

85468551
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
8547-
if (ICmpInst::isUnsigned(LPred) && ICmpInst::isUnsigned(RPred)) {
8548-
if (L0 == R1) {
8549-
std::swap(R0, R1);
8550-
RPred = ICmpInst::getSwappedPredicate(RPred);
8551-
}
8552-
if (L1 == R0) {
8553-
std::swap(L0, L1);
8554-
LPred = ICmpInst::getSwappedPredicate(LPred);
8555-
}
8556-
if (L1 == R1) {
8557-
std::swap(L0, L1);
8558-
LPred = ICmpInst::getSwappedPredicate(LPred);
8559-
std::swap(R0, R1);
8560-
RPred = ICmpInst::getSwappedPredicate(RPred);
8561-
}
8562-
if (L0 == R0 &&
8563-
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
8564-
(RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) &&
8565-
match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
8566-
return LPred == RPred;
8567-
}
8552+
if (L0 == R0 &&
8553+
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
8554+
(RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) &&
8555+
match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
8556+
return LPred == RPred;
85688557

85698558
if (LPred == RPred)
85708559
return isImpliedCondOperands(LPred, L0, L1, R0, R1, DL, Depth);

llvm/test/Transforms/InstCombine/assume.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ define i1 @nonnull5(ptr %a) {
386386
define i32 @assumption_conflicts_with_known_bits(i32 %a, i32 %b) {
387387
; CHECK-LABEL: @assumption_conflicts_with_known_bits(
388388
; CHECK-NEXT: store i1 true, ptr poison, align 1
389-
; CHECK-NEXT: ret i32 1
389+
; CHECK-NEXT: ret i32 poison
390390
;
391391
%and1 = and i32 %b, 3
392392
%B1 = lshr i32 %and1, %and1

llvm/test/Transforms/InstCombine/icmp-select-implies-common-op.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
define i1 @sgt_3_impliesF_eq_2(i8 %x, i8 %y) {
55
; CHECK-LABEL: @sgt_3_impliesF_eq_2(
6-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 3
7-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
8-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[SEL]], [[X]]
9-
; CHECK-NEXT: ret i1 [[CMP2]]
6+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 4
7+
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[SEL:%.*]], [[X]]
8+
; CHECK-NEXT: [[CMP3:%.*]] = select i1 [[CMP]], i1 [[CMP2]], i1 false
9+
; CHECK-NEXT: ret i1 [[CMP3]]
1010
;
1111
%cmp = icmp sgt i8 %x, 3
1212
%sel = select i1 %cmp, i8 2, i8 %y
@@ -16,10 +16,10 @@ define i1 @sgt_3_impliesF_eq_2(i8 %x, i8 %y) {
1616

1717
define i1 @sgt_3_impliesT_sgt_2(i8 %x, i8 %y) {
1818
; CHECK-LABEL: @sgt_3_impliesT_sgt_2(
19-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 3
20-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
21-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[SEL]], [[X]]
22-
; CHECK-NEXT: ret i1 [[CMP2]]
19+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 4
20+
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[SEL:%.*]], [[X]]
21+
; CHECK-NEXT: [[CMP3:%.*]] = select i1 [[CMP]], i1 [[CMP2]], i1 false
22+
; CHECK-NEXT: ret i1 [[CMP3]]
2323
;
2424
%cmp = icmp sgt i8 %x, 3
2525
%sel = select i1 %cmp, i8 2, i8 %y
@@ -68,10 +68,10 @@ define i1 @ult_x_impliesT_eq_umax_todo(i8 %x, i8 %y, i8 %z) {
6868

6969
define i1 @ult_1_impliesF_eq_1(i8 %x, i8 %y) {
7070
; CHECK-LABEL: @ult_1_impliesF_eq_1(
71-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SEL:%.*]], 0
72-
; CHECK-NEXT: [[X:%.*]] = select i1 [[CMP]], i8 1, i8 [[Y:%.*]]
73-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[X]], [[SEL]]
74-
; CHECK-NEXT: ret i1 [[CMP2]]
71+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[SEL:%.*]], 0
72+
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[X:%.*]], [[SEL]]
73+
; CHECK-NEXT: [[CMP3:%.*]] = select i1 [[CMP]], i1 [[CMP2]], i1 false
74+
; CHECK-NEXT: ret i1 [[CMP3]]
7575
;
7676
%cmp = icmp ult i8 %x, 1
7777
%sel = select i1 %cmp, i8 1, i8 %y

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,10 +2925,8 @@ define i8 @select_replacement_loop3(i32 noundef %x) {
29252925

29262926
define i16 @select_replacement_loop4(i16 noundef %p_12) {
29272927
; CHECK-LABEL: @select_replacement_loop4(
2928-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i16 [[P_12:%.*]], 2
2929-
; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12]], 1
2930-
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[CMP1]], i16 [[AND1]], i16 0
2931-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[AND2]], [[P_12]]
2928+
; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12:%.*]], 1
2929+
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i16 [[P_12]], 2
29322930
; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP2]], i16 [[AND1]], i16 0
29332931
; CHECK-NEXT: ret i16 [[AND3]]
29342932
;

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,12 +1751,11 @@ define void @ashr_out_of_range_1(ptr %A) {
17511751
; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4
17521752
; CHECK-NEXT: [[L_FROZEN:%.*]] = freeze i177 [[L]]
17531753
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -1
1754-
; CHECK-NEXT: [[B:%.*]] = select i1 [[TMP1]], i177 0, i177 [[L_FROZEN]]
1755-
; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[B]] to i64
1754+
; CHECK-NEXT: [[TMP6:%.*]] = trunc i177 [[L_FROZEN]] to i64
1755+
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP6]]
17561756
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]]
17571757
; CHECK-NEXT: [[G11:%.*]] = getelementptr i8, ptr [[TMP3]], i64 -24
1758-
; CHECK-NEXT: [[C17:%.*]] = icmp sgt i177 [[B]], [[L_FROZEN]]
1759-
; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[C17]] to i64
1758+
; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP1]] to i64
17601759
; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP4]]
17611760
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i177 [[L_FROZEN]], -1
17621761
; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP5]], i177 0, i177 [[L_FROZEN]]

0 commit comments

Comments
 (0)