From 56ea579010002dfe882e5163512c372e9b29a03b Mon Sep 17 00:00:00 2001 From: Mikhail Gudim Date: Thu, 21 Dec 2023 11:36:46 -0500 Subject: [PATCH] Revert "[InstCombine] Extend `foldICmpBinOp` to `add`-like `or`. (#71396)" This reverts commit 8773c9be3d9868288f1f46957945d50ff58e4e91. --- .../InstCombine/InstCombineCompares.cpp | 62 +++++----- llvm/test/Transforms/InstCombine/icmp.ll | 117 ++++-------------- 2 files changed, 53 insertions(+), 126 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 0ad87eeb4c91a..289976718e52f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4624,35 +4624,27 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, } bool NoOp0WrapProblem = false, NoOp1WrapProblem = false; - bool Op0HasNUW = false, Op1HasNUW = false; - bool Op0HasNSW = false, Op1HasNSW = false; + if (BO0 && isa(BO0)) + NoOp0WrapProblem = + ICmpInst::isEquality(Pred) || + (CmpInst::isUnsigned(Pred) && BO0->hasNoUnsignedWrap()) || + (CmpInst::isSigned(Pred) && BO0->hasNoSignedWrap()); + if (BO1 && isa(BO1)) + NoOp1WrapProblem = + ICmpInst::isEquality(Pred) || + (CmpInst::isUnsigned(Pred) && BO1->hasNoUnsignedWrap()) || + (CmpInst::isSigned(Pred) && BO1->hasNoSignedWrap()); + // Analyze the case when either Op0 or Op1 is an add instruction. // Op0 = A + B (or A and B are null); Op1 = C + D (or C and D are null). - auto hasNoWrapProblem = [](const BinaryOperator &BO, CmpInst::Predicate Pred, - bool &HasNSW, bool &HasNUW) -> bool { - if (isa(BO)) { - HasNUW = BO.hasNoUnsignedWrap(); - HasNSW = BO.hasNoSignedWrap(); - return ICmpInst::isEquality(Pred) || - (CmpInst::isUnsigned(Pred) && HasNUW) || - (CmpInst::isSigned(Pred) && HasNSW); - } else if (BO.getOpcode() == Instruction::Or) { - HasNUW = true; - HasNSW = true; - return true; - } else { - return false; - } - }; Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr; - - if (BO0) { - match(BO0, m_AddLike(m_Value(A), m_Value(B))); - NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW); + if (BO0 && BO0->getOpcode() == Instruction::Add) { + A = BO0->getOperand(0); + B = BO0->getOperand(1); } - if (BO1) { - match(BO1, m_AddLike(m_Value(C), m_Value(D))); - NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW); + if (BO1 && BO1->getOpcode() == Instruction::Add) { + C = BO1->getOperand(0); + D = BO1->getOperand(1); } // icmp (A+B), A -> icmp B, 0 for equalities or if there is no overflow. @@ -4772,15 +4764,17 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, APInt AP2Abs = AP2->abs(); if (AP1Abs.uge(AP2Abs)) { APInt Diff = *AP1 - *AP2; + bool HasNUW = BO0->hasNoUnsignedWrap() && Diff.ule(*AP1); + bool HasNSW = BO0->hasNoSignedWrap(); Constant *C3 = Constant::getIntegerValue(BO0->getType(), Diff); - Value *NewAdd = Builder.CreateAdd( - A, C3, "", Op0HasNUW && Diff.ule(*AP1), Op0HasNSW); + Value *NewAdd = Builder.CreateAdd(A, C3, "", HasNUW, HasNSW); return new ICmpInst(Pred, NewAdd, C); } else { APInt Diff = *AP2 - *AP1; + bool HasNUW = BO1->hasNoUnsignedWrap() && Diff.ule(*AP2); + bool HasNSW = BO1->hasNoSignedWrap(); Constant *C3 = Constant::getIntegerValue(BO0->getType(), Diff); - Value *NewAdd = Builder.CreateAdd( - C, C3, "", Op1HasNUW && Diff.ule(*AP1), Op1HasNSW); + Value *NewAdd = Builder.CreateAdd(C, C3, "", HasNUW, HasNSW); return new ICmpInst(Pred, A, NewAdd); } } @@ -4874,14 +4868,16 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, isKnownNonZero(Z, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT); // if Z != 0 and nsw(X * Z) and nsw(Y * Z) // X * Z eq/ne Y * Z -> X eq/ne Y - if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW) + if (NonZero && BO0 && BO1 && BO0->hasNoSignedWrap() && + BO1->hasNoSignedWrap()) return new ICmpInst(Pred, X, Y); } else NonZero = isKnownNonZero(Z, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT); // If Z != 0 and nuw(X * Z) and nuw(Y * Z) // X * Z u{lt/le/gt/ge}/eq/ne Y * Z -> X u{lt/le/gt/ge}/eq/ne Y - if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW) + if (NonZero && BO0 && BO1 && BO0->hasNoUnsignedWrap() && + BO1->hasNoUnsignedWrap()) return new ICmpInst(Pred, X, Y); } } @@ -4980,8 +4976,8 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); case Instruction::Shl: { - bool NUW = Op0HasNUW && Op1HasNUW; - bool NSW = Op0HasNSW && Op1HasNSW; + bool NUW = BO0->hasNoUnsignedWrap() && BO1->hasNoUnsignedWrap(); + bool NSW = BO0->hasNoSignedWrap() && BO1->hasNoSignedWrap(); if (!NUW && !NSW) break; if (!NSW && I.isSigned()) diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index fe831934f4f33..1c7bb36f0d34c 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -3862,9 +3862,10 @@ define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) { define i1 @knownbits1(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits1( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 5 @@ -3878,9 +3879,10 @@ define i1 @knownbits1(i8 %a, i8 %b) { define i1 @knownbits2(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits2( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 5 @@ -3894,9 +3896,10 @@ define i1 @knownbits2(i8 %a, i8 %b) { define i1 @knownbits3(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits3( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 5 @@ -3910,9 +3913,10 @@ define i1 @knownbits3(i8 %a, i8 %b) { define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @knownbits4( ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], +; CHECK-NEXT: [[A2:%.*]] = or disjoint <2 x i8> [[A1]], ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], -; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], [[A1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint <2 x i8> [[B1]], +; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]] ; CHECK-NEXT: ret <2 x i1> [[C]] ; %a1 = and <2 x i8> %a, @@ -3928,9 +3932,10 @@ define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { define i1 @knownbits5(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits5( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 133 @@ -3944,9 +3949,10 @@ define i1 @knownbits5(i8 %a, i8 %b) { define i1 @knownbits6(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits6( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 133 @@ -3960,9 +3966,10 @@ define i1 @knownbits6(i8 %a, i8 %b) { define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @knownbits7( ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], +; CHECK-NEXT: [[A2:%.*]] = or disjoint <2 x i8> [[A1]], ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], -; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[TMP1]], [[A1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint <2 x i8> [[B1]], +; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]] ; CHECK-NEXT: ret <2 x i1> [[C]] ; %a1 = and <2 x i8> %a, @@ -3976,9 +3983,10 @@ define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { define i1 @knownbits8(i8 %a, i8 %b) { ; CHECK-LABEL: @knownbits8( ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 +; CHECK-NEXT: [[A2:%.*]] = or disjoint i8 [[A1]], 4 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 -; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 -; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], [[A1]] +; CHECK-NEXT: [[B2:%.*]] = or disjoint i8 [[B1]], 5 +; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]] ; CHECK-NEXT: ret i1 [[C]] ; %a1 = and i8 %a, 133 @@ -4904,80 +4912,3 @@ define i1 @or_positive_sgt_zero_multi_use(i8 %a) { %cmp = icmp sgt i8 %b, 0 ret i1 %cmp } - - -define i1 @disjoint_or_sgt_1(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_sgt_1( -; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp sle i8 [[B1]], [[A:%.*]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 1 - %b1 = add nsw i8 %b, 2 - %icmp_ = icmp sgt i8 %a1, %b1 - ret i1 %icmp_ -} - -define i1 @disjoint_or_sgt_2(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_sgt_2( -; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 -; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 2 - %b1 = add i8 %b, 1 - %icmp_ = icmp sgt i8 %a1, %b1 - ret i1 %icmp_ -} - -define i1 @disjoint_or_sgt_3(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_sgt_3( -; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 -; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 2 - %b1 = add nuw i8 %b, 1 - %icmp_ = icmp sgt i8 %a1, %b1 - ret i1 %icmp_ -} - -define i1 @disjoint_or_ugt_1(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_ugt_1( -; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp ule i8 [[B1]], [[A:%.*]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 1 - %b1 = add nsw i8 %b, 2 - %icmp_ = icmp ugt i8 %a1, %b1 - ret i1 %icmp_ -} - -define i1 @disjoint_or_ugt_2(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_ugt_2( -; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 -; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 2 - %b1 = add i8 %b, 1 - %icmp_ = icmp ugt i8 %a1, %b1 - ret i1 %icmp_ -} - -define i1 @disjoint_or_ugt_3(i8 %a, i8 %b) { -; CHECK-LABEL: @disjoint_or_ugt_3( -; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 -; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1 -; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]] -; CHECK-NEXT: ret i1 [[ICMP_]] -; - %a1 = or disjoint i8 %a, 2 - %b1 = add nuw i8 %b, 1 - %icmp_ = icmp ugt i8 %a1, %b1 - ret i1 %icmp_ -}