-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[ValueTracking] Improve isImpliedCondICmps
to handle binops
#69840
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-amdgpu @llvm/pr-subscribers-llvm-analysis Author: Yingwei Zheng (dtcxzyw) ChangesThis PR improves Full diff: https://github.com/llvm/llvm-project/pull/69840.diff 4 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 8824a05e3aa6ccd..e1fae66946e0e56 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8231,14 +8231,11 @@ isImpliedCondMatchingOperands(CmpInst::Predicate LPred,
return std::nullopt;
}
-/// Return true if "icmp LPred X, LC" implies "icmp RPred X, RC" is true.
-/// Return false if "icmp LPred X, LC" implies "icmp RPred X, RC" is false.
+/// Return true if `X in DomCR` implies `X in CR` is true.
+/// Return false if `X in DomCR` implies `X in CR` is false.
/// Otherwise, return std::nullopt if we can't infer anything.
-static std::optional<bool> isImpliedCondCommonOperandWithConstants(
- CmpInst::Predicate LPred, const APInt &LC, CmpInst::Predicate RPred,
- const APInt &RC) {
- ConstantRange DomCR = ConstantRange::makeExactICmpRegion(LPred, LC);
- ConstantRange CR = ConstantRange::makeExactICmpRegion(RPred, RC);
+static std::optional<bool> isImpliedCondWithRange(const ConstantRange &DomCR,
+ const ConstantRange &CR) {
ConstantRange Intersection = DomCR.intersectWith(CR);
ConstantRange Difference = DomCR.difference(CR);
if (Intersection.isEmptySet())
@@ -8248,6 +8245,17 @@ static std::optional<bool> isImpliedCondCommonOperandWithConstants(
return std::nullopt;
}
+/// Return true if "icmp LPred X, LC" implies "icmp RPred X, RC" is true.
+/// Return false if "icmp LPred X, LC" implies "icmp RPred X, RC" is false.
+/// Otherwise, return std::nullopt if we can't infer anything.
+static std::optional<bool> isImpliedCondCommonOperandWithConstants(
+ CmpInst::Predicate LPred, const APInt &LC, CmpInst::Predicate RPred,
+ const APInt &RC) {
+ ConstantRange DomCR = ConstantRange::makeExactICmpRegion(LPred, LC);
+ ConstantRange CR = ConstantRange::makeExactICmpRegion(RPred, RC);
+ return isImpliedCondWithRange(DomCR, CR);
+}
+
/// Return true if LHS implies RHS (expanded to its components as "R0 RPred R1")
/// is true. Return false if LHS implies RHS is false. Otherwise, return
/// std::nullopt if we can't infer anything.
@@ -8298,6 +8306,32 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
return LPred == RPred;
}
+ // handle R0 = L0 binop V
+ Value *R0Op1 = nullptr;
+ if (match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)) &&
+ match(R0, m_c_BinOp(m_Specific(L0), m_Value(R0Op1)))) {
+ ConstantRange LHSRange = ConstantRange::makeExactICmpRegion(LPred, *LC);
+ ConstantRange CR = ConstantRange::makeExactICmpRegion(RPred, *RC);
+ // TODO: use contextual information from SimplifyQuery
+ ConstantRange RHSRange = computeConstantRange(
+ R0Op1, ICmpInst::isSigned(RPred), /*UseInstrInfo*/ true, /*AC*/ nullptr,
+ /*CtxI*/ nullptr, /*DT*/ nullptr, Depth);
+ auto BO = cast<BinaryOperator>(R0);
+ if (BO->getOperand(0) != L0)
+ std::swap(LHSRange, RHSRange);
+ unsigned NoWrapKind = 0;
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) {
+ if (OBO->hasNoUnsignedWrap())
+ NoWrapKind |= OverflowingBinaryOperator::NoUnsignedWrap;
+ if (OBO->hasNoSignedWrap())
+ NoWrapKind |= OverflowingBinaryOperator::NoSignedWrap;
+ }
+ ConstantRange Range =
+ LHSRange.overflowingBinaryOp(BO->getOpcode(), RHSRange, NoWrapKind);
+ if (auto Res = isImpliedCondWithRange(Range, CR))
+ return Res;
+ }
+
if (LPred == RPred)
return isImpliedCondOperands(LPred, L0, L1, R0, R1, DL, Depth);
diff --git a/llvm/test/Analysis/ValueTracking/implied-icmp-binop.ll b/llvm/test/Analysis/ValueTracking/implied-icmp-binop.ll
new file mode 100644
index 000000000000000..882c38f329bd884
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/implied-icmp-binop.ll
@@ -0,0 +1,193 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+; Tests from PR68799
+
+define i1 @f_and(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_and(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp = icmp ne i32 %x, 0
+ %0 = or i32 %x, %y
+ %and14 = icmp eq i32 %0, 0
+ %and1115 = and i1 %cmp, %and14
+ ret i1 %and1115
+}
+
+define i1 @f_or(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_or(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %cmp.not = icmp eq i32 %x, 0
+ %0 = or i32 %x, %y
+ %or14 = icmp ne i32 %0, 0
+ %or1115 = or i1 %cmp.not, %or14
+ ret i1 %or1115
+}
+
+; Tests for more binops
+
+define i1 @f_add(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_add(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %yr = and i32 %y, 7
+ %cmp = icmp ult i32 %x, 8
+ %0 = add i32 %yr, %x
+ %cmp2 = icmp ugt i32 %0, 16
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+define i1 @f_add_nsw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_add_nsw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %yr = and i32 %y, 2147483647
+ %cmp = icmp sgt i32 %x, 5
+ %0 = add nsw i32 %yr, %x
+ %cmp2 = icmp slt i32 %0, 5
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+define i1 @f_add_nuw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_add_nuw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp = icmp ugt i32 %x, 1
+ %0 = add nuw i32 %x, %y
+ %cmp2 = icmp eq i32 %0, 1
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+define i1 @f_sub_nsw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_sub_nsw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 5
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %yr = and i32 %y, 2147483647
+ %cmp = icmp slt i32 %x, 5
+ %0 = sub nsw i32 %x, %yr
+ %cmp2 = icmp slt i32 %0, 5
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+define i1 @f_sub_nuw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_sub_nuw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp = icmp ult i32 %x, 5
+ %0 = sub nuw i32 %x, %y
+ %cmp2 = icmp eq i32 %0, 6
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+; Negative tests
+
+; non-constant range
+define i1 @f_add_nofold1(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @f_add_nofold1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[YR:%.*]] = and i32 [[Y]], 7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Z]]
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[YR]], [[X]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[TMP0]], 16
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[CMP2]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+entry:
+ %yr = and i32 %y, 7
+ %cmp = icmp ult i32 %x, %z
+ %0 = add i32 %yr, %x
+ %cmp2 = icmp ugt i32 %0, 16
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+define i1 @f_add_nofold2(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i1 @f_add_nofold2(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[YR:%.*]] = and i32 [[Y]], 7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], 8
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[YR]], [[X]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[TMP0]], [[Z]]
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[CMP2]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+entry:
+ %yr = and i32 %y, 7
+ %cmp = icmp ult i32 %x, 8
+ %0 = add i32 %yr, %x
+ %cmp2 = icmp ugt i32 %0, %z
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+; narrower range
+define i1 @f_add_nofold3(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_add_nofold3(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[YR:%.*]] = and i32 [[Y]], 7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], 8
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[YR]], [[X]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[TMP0]], 10
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[CMP2]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+entry:
+ %yr = and i32 %y, 7
+ %cmp = icmp ult i32 %x, 8
+ %0 = add i32 %yr, %x
+ %cmp2 = icmp ugt i32 %0, 10
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
+
+; sub is not commutative
+define i1 @f_sub_nsw_nofold(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @f_sub_nsw_nofold(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[YR:%.*]] = and i32 [[Y]], 2147483647
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 5
+; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i32 [[YR]], [[X]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[TMP0]], 5
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[CMP2]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+entry:
+ %yr = and i32 %y, 2147483647
+ %cmp = icmp slt i32 %x, 5
+ %0 = sub nsw i32 %yr, %x
+ %cmp2 = icmp slt i32 %0, 5
+ %and = and i1 %cmp, %cmp2
+ ret i1 %and
+}
diff --git a/llvm/test/Transforms/InstCombine/icmp-or.ll b/llvm/test/Transforms/InstCombine/icmp-or.ll
index 922845c1e7e2d82..a96341f31132943 100644
--- a/llvm/test/Transforms/InstCombine/icmp-or.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-or.ll
@@ -430,13 +430,8 @@ define i1 @icmp_or_xor_2_ne_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
; CHECK-LABEL: @icmp_or_xor_2_3_fail(
-; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X1:%.*]], [[Y1:%.*]]
-; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]]
-; CHECK-NEXT: [[OR:%.*]] = or i64 [[XOR]], [[XOR1]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 0
-; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[XOR]], 0
-; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP]], [[CMP_1]]
-; CHECK-NEXT: ret i1 [[OR1]]
+; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[X1:%.*]], [[Y1:%.*]]
+; CHECK-NEXT: ret i1 [[CMP_1]]
;
%xor = xor i64 %x1, %y1
%xor1 = xor i64 %x2, %y2
@@ -451,13 +446,8 @@ define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
define i1 @icmp_or_xor_2_4_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
; CHECK-LABEL: @icmp_or_xor_2_4_fail(
-; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X1:%.*]], [[Y1:%.*]]
-; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]]
-; CHECK-NEXT: [[OR:%.*]] = or i64 [[XOR]], [[XOR1]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 0
-; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[XOR1]], 0
-; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP]], [[CMP_1]]
-; CHECK-NEXT: ret i1 [[OR1]]
+; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[X2:%.*]], [[Y2:%.*]]
+; CHECK-NEXT: ret i1 [[CMP_1]]
;
%xor = xor i64 %x1, %y1
%xor1 = xor i64 %x2, %y2
diff --git a/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll b/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
index 82fcca07a00ac66..27ecc5686066cf1 100644
--- a/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
@@ -250,10 +250,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_256_239_gap_in_mask_fail(i3
define i1 @icmp_power2_and_icmp_shifted_mask_8_112_mask_to_left_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_112_mask_to_left_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 112
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 112
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 112
@@ -265,10 +262,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_112_mask_to_left_fail(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_112_mask_to_left_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_112_mask_to_left_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 112
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 112
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 112
@@ -281,10 +275,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_112_mask_to_left_fail(i32
define i1 @icmp_power2_and_icmp_shifted_mask_8_56_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_56_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 56
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 56
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 56
@@ -296,10 +287,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_56_mask_overlap_fail(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_56_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_56_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 56
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 56
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 56
@@ -312,10 +300,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_56_mask_overlap_fail(i32
define i1 @icmp_power2_and_icmp_shifted_mask_8_24_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_24_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 24
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 24
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 24
@@ -327,10 +312,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_24_mask_overlap_fail(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_24_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_24_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 24
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 24
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 24
@@ -343,10 +325,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_24_mask_overlap_fail(i32
define i1 @icmp_power2_and_icmp_shifted_mask_8_12_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_12_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 12
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 12
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 12
@@ -358,10 +337,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_12_mask_overlap_fail(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_12_mask_overlap_fail(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_12_mask_overlap_fail(
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 12
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 12
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
-; CHECK-NEXT: ret i1 [[T4]]
+; CHECK-NEXT: ret i1 [[T1]]
;
%t1 = icmp ult i32 %x, 8
%t2 = and i32 %x, 12
|
I will update the failed tests soon. |
02dca88
to
374533a
Compare
Ping. |
374533a
to
a872293
Compare
Ping. |
Ping. |
This is a specific instance of the general "optimize using constant range at use" problem, and I'm not convinced that extending isImpliedCond() in this direction makes sense. I'm not sure what the best way to approach this is yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs update to main, also last comment questions approach
This PR improves
isImpliedCondICmps
to handle the patternR0 = L0 binop V
.Alive2: https://alive2.llvm.org/ce/z/B9nc5d
Fixes #68799.
Fixes #69038.