diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 8407be99a82b14..ccdf29cf3a187b 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -575,7 +575,6 @@ class ScalarEvolution { const SCEV *getGEPExpr(GEPOperator *GEP, const SmallVectorImpl &IndexExprs); const SCEV *getAbsExpr(const SCEV *Op, bool IsNSW); - const SCEV *getSignumExpr(const SCEV *Op); const SCEV *getMinMaxExpr(SCEVTypes Kind, SmallVectorImpl &Operands); const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 4630c5562623cc..f92cccd4481677 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3503,11 +3503,6 @@ const SCEV *ScalarEvolution::getAbsExpr(const SCEV *Op, bool IsNSW) { return getSMaxExpr(Op, getNegativeSCEV(Op, Flags)); } -const SCEV *ScalarEvolution::getSignumExpr(const SCEV *Op) { - Type *Ty = Op->getType(); - return getSMinExpr(getSMaxExpr(Op, getMinusOne(Ty)), getOne(Ty)); -} - const SCEV *ScalarEvolution::getMinMaxExpr(SCEVTypes Kind, SmallVectorImpl &Ops) { assert(!Ops.empty() && "Cannot get empty (u|s)(min|max)!"); @@ -4559,7 +4554,6 @@ struct BinaryOp { Value *RHS; bool IsNSW = false; bool IsNUW = false; - bool IsExact = false; /// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or /// constant expression. @@ -4572,14 +4566,11 @@ struct BinaryOp { IsNSW = OBO->hasNoSignedWrap(); IsNUW = OBO->hasNoUnsignedWrap(); } - if (auto *PEO = dyn_cast(Op)) - IsExact = PEO->isExact(); } explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS, bool IsNSW = false, - bool IsNUW = false, bool IsExact = false) - : Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW), - IsExact(IsExact) {} + bool IsNUW = false) + : Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW) {} }; } // end anonymous namespace @@ -6745,15 +6736,6 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { } } } - if (BO->IsExact) { - // Given exact arithmetic in-bounds right-shift by a constant, - // we can lower it into: (abs(x) EXACT/u (1<LHS); - const SCEV *AbsX = getAbsExpr(X, /*IsNSW=*/false); - APInt Mult = APInt::getOneBitSet(BitWidth, AShrAmt); - const SCEV *Div = getUDivExactExpr(AbsX, getConstant(Mult)); - return getMulExpr(Div, getSignumExpr(X), SCEV::FlagNSW); - } break; } } diff --git a/llvm/test/Analysis/ScalarEvolution/ashr.ll b/llvm/test/Analysis/ScalarEvolution/ashr.ll index 0da69e5d082f66..b8bf8a42fbb647 100644 --- a/llvm/test/Analysis/ScalarEvolution/ashr.ll +++ b/llvm/test/Analysis/ScalarEvolution/ashr.ll @@ -42,7 +42,7 @@ define i32 @t3(i32 %x, i32 %y) { ; CHECK-LABEL: 't3' ; CHECK-NEXT: Classifying expressions for: @t3 ; CHECK-NEXT: %i0 = ashr exact i32 %x, 4 -; CHECK-NEXT: --> ((((-1 * %x) smax %x) /u 16) * (1 smin (-1 smax %x))) U: [-268435455,268435456) S: [-268435455,268435456) +; CHECK-NEXT: --> %i0 U: [-134217728,134217728) S: [-134217728,134217728) ; CHECK-NEXT: Determining loop execution counts for: @t3 ; %i0 = ashr exact i32 %x, 4 @@ -65,7 +65,7 @@ define i32 @t5(i32 %x, i32 %y) { ; CHECK-LABEL: 't5' ; CHECK-NEXT: Classifying expressions for: @t5 ; CHECK-NEXT: %i0 = ashr exact i32 %x, 5 -; CHECK-NEXT: --> ((((-1 * %x) smax %x) /u 32) * (1 smin (-1 smax %x))) U: [-134217727,134217728) S: [-134217727,134217728) +; CHECK-NEXT: --> %i0 U: [-67108864,67108864) S: [-67108864,67108864) ; CHECK-NEXT: Determining loop execution counts for: @t5 ; %i0 = ashr exact i32 %x, 5 diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll index 3c3da6c4daabe7..6f5785f42b92a0 100644 --- a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll +++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll @@ -473,9 +473,9 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) { ; X64-NEXT: %i10 = sub i64 %i9, %i4 ; X64-NEXT: --> {0,+,4}<%bb6> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: (4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i11 = ashr exact i64 %i10, 2 -; X64-NEXT: --> ((({0,+,4}<%bb6> smax {0,+,-4}<%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<%bb6>))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: ((((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))))) LoopDispositions: { %bb6: Computable } +; X64-NEXT: --> %i11 U: [-2305843009213693952,2305843009213693952) S: [-2305843009213693952,2305843009213693952) Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; X64-NEXT: --> ((4 * (({0,+,4}<%bb6> smax {0,+,-4}<%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<%bb6>))) + %arg2) U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))))) + %arg2) LoopDispositions: { %bb6: Computable } +; X64-NEXT: --> ((4 * %i11) + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i13 = load i32, i32* %i12, align 4 ; X64-NEXT: --> %i13 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i14 = add nsw i32 %i13, %i8 @@ -502,9 +502,9 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) { ; X32-NEXT: %i10 = sub i64 %i9, %i4 ; X32-NEXT: --> {0,+,4}<%bb6> U: [0,4294967293) S: [0,4294967293) Exits: (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4)) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i11 = ashr exact i64 %i10, 2 -; X32-NEXT: --> ({0,+,1}<%bb6> * (1 smin {0,+,4}<%bb6>)) U: [0,1073741824) S: [0,1073741824) Exits: (((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4) * (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4)))) LoopDispositions: { %bb6: Computable } +; X32-NEXT: --> %i11 U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; X32-NEXT: --> (((trunc i64 (1 smin {0,+,4}<%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2) U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg2) LoopDispositions: { %bb6: Computable } +; X32-NEXT: --> ((4 * (trunc i64 %i11 to i32)) + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i13 = load i32, i32* %i12, align 4 ; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i14 = add nsw i32 %i13, %i8 diff --git a/llvm/test/Transforms/IndVarSimplify/ashr-expansion.ll b/llvm/test/Transforms/IndVarSimplify/ashr-expansion.ll index a4eb654d28fcf6..23dbeffffd24e3 100644 --- a/llvm/test/Transforms/IndVarSimplify/ashr-expansion.ll +++ b/llvm/test/Transforms/IndVarSimplify/ashr-expansion.ll @@ -6,13 +6,8 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" define float @ashr_expansion_valid(i64 %x, float* %ptr) { ; CHECK-LABEL: @ashr_expansion_valid( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 -1) -; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 1) -; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[X]] -; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[X]], i64 [[TMP0]]) -; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[SMAX1]], 4 -; CHECK-NEXT: [[TMP2:%.*]] = mul nsw i64 [[SMIN]], [[TMP1]] -; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 1) +; CHECK-NEXT: [[BOUND:%.*]] = ashr exact i64 [[X:%.*]], 4 +; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]