From 7eb3d72a84c01d3ff9c3ebceb98af6ba7eb05e0b Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 2 Aug 2025 16:48:29 +0100 Subject: [PATCH] [SCEV] Distinguish between full and wrapping AddRec in proveNoWrapViaCR. Try to widen integer AddRecs to a type one bit wider to distinguish between the AddRec wrapping or just hitting all possible values. Alternative to https://github.com/llvm/llvm-project/pull/131538. Note that now we can end up in the awkward situation that we fail to compute an unpredicated BTC on the first try, but succeed on the second try, because we now have a accurate max BTC. For now, I updated getPredicatedBackedgeTakencCount to remove cached BTC if that happens, but perhaps there's a better solution? --- llvm/lib/Analysis/ScalarEvolution.cpp | 43 +++++-- .../ScalarEvolution/exit-count-non-strict.ll | 12 +- .../ScalarEvolution/exit-count-select-safe.ll | 108 +++++++++--------- ...en-count-guard-info-rewrite-expressions.ll | 4 +- .../ScalarEvolution/umin-umax-folds.ll | 12 +- .../LoopUnrollAndJam/unroll-and-jam.ll | 4 +- 6 files changed, 102 insertions(+), 81 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 477e4771e04aa..c8e90dc1d73da 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5092,9 +5092,29 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) { } if (!AR->hasNoUnsignedWrap()) { - ConstantRange AddRecRange = getUnsignedRange(AR); - ConstantRange IncRange = getUnsignedRange(AR->getStepRecurrence(*this)); - + const SCEVAddRecExpr *NewAR = AR; + unsigned BitWidth = getTypeSizeInBits(AR->getType()); + // For integer AddRecs, try to evaluate the AddRec in a type one bit wider + // than the original type, to be able to differentiate between the AddRec + // hitting the full range or wrapping. + const SCEV *Step = AR->getStepRecurrence(*this); + if (AR->getType()->isIntegerTy() && isKnownNonNegative(Step)) { + Type *WiderTy = IntegerType::get(getContext(), BitWidth + 1); + NewAR = cast( + getAddRecExpr(getSignExtendExpr(AR->getStart(), WiderTy), + getZeroExtendExpr(Step, WiderTy), AR->getLoop(), + AR->getNoWrapFlags())); + ConstantRange AddRecRange = getUnsignedRange(NewAR); + // If the wider AddRec range matches the original range after stripping + // the top bit, the original AddRec does not self-wrap. + if (AddRecRange != + AddRecRange.truncate(BitWidth).zeroExtend(BitWidth + 1)) + NewAR = AR; + } + ConstantRange AddRecRange = getUnsignedRange(NewAR); + ConstantRange IncRange = getUnsignedRange(Step); + if (NewAR != AR) + IncRange = IncRange.zeroExtend(getTypeSizeInBits(NewAR->getType())); auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion( Instruction::Add, IncRange, OBO::NoUnsignedWrap); if (NUWRegion.contains(AddRecRange)) @@ -8336,7 +8356,13 @@ const SCEV *ScalarEvolution::getPredicatedExitCount( const SCEV *ScalarEvolution::getPredicatedBackedgeTakenCount( const Loop *L, SmallVectorImpl &Preds) { - return getPredicatedBackedgeTakenInfo(L).getExact(L, this, &Preds); + auto *Res = getPredicatedBackedgeTakenInfo(L).getExact(L, this, &Preds); + if (!isa(Res) && Preds.empty()) { + auto I = BackedgeTakenCounts.find(L); + if (I != BackedgeTakenCounts.end() && !I->second.isComplete()) + BackedgeTakenCounts.erase(I); + } + return Res; } const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L, @@ -13858,7 +13884,8 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, SmallVector Preds; auto *PBT = SE->getPredicatedBackedgeTakenCount(L, Preds); if (PBT != BTC) { - assert(!Preds.empty() && "Different predicated BTC, but no predicates"); + assert((!Preds.empty() || PBT == SE->getBackedgeTakenCount(L)) && + "Different predicated BTC, but no predicates"); OS << "Loop "; L->getHeader()->printAsOperand(OS, /*PrintType=*/false); OS << ": "; @@ -13877,7 +13904,8 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, auto *PredConstantMax = SE->getPredicatedConstantMaxBackedgeTakenCount(L, Preds); if (PredConstantMax != ConstantBTC) { - assert(!Preds.empty() && + assert((!Preds.empty() || + PredConstantMax == SE->getConstantMaxBackedgeTakenCount(L)) && "different predicated constant max BTC but no predicates"); OS << "Loop "; L->getHeader()->printAsOperand(OS, /*PrintType=*/false); @@ -13897,7 +13925,8 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, auto *PredSymbolicMax = SE->getPredicatedSymbolicMaxBackedgeTakenCount(L, Preds); if (SymbolicBTC != PredSymbolicMax) { - assert(!Preds.empty() && + assert((!Preds.empty() || + PredSymbolicMax == SE->getSymbolicMaxBackedgeTakenCount(L)) && "Different predicated symbolic max BTC, but no predicates"); OS << "Loop "; L->getHeader()->printAsOperand(OS, /*PrintType=*/false); diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll index 1e15d2d0d6461..0d19ed96d19a6 100644 --- a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll @@ -153,7 +153,6 @@ define void @ule_from_zero_no_nuw(i32 %M, i32 %N) { ; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: predicated exit count for loop: (1 + (zext i32 %M to i64)) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-EMPTY: ; CHECK-NEXT: exit count for latch: %N ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 @@ -161,18 +160,15 @@ define void @ule_from_zero_no_nuw(i32 %M, i32 %N) { ; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: predicated symbolic max exit count for loop: (1 + (zext i32 %M to i64)) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-EMPTY: ; CHECK-NEXT: symbolic max exit count for latch: %N ; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295 ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: +; CHECK-NEXT: Loop %loop: Trip multiple is 1 ; entry: br label %loop @@ -198,7 +194,6 @@ define void @le_from_zero_no_nuw(i32 %M, i32 %N) { ; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: predicated exit count for loop: (1 + (zext i32 %M to i64)) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-EMPTY: ; CHECK-NEXT: exit count for latch: %N ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1 @@ -206,18 +201,15 @@ define void @le_from_zero_no_nuw(i32 %M, i32 %N) { ; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: predicated symbolic max exit count for loop: (1 + (zext i32 %M to i64)) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-EMPTY: ; CHECK-NEXT: symbolic max exit count for latch: %N ; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295 ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: ; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))) ; CHECK-NEXT: Predicates: -; CHECK-NEXT: {0,+,1}<%loop> Added Flags: +; CHECK-NEXT: Loop %loop: Trip multiple is 1 ; entry: br label %loop diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll index 1043b2f6f56f6..df97d0b1d4d68 100644 --- a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll @@ -5,9 +5,9 @@ define i32 @logical_and_2ops(i32 %n, i32 %m) { ; CHECK-LABEL: 'logical_and_2ops' ; CHECK-NEXT: Classifying expressions for: @logical_and_2ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops @@ -33,9 +33,9 @@ define i32 @logical_or_2ops(i32 %n, i32 %m) { ; CHECK-LABEL: 'logical_or_2ops' ; CHECK-NEXT: Classifying expressions for: @logical_or_2ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 true, i1 %cond_p1 ; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_2ops @@ -61,9 +61,9 @@ define i32 @logical_and_3ops(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_and_3ops' ; CHECK-NEXT: Classifying expressions for: @logical_and_3ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 %cond_p2, i1 false @@ -93,9 +93,9 @@ define i32 @logical_or_3ops(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_or_3ops' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 ; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 @@ -125,9 +125,9 @@ define i32 @logical_or_3ops_duplicate(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_or_3ops_duplicate' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_duplicate ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p0, i1 true, i1 %cond_p1 ; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond_p5 = select i1 %cond_p4, i1 true, i1 %cond_p2 @@ -161,9 +161,9 @@ define i32 @logical_or_3ops_redundant_uminseq_operand(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_or_3ops_redundant_uminseq_operand' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_redundant_uminseq_operand ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 @@ -196,9 +196,9 @@ define i32 @logical_or_3ops_redundant_umin_operand(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_or_3ops_redundant_umin_operand' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_redundant_umin_operand ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %k umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %k umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %k umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %k umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 @@ -231,9 +231,9 @@ define i32 @logical_or_4ops_redundant_operand_across_umins(i32 %n, i32 %m, i32 % ; CHECK-LABEL: 'logical_or_4ops_redundant_operand_across_umins' ; CHECK-NEXT: Classifying expressions for: @logical_or_4ops_redundant_operand_across_umins ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k umin_seq %q) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k umin_seq %q) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k umin_seq %q)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k umin_seq %q)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %q) @@ -269,9 +269,9 @@ define i32 @logical_or_3ops_operand_wise_redundant_umin(i32 %n, i32 %m, i32 %k) ; CHECK-LABEL: 'logical_or_3ops_operand_wise_redundant_umin' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_operand_wise_redundant_umin ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %k) @@ -307,9 +307,9 @@ define i32 @logical_or_3ops_partially_redundant_umin(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: 'logical_or_3ops_partially_redundant_umin' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_partially_redundant_umin ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq (%m umin %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq (%m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%m umin %k))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%m umin %k))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %k) @@ -341,21 +341,21 @@ define i32 @logical_or_5ops_redundant_opearand_of_inner_uminseq(i32 %a, i32 %b, ; CHECK-LABEL: 'logical_or_5ops_redundant_opearand_of_inner_uminseq' ; CHECK-NEXT: Classifying expressions for: @logical_or_5ops_redundant_opearand_of_inner_uminseq ; CHECK-NEXT: %first.i = phi i32 [ 0, %entry ], [ %first.i.next, %first.loop ] -; CHECK-NEXT: --> {0,+,1}<%first.loop> U: full-set S: full-set Exits: (%e umin_seq %d umin_seq %a) LoopDispositions: { %first.loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%first.loop> U: full-set S: full-set Exits: (%e umin_seq %d umin_seq %a) LoopDispositions: { %first.loop: Computable } ; CHECK-NEXT: %first.i.next = add i32 %first.i, 1 -; CHECK-NEXT: --> {1,+,1}<%first.loop> U: full-set S: full-set Exits: (1 + (%e umin_seq %d umin_seq %a)) LoopDispositions: { %first.loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%first.loop> U: full-set S: full-set Exits: (1 + (%e umin_seq %d umin_seq %a)) LoopDispositions: { %first.loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 ; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p3, i1 true, i1 %cond_p2 ; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %i = phi i32 [ 0, %first.loop.exit ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c, i32 %d) ; CHECK-NEXT: --> (%c umin %d) U: full-set S: full-set Exits: (%c umin %d) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %first.i) -; CHECK-NEXT: --> ({0,+,1}<%first.loop> umin %c umin %d) U: full-set S: full-set --> ((%e umin_seq %d umin_seq %a) umin %c umin %d) U: full-set S: full-set Exits: ((%e umin_seq %d umin_seq %a) umin %c umin %d) LoopDispositions: { %loop: Invariant } +; CHECK-NEXT: --> ({0,+,1}<%first.loop> umin %c umin %d) U: full-set S: full-set --> ((%e umin_seq %d umin_seq %a) umin %c umin %d) U: full-set S: full-set Exits: ((%e umin_seq %d umin_seq %a) umin %c umin %d) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p8 = select i1 %cond_p5, i1 true, i1 %cond_p6 ; CHECK-NEXT: --> (true + ((true + %cond_p5) umin_seq (true + %cond_p6))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p8, i1 true, i1 %cond_p7 @@ -501,15 +501,15 @@ define i64 @uminseq_vs_ptrtoint_complexity(i64 %n, i64 %m, ptr %ptr) { ; CHECK-LABEL: 'uminseq_vs_ptrtoint_complexity' ; CHECK-NEXT: Classifying expressions for: @uminseq_vs_ptrtoint_complexity ; CHECK-NEXT: %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i64 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %ptr.int = ptrtoint ptr %ptr to i64 ; CHECK-NEXT: --> (ptrtoint ptr %ptr to i64) U: full-set S: full-set ; CHECK-NEXT: %r = add i64 %i, %ptr.int -; CHECK-NEXT: --> {(ptrtoint ptr %ptr to i64),+,1}<%loop> U: full-set S: full-set --> ((%n umin_seq %m) + (ptrtoint ptr %ptr to i64)) U: full-set S: full-set +; CHECK-NEXT: --> {(ptrtoint ptr %ptr to i64),+,1}<%loop> U: full-set S: full-set --> ((%n umin_seq %m) + (ptrtoint ptr %ptr to i64)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @uminseq_vs_ptrtoint_complexity ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 @@ -537,9 +537,9 @@ define i32 @logical_and_implies_poison1(i32 %n) { ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison1 @@ -568,9 +568,9 @@ define i32 @logical_and_implies_poison2(i32 %n) { ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison2 @@ -599,9 +599,9 @@ define i32 @logical_and_implies_poison3(i32 %n, i32 %m) { ; CHECK-NEXT: %add = add i32 %n, %m ; CHECK-NEXT: --> (%n + %m) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin %n) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin %n) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison3 @@ -630,9 +630,9 @@ define i32 @logical_and_implies_poison_wrong_direction(i32 %n, i32 %m) { ; CHECK-NEXT: %add = add i32 %n, %m ; CHECK-NEXT: --> (%n + %m) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq (%n + %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq (%n + %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%n + %m))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%n + %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_wrong_direction @@ -659,9 +659,9 @@ define i32 @logical_and_implies_poison_noundef(i32 %n, i32 noundef %m) { ; CHECK-LABEL: 'logical_and_implies_poison_noundef' ; CHECK-NEXT: Classifying expressions for: @logical_and_implies_poison_noundef ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef @@ -687,9 +687,9 @@ define i32 @logical_and_implies_poison_noundef_wrong_direction(i32 %n, i32 nound ; CHECK-LABEL: 'logical_and_implies_poison_noundef_wrong_direction' ; CHECK-NEXT: Classifying expressions for: @logical_and_implies_poison_noundef_wrong_direction ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq %n) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq %n) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef_wrong_direction @@ -719,9 +719,9 @@ define i32 @logical_and_implies_poison_complex1(i32 %n, i32 %m) { ; CHECK-NEXT: %add1 = add i32 %add, 1 ; CHECK-NEXT: --> (1 + %n + %m) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin (1 + %n + %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin (1 + %n + %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (1 + %n + %m))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (1 + %n + %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex1 @@ -753,9 +753,9 @@ define i32 @logical_and_implies_poison_complex2(i32 %n, i32 %m, i32 %l) { ; CHECK-NEXT: %add1 = add i32 %add, %l ; CHECK-NEXT: --> (%n + %m + %l) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin (%n + %m + %l)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin (%n + %m + %l)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex2 @@ -787,9 +787,9 @@ define i32 @logical_and_implies_poison_complex_wrong_direction(i32 %n, i32 %m, i ; CHECK-NEXT: %add1 = add i32 %add, %l ; CHECK-NEXT: --> (%n + %m + %l) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin_seq (%n + %m + %l)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin_seq (%n + %m + %l)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin_seq (%n + %m + %l))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin_seq (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex_wrong_direction @@ -819,9 +819,9 @@ define i32 @logical_and_implies_multiple_ops(i32 %n, i32 %m) { ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (((1 + %n) umin %n) umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (((1 + %n) umin %n) umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (((1 + %n) umin %n) umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (((1 + %n) umin %n) umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false @@ -854,9 +854,9 @@ define i32 @logical_and_implies_multiple_ops2(i32 %n, i32 %m) { ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq ((1 + %n) umin %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq ((1 + %n) umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq ((1 + %n) umin %m))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq ((1 + %n) umin %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false @@ -889,9 +889,9 @@ define i32 @logical_and_implies_multiple_ops3(i32 %n, i32 %m) { ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq ((1 + %n) umin %n))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq ((1 + %n) umin %n))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false @@ -990,9 +990,9 @@ define i32 @logical_and_not_zero_needs_context(i32 %n, i32 %m) { ; CHECK-LABEL: 'logical_and_not_zero_needs_context' ; CHECK-NEXT: Classifying expressions for: @logical_and_not_zero_needs_context ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false ; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero_needs_context diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll index 8c77d704eac6a..aac7bc813ce2e 100644 --- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll +++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll @@ -808,9 +808,9 @@ define void @rewrite_add_rec() { ; CHECK-NEXT: %n.vec = and i64 %sub, -2 ; CHECK-NEXT: --> (2 * ({9,+,-1}<%outer.header> /u 2)) U: [0,9) S: [0,9) Exits: 0 LoopDispositions: { %outer.header: Computable, %inner: Invariant } ; CHECK-NEXT: %inner.iv = phi i64 [ 0, %inner.ph ], [ %inner.iv.next, %inner ] -; CHECK-NEXT: --> {0,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 * ((-2 + (2 * ({9,+,-1}<%outer.header> /u 2))) /u 2)) LoopDispositions: { %inner: Computable, %outer.header: Variant } +; CHECK-NEXT: --> {0,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 * ((-2 + (2 * ({9,+,-1}<%outer.header> /u 2))) /u 2)) LoopDispositions: { %inner: Computable, %outer.header: Variant } ; CHECK-NEXT: %inner.iv.next = add i64 %inner.iv, 2 -; CHECK-NEXT: --> {2,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 + (2 * ((-2 + (2 * ({9,+,-1}<%outer.header> /u 2))) /u 2))) LoopDispositions: { %inner: Computable, %outer.header: Variant } +; CHECK-NEXT: --> {2,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 + (2 * ((-2 + (2 * ({9,+,-1}<%outer.header> /u 2))) /u 2))) LoopDispositions: { %inner: Computable, %outer.header: Variant } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 ; CHECK-NEXT: --> {1,+,1}<%outer.header> U: [1,11) S: [1,11) Exits: 10 LoopDispositions: { %outer.header: Computable, %inner: Invariant } ; CHECK-NEXT: Determining loop execution counts for: @rewrite_add_rec diff --git a/llvm/test/Analysis/ScalarEvolution/umin-umax-folds.ll b/llvm/test/Analysis/ScalarEvolution/umin-umax-folds.ll index fbdbefb875fba..b97afae894621 100644 --- a/llvm/test/Analysis/ScalarEvolution/umin-umax-folds.ll +++ b/llvm/test/Analysis/ScalarEvolution/umin-umax-folds.ll @@ -77,9 +77,9 @@ define void @uge_sext_x_zext_x(i32 %len) { ; CHECK-NEXT: %len.sext = sext i32 %len to i64 ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %sel = select i1 %cmp1, i64 %len.zext, i64 %len.sext ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: Determining loop execution counts for: @uge_sext_x_zext_x @@ -145,9 +145,9 @@ define void @ugt_sext_x_zext_x(i32 %len) { ; CHECK-NEXT: %len.sext = sext i32 %len to i64 ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umax = select i1 %cmp1, i64 %len.zext, i64 %len.sext ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: Determining loop execution counts for: @ugt_sext_x_zext_x @@ -247,9 +247,9 @@ define void @slt_sext_x_zext_x(i32 %len) { ; CHECK-NEXT: %len.sext = sext i32 %len to i64 ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (sext i32 %len to i64)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = select i1 %cmp1, i64 %len.zext, i64 %len.sext ; CHECK-NEXT: --> (sext i32 %len to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 %len to i64) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: Determining loop execution counts for: @slt_sext_x_zext_x diff --git a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll index 89ce66767ccc9..55603dc264a17 100644 --- a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll +++ b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll @@ -730,7 +730,7 @@ define void @test7(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocaptu ; CHECK-NEXT: [[ADD_3]] = add nuw i32 [[I]], 4 ; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_3]] ; CHECK-NEXT: store i32 2, ptr [[ARRAYIDX2_3]], align 4, !tbaa [[TBAA0]] -; CHECK-NEXT: [[NITER_NEXT_3]] = add i32 [[NITER]], 4 +; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4 ; CHECK-NEXT: br label [[FOR_INNER:%.*]] ; CHECK: for.latch: ; CHECK-NEXT: [[ADD9_LCSSA:%.*]] = phi i32 [ [[ADD9:%.*]], [[FOR_INNER]] ] @@ -928,7 +928,7 @@ define void @test8(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocaptu ; CHECK-NEXT: [[ADD_3]] = add nuw i32 [[I]], 4 ; CHECK-NEXT: [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_3]] ; CHECK-NEXT: store i32 2, ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]] -; CHECK-NEXT: [[NITER_NEXT_3]] = add i32 [[NITER]], 4 +; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4 ; CHECK-NEXT: br label [[FOR_INNER:%.*]] ; CHECK: for.inner: ; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9:%.*]], [[FOR_INNER]] ]