[llvm] [SCEV] Rework wrap-flag-inference for sext-addrec (PR #217362)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 22 11:31:44 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/217362
>From c249fc3a2e7a83de1d9b110866e85a06531decc1 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 19 Aug 2026 18:36:12 +0100
Subject: [PATCH 1/4] [SCEV] Rework wrap-flag-inferrence for sext-addrec
Rewrite getSignExtendExprImpl to avoid the roundabout method of creating
sign-extend expressions to check no-wrap, by computing the no-wrap
information using induction and reading it off the expression directly.
The new code has much better compile-time, while not being exactly
equivalent to the old code.
---
llvm/lib/Analysis/ScalarEvolution.cpp | 95 ++-----------------
.../Analysis/ScalarEvolution/incorrect-nsw.ll | 6 +-
2 files changed, 10 insertions(+), 91 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index a05b7e9714f01..68ebbe69890b9 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2044,91 +2044,17 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
// operands (often constants). This allows analysis of something like
// this: for (signed char X = 0; X < 100; ++X) { int Y = X; }
if (match(Op, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Step), m_Loop(L)))) {
+ // Redo the AddRec check, computing nsw this time.
const auto *AR = cast<SCEVAddRecExpr>(Op);
- unsigned BitWidth = getTypeSizeInBits(AR->getType());
-
- // The no-signed-wrap case is handled before the uniquing lookup above.
-
- // Check whether the backedge-taken count is SCEVCouldNotCompute.
- // Note that this serves two purposes: It filters out loops that are
- // simply not analyzable, and it covers the case where this code is
- // being called from within backedge-taken count analysis, such that
- // attempting to ask for the backedge-taken count would likely result
- // in infinite recursion. In the later case, the analysis code will
- // cope with a conservative value, and it will take care to purge
- // that value once it has finished.
- const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
- if (!isa<SCEVCouldNotCompute>(MaxBECount)) {
- // Manually compute the final value for AR, checking for
- // overflow.
-
- // Check whether the backedge-taken count can be losslessly casted to
- // the addrec's type. The count is always unsigned.
- const SCEV *CastedMaxBECount =
- getTruncateOrZeroExtend(MaxBECount, Start->getType(), Depth);
- const SCEV *RecastedMaxBECount = getTruncateOrZeroExtend(
- CastedMaxBECount, MaxBECount->getType(), Depth);
- if (MaxBECount == RecastedMaxBECount) {
- Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
- // Check whether Start+Step*MaxBECount has no signed overflow.
- const SCEV *SMul =
- getMulExpr(CastedMaxBECount, Step, SCEV::FlagAnyWrap, Depth + 1);
- const SCEV *SAdd = getSignExtendExpr(
- getAddExpr(Start, SMul, SCEV::FlagAnyWrap, Depth + 1), WideTy,
- Depth + 1);
- const SCEV *WideStart = getSignExtendExpr(Start, WideTy, Depth + 1);
- const SCEV *WideMaxBECount =
- getZeroExtendExpr(CastedMaxBECount, WideTy, Depth + 1);
- const SCEV *OperandExtendedAdd =
- getAddExpr(WideStart,
- getMulExpr(WideMaxBECount,
- getSignExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
- if (SAdd == OperandExtendedAdd) {
- // Cache knowledge of AR NSW, which is propagated to this AddRec.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
- // Return the expression with the addrec on the outside.
- Start =
- getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getSignExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
- }
- // Similar to above, only this time treat the step value as unsigned.
- // This covers loops that count up with an unsigned step.
- OperandExtendedAdd =
- getAddExpr(WideStart,
- getMulExpr(WideMaxBECount,
- getZeroExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
- if (SAdd == OperandExtendedAdd) {
- // If AR wraps around then
- //
- // abs(Step) * MaxBECount > unsigned-max(AR->getType())
- // => SAdd != OperandExtendedAdd
- //
- // Thus (AR is not NW => SAdd != OperandExtendedAdd) <=>
- // (SAdd == OperandExtendedAdd => AR is NW)
-
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
-
- // Return the expression with the addrec on the outside.
- Start =
- getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getZeroExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
- }
- }
- }
-
+ inferNoWrapViaConstantRanges(AR);
auto NewFlags = proveNoSignedWrapViaInduction(AR);
+ if (!hasFlags(NewFlags, SCEV::FlagNSW) &&
+ proveNoWrapByVaryingStart<SCEVSignExtendExpr>(Start, Step, L))
+ NewFlags |= SCEV::FlagNSW;
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
+
+ // If we have nsw, the sign-extend distributes over the recurrence.
if (AR->hasNoSignedWrap()) {
- // Same as nsw case above - duplicated here to avoid a compile time
- // issue. It's not clear that the order of checks does matter, but
- // it's one of two issue possible causes for a change which was
- // reverted. Be conservative for the moment.
Start = getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
Step = getSignExtendExpr(Step, Ty, Depth + 1);
return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
@@ -2149,13 +2075,6 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
Depth + 1);
}
}
-
- if (proveNoWrapByVaryingStart<SCEVSignExtendExpr>(Start, Step, L)) {
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
- Start = getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getSignExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
- }
}
// If the input value is provably positive and we could not simplify
diff --git a/llvm/test/Analysis/ScalarEvolution/incorrect-nsw.ll b/llvm/test/Analysis/ScalarEvolution/incorrect-nsw.ll
index f7edf493c64c4..1490c6710bced 100644
--- a/llvm/test/Analysis/ScalarEvolution/incorrect-nsw.ll
+++ b/llvm/test/Analysis/ScalarEvolution/incorrect-nsw.ll
@@ -3,13 +3,13 @@
define void @bad.nsw() {
; CHECK-LABEL: Classifying expressions for: @bad.nsw
; CHECK-LABEL: Classifying expressions for: @bad.nsw
- entry:
+ entry:
br label %loop
loop:
%i = phi i8 [ -1, %entry ], [ %i.inc, %loop ]
; CHECK: %i = phi i8 [ -1, %entry ], [ %i.inc, %loop ]
-; CHECK-NEXT: --> {-1,+,-128}<nw><%loop>
+; CHECK-NEXT: --> {-1,+,-128}<%loop>
; CHECK-NOT: --> {-1,+,-128}<nsw><%loop>
%counter = phi i8 [ 0, %entry ], [ %counter.inc, %loop ]
@@ -22,5 +22,5 @@ define void @bad.nsw() {
br i1 %continue, label %exit, label %loop
exit:
- ret void
+ ret void
}
>From 93473e4825ae1ef14e16fc25cd0b1fd367954317 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 21 Aug 2026 20:29:25 +0100
Subject: [PATCH 2/4] [SCEV] Cover old no-self-wrap logic, but better!
---
llvm/lib/Analysis/ScalarEvolution.cpp | 21 +-
.../ScalarEvolution/flags-from-poison.ll | 2 +-
llvm/test/Analysis/ScalarEvolution/pr27315.ll | 31 +-
.../ptrtoint-constantexpr-loop.ll | 12 +-
.../RISCV/loop-strength-reduce-loop-invar.ll | 24 +-
.../IndVarSimplify/X86/overflow-intrinsics.ll | 4 +-
.../IndVarSimplify/range-iter-threshold.ll | 7 +-
.../simplify-icmp-operands-order.ll | 2 +-
.../IndVarSimplify/strengthen-overflow.ll | 4 +-
.../IndVarSimplify/turn-to-invariant.ll | 2 +-
.../X86/2008-08-14-ShadowIV.ll | 268 ++++++---
.../X86/2012-01-13-phielim.ll | 2 +-
.../LoopStrengthReduce/X86/pr17473.ll | 38 +-
.../LoopUnroll/AArch64/apple-unrolling.ll | 10 +-
.../LoopUnroll/ARM/loop-unrolling.ll | 557 +++++++++++++++---
.../Transforms/LoopUnroll/ARM/multi-blocks.ll | 4 +-
.../LoopUnroll/WebAssembly/basic-unrolling.ll | 16 +-
.../peel-last-iteration-with-guards.ll | 4 +-
.../peel-loop-noalias-scope-decl.ll | 82 +--
.../runtime-exit-phi-scev-invalidation.ll | 6 +-
.../dependencies_visit_order.ll | 5 +-
.../LoopUnrollAndJam/unroll-and-jam.ll | 8 +-
.../Transforms/LoopVectorize/alias-mask.ll | 9 +-
...irst-order-recurrence-dead-instructions.ll | 29 +-
...ple-unreachable-exits-for-vectorization.ll | 4 +-
.../PhaseOrdering/loop-access-checks.ll | 2 +-
.../AMDGPU/inst-count-heuristic.ll | 46 +-
27 files changed, 862 insertions(+), 337 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 68ebbe69890b9..a4fb250e95ba6 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2044,7 +2044,7 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
// operands (often constants). This allows analysis of something like
// this: for (signed char X = 0; X < 100; ++X) { int Y = X; }
if (match(Op, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Step), m_Loop(L)))) {
- // Redo the AddRec check, computing nsw this time.
+ // Redo the AddRec check, attempting to prove no-wrap this time.
const auto *AR = cast<SCEVAddRecExpr>(Op);
inferNoWrapViaConstantRanges(AR);
auto NewFlags = proveNoSignedWrapViaInduction(AR);
@@ -2060,6 +2060,25 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
}
+ // For a positive step, we can zero-extend the step iff doing so only
+ // traverses values in the range zext([0,UMAX]).
+ if (isKnownPositive(Step)) {
+ unsigned BitWidth = getTypeSizeInBits(AR->getType());
+ const SCEV *N = getConstant(APInt::getSignedMinValue(BitWidth) -
+ getUnsignedRangeMin(Step));
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT, AR, N) ||
+ isKnownOnEveryIteration(ICmpInst::ICMP_SLT, AR, N) ||
+ proveNoWrapByVaryingStart<SCEVZeroExtendExpr>(Start, Step, L)) {
+ // no-self-wrap is an opportunistic fact we get for free. It is not a
+ // pre-condition for the transform.
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
+ Start =
+ getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
+ Step = getZeroExtendExpr(Step, Ty, Depth + 1);
+ return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
+ }
+ }
+
// sext({C,+,Step}) --> (sext(D) + sext({C-D,+,Step}))<nuw><nsw>
// if D + (C - D + Step * n) could be proven to not signed wrap
// where D maximizes the number of trailing zeros of (C - D + Step * n)
diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
index ce899726d44cd..3ae5f0afd7299 100644
--- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
+++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
@@ -141,7 +141,7 @@ define void @test-add-scope-bound(ptr %input, i32 %needle) {
; CHECK-NEXT: %of_interest = add nuw nsw i32 %i.next, %offset
; CHECK-NEXT: --> ({1,+,1}<nuw><%loop> + %offset)<nuw><nsw> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %of_interest
-; CHECK-NEXT: --> ((4 * ((sext i32 {1,+,1}<nuw><%loop> to i64) + (sext i32 %offset to i64))<nsw>)<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> ((4 * ((sext i32 %offset to i64) + {1,+,1}<nuw><%loop>)<nsw>) + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
diff --git a/llvm/test/Analysis/ScalarEvolution/pr27315.ll b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
index 1c99075f5f1b4..405d2f62e5268 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr27315.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
@@ -1,16 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
declare i1 @use(i64)
define void @f_0() {
-; CHECK-LABEL: Classifying expressions for: @f_0
+; CHECK-LABEL: 'f_0'
+; CHECK-NEXT: Classifying expressions for: @f_0
+; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %iv.inc.maywrap = add i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %cond0 = call i1 @use(i64 %iv.inc.maywrap.sext)
+; CHECK-NEXT: --> %cond0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: %iv.inc.nowrap = add nsw i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %be.cond = call i1 @use(i64 0)
+; CHECK-NEXT: --> %be.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: Determining loop execution counts for: @f_0
+; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: exit count for be: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: symbolic max exit count for be: ***COULDNOTCOMPUTE***
+;
-; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
-; CHECK: %iv.inc.maywrap = add i32 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop>
-; CHECK: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
-; CHECK-NEXT: --> (sext i32 {1,+,1}<nuw><%loop> to i64)
entry:
br label %loop
diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
index 99ecb3c9a7cb9..daa0bd3e3cbc5 100644
--- a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
@@ -325,9 +325,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR64_IDX64-LABEL: 'sext_like_noop'
; PTR64_IDX64-NEXT: Classifying expressions for: @sext_like_noop
; PTR64_IDX64-NEXT: %ii = sext i32 %i to i64
-; PTR64_IDX64-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (ptr @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
+; PTR64_IDX64-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
; PTR64_IDX64-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX64-NEXT: --> %div U: full-set S: full-set
+; PTR64_IDX64-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
; PTR64_IDX64-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX64-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX64-NEXT: %inc = add nuw i32 %i, 1
@@ -341,9 +341,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR64_IDX32-LABEL: 'sext_like_noop'
; PTR64_IDX32-NEXT: Classifying expressions for: @sext_like_noop
; PTR64_IDX32-NEXT: %ii = sext i32 %i to i64
-; PTR64_IDX32-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (ptr @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
+; PTR64_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
; PTR64_IDX32-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX32-NEXT: --> %div U: full-set S: full-set
+; PTR64_IDX32-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
; PTR64_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX32-NEXT: %inc = add nuw i32 %i, 1
@@ -357,9 +357,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR16_IDX16-LABEL: 'sext_like_noop'
; PTR16_IDX16-NEXT: Classifying expressions for: @sext_like_noop
; PTR16_IDX16-NEXT: %ii = sext i32 %i to i64
-; PTR16_IDX16-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i32 ptrtoint (ptr @sext_like_noop to i32) to i64))<nsw> U: [-1,65535) S: [-1,65535)
+; PTR16_IDX16-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32))<nsw> to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
; PTR16_IDX16-NEXT: %div = sdiv i64 55555, %ii
-; PTR16_IDX16-NEXT: --> %div U: full-set S: full-set
+; PTR16_IDX16-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32))<nsw> to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
; PTR16_IDX16-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR16_IDX16-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32))<nsw> LoopDispositions: { %for.body: Computable }
; PTR16_IDX16-NEXT: %inc = add nuw i32 %i, 1
diff --git a/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll b/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
index d11e5280b5aeb..9376a88b8bf4b 100644
--- a/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
+++ b/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
@@ -54,23 +54,23 @@ define void @test(i32 signext %row, i32 signext %N.in) nounwind {
; RV64-NEXT: blez a1, .LBB0_3
; RV64-NEXT: # %bb.1: # %cond_true.preheader
; RV64-NEXT: slli a0, a0, 6
+; RV64-NEXT: addi a1, a1, -1
; RV64-NEXT: lui a2, %hi(A)
; RV64-NEXT: addi a2, a2, %lo(A)
-; RV64-NEXT: addiw a1, a1, 2
+; RV64-NEXT: slli a1, a1, 32
; RV64-NEXT: add a0, a0, a2
-; RV64-NEXT: li a2, 2
-; RV64-NEXT: addi a3, a0, 4
-; RV64-NEXT: li a4, 4
-; RV64-NEXT: li a5, 5
+; RV64-NEXT: srli a1, a1, 30
+; RV64-NEXT: add a1, a0, a1
+; RV64-NEXT: addi a0, a0, 8
+; RV64-NEXT: addi a1, a1, 12
+; RV64-NEXT: li a2, 4
+; RV64-NEXT: li a3, 5
; RV64-NEXT: .LBB0_2: # %cond_true
; RV64-NEXT: # =>This Inner Loop Header: Depth=1
-; RV64-NEXT: sw a4, 0(a3)
-; RV64-NEXT: slli a6, a2, 2
-; RV64-NEXT: add a6, a0, a6
-; RV64-NEXT: addiw a2, a2, 1
-; RV64-NEXT: sw a5, 0(a6)
-; RV64-NEXT: addi a3, a3, 4
-; RV64-NEXT: bne a2, a1, .LBB0_2
+; RV64-NEXT: sw a2, -4(a0)
+; RV64-NEXT: sw a3, 0(a0)
+; RV64-NEXT: addi a0, a0, 4
+; RV64-NEXT: bne a0, a1, .LBB0_2
; RV64-NEXT: .LBB0_3: # %return
; RV64-NEXT: ret
entry:
diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index 9b9bc68ba7ad8..f3fe59a31fbbf 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -60,12 +60,12 @@ define void @f_sadd_overflow(ptr %a) {
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 2147483645, %[[ENTRY]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
; CHECK-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1
-; CHECK-NEXT: br i1 true, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
; CHECK: [[TRAP]]:
; CHECK-NEXT: tail call void @llvm.trap(), !nosanitize [[META0]]
; CHECK-NEXT: unreachable, !nosanitize [[META0]]
; CHECK: [[CONT]]:
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
;
entry:
diff --git a/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll b/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
index 9c442710e2191..25ab339c5d675 100644
--- a/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
+++ b/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
@@ -10,12 +10,12 @@ define i32 @test(i1 %c.0, i32 %m) {
; COMMON-NEXT: entry:
; COMMON-NEXT: br label [[OUTER_HEADER:%.*]]
; COMMON: outer.header:
-; COMMON-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[OUTER_LATCH:%.*]] ]
+; COMMON-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
+; COMMON-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_1_NEXT:%.*]], [[OUTER_LATCH]] ]
; COMMON-NEXT: [[MAX_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[MAX_1:%.*]], [[OUTER_LATCH]] ]
-; COMMON-NEXT: [[TMP0:%.*]] = sext i32 [[IV_1]] to i64
; COMMON-NEXT: br label [[INNER_1:%.*]]
; COMMON: inner.1:
-; COMMON-NEXT: [[C_1:%.*]] = icmp slt i64 0, [[TMP0]]
+; COMMON-NEXT: [[C_1:%.*]] = icmp slt i64 0, [[INDVARS_IV]]
; COMMON-NEXT: br i1 [[C_1]], label [[INNER_1]], label [[INNER_2_HEADER_PREHEADER:%.*]]
; COMMON: inner.2.header.preheader:
; COMMON-NEXT: br label [[INNER_2_HEADER:%.*]]
@@ -30,6 +30,7 @@ define i32 @test(i1 %c.0, i32 %m) {
; COMMON-NEXT: [[MAX_1]] = phi i32 [ [[M]], [[INNER_2_LATCH]] ], [ 0, [[INNER_2_HEADER]] ]
; COMMON-NEXT: [[IV_1_NEXT]] = add i32 [[IV_1]], 1
; COMMON-NEXT: [[C_3:%.*]] = icmp ugt i32 [[IV_1]], [[MAX_0]]
+; COMMON-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
; COMMON-NEXT: br i1 [[C_3]], label [[EXIT:%.*]], label [[OUTER_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]
; COMMON: exit:
; COMMON-NEXT: ret i32 0
diff --git a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
index fb2fdb116f904..74efc110bbc17 100644
--- a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
+++ b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
@@ -83,7 +83,7 @@ define void @test_simplifycompare_rhs_not_constant2(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
; CHECK: [[OUTER_HEADER_LOOPEXIT:.*]]:
-; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[INDVARS_IV:%.*]], 2
+; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 2
; CHECK-NEXT: br label %[[OUTER_HEADER]]
; CHECK: [[OUTER_HEADER]]:
; CHECK-NEXT: [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], %[[OUTER_HEADER_LOOPEXIT]] ], [ 0, %[[ENTRY]] ]
diff --git a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
index 4a230b781d2db..6a889cf4c00b6 100644
--- a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
+++ b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
@@ -309,7 +309,7 @@ define void @test_infer_nsw(ptr %p) {
; CHECK-NEXT: br i1 [[ICMP]], label [[BB2]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: store i16 1, ptr [[P:%.*]], align 2
-; CHECK-NEXT: [[ADD]] = add nuw i32 [[PHI]], 2
+; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[PHI]], 2
; CHECK-NEXT: br label [[BB1]]
; CHECK: bb3:
; CHECK-NEXT: ret void
@@ -432,7 +432,7 @@ define void @test_shl_nuw_only(ptr %p) {
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[OFF:%.*]] = shl nuw i8 [[IV]], 1
; CHECK-NEXT: store i8 [[OFF]], ptr [[P:%.*]], align 1
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], -128
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
diff --git a/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll b/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
index 406b6ecd944f4..96516cbcc0889 100644
--- a/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
+++ b/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
@@ -1065,7 +1065,7 @@ define i32 @not_invariant_samesign(i32 %unknown_limit, ptr %length_ptr) {
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: [[RANGE_CHECK1_FIRST_ITER:%.*]] = icmp samesign ult i32 [[IV_NEXT]], [[UNKNOWN_LIMIT:%.*]]
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[UNKNOWN_LIMIT]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[RANGE_CHECK1_FIRST_ITER]], [[IS_POSITIVE]]
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
index da14e631f5142..3c37ee6b6b98a 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -loop-reduce -S -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s
; Provide legal integer types.
@@ -5,122 +6,201 @@ target datalayout = "n8:16:32:64"
define void @foobar(i32 %n) nounwind {
-
-; CHECK-LABEL: foobar(
-; CHECK: phi double
+; CHECK-LABEL: define void @foobar(
+; CHECK-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N]], 0
+; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_NPH:.*]]
+; CHECK: [[BB_NPH]]:
+; CHECK-NEXT: br label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ 0.000000e+00, %[[BB_NPH]] ], [ [[IV_S_NEXT_:%.*]], %[[BB]] ]
+; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, %[[BB_NPH]] ], [ [[INDVAR_NEXT:%.*]], %[[BB]] ]
+; CHECK-NEXT: tail call void @bar(i32 [[I_03]]) #[[ATTR0]]
+; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
+; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], 1.000000e+00
+; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i32 [[I_03]], 1
+; CHECK-NEXT: [[SCMP:%.*]] = icmp uge i32 [[INDVAR_NEXT]], [[N]]
+; CHECK-NEXT: br i1 [[SCMP]], label %[[RETURN_LOOPEXIT:.*]], label %[[BB]]
+; CHECK: [[RETURN_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
- %cond = icmp eq i32 %n, 0 ; <i1>:0 [#uses=2]
- br i1 %cond, label %return, label %bb.nph
+ %cond = icmp eq i32 %n, 0 ; <i1>:0 [#uses=2]
+ br i1 %cond, label %return, label %bb.nph
bb.nph: ; preds = %entry
- %umax = select i1 %cond, i32 1, i32 %n ; <i32> [#uses=1]
- br label %bb
+ %umax = select i1 %cond, i32 1, i32 %n ; <i32> [#uses=1]
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- tail call void @bar( i32 %i.03 ) nounwind
- %tmp1 = uitofp i32 %i.03 to double ; <double>:1 [#uses=1]
- tail call void @foo( double %tmp1 ) nounwind
- %indvar.next = add nsw nuw i32 %i.03, 1 ; <i32> [#uses=2]
- %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ tail call void @bar( i32 %i.03 ) nounwind
+ %tmp1 = uitofp i32 %i.03 to double ; <double>:1 [#uses=1]
+ tail call void @foo( double %tmp1 ) nounwind
+ %indvar.next = add nsw nuw i32 %i.03, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast because the mantissa bits for double are not enough
; to hold all of i64 IV bits.
define void @foobar2(i64 %n) nounwind {
-
-; CHECK-LABEL: foobar2(
-; CHECK-NOT: phi double
-; CHECK-NOT: phi float
+; CHECK-LABEL: define void @foobar2(
+; CHECK-SAME: i64 [[N:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[N]], 0
+; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_NPH:.*]]
+; CHECK: [[BB_NPH]]:
+; CHECK-NEXT: br label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[I_03:%.*]] = phi i64 [ 0, %[[BB_NPH]] ], [ [[INDVAR_NEXT:%.*]], %[[BB]] ]
+; CHECK-NEXT: [[TMP:%.*]] = trunc i64 [[I_03]] to i32
+; CHECK-NEXT: tail call void @bar(i32 [[TMP]]) #[[ATTR0]]
+; CHECK-NEXT: [[TMP2:%.*]] = uitofp i64 [[I_03]] to double
+; CHECK-NEXT: tail call void @foo(double [[TMP2]]) #[[ATTR0]]
+; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i64 [[I_03]], 1
+; CHECK-NEXT: [[SCMP:%.*]] = icmp uge i64 [[INDVAR_NEXT]], [[N]]
+; CHECK-NEXT: br i1 [[SCMP]], label %[[RETURN_LOOPEXIT:.*]], label %[[BB]]
+; CHECK: [[RETURN_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
- %cond = icmp eq i64 %n, 0 ; <i1>:0 [#uses=2]
- br i1 %cond, label %return, label %bb.nph
+ %cond = icmp eq i64 %n, 0 ; <i1>:0 [#uses=2]
+ br i1 %cond, label %return, label %bb.nph
bb.nph: ; preds = %entry
- %umax = select i1 %cond, i64 1, i64 %n ; <i64> [#uses=1]
- br label %bb
+ %umax = select i1 %cond, i64 1, i64 %n ; <i64> [#uses=1]
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
- %tmp1 = trunc i64 %i.03 to i32 ; <i32>:1 [#uses=1]
- tail call void @bar( i32 %tmp1 ) nounwind
- %tmp2 = uitofp i64 %i.03 to double ; <double>:2 [#uses=1]
- tail call void @foo( double %tmp2 ) nounwind
- %indvar.next = add nsw nuw i64 %i.03, 1 ; <i64> [#uses=2]
- %exitcond = icmp eq i64 %indvar.next, %umax ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
+ %tmp1 = trunc i64 %i.03 to i32 ; <i32>:1 [#uses=1]
+ tail call void @bar( i32 %tmp1 ) nounwind
+ %tmp2 = uitofp i64 %i.03 to double ; <double>:2 [#uses=1]
+ tail call void @foo( double %tmp2 ) nounwind
+ %indvar.next = add nsw nuw i64 %i.03, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %umax ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast due to potentional overflow.
define void @foobar3() nounwind {
-
-; CHECK-LABEL: foobar3(
-; CHECK-NOT: phi double
-; CHECK-NOT: phi float
+; CHECK-LABEL: define void @foobar3(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 (...) @nn() #[[ATTR0]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_PREHEADER:.*]]
+; CHECK: [[BB_PREHEADER]]:
+; CHECK-NEXT: br label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ [[INDVAR_NEXT:%.*]], %[[BB]] ], [ 0, %[[BB_PREHEADER]] ]
+; CHECK-NEXT: tail call void @bar(i32 [[I_03]]) #[[ATTR0]]
+; CHECK-NEXT: [[TMP2:%.*]] = uitofp i32 [[I_03]] to double
+; CHECK-NEXT: tail call void @foo(double [[TMP2]]) #[[ATTR0]]
+; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i32 [[I_03]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 (...) @nn() #[[ATTR0]]
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[TMP4]], [[INDVAR_NEXT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[BB]], label %[[RETURN_LOOPEXIT:.*]]
+; CHECK: [[RETURN_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
- %tmp0 = tail call i32 (...) @nn( ) nounwind ; <i32>:0 [#uses=1]
- %cond = icmp eq i32 %tmp0, 0 ; <i1>:1 [#uses=1]
- br i1 %cond, label %return, label %bb
+ %tmp0 = tail call i32 (...) @nn( ) nounwind ; <i32>:0 [#uses=1]
+ %cond = icmp eq i32 %tmp0, 0 ; <i1>:1 [#uses=1]
+ br i1 %cond, label %return, label %bb
bb: ; preds = %bb, %entry
- %i.03 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- tail call void @bar( i32 %i.03 ) nounwind
- %tmp2 = uitofp i32 %i.03 to double ; <double>:2 [#uses=1]
- tail call void @foo( double %tmp2 ) nounwind
- %indvar.next = add nuw nsw i32 %i.03, 1 ; <i32>:3 [#uses=2]
- %tmp4 = tail call i32 (...) @nn( ) nounwind ; <i32>:4 [#uses=1]
- %exitcond = icmp ugt i32 %tmp4, %indvar.next ; <i1>:5 [#uses=1]
- br i1 %exitcond, label %bb, label %return
+ %i.03 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ tail call void @bar( i32 %i.03 ) nounwind
+ %tmp2 = uitofp i32 %i.03 to double ; <double>:2 [#uses=1]
+ tail call void @foo( double %tmp2 ) nounwind
+ %indvar.next = add nuw nsw i32 %i.03, 1 ; <i32>:3 [#uses=2]
+ %tmp4 = tail call i32 (...) @nn( ) nounwind ; <i32>:4 [#uses=1]
+ %exitcond = icmp ugt i32 %tmp4, %indvar.next ; <i1>:5 [#uses=1]
+ br i1 %exitcond, label %bb, label %return
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast due to overflow.
define void @foobar4() nounwind {
-
-; CHECK-LABEL: foobar4(
-; CHECK-NOT: phi double
-; CHECK-NOT: phi float
+; CHECK-LABEL: define void @foobar4(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[BB_NPH:.*]]
+; CHECK: [[BB_NPH]]:
+; CHECK-NEXT: br label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[BB]] ], [ 0, %[[BB_NPH]] ]
+; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ 0.000000e+00, %[[BB_NPH]] ], [ [[IV_S_NEXT_:%.*]], %[[BB]] ]
+; CHECK-NEXT: tail call void @bar(i32 [[LSR_IV]]) #[[ATTR0]]
+; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
+; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], 1.000000e+00
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 32767
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[RETURN:.*]], label %[[BB]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
- br label %bb.nph
+ br label %bb.nph
bb.nph: ; preds = %entry
- br label %bb
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i8 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- %tmp2 = sext i8 %i.03 to i32 ; <i32>:0 [#uses=1]
- tail call void @bar( i32 %tmp2 ) nounwind
- %tmp3 = uitofp i8 %i.03 to double ; <double>:1 [#uses=1]
- tail call void @foo( double %tmp3 ) nounwind
- %indvar.next = add nsw nuw i8 %i.03, 1 ; <i32> [#uses=2]
- %tmp = sext i8 %indvar.next to i32
- %exitcond = icmp eq i32 %tmp, 32767 ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i8 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ %tmp2 = sext i8 %i.03 to i32 ; <i32>:0 [#uses=1]
+ tail call void @bar( i32 %tmp2 ) nounwind
+ %tmp3 = uitofp i8 %i.03 to double ; <double>:1 [#uses=1]
+ tail call void @foo( double %tmp3 ) nounwind
+ %indvar.next = add nsw nuw i8 %i.03, 1 ; <i32> [#uses=2]
+ %tmp = sext i8 %indvar.next to i32
+ %exitcond = icmp eq i32 %tmp, 32767 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast because the integer IV overflows (accum exceeds
; SINT_MAX).
define i32 @foobar5() {
-; CHECK-LABEL: foobar5(
-; CHECK-NOT: phi double
-; CHECK-NOT: phi float
+; CHECK-LABEL: define i32 @foobar5() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
+; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = sitofp i32 [[ACCUM]] to double
+; CHECK-NEXT: tail call void @foo(double [[TMP1]]) #[[ATTR0]]
+; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
+;
entry:
br label %loop
@@ -141,8 +221,22 @@ exit: ; preds = %loop
; Can eliminate if we set nsw and, thus, think that we don't overflow SINT_MAX.
define i32 @foobar6() {
-; CHECK-LABEL: foobar6(
-; CHECK: phi double
+; CHECK-LABEL: define i32 @foobar6() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ -3.220000e+03, %[[ENTRY]] ], [ [[IV_S_NEXT_:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
+; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], f0x41624E65A0000000
+; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
+;
entry:
br label %loop
@@ -165,9 +259,21 @@ exit: ; preds = %loop
; UINT_MAX).
define i32 @foobar7() {
-; CHECK-LABEL: foobar7(
-; CHECK-NOT: phi double
-; CHECK-NOT: phi float
+; CHECK-LABEL: define i32 @foobar7() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
+; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = uitofp i32 [[ACCUM]] to double
+; CHECK-NEXT: tail call void @foo(double [[TMP1]]) #[[ATTR0]]
+; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
+;
entry:
br label %loop
@@ -188,8 +294,22 @@ exit: ; preds = %loop
; Can eliminate if we set nuw and, thus, think that we don't overflow UINT_MAX.
define i32 @foobar8() {
-; CHECK-LABEL: foobar8(
-; CHECK: phi double
+; CHECK-LABEL: define i32 @foobar8() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ f0x41EFFFFE6D800000, %[[ENTRY]] ], [ [[IV_S_NEXT_:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
+; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], f0x41624E65A0000000
+; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
+;
entry:
br label %loop
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
index f780bee7874cf..a5300b3fb81e1 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
@@ -108,7 +108,7 @@ define void @test2(i32 %n, i1 %arg) nounwind uwtable {
; CHECK-NEXT: br label [[FOR_INC498:%.*]]
; CHECK: if.then477:
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV]], i64 12
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw i32 [[LSR_IV1]], 1
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV1]], 1
; CHECK-NEXT: br label [[FOR_COND468]]
; CHECK: for.inc498:
; CHECK-NEXT: br label [[FOR_INC498]]
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
index a878fc2c39e82..f39d33e77b7a4 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -loop-reduce -S | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
@@ -7,8 +8,6 @@ target triple = "x86_64-apple-macosx10.9.0"
; expression. In this testcase, the normalized expression was denormalized to
; an expression different from the original, and we were losing sign extension.
-; CHECK: [[TMP:%[a-z]+]] = trunc i32 {{.*}} to i8
-; CHECK: {{%[a-z0-9]+}} = sext i8 [[TMP]] to i32
@j = common global i32 0, align 4
@c = common global i32 0, align 4
@@ -23,6 +22,41 @@ target triple = "x86_64-apple-macosx10.9.0"
; Function Attrs: nounwind optsize ssp uwtable
define i32 @main() #0 {
+; CHECK-LABEL: define i32 @main(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: store i8 0, ptr @h, align 1
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @j, align 4
+; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @d, align 4
+; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[TMP1]], -1
+; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[TMP1]], 31
+; CHECK-NEXT: [[DOTLOBIT_NOT:%.*]] = xor i32 [[DOTLOBIT]], 1
+; CHECK-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i32 [ [[LSR_IV_NEXT2:%.*]], %[[FN3_EXIT:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[FN3_EXIT]] ], [ -1, %[[ENTRY]] ]
+; CHECK-NEXT: br i1 [[TOBOOL_I]], label %[[FN3_EXIT]], label %[[LAND_RHS_I:.*]]
+; CHECK: [[LAND_RHS_I]]:
+; CHECK-NEXT: store i32 0, ptr @c, align 4
+; CHECK-NEXT: br label %[[FN3_EXIT]]
+; CHECK: [[FN3_EXIT]]:
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], 2
+; CHECK-NEXT: [[LSR_IV_NEXT2]] = add nuw nsw i32 [[LSR_IV1]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[LSR_IV_NEXT2]] to i8
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[TMP3]], -1
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
+; CHECK: [[FOR_END]]:
+; CHECK-NEXT: [[DOTLOBIT_NOT_:%.*]] = select i1 [[CMP3]], i32 [[DOTLOBIT_NOT]], i32 0
+; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[LSR_IV_NEXT2]], -1
+; CHECK-NEXT: store i32 [[TMP2]], ptr @g, align 4
+; CHECK-NEXT: store i32 [[DOTLOBIT_NOT_]], ptr @i, align 4
+; CHECK-NEXT: [[TMP:%.*]] = trunc i32 [[LSR_IV_NEXT2]] to i8
+; CHECK-NEXT: store i8 [[TMP]], ptr @h, align 1
+; CHECK-NEXT: store i32 [[LSR_IV_NEXT]], ptr @e, align 4
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 (ptr, ...) @printf(ptr @.str, i32 [[LSR_IV_NEXT]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret i32 0
+;
entry:
store i8 0, ptr @h, align 1
%0 = load i32, ptr @j, align 4
diff --git a/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll b/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
index 10b22974080dc..bfc46c1219716 100644
--- a/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
@@ -313,7 +313,7 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; APPLE: [[EXIT]]:
; APPLE-NEXT: ret void
;
-; ; OTHER-LABEL: define void @load_op_store_loop_multiblock(
+; OTHER-LABEL: define void @load_op_store_loop_multiblock(
; OTHER-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]], i64 [[N:%.*]], i64 [[SCALE:%.*]], float [[K:%.*]]) #[[ATTR0]] {
; OTHER-NEXT: [[ENTRY:.*]]:
; OTHER-NEXT: br label %[[LOOP:.*]]
@@ -321,12 +321,12 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; OTHER-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOPCONT:.*]] ]
; OTHER-NEXT: [[SCALED_IV:%.*]] = mul nuw nsw i64 [[IV]], [[SCALE]]
; OTHER-NEXT: [[GEP_SRC:%.*]] = getelementptr inbounds float, ptr [[SRC]], i64 [[SCALED_IV]]
-; OTHER-NEXT: [[L:%.*]] = load float, ptr [[GEP_SRC]], align 4
+; OTHER-NEXT: [[L1:%.*]] = load float, ptr [[GEP_SRC]], align 4
; OTHER-NEXT: [[AND:%.*]] = and i64 [[IV]], 1
; OTHER-NEXT: [[ODD:%.*]] = icmp eq i64 [[AND]], 1
; OTHER-NEXT: br i1 [[ODD]], label %[[LOOPODD:.*]], label %[[LOOPCONT]]
; OTHER: [[LOOPCONT]]:
-; OTHER-NEXT: [[D:%.*]] = phi float [ [[L2:%.*]], %[[LOOPODD]] ], [ [[L]], %[[LOOP]] ]
+; OTHER-NEXT: [[D:%.*]] = phi float [ [[L2:%.*]], %[[LOOPODD]] ], [ [[L1]], %[[LOOP]] ]
; OTHER-NEXT: [[O:%.*]] = fadd float [[D]], [[K]]
; OTHER-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds float, ptr [[DST]], i64 [[IV]]
; OTHER-NEXT: store float [[O]], ptr [[GEP_DST]], align 4
@@ -334,7 +334,7 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; OTHER-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; OTHER-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
; OTHER: [[LOOPODD]]:
-; OTHER-NEXT: [[L2]] = fneg float [[L]]
+; OTHER-NEXT: [[L2]] = fneg float [[L1]]
; OTHER-NEXT: br label %[[LOOPCONT]]
; OTHER: [[EXIT]]:
; OTHER-NEXT: ret void
@@ -1062,7 +1062,7 @@ define i32 @test_add_reduction_runtime(ptr %a, i64 noundef %n) {
; APPLE-NEXT: [[TMP5:%.*]] = load i32, ptr [[GEP_A_3]], align 2
; APPLE-NEXT: [[RDX_NEXT_3]] = add i32 [[RDX_3]], [[TMP5]]
; APPLE-NEXT: [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4
-; APPLE-NEXT: [[NITER_NEXT_3]] = add nuw i64 [[NITER]], 4
+; APPLE-NEXT: [[NITER_NEXT_3]] = add nuw nsw i64 [[NITER]], 4
; APPLE-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i64 [[NITER_NEXT_3]], [[UNROLL_ITER]]
; APPLE-NEXT: br i1 [[NITER_NCMP_3]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]]
; APPLE: [[EXIT_UNR_LCSSA]]:
diff --git a/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll b/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
index c00f744ac3ddf..8060501fc5dd9 100644
--- a/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -mtriple=armv7 -mcpu=cortex-a57 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
; RUN: opt -mtriple=thumbv7 -mcpu=cortex-a57 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
; RUN: opt -mtriple=thumbv7 -mcpu=cortex-a72 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
@@ -5,40 +6,177 @@
; RUN: opt -mtriple=thumbv8m.main -mcpu=cortex-m33 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-UNROLL
; RUN: opt -mtriple=thumbv7em -mcpu=cortex-m7 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-UNROLL
-; CHECK-LABEL: partial
define arm_aapcs_vfpcc void @partial(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B) local_unnamed_addr #0 {
+; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @partial(
+; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-NOUNROLL-NEXT: [[ENTRY:.*]]:
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY]]:
+; CHECK-NOUNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC_1:%.*]], %[[FOR_BODY]] ]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_08]], 1
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC_1]] = add nuw nsw i32 [[I_08]], 2
+; CHECK-NOUNROLL-NEXT: [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 1024
+; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND_1]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
+; CHECK-NOUNROLL-NEXT: ret void
+;
+; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @partial(
+; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-UNROLL-NEXT: [[ENTRY:.*]]:
+; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-UNROLL: [[FOR_BODY]]:
+; CHECK-UNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC_15:%.*]], %[[FOR_BODY]] ]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-UNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-UNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_08]], 1
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
+; CHECK-UNROLL-NEXT: [[INC_1:%.*]] = add nuw nsw i32 [[I_08]], 2
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_2]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_2:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_2]], ptr [[ARRAYIDX2_2]], align 4
+; CHECK-UNROLL-NEXT: [[INC_2:%.*]] = add nuw nsw i32 [[I_08]], 3
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_3]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_3:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_3]], ptr [[ARRAYIDX2_3]], align 4
+; CHECK-UNROLL-NEXT: [[INC_3:%.*]] = add nuw nsw i32 [[I_08]], 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_3]]
+; CHECK-UNROLL-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_4:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_3]]
+; CHECK-UNROLL-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX1_4]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_4:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_4:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_3]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_4]], ptr [[ARRAYIDX2_4]], align 4
+; CHECK-UNROLL-NEXT: [[INC_4:%.*]] = add nuw nsw i32 [[I_08]], 5
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_4]]
+; CHECK-UNROLL-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_5:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_4]]
+; CHECK-UNROLL-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX1_5]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_5:%.*]] = mul nsw i32 [[TMP11]], [[TMP10]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_5:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_4]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_5]], ptr [[ARRAYIDX2_5]], align 4
+; CHECK-UNROLL-NEXT: [[INC_5:%.*]] = add nuw nsw i32 [[I_08]], 6
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_5]]
+; CHECK-UNROLL-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_6:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_5]]
+; CHECK-UNROLL-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX1_6]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_6:%.*]] = mul nsw i32 [[TMP13]], [[TMP12]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_6:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_5]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_6]], ptr [[ARRAYIDX2_6]], align 4
+; CHECK-UNROLL-NEXT: [[INC_6:%.*]] = add nuw nsw i32 [[I_08]], 7
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_6]]
+; CHECK-UNROLL-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_7:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_6]]
+; CHECK-UNROLL-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX1_7]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_7:%.*]] = mul nsw i32 [[TMP15]], [[TMP14]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_7:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_6]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_7]], ptr [[ARRAYIDX2_7]], align 4
+; CHECK-UNROLL-NEXT: [[INC_7:%.*]] = add nuw nsw i32 [[I_08]], 8
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_8:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_7]]
+; CHECK-UNROLL-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX_8]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_8:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_7]]
+; CHECK-UNROLL-NEXT: [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX1_8]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_8:%.*]] = mul nsw i32 [[TMP17]], [[TMP16]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_8:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_7]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_8]], ptr [[ARRAYIDX2_8]], align 4
+; CHECK-UNROLL-NEXT: [[INC_8:%.*]] = add nuw nsw i32 [[I_08]], 9
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_9:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_8]]
+; CHECK-UNROLL-NEXT: [[TMP18:%.*]] = load i32, ptr [[ARRAYIDX_9]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_9:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_8]]
+; CHECK-UNROLL-NEXT: [[TMP19:%.*]] = load i32, ptr [[ARRAYIDX1_9]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_9:%.*]] = mul nsw i32 [[TMP19]], [[TMP18]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_9:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_8]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_9]], ptr [[ARRAYIDX2_9]], align 4
+; CHECK-UNROLL-NEXT: [[INC_9:%.*]] = add nuw nsw i32 [[I_08]], 10
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_10:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_9]]
+; CHECK-UNROLL-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARRAYIDX_10]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_10:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_9]]
+; CHECK-UNROLL-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX1_10]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_10:%.*]] = mul nsw i32 [[TMP21]], [[TMP20]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_10:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_9]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_10]], ptr [[ARRAYIDX2_10]], align 4
+; CHECK-UNROLL-NEXT: [[INC_10:%.*]] = add nuw nsw i32 [[I_08]], 11
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_11:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_10]]
+; CHECK-UNROLL-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX_11]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_11:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_10]]
+; CHECK-UNROLL-NEXT: [[TMP23:%.*]] = load i32, ptr [[ARRAYIDX1_11]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_11:%.*]] = mul nsw i32 [[TMP23]], [[TMP22]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_11:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_10]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_11]], ptr [[ARRAYIDX2_11]], align 4
+; CHECK-UNROLL-NEXT: [[INC_11:%.*]] = add nuw nsw i32 [[I_08]], 12
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_12:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_11]]
+; CHECK-UNROLL-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX_12]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_12:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_11]]
+; CHECK-UNROLL-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX1_12]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_12:%.*]] = mul nsw i32 [[TMP25]], [[TMP24]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_12:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_11]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_12]], ptr [[ARRAYIDX2_12]], align 4
+; CHECK-UNROLL-NEXT: [[INC_12:%.*]] = add nuw nsw i32 [[I_08]], 13
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_13:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_12]]
+; CHECK-UNROLL-NEXT: [[TMP26:%.*]] = load i32, ptr [[ARRAYIDX_13]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_13:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_12]]
+; CHECK-UNROLL-NEXT: [[TMP27:%.*]] = load i32, ptr [[ARRAYIDX1_13]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_13:%.*]] = mul nsw i32 [[TMP27]], [[TMP26]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_13:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_12]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_13]], ptr [[ARRAYIDX2_13]], align 4
+; CHECK-UNROLL-NEXT: [[INC_13:%.*]] = add nuw nsw i32 [[I_08]], 14
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_14:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_13]]
+; CHECK-UNROLL-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX_14]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_14:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_13]]
+; CHECK-UNROLL-NEXT: [[TMP29:%.*]] = load i32, ptr [[ARRAYIDX1_14]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_14:%.*]] = mul nsw i32 [[TMP29]], [[TMP28]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_14:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_13]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_14]], ptr [[ARRAYIDX2_14]], align 4
+; CHECK-UNROLL-NEXT: [[INC_14:%.*]] = add nuw nsw i32 [[I_08]], 15
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_15:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_14]]
+; CHECK-UNROLL-NEXT: [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX_15]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_15:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_14]]
+; CHECK-UNROLL-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1_15]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_15:%.*]] = mul nsw i32 [[TMP31]], [[TMP30]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_15:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_14]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_15]], ptr [[ARRAYIDX2_15]], align 4
+; CHECK-UNROLL-NEXT: [[INC_15]] = add nuw nsw i32 [[I_08]], 16
+; CHECK-UNROLL-NEXT: [[EXITCOND_15:%.*]] = icmp eq i32 [[INC_15]], 1024
+; CHECK-UNROLL-NEXT: br i1 [[EXITCOND_15]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP]]:
+; CHECK-UNROLL-NEXT: ret void
+;
entry:
br label %for.body
-; CHECK-LABEL: for.body
for.body:
-
-; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV2:%[a-z.0-9]+]], %for.body ]
-; CHECK-NOUNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-NOUNROLL: [[IV2]] = add nuw nsw i32 [[IV0]], 2
-; CHECK-NOUNROLL: [[CMP:%[a-z.0-9]+]] = icmp eq i32 [[IV2]], 1024
-; CHECK-NOUNROLL: br i1 [[CMP]], label [[END:%[a-z.]+]], label %for.body
-
-; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV16:%[a-z.0-9]+]], %for.body ]
-; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
-; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
-; CHECK-UNROLL: [[IV4:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 4
-; CHECK-UNROLL: [[IV5:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 5
-; CHECK-UNROLL: [[IV6:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 6
-; CHECK-UNROLL: [[IV7:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 7
-; CHECK-UNROLL: [[IV8:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 8
-; CHECK-UNROLL: [[IV9:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 9
-; CHECK-UNROLL: [[IV10:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 10
-; CHECK-UNROLL: [[IV11:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 11
-; CHECK-UNROLL: [[IV12:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 12
-; CHECK-UNROLL: [[IV13:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 13
-; CHECK-UNROLL: [[IV14:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 14
-; CHECK-UNROLL: [[IV15:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 15
-; CHECK-UNROLL: [[IV16]] = add nuw nsw i32 [[IV0]], 16
-; CHECK-UNROLL: [[CMP:%[a-z.0-9]+]] = icmp eq i32 [[IV16]], 1024
-; CHECK-UNROLL: br i1 [[CMP]], label [[END:%[a-z.]+]], label %for.body
-
%i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.08
%0 = load i32, ptr %arrayidx, align 4
@@ -55,30 +193,168 @@ for.cond.cleanup:
ret void
}
-; CHECK-LABEL: runtime
define arm_aapcs_vfpcc void @runtime(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B, i32 %N) local_unnamed_addr #0 {
+; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @runtime(
+; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
+; CHECK-NOUNROLL-NEXT: [[CMP8:%.*]] = icmp eq i32 [[N]], 0
+; CHECK-NOUNROLL-NEXT: br i1 [[CMP8]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY_PREHEADER:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY_PREHEADER]]:
+; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
+; CHECK-NOUNROLL-NEXT: [[XTRAITER:%.*]] = and i32 [[N]], 1
+; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 1
+; CHECK-NOUNROLL-NEXT: br i1 [[TMP1]], label %[[FOR_BODY_EPIL_PREHEADER:.*]], label %[[FOR_BODY_PREHEADER_NEW:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY_PREHEADER_NEW]]:
+; CHECK-NOUNROLL-NEXT: [[UNROLL_ITER:%.*]] = sub i32 [[N]], [[XTRAITER]]
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY]]:
+; CHECK-NOUNROLL-NEXT: [[I_09:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1:%.*]], %[[FOR_BODY]] ]
+; CHECK-NOUNROLL-NEXT: [[NITER:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], %[[FOR_BODY]] ]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]]
+; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]]
+; CHECK-NOUNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]]
+; CHECK-NOUNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_09]], 1
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
+; CHECK-NOUNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC_1]] = add nuw nsw i32 [[I_09]], 2
+; CHECK-NOUNROLL-NEXT: [[NITER_NEXT_1]] = add nuw nsw i32 [[NITER]], 2
+; CHECK-NOUNROLL-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]
+; CHECK-NOUNROLL-NEXT: br i1 [[NITER_NCMP_1]], label %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:.*]], label %[[FOR_BODY]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]]:
+; CHECK-NOUNROLL-NEXT: [[I_09_UNR:%.*]] = phi i32 [ [[INC_1]], %[[FOR_BODY]] ]
+; CHECK-NOUNROLL-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
+; CHECK-NOUNROLL-NEXT: br i1 [[LCMP_MOD]], label %[[FOR_BODY_EPIL_PREHEADER]], label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY_EPIL_PREHEADER]]:
+; CHECK-NOUNROLL-NEXT: [[I_09_EPIL_INIT:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[I_09_UNR]], %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]] ]
+; CHECK-NOUNROLL-NEXT: [[LCMP_MOD1:%.*]] = icmp ne i32 [[XTRAITER]], 0
+; CHECK-NOUNROLL-NEXT: call void @llvm.assume(i1 [[LCMP_MOD1]])
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY_EPIL:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY_EPIL]]:
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09_EPIL_INIT]]
+; CHECK-NOUNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09_EPIL_INIT]]
+; CHECK-NOUNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4
+; CHECK-NOUNROLL-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09_EPIL_INIT]]
+; CHECK-NOUNROLL-NEXT: store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT]]:
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
+; CHECK-NOUNROLL-NEXT: ret void
+;
+; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @runtime(
+; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-UNROLL-NEXT: [[ENTRY:.*:]]
+; CHECK-UNROLL-NEXT: [[CMP8:%.*]] = icmp eq i32 [[N]], 0
+; CHECK-UNROLL-NEXT: br i1 [[CMP8]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY_PREHEADER:.*]]
+; CHECK-UNROLL: [[FOR_BODY_PREHEADER]]:
+; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
+; CHECK-UNROLL-NEXT: [[XTRAITER:%.*]] = and i32 [[N]], 3
+; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
+; CHECK-UNROLL-NEXT: br i1 [[TMP1]], label %[[FOR_BODY_EPIL_PREHEADER:.*]], label %[[FOR_BODY_PREHEADER_NEW:.*]]
+; CHECK-UNROLL: [[FOR_BODY_PREHEADER_NEW]]:
+; CHECK-UNROLL-NEXT: [[UNROLL_ITER:%.*]] = sub i32 [[N]], [[XTRAITER]]
+; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-UNROLL: [[FOR_BODY]]:
+; CHECK-UNROLL-NEXT: [[I_09:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_3:%.*]], %[[FOR_BODY]] ]
+; CHECK-UNROLL-NEXT: [[NITER:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], %[[FOR_BODY]] ]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]]
+; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]]
+; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-UNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-UNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_09]], 1
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
+; CHECK-UNROLL-NEXT: [[INC_1:%.*]] = add nuw nsw i32 [[I_09]], 2
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_2]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_2:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_1]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_2]], ptr [[ARRAYIDX2_2]], align 4
+; CHECK-UNROLL-NEXT: [[INC_2:%.*]] = add nuw nsw i32 [[I_09]], 3
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX1_3]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_3:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_2]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_3]], ptr [[ARRAYIDX2_3]], align 4
+; CHECK-UNROLL-NEXT: [[INC_3]] = add nuw nsw i32 [[I_09]], 4
+; CHECK-UNROLL-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
+; CHECK-UNROLL-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
+; CHECK-UNROLL-NEXT: br i1 [[NITER_NCMP_3]], label %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:.*]], label %[[FOR_BODY]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]]:
+; CHECK-UNROLL-NEXT: [[I_09_UNR:%.*]] = phi i32 [ [[INC_3]], %[[FOR_BODY]] ]
+; CHECK-UNROLL-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
+; CHECK-UNROLL-NEXT: br i1 [[LCMP_MOD]], label %[[FOR_BODY_EPIL_PREHEADER]], label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
+; CHECK-UNROLL: [[FOR_BODY_EPIL_PREHEADER]]:
+; CHECK-UNROLL-NEXT: [[I_09_EPIL_INIT:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[I_09_UNR]], %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]] ]
+; CHECK-UNROLL-NEXT: [[LCMP_MOD1:%.*]] = icmp ne i32 [[XTRAITER]], 0
+; CHECK-UNROLL-NEXT: call void @llvm.assume(i1 [[LCMP_MOD1]])
+; CHECK-UNROLL-NEXT: br label %[[FOR_BODY_EPIL:.*]]
+; CHECK-UNROLL: [[FOR_BODY_EPIL]]:
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09_EPIL_INIT]]
+; CHECK-UNROLL-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09_EPIL_INIT]]
+; CHECK-UNROLL-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[TMP11]], [[TMP10]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09_EPIL_INIT]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4
+; CHECK-UNROLL-NEXT: [[INC_EPIL:%.*]] = add nuw i32 [[I_09_EPIL_INIT]], 1
+; CHECK-UNROLL-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
+; CHECK-UNROLL-NEXT: br i1 [[EPIL_ITER_CMP]], label %[[FOR_BODY_EPIL_1:.*]], label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA:.*]]
+; CHECK-UNROLL: [[FOR_BODY_EPIL_1]]:
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_EPIL]]
+; CHECK-UNROLL-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_1]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_EPIL]]
+; CHECK-UNROLL-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL_1]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_EPIL_1:%.*]] = mul nsw i32 [[TMP13]], [[TMP12]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_EPIL]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL_1]], ptr [[ARRAYIDX2_EPIL_1]], align 4
+; CHECK-UNROLL-NEXT: [[INC_EPIL_1:%.*]] = add nuw i32 [[I_09_EPIL_INIT]], 2
+; CHECK-UNROLL-NEXT: [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
+; CHECK-UNROLL-NEXT: br i1 [[EPIL_ITER_CMP_1]], label %[[FOR_BODY_EPIL_2:.*]], label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]
+; CHECK-UNROLL: [[FOR_BODY_EPIL_2]]:
+; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_EPIL_1]]
+; CHECK-UNROLL-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_2]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_EPIL_1]]
+; CHECK-UNROLL-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL_2]], align 4
+; CHECK-UNROLL-NEXT: [[MUL_EPIL_2:%.*]] = mul nsw i32 [[TMP15]], [[TMP14]]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_EPIL_1]]
+; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL_2]], ptr [[ARRAYIDX2_EPIL_2]], align 4
+; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]:
+; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT]]:
+; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP]]:
+; CHECK-UNROLL-NEXT: ret void
+;
entry:
%cmp8 = icmp eq i32 %N, 0
br i1 %cmp8, label %for.cond.cleanup, label %for.body
-; CHECK-LABEL: for.body
for.body:
-; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z.0-9]+]] ], [ [[IV2:%[a-z.0-9]+]], %for.body ]
-; CHECK-NOUNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-NOUNROLL: [[IV2]] = add nuw i32 [[IV0]], 2
-; CHECK-NOUNROLL: br
-
-; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z.0-9]+]] ], [ [[IV4:%[a-z.0-9]+]], %for.body ]
-; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
-; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
-; CHECK-UNROLL: [[IV4]] = add nuw i32 [[IV0]], 4
-; CHECK-UNROLL: br
-
-; CHECK-UNROLL: for.body.epil:
-; CHECK-UNROLL: for.body.epil.1:
-; CHECK-UNROLL: for.body.epil.2:
-
%i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.09
%0 = load i32, ptr %arrayidx, align 4
@@ -95,8 +371,44 @@ for.cond.cleanup:
ret void
}
-; CHECK-LABEL: nested_runtime
define arm_aapcs_vfpcc void @nested_runtime(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B, i32 %N) local_unnamed_addr #0 {
+; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @nested_runtime(
+; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
+; CHECK-NOUNROLL-NEXT: [[CMP25:%.*]] = icmp eq i32 [[N]], 0
+; CHECK-NOUNROLL-NEXT: br i1 [[CMP25]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY4_LR_PH_PREHEADER:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY4_LR_PH_PREHEADER]]:
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY4_LR_PH:.*]]
+; CHECK-NOUNROLL: [[FOR_BODY4_LR_PH]]:
+; CHECK-NOUNROLL-NEXT: [[H_026:%.*]] = phi i32 [ [[INC11:%.*]], %[[FOR_COND_CLEANUP3:.*]] ], [ 0, %[[FOR_BODY4_LR_PH_PREHEADER]] ]
+; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul i32 [[H_026]], [[N]]
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT:.*]]:
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
+; CHECK-NOUNROLL-NEXT: ret void
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP3]]:
+; CHECK-NOUNROLL-NEXT: [[INC11]] = add nuw i32 [[H_026]], 1
+; CHECK-NOUNROLL-NEXT: [[EXITCOND27:%.*]] = icmp eq i32 [[INC11]], [[N]]
+; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND27]], label %[[FOR_COND_CLEANUP_LOOPEXIT]], label %[[FOR_BODY4_LR_PH]]
+; CHECK-NOUNROLL: [[FOR_BODY4]]:
+; CHECK-NOUNROLL-NEXT: [[W_024:%.*]] = phi i32 [ 0, %[[FOR_BODY4_LR_PH]] ], [ [[INC:%.*]], %[[FOR_BODY4]] ]
+; CHECK-NOUNROLL-NEXT: [[ADD:%.*]] = add i32 [[W_024]], [[MUL]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[A]], i32 [[ADD]]
+; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
+; CHECK-NOUNROLL-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[W_024]]
+; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX5]], align 2
+; CHECK-NOUNROLL-NEXT: [[CONV6:%.*]] = sext i16 [[TMP1]] to i32
+; CHECK-NOUNROLL-NEXT: [[MUL7:%.*]] = mul nsw i32 [[CONV6]], [[CONV]]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[W_024]]
+; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX8]], align 4
+; CHECK-NOUNROLL-NEXT: [[ADD9:%.*]] = add nsw i32 [[MUL7]], [[TMP2]]
+; CHECK-NOUNROLL-NEXT: store i32 [[ADD9]], ptr [[ARRAYIDX8]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC]] = add nuw i32 [[W_024]], 1
+; CHECK-NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]]
+; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]]
+;
entry:
%cmp25 = icmp eq i32 %N, 0
br i1 %cmp25, label %for.cond.cleanup, label %for.body4.lr.ph
@@ -114,22 +426,7 @@ for.cond.cleanup3:
%exitcond27 = icmp eq i32 %inc11, %N
br i1 %exitcond27, label %for.cond.cleanup, label %for.body4.lr.ph
-; CHECK-LABEL: for.body4
for.body4:
-; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z0-9.]+]] ], [ [[IV1:%[a-z.0-9]+]], %for.body4 ]
-; CHECK-NOUNROLL: [[IV1]] = add nuw i32 [[IV0]], 1
-; CHECK-NOUNROLL: br
-
-; CHECK-UNROLL: for.body4.epil:
-; CHECK-UNROLL: for.body4.epil.1:
-; CHECK-UNROLL: for.body4.epil.2:
-; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z0-9.]+]] ], [ [[IV4:%[a-z.0-9]+]], %for.body4 ]
-; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
-; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
-; CHECK-UNROLL: [[IV4]] = add nuw i32 [[IV0]], 4
-; CHECK-UNROLL: br
-
%w.024 = phi i32 [ 0, %for.body4.lr.ph ], [ %inc, %for.body4 ]
%add = add i32 %w.024, %mul
%arrayidx = getelementptr inbounds i16, ptr %A, i32 %add
@@ -148,26 +445,52 @@ for.body4:
br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
}
-; CHECK-LABEL: loop_call
define arm_aapcs_vfpcc void @loop_call(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B) local_unnamed_addr #1 {
+; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @loop_call(
+; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NOUNROLL-NEXT: [[ENTRY:.*]]:
+; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-NOUNROLL: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NOUNROLL-NEXT: ret void
+; CHECK-NOUNROLL: [[FOR_BODY]]:
+; CHECK-NOUNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-NOUNROLL-NEXT: [[CALL:%.*]] = tail call arm_aapcs_vfpcc i32 @some_func(i32 [[TMP0]], i32 [[TMP1]])
+; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
+; CHECK-NOUNROLL-NEXT: store i32 [[CALL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-NOUNROLL-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1
+; CHECK-NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1024
+; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
+;
+; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @loop_call(
+; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-UNROLL-NEXT: [[ENTRY:.*]]:
+; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK-UNROLL: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-UNROLL-NEXT: ret void
+; CHECK-UNROLL: [[FOR_BODY]]:
+; CHECK-UNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
+; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; CHECK-UNROLL-NEXT: [[CALL:%.*]] = tail call arm_aapcs_vfpcc i32 @some_func(i32 [[TMP0]], i32 [[TMP1]])
+; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
+; CHECK-UNROLL-NEXT: store i32 [[CALL]], ptr [[ARRAYIDX2]], align 4
+; CHECK-UNROLL-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1
+; CHECK-UNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1024
+; CHECK-UNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
+;
entry:
br label %for.body
for.cond.cleanup:
ret void
-; CHECK-LABEL: for.body
for.body:
-; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV1:%[a-z.0-9]+]], %for.body ]
-; CHECK-NOUNROLL: [[IV1]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-NOUNROLL: icmp eq i32 [[IV1]], 1024
-; CHECK-NOUNROLL: br
-
-; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV1:%[a-z.0-9]+]], %for.body ]
-; CHECK-UNROLL: [[IV1]] = add nuw nsw i32 [[IV0]], 1
-; CHECK-UNROLL: icmp eq i32 [[IV1]], 1024
-; CHECK-UNROLL: br
-
%i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.08
%0 = load i32, ptr %arrayidx, align 4
@@ -181,27 +504,75 @@ for.body:
br i1 %exitcond, label %for.cond.cleanup, label %for.body
}
-; CHECK-LABEL: iterate_inc
-; CHECK-NOUNROLL: %n.addr.04 = phi ptr [ %1, %while.body ], [ %n, %while.body.preheader ]
-; CHECK-NOUNROLL: %tobool = icmp eq ptr %1, null
-; CHECK-NOUNROLL: br i1 %tobool
-; CHECK-NOUNROLL-NOT: load
-
-; CHECK-UNROLL: [[CMP0:%[a-z.0-9]+]] = icmp eq ptr [[VAR0:%[a-z.0-9]+]], null
-; CHECK-UNROLL: br i1 [[CMP0]], label [[END:%[a-z.0-9]+]]
-; CHECK-UNROLL: [[CMP1:%[a-z.0-9]+]] = icmp eq ptr [[VAR1:%[a-z.0-9]+]], null
-; CHECK-UNROLL: br i1 [[CMP1]], label [[END]]
-; CHECK-UNROLL: [[CMP2:%[a-z.0-9]+]] = icmp eq ptr [[VAR2:%[a-z.0-9]+]], null
-; CHECK-UNROLL: br i1 [[CMP2]], label [[END]]
-; CHECK-UNROLL: [[CMP3:%[a-z.0-9]+]] = icmp eq ptr [[VAR3:%[a-z.0-9]+]], null
-; CHECK-UNROLL: br i1 [[CMP3]], label [[END]]
-; CHECK-UNROLL: [[CMP4:%[a-z.0-9]+]] = icmp eq ptr [[VAR4:%[a-z.0-9]+]], null
-; CHECK-UNROLL: br i1 [[CMP4]], label [[END]]
-; CHECK-UNROLL-NOT: load
-
%struct.Node = type { ptr, i32 }
define arm_aapcscc void @iterate_inc(ptr %n) local_unnamed_addr #0 {
+; CHECK-NOUNROLL-LABEL: define arm_aapcscc void @iterate_inc(
+; CHECK-NOUNROLL-SAME: ptr [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
+; CHECK-NOUNROLL-NEXT: [[TOBOOL3:%.*]] = icmp eq ptr [[N]], null
+; CHECK-NOUNROLL-NEXT: br i1 [[TOBOOL3]], label %[[WHILE_END:.*]], label %[[WHILE_BODY_PREHEADER:.*]]
+; CHECK-NOUNROLL: [[WHILE_BODY_PREHEADER]]:
+; CHECK-NOUNROLL-NEXT: br label %[[WHILE_BODY:.*]]
+; CHECK-NOUNROLL: [[WHILE_BODY]]:
+; CHECK-NOUNROLL-NEXT: [[N_ADDR_04:%.*]] = phi ptr [ [[TMP1:%.*]], %[[WHILE_BODY]] ], [ [[N]], %[[WHILE_BODY_PREHEADER]] ]
+; CHECK-NOUNROLL-NEXT: [[VAL:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[N_ADDR_04]], i32 0, i32 1
+; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4
+; CHECK-NOUNROLL-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 1
+; CHECK-NOUNROLL-NEXT: store i32 [[ADD]], ptr [[VAL]], align 4
+; CHECK-NOUNROLL-NEXT: [[TMP1]] = load ptr, ptr [[N_ADDR_04]], align 4
+; CHECK-NOUNROLL-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[TMP1]], null
+; CHECK-NOUNROLL-NEXT: br i1 [[TOBOOL]], label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY]]
+; CHECK-NOUNROLL: [[WHILE_END_LOOPEXIT]]:
+; CHECK-NOUNROLL-NEXT: br label %[[WHILE_END]]
+; CHECK-NOUNROLL: [[WHILE_END]]:
+; CHECK-NOUNROLL-NEXT: ret void
+;
+; CHECK-UNROLL-LABEL: define arm_aapcscc void @iterate_inc(
+; CHECK-UNROLL-SAME: ptr [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-UNROLL-NEXT: [[ENTRY:.*:]]
+; CHECK-UNROLL-NEXT: [[TOBOOL3:%.*]] = icmp eq ptr [[N]], null
+; CHECK-UNROLL-NEXT: br i1 [[TOBOOL3]], label %[[WHILE_END:.*]], label %[[WHILE_BODY_PREHEADER:.*]]
+; CHECK-UNROLL: [[WHILE_BODY_PREHEADER]]:
+; CHECK-UNROLL-NEXT: br label %[[WHILE_BODY:.*]]
+; CHECK-UNROLL: [[WHILE_BODY]]:
+; CHECK-UNROLL-NEXT: [[N_ADDR_04:%.*]] = phi ptr [ [[N]], %[[WHILE_BODY_PREHEADER]] ], [ [[TMP7:%.*]], %[[WHILE_BODY_3:.*]] ]
+; CHECK-UNROLL-NEXT: [[VAL:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[N_ADDR_04]], i32 0, i32 1
+; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4
+; CHECK-UNROLL-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 1
+; CHECK-UNROLL-NEXT: store i32 [[ADD]], ptr [[VAL]], align 4
+; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[N_ADDR_04]], align 4
+; CHECK-UNROLL-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[TMP1]], null
+; CHECK-UNROLL-NEXT: br i1 [[TOBOOL]], label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY_1:.*]]
+; CHECK-UNROLL: [[WHILE_BODY_1]]:
+; CHECK-UNROLL-NEXT: [[VAL_1:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP1]], i32 0, i32 1
+; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[VAL_1]], align 4
+; CHECK-UNROLL-NEXT: [[ADD_1:%.*]] = add nsw i32 [[TMP2]], 1
+; CHECK-UNROLL-NEXT: store i32 [[ADD_1]], ptr [[VAL_1]], align 4
+; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP1]], align 4
+; CHECK-UNROLL-NEXT: [[TOBOOL_1:%.*]] = icmp eq ptr [[TMP3]], null
+; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_1]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY_2:.*]]
+; CHECK-UNROLL: [[WHILE_BODY_2]]:
+; CHECK-UNROLL-NEXT: [[VAL_2:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP3]], i32 0, i32 1
+; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[VAL_2]], align 4
+; CHECK-UNROLL-NEXT: [[ADD_2:%.*]] = add nsw i32 [[TMP4]], 1
+; CHECK-UNROLL-NEXT: store i32 [[ADD_2]], ptr [[VAL_2]], align 4
+; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP3]], align 4
+; CHECK-UNROLL-NEXT: [[TOBOOL_2:%.*]] = icmp eq ptr [[TMP5]], null
+; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_2]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY_3]]
+; CHECK-UNROLL: [[WHILE_BODY_3]]:
+; CHECK-UNROLL-NEXT: [[VAL_3:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP5]], i32 0, i32 1
+; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[VAL_3]], align 4
+; CHECK-UNROLL-NEXT: [[ADD_3:%.*]] = add nsw i32 [[TMP6]], 1
+; CHECK-UNROLL-NEXT: store i32 [[ADD_3]], ptr [[VAL_3]], align 4
+; CHECK-UNROLL-NEXT: [[TMP7]] = load ptr, ptr [[TMP5]], align 4
+; CHECK-UNROLL-NEXT: [[TOBOOL_3:%.*]] = icmp eq ptr [[TMP7]], null
+; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_3]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY]]
+; CHECK-UNROLL: [[WHILE_END_LOOPEXIT]]:
+; CHECK-UNROLL-NEXT: br label %[[WHILE_END]]
+; CHECK-UNROLL: [[WHILE_END]]:
+; CHECK-UNROLL-NEXT: ret void
+;
entry:
%tobool3 = icmp eq ptr %n, null
br i1 %tobool3, label %while.end, label %while.body.preheader
diff --git a/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll b/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
index 066a8b65bfce8..e624bd14809b0 100644
--- a/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
+++ b/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
@@ -131,8 +131,8 @@ define void @test_three_blocks(ptr nocapture %Output, ptr nocapture readonly %Co
; CHECK-NEXT: br label [[FOR_INC_3]]
; CHECK: for.inc.3:
; CHECK-NEXT: [[TEMP_1_3]] = phi i32 [ [[ADD_3]], [[IF_THEN_3]] ], [ [[TEMP_1_2]], [[FOR_INC_2]] ]
-; CHECK-NEXT: [[INC_3]] = add nuw i32 [[J_010]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
+; CHECK-NEXT: [[INC_3]] = add nuw nsw i32 [[J_010]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
; CHECK-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
; CHECK-NEXT: br i1 [[NITER_NCMP_3]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]]
;
diff --git a/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll b/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
index d842c4adcb74d..91ccde58e33db 100644
--- a/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
@@ -148,23 +148,23 @@ define hidden void @runtime(ptr nocapture %a, ptr nocapture readonly %b, ptr noc
; CHECK: for.body:
; CHECK-NEXT: [[I_09:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1]], [[FOR_BODY]] ]
; CHECK-NEXT: [[NITER:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i8], ptr [[B]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[B]], i32 [[I_09]]
; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [4 x i8], ptr [[C]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[C]], i32 [[I_09]]
; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]]
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [4 x i8], ptr [[A]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[A]], i32 [[I_09]]
; CHECK-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
; CHECK-NEXT: [[INC:%.*]] = or disjoint i32 [[I_09]], 1
-; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[B]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[B]], i32 [[INC]]
; CHECK-NEXT: [[I_1:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[C]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[C]], i32 [[INC]]
; CHECK-NEXT: [[I1_1:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
; CHECK-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[I1_1]], [[I_1]]
-; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[A]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[A]], i32 [[INC]]
; CHECK-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-NEXT: [[INC_1]] = add nuw i32 [[I_09]], 2
-; CHECK-NEXT: [[NITER_NEXT_1]] = add nuw i32 [[NITER]], 2
+; CHECK-NEXT: [[INC_1]] = add nuw nsw i32 [[I_09]], 2
+; CHECK-NEXT: [[NITER_NEXT_1]] = add nuw nsw i32 [[NITER]], 2
; CHECK-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]
; CHECK-NEXT: br i1 [[NITER_NCMP_1]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]]
;
diff --git a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
index c763f14b73cb8..90f4403244630 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
@@ -182,7 +182,7 @@ define void @peel_with_guard2(i32 %n) {
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]]
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]
@@ -254,7 +254,7 @@ define void @test_peel_guard_sub_1_btc(i32 %n) {
; CHECK-NEXT: [[CALL136:%.*]] = load volatile ptr, ptr null, align 4294967296
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]]
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP4:![0-9]+]]
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
index 839bdbd541e4b..32267cb104d3b 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
@@ -10,35 +10,35 @@ target triple = "x86_64-unknown-linux-gnu"
define internal fastcc void @test01(ptr %p0, ptr %p1, ptr %p2) unnamed_addr align 2 {
; CHECK-LABEL: @test01(
; CHECK-NEXT: for.body47.lr.ph:
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
; CHECK-NEXT: br label [[FOR_BODY47_PEEL_BEGIN:%.*]]
; CHECK: for.body47.peel.begin:
; CHECK-NEXT: br label [[FOR_BODY47_PEEL:%.*]]
; CHECK: for.body47.peel:
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3)
-; CHECK-NEXT: store i8 42, ptr [[P0:%.*]], align 1, !alias.scope !3
-; CHECK-NEXT: store i8 43, ptr [[P1:%.*]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 44, ptr [[P2:%.*]], align 1, !alias.scope !5
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !3
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !5
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
+; CHECK-NEXT: store i8 42, ptr [[P0:%.*]], align 1, !alias.scope [[META3]]
+; CHECK-NEXT: store i8 43, ptr [[P1:%.*]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 44, ptr [[P2:%.*]], align 1, !alias.scope [[META5:![0-9]+]]
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias [[META3]]
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias [[META5]]
; CHECK-NEXT: [[CMP52_PEEL:%.*]] = icmp eq i32 0, 0
; CHECK-NEXT: br i1 [[CMP52_PEEL]], label [[COND_TRUE_PEEL:%.*]], label [[COND_END_PEEL:%.*]]
; CHECK: cond.true.peel:
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !3
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !5
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !3
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !5
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope [[META3]]
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope [[META5]]
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias [[META3]]
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias [[META5]]
; CHECK-NEXT: br label [[COND_END_PEEL]]
; CHECK: cond.end.peel:
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !3
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !5
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !3
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !5
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope [[META3]]
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope [[META5]]
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias [[META3]]
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias [[META5]]
; CHECK-NEXT: [[INC_PEEL:%.*]] = add nuw i32 0, 1
; CHECK-NEXT: [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], undef
; CHECK-NEXT: br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP46:%.*]], label [[FOR_BODY47_PEEL_NEXT:%.*]]
@@ -54,31 +54,31 @@ define internal fastcc void @test01(ptr %p0, ptr %p1, ptr %p2) unnamed_addr alig
; CHECK-NEXT: ret void
; CHECK: for.body47:
; CHECK-NEXT: [[J_02:%.*]] = phi i32 [ [[INC_PEEL]], [[FOR_BODY47_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[COND_END:%.*]] ]
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !6)
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !alias.scope !6
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !alias.scope !8
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !6
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !8
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]])
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !alias.scope [[META6]]
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !alias.scope [[META8:![0-9]+]]
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias [[META6]]
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias [[META8]]
; CHECK-NEXT: br i1 false, label [[COND_TRUE:%.*]], label [[COND_END]]
; CHECK: cond.true:
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !6
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !8
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !6
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !8
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope [[META6]]
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope [[META8]]
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias [[META6]]
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias [[META8]]
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !6
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !8
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !6
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !8
-; CHECK-NEXT: [[INC]] = add nuw i32 [[J_02]], 1
-; CHECK-NEXT: br i1 undef, label [[FOR_COND_CLEANUP46_LOOPEXIT:%.*]], label [[FOR_BODY47]], [[LOOP9:!llvm.loop !.*]]
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope [[META6]]
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope [[META0]]
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope [[META8]]
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias [[META6]]
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias [[META0]]
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias [[META8]]
+; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[J_02]], 1
+; CHECK-NEXT: br i1 undef, label [[FOR_COND_CLEANUP46_LOOPEXIT:%.*]], label [[FOR_BODY47]], !llvm.loop [[LOOP9:![0-9]+]]
;
for.body47.lr.ph:
call void @llvm.experimental.noalias.scope.decl(metadata !5)
diff --git a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
index 047360178aa06..8ec4fa2fdd21a 100644
--- a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
+++ b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
@@ -95,7 +95,7 @@ define void @pr56282() {
; CHECK: inner.2.preheader:
; CHECK-NEXT: br label [[INNER_2]]
; CHECK: inner.2:
-; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nuw i64 [[OUTER_IV]], 1
+; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nuw nsw i64 [[OUTER_IV]], 1
; CHECK-NEXT: br label [[OUTER_HEADER]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -188,7 +188,7 @@ define void @pr56286(i64 %x, ptr %src, ptr %dst, ptr %ptr.src) !prof !0 {
; CHECK-NEXT: [[L_1_LCSSA_UNR:%.*]] = phi i32 [ poison, [[OUTER_HEADER]] ], [ [[L_1_LCSSA_UNR_PH]], [[INNER_1_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
; CHECK-NEXT: [[INNER_1_IV_UNR:%.*]] = phi i64 [ [[X]], [[OUTER_HEADER]] ], [ [[INNER_1_IV_UNR_PH]], [[INNER_1_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 7
-; CHECK-NEXT: br i1 [[TMP4]], label [[OUTER_MIDDLE:%.*]], label [[OUTER_HEADER_NEW:%.*]], !prof [[PROF6:![0-9]+]]
+; CHECK-NEXT: br i1 [[TMP4]], label [[OUTER_MIDDLE:%.*]], label [[OUTER_HEADER_NEW:%.*]], !prof [[PROF3]]
; CHECK: outer.header.new:
; CHECK-NEXT: br label [[INNER_1_HEADER:%.*]]
; CHECK: inner.1.header:
@@ -232,7 +232,7 @@ define void @pr56286(i64 %x, ptr %src, ptr %dst, ptr %ptr.src) !prof !0 {
; CHECK-NEXT: store i32 [[L_1_7]], ptr [[DST]], align 8
; CHECK-NEXT: [[INNER_1_IV_NEXT_7]] = add i64 [[INNER_1_IV]], 8
; CHECK-NEXT: [[CMP_2_7:%.*]] = icmp sgt i64 [[INNER_1_IV_NEXT_6]], 0
-; CHECK-NEXT: br i1 [[CMP_2_7]], label [[OUTER_MIDDLE_UNR_LCSSA:%.*]], label [[INNER_1_HEADER]], !prof [[PROF7:![0-9]+]], !llvm.loop [[LOOP8:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP_2_7]], label [[OUTER_MIDDLE_UNR_LCSSA:%.*]], label [[INNER_1_HEADER]], !prof [[PROF6:![0-9]+]], !llvm.loop [[LOOP7:![0-9]+]]
; CHECK: outer.middle.unr-lcssa:
; CHECK-NEXT: [[L_1_LCSSA_PH:%.*]] = phi i32 [ [[L_1_7]], [[INNER_1_LATCH_7]] ]
; CHECK-NEXT: br label [[OUTER_MIDDLE]]
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
index 351065080119d..dcf6e396cf0e4 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
@@ -24,13 +24,12 @@ define void @test1() {
; CHECK-NEXT: [[I4017_3:%.*]] = zext i16 [[I42_2]] to i64
; CHECK-NEXT: [[I13_I_3:%.*]] = add nuw nsw i64 [[I4017_3]], 1
; CHECK-NEXT: [[I42_3]] = trunc i64 [[I13_I_3]] to i16
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i16 [[NITER]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i16 [[NITER]], 4
; CHECK-NEXT: br label [[BB10_PREHEADER:%.*]]
; CHECK: bb10.preheader:
; CHECK-NEXT: br i1 true, label [[BB38]], label [[BB10_PREHEADER]]
; CHECK: bb38:
-; CHECK-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i16 [[NITER_NEXT_3]], -28
-; CHECK-NEXT: br i1 [[NITER_NCMP_3]], label [[BB1_BB43_CRIT_EDGE_UNR_LCSSA:%.*]], label [[BB5_PREHEADER]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-NEXT: br i1 false, label [[BB1_BB43_CRIT_EDGE_UNR_LCSSA:%.*]], label [[BB5_PREHEADER]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: bb1.bb43_crit_edge.unr-lcssa:
; CHECK-NEXT: [[I10_UNR:%.*]] = phi i16 [ [[I42_3]], [[BB38]] ]
; CHECK-NEXT: br i1 true, label [[BB5_PREHEADER_EPIL_PREHEADER]], label [[BB1_BB43_CRIT_EDGE:%.*]]
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
index 27b4143303692..1d740ef0a1cc0 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
@@ -27,8 +27,8 @@ define void @test1(i32 %N, i32 %M, ptr noalias nocapture %A, ptr noalias nocaptu
; CHECK-NEXT: [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
; CHECK-NEXT: [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
; CHECK-NEXT: [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
-; CHECK-NEXT: [[ADD8_3]] = add nuw i32 [[I]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
+; CHECK-NEXT: [[ADD8_3]] = add nuw nsw i32 [[I]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
; CHECK-NEXT: br label %[[FOR_INNER:.*]]
; CHECK: [[FOR_INNER]]:
; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_OUTER]] ], [ [[INC:%.*]], %[[FOR_INNER]] ]
@@ -1127,8 +1127,8 @@ define void @test9(i32 %N, i32 %M, ptr nocapture %A, ptr nocapture readonly %B)
; CHECK-NEXT: [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
; CHECK-NEXT: [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
; CHECK-NEXT: [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
-; CHECK-NEXT: [[ADD8_3]] = add nuw i32 [[I]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
+; CHECK-NEXT: [[ADD8_3]] = add nuw nsw i32 [[I]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
; CHECK-NEXT: br label %[[FOR_INNER:.*]]
; CHECK: [[FOR_INNER]]:
; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_OUTER]] ], [ [[INC:%.*]], %[[FOR_INNER]] ]
diff --git a/llvm/test/Transforms/LoopVectorize/alias-mask.ll b/llvm/test/Transforms/LoopVectorize/alias-mask.ll
index 47e2cd8f9f3ec..e5acedf8b01b7 100644
--- a/llvm/test/Transforms/LoopVectorize/alias-mask.ll
+++ b/llvm/test/Transforms/LoopVectorize/alias-mask.ll
@@ -574,14 +574,11 @@ define i64 @any_of_reduction(i64 %a, ptr %src, ptr %dst, i32 %n) {
; CHECK-SAME: i64 [[A:%.*]], ptr [[SRC:%.*]], ptr [[DST:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[DST1:%.*]] = ptrtoaddr ptr [[DST]] to i64
-; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[DST1]], 4
+; CHECK-NEXT: [[TMP0:%.*]] = add nuw i64 [[DST1]], 4
; CHECK-NEXT: [[SRC2:%.*]] = ptrtoaddr ptr [[SRC]] to i64
-; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[SRC2]], 4
+; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[SRC2]], 4
; CHECK-NEXT: br label %[[VECTOR_SCEVCHECK:.*]]
; CHECK: [[VECTOR_SCEVCHECK]]:
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[N]], 1
-; CHECK-NEXT: br i1 [[TMP2]], label %[[SCALAR_PH:.*]], label %[[VECTOR_CLAMPED_VF_CHECK:.*]]
-; CHECK: [[VECTOR_CLAMPED_VF_CHECK]]:
; CHECK-NEXT: [[ALIAS_MASK:%.*]] = call <4 x i1> @llvm.loop.dependence.war.mask.v4i1.i64(i64 [[TMP1]], i64 [[TMP0]], i64 4)
; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i1> [[ALIAS_MASK]] to <4 x i64>
; CHECK-NEXT: [[NUM_ACTIVE_LANES:%.*]] = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> [[TMP4]])
@@ -590,7 +587,7 @@ define i64 @any_of_reduction(i64 %a, ptr %src, ptr %dst, i32 %n) {
; CHECK-NEXT: [[TMP7:%.*]] = sub i32 -1, [[N]]
; CHECK-NEXT: [[VF_STEP_OVERFLOW:%.*]] = icmp ult i32 [[TMP7]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[VF_IS_SCALAR]], [[VF_STEP_OVERFLOW]]
-; CHECK-NEXT: br i1 [[TMP8]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]]
+; CHECK-NEXT: br i1 [[TMP8]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[TMP9:%.*]] = sub i32 [[TMP6]], 1
diff --git a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
index db6aa937120c3..e44434d01adf3 100644
--- a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
+++ b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
@@ -15,33 +15,10 @@ define i8 @recurrence_phi_with_same_incoming_values_after_simplifications(i8 %fo
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 1, [[INDEX]]
-; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[OFFSET_IDX]], 1
-; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[OFFSET_IDX]], 2
-; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[OFFSET_IDX]], 3
-; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[OFFSET_IDX]], 4
-; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[OFFSET_IDX]], 5
-; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[OFFSET_IDX]], 6
-; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[OFFSET_IDX]], 7
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[OFFSET_IDX]]
-; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP2]]
-; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP3]]
-; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP4]]
-; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP5]]
-; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP6]]
-; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP7]]
-; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP8]]
-; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i8> [[TMP0]], i64 0
-; CHECK-NEXT: store i8 [[TMP17]], ptr [[TMP9]], align 1
-; CHECK-NEXT: [[TMP18:%.*]] = extractelement <4 x i8> [[TMP0]], i64 1
-; CHECK-NEXT: store i8 [[TMP18]], ptr [[TMP10]], align 1
-; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i8> [[TMP0]], i64 2
-; CHECK-NEXT: store i8 [[TMP19]], ptr [[TMP11]], align 1
-; CHECK-NEXT: [[TMP20:%.*]] = extractelement <4 x i8> [[TMP0]], i64 3
-; CHECK-NEXT: store i8 [[TMP20]], ptr [[TMP12]], align 1
-; CHECK-NEXT: store i8 [[TMP17]], ptr [[TMP13]], align 1
-; CHECK-NEXT: store i8 [[TMP18]], ptr [[TMP14]], align 1
-; CHECK-NEXT: store i8 [[TMP19]], ptr [[TMP15]], align 1
-; CHECK-NEXT: store i8 [[TMP20]], ptr [[TMP16]], align 1
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP9]], i64 4
+; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[TMP9]], align 1
+; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[TMP3]], align 1
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 8
; CHECK-NEXT: [[TMP21:%.*]] = icmp eq i32 [[INDEX_NEXT]], -8
; CHECK-NEXT: br i1 [[TMP21]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
index 0ecc93c8d1cf5..4122496e99482 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
@@ -95,7 +95,7 @@ define i64 @sum_2_at_with_int_conversion(ptr %A, ptr %B, i64 %N) {
; CHECK-NEXT: [[LV_I9:%.*]] = load i64, ptr [[GEP_IDX_I8]], align 8
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[LV_I]], [[SUM]]
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[ADD]], [[LV_I9]]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[SMAX]]
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: error.i:
@@ -241,7 +241,7 @@ define i64 @sum_3_at_with_int_conversion(ptr %A, ptr %B, ptr %C, i64 %N) {
; CHECK-NEXT: [[ADD_1:%.*]] = add i64 [[LV_I]], [[SUM]]
; CHECK-NEXT: [[ADD_2:%.*]] = add i64 [[ADD_1]], [[LV_I9]]
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[ADD_2]], [[LV_I20]]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[SMAX]]
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
; CHECK: error.i:
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index 7bba70a97b1bb..95e0215c81fcc 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -354,7 +354,7 @@ define void @monkey(ptr noundef %arr, i32 noundef %len) {
; CHECK: [[FOR_COND_CLEANUP]]:
; CHECK-NEXT: ret void
; CHECK: [[FOR_COND_CLEANUP3]]:
-; CHECK-NEXT: [[INC]] = add nuw i32 [[I_09]], 1
+; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_09]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC]], [[LEN]]
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY4_PREHEADER]], label %[[FOR_COND_CLEANUP]]
; CHECK: [[FOR_BODY4]]:
diff --git a/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll b/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
index 1df51312f7015..c5e1973f41bd6 100644
--- a/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
+++ b/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
@@ -12,26 +12,21 @@ define amdgpu_kernel void @phi5_rotate(
; GFX950-LABEL: define amdgpu_kernel void @phi5_rotate(
; GFX950-SAME: ptr addrspace(1) captures(none) [[OUT:%.*]], i32 [[N:%.*]], i32 [[S0:%.*]], i32 [[S1:%.*]], i32 [[S2:%.*]], i32 [[S3:%.*]], i32 [[S4:%.*]]) {
; GFX950-NEXT: [[ENTRY:.*]]:
-; GFX950-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[S0]], i64 0
-; GFX950-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[S1]], i64 1
-; GFX950-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> poison, i32 [[S4]], i64 0
-; GFX950-NEXT: [[TMP3:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[S0]], i64 1
-; GFX950-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[S3]], i64 0
-; GFX950-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[S4]], i64 1
-; GFX950-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[S2]], i64 0
-; GFX950-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[S3]], i64 1
; GFX950-NEXT: br label %[[LOOP:.*]]
; GFX950: [[LOOP]]:
; GFX950-NEXT: [[I1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ [[TMP1]], %[[ENTRY]] ], [ [[TMP9:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[TMP9]] = phi <2 x i32> [ [[TMP3]], %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[TMP10]] = phi <2 x i32> [ [[TMP5]], %[[ENTRY]] ], [ [[TMP11:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[TMP11]] = phi <2 x i32> [ [[TMP7]], %[[ENTRY]] ], [ [[TMP12:%.*]], %[[LOOP]] ]
+; GFX950-NEXT: [[X0:%.*]] = phi i32 [ [[S0]], %[[ENTRY]] ], [ [[X4:%.*]], %[[LOOP]] ]
+; GFX950-NEXT: [[X1:%.*]] = phi i32 [ [[S1]], %[[ENTRY]] ], [ [[X0]], %[[LOOP]] ]
+; GFX950-NEXT: [[X2:%.*]] = phi i32 [ [[S2]], %[[ENTRY]] ], [ [[X1]], %[[LOOP]] ]
+; GFX950-NEXT: [[X3:%.*]] = phi i32 [ [[S3]], %[[ENTRY]] ], [ [[X2]], %[[LOOP]] ]
+; GFX950-NEXT: [[X4]] = phi i32 [ [[S4]], %[[ENTRY]] ], [ [[X3]], %[[LOOP]] ]
; GFX950-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I1]]
-; GFX950-NEXT: store <2 x i32> [[TMP8]], ptr addrspace(1) [[GEP1]], align 4
+; GFX950-NEXT: store i32 [[X0]], ptr addrspace(1) [[GEP1]], align 4
+; GFX950-NEXT: [[I2:%.*]] = or disjoint i32 [[I1]], 1
+; GFX950-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I2]]
+; GFX950-NEXT: store i32 [[X1]], ptr addrspace(1) [[GEP2]], align 4
; GFX950-NEXT: [[I_NEXT]] = add nuw i32 [[I1]], 2
; GFX950-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
-; GFX950-NEXT: [[TMP12]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> [[TMP11]], <2 x i32> <i32 1, i32 2>
; GFX950-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
; GFX950: [[EXIT]]:
; GFX950-NEXT: ret void
@@ -39,26 +34,21 @@ define amdgpu_kernel void @phi5_rotate(
; GFX942-LABEL: define amdgpu_kernel void @phi5_rotate(
; GFX942-SAME: ptr addrspace(1) captures(none) [[OUT:%.*]], i32 [[N:%.*]], i32 [[S0:%.*]], i32 [[S1:%.*]], i32 [[S2:%.*]], i32 [[S3:%.*]], i32 [[S4:%.*]]) {
; GFX942-NEXT: [[ENTRY:.*]]:
-; GFX942-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[S0]], i64 0
-; GFX942-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[S1]], i64 1
-; GFX942-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> poison, i32 [[S4]], i64 0
-; GFX942-NEXT: [[TMP3:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[S0]], i64 1
-; GFX942-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[S3]], i64 0
-; GFX942-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[S4]], i64 1
-; GFX942-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[S2]], i64 0
-; GFX942-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[S3]], i64 1
; GFX942-NEXT: br label %[[LOOP:.*]]
; GFX942: [[LOOP]]:
; GFX942-NEXT: [[I1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ [[TMP1]], %[[ENTRY]] ], [ [[TMP9:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[TMP9]] = phi <2 x i32> [ [[TMP3]], %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[TMP10]] = phi <2 x i32> [ [[TMP5]], %[[ENTRY]] ], [ [[TMP11:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[TMP11]] = phi <2 x i32> [ [[TMP7]], %[[ENTRY]] ], [ [[TMP12:%.*]], %[[LOOP]] ]
+; GFX942-NEXT: [[X0:%.*]] = phi i32 [ [[S0]], %[[ENTRY]] ], [ [[X4:%.*]], %[[LOOP]] ]
+; GFX942-NEXT: [[X1:%.*]] = phi i32 [ [[S1]], %[[ENTRY]] ], [ [[X0]], %[[LOOP]] ]
+; GFX942-NEXT: [[X2:%.*]] = phi i32 [ [[S2]], %[[ENTRY]] ], [ [[X1]], %[[LOOP]] ]
+; GFX942-NEXT: [[X3:%.*]] = phi i32 [ [[S3]], %[[ENTRY]] ], [ [[X2]], %[[LOOP]] ]
+; GFX942-NEXT: [[X4]] = phi i32 [ [[S4]], %[[ENTRY]] ], [ [[X3]], %[[LOOP]] ]
; GFX942-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I1]]
-; GFX942-NEXT: store <2 x i32> [[TMP8]], ptr addrspace(1) [[GEP1]], align 4
+; GFX942-NEXT: store i32 [[X0]], ptr addrspace(1) [[GEP1]], align 4
+; GFX942-NEXT: [[I2:%.*]] = or disjoint i32 [[I1]], 1
+; GFX942-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I2]]
+; GFX942-NEXT: store i32 [[X1]], ptr addrspace(1) [[GEP2]], align 4
; GFX942-NEXT: [[I_NEXT]] = add nuw i32 [[I1]], 2
; GFX942-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
-; GFX942-NEXT: [[TMP12]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> [[TMP11]], <2 x i32> <i32 1, i32 2>
; GFX942-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
; GFX942: [[EXIT]]:
; GFX942-NEXT: ret void
>From 28d0db2b603c3d1859bab100b454eea613ec1864 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sat, 22 Aug 2026 12:19:19 +0100
Subject: [PATCH 3/4] [SCEV] Final fix
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 2 +-
llvm/lib/Analysis/ScalarEvolution.cpp | 35 +-
.../ScalarEvolution/flags-from-poison.ll | 2 +-
llvm/test/Analysis/ScalarEvolution/pr27315.ll | 31 +-
.../ptrtoint-constantexpr-loop.ll | 12 +-
.../RISCV/loop-strength-reduce-loop-invar.ll | 24 +-
.../IndVarSimplify/X86/overflow-intrinsics.ll | 4 +-
.../IndVarSimplify/range-iter-threshold.ll | 7 +-
.../simplify-icmp-operands-order.ll | 2 +-
.../IndVarSimplify/strengthen-overflow.ll | 4 +-
.../IndVarSimplify/turn-to-invariant.ll | 2 +-
.../X86/2008-08-14-ShadowIV.ll | 268 +++------
.../X86/2012-01-13-phielim.ll | 2 +-
.../LoopStrengthReduce/X86/pr17473.ll | 38 +-
.../LoopUnroll/AArch64/apple-unrolling.ll | 10 +-
.../LoopUnroll/ARM/loop-unrolling.ll | 557 +++---------------
.../Transforms/LoopUnroll/ARM/multi-blocks.ll | 4 +-
.../LoopUnroll/WebAssembly/basic-unrolling.ll | 16 +-
.../peel-last-iteration-with-guards.ll | 4 +-
.../peel-loop-noalias-scope-decl.ll | 82 +--
.../runtime-exit-phi-scev-invalidation.ll | 6 +-
.../dependencies_visit_order.ll | 5 +-
.../LoopUnrollAndJam/unroll-and-jam.ll | 8 +-
.../Transforms/LoopVectorize/alias-mask.ll | 9 +-
...irst-order-recurrence-dead-instructions.ll | 29 +-
...ple-unreachable-exits-for-vectorization.ll | 4 +-
.../PhaseOrdering/loop-access-checks.ll | 2 +-
.../AMDGPU/inst-count-heuristic.ll | 46 +-
28 files changed, 350 insertions(+), 865 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index d17c21ea3401e..3e15471a38a8f 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -2413,7 +2413,7 @@ class ScalarEvolution {
/// equivalent to proving no signed (resp. unsigned) wrap in
/// {`Start`,+,`Step`} if `ExtendOpTy` is `SCEVSignExtendExpr`
/// (resp. `SCEVZeroExtendExpr`).
- template <typename ExtendOpTy>
+ template <typename ExtendOpTy, SCEVNoWrapFlags WrapType>
bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step,
const Loop *L);
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index a4fb250e95ba6..70891c6d89023 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1471,12 +1471,11 @@ static const SCEV *getExtendAddRecStart(const SCEVAddRecExpr *AR, Type *Ty,
//
// In the current context, S is `Start`, X is `Step`, Ext is `ExtendOpTy` and T
// is `Delta` (defined below).
-template <typename ExtendOpTy>
+template <typename ExtendOpTy,
+ SCEVNoWrapFlags WrapType = ExtendOpTraits<ExtendOpTy>::WrapType>
bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
const SCEV *Step,
const Loop *L) {
- auto WrapType = ExtendOpTraits<ExtendOpTy>::WrapType;
-
// We restrict `Start` to a constant to prevent SCEV from spending too much
// time here. It is correct (but more expensive) to continue with a
// non-constant `Start` and do a general SCEV subtraction to compute
@@ -2060,25 +2059,6 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
}
- // For a positive step, we can zero-extend the step iff doing so only
- // traverses values in the range zext([0,UMAX]).
- if (isKnownPositive(Step)) {
- unsigned BitWidth = getTypeSizeInBits(AR->getType());
- const SCEV *N = getConstant(APInt::getSignedMinValue(BitWidth) -
- getUnsignedRangeMin(Step));
- if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT, AR, N) ||
- isKnownOnEveryIteration(ICmpInst::ICMP_SLT, AR, N) ||
- proveNoWrapByVaryingStart<SCEVZeroExtendExpr>(Start, Step, L)) {
- // no-self-wrap is an opportunistic fact we get for free. It is not a
- // pre-condition for the transform.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
- Start =
- getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getZeroExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
- }
- }
-
// sext({C,+,Step}) --> (sext(D) + sext({C-D,+,Step}))<nuw><nsw>
// if D + (C - D + Step * n) could be proven to not signed wrap
// where D maximizes the number of trailing zeros of (C - D + Step * n)
@@ -2094,6 +2074,17 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
Depth + 1);
}
}
+
+ // Handle the nsuw case. nuw on pre-inc AR and no-overflow proven with
+ // signed overflow limit implies nsuw on the parent AR, of which nw is a
+ // weaker version.
+ if (proveNoWrapByVaryingStart<SCEVSignExtendExpr, SCEV::FlagNUW>(Start,
+ Step, L)) {
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
+ Start = getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
+ Step = getZeroExtendExpr(Step, Ty, Depth + 1);
+ return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
+ }
}
// If the input value is provably positive and we could not simplify
diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
index 3ae5f0afd7299..ce899726d44cd 100644
--- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
+++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
@@ -141,7 +141,7 @@ define void @test-add-scope-bound(ptr %input, i32 %needle) {
; CHECK-NEXT: %of_interest = add nuw nsw i32 %i.next, %offset
; CHECK-NEXT: --> ({1,+,1}<nuw><%loop> + %offset)<nuw><nsw> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %of_interest
-; CHECK-NEXT: --> ((4 * ((sext i32 %offset to i64) + {1,+,1}<nuw><%loop>)<nsw>) + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> ((4 * ((sext i32 {1,+,1}<nuw><%loop> to i64) + (sext i32 %offset to i64))<nsw>)<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
diff --git a/llvm/test/Analysis/ScalarEvolution/pr27315.ll b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
index 405d2f62e5268..1c99075f5f1b4 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr27315.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
@@ -1,33 +1,16 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
declare i1 @use(i64)
define void @f_0() {
-; CHECK-LABEL: 'f_0'
-; CHECK-NEXT: Classifying expressions for: @f_0
-; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
-; CHECK-NEXT: %iv.inc.maywrap = add i32 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
-; CHECK-NEXT: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
-; CHECK-NEXT: %cond0 = call i1 @use(i64 %iv.inc.maywrap.sext)
-; CHECK-NEXT: --> %cond0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
-; CHECK-NEXT: %iv.inc.nowrap = add nsw i32 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
-; CHECK-NEXT: %be.cond = call i1 @use(i64 0)
-; CHECK-NEXT: --> %be.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
-; CHECK-NEXT: Determining loop execution counts for: @f_0
-; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
-; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
-; CHECK-NEXT: exit count for be: ***COULDNOTCOMPUTE***
-; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
-; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
-; CHECK-NEXT: symbolic max exit count for be: ***COULDNOTCOMPUTE***
-;
+; CHECK-LABEL: Classifying expressions for: @f_0
+; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
+; CHECK: %iv.inc.maywrap = add i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop>
+; CHECK: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
+; CHECK-NEXT: --> (sext i32 {1,+,1}<nuw><%loop> to i64)
entry:
br label %loop
diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
index daa0bd3e3cbc5..99ecb3c9a7cb9 100644
--- a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll
@@ -325,9 +325,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR64_IDX64-LABEL: 'sext_like_noop'
; PTR64_IDX64-NEXT: Classifying expressions for: @sext_like_noop
; PTR64_IDX64-NEXT: %ii = sext i32 %i to i64
-; PTR64_IDX64-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
+; PTR64_IDX64-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (ptr @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
; PTR64_IDX64-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX64-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
+; PTR64_IDX64-NEXT: --> %div U: full-set S: full-set
; PTR64_IDX64-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX64-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX64-NEXT: %inc = add nuw i32 %i, 1
@@ -341,9 +341,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR64_IDX32-LABEL: 'sext_like_noop'
; PTR64_IDX32-NEXT: Classifying expressions for: @sext_like_noop
; PTR64_IDX32-NEXT: %ii = sext i32 %i to i64
-; PTR64_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
+; PTR64_IDX32-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (ptr @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
; PTR64_IDX32-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX32-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32)) to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
+; PTR64_IDX32-NEXT: --> %div U: full-set S: full-set
; PTR64_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX32-NEXT: %inc = add nuw i32 %i, 1
@@ -357,9 +357,9 @@ define i64 @sext_like_noop(i32 %n) {
; PTR16_IDX16-LABEL: 'sext_like_noop'
; PTR16_IDX16-NEXT: Classifying expressions for: @sext_like_noop
; PTR16_IDX16-NEXT: %ii = sext i32 %i to i64
-; PTR16_IDX16-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,4294967297) S: [1,4294967297) --> (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32))<nsw> to i64))<nuw><nsw> U: [1,4294967297) S: [1,4294967297)
+; PTR16_IDX16-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i32 ptrtoint (ptr @sext_like_noop to i32) to i64))<nsw> U: [-1,65535) S: [-1,65535)
; PTR16_IDX16-NEXT: %div = sdiv i64 55555, %ii
-; PTR16_IDX16-NEXT: --> (55555 /u {1,+,1}<nuw><nsw><%for.body>) U: [0,55556) S: [0,55556) --> (55555 /u (1 + (zext i32 (-2 + ptrtoint (ptr @sext_like_noop to i32))<nsw> to i64))<nuw><nsw>) U: [0,55556) S: [0,55556)
+; PTR16_IDX16-NEXT: --> %div U: full-set S: full-set
; PTR16_IDX16-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR16_IDX16-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (ptr @sext_like_noop to i32))<nsw> LoopDispositions: { %for.body: Computable }
; PTR16_IDX16-NEXT: %inc = add nuw i32 %i, 1
diff --git a/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll b/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
index 9376a88b8bf4b..d11e5280b5aeb 100644
--- a/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
+++ b/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
@@ -54,23 +54,23 @@ define void @test(i32 signext %row, i32 signext %N.in) nounwind {
; RV64-NEXT: blez a1, .LBB0_3
; RV64-NEXT: # %bb.1: # %cond_true.preheader
; RV64-NEXT: slli a0, a0, 6
-; RV64-NEXT: addi a1, a1, -1
; RV64-NEXT: lui a2, %hi(A)
; RV64-NEXT: addi a2, a2, %lo(A)
-; RV64-NEXT: slli a1, a1, 32
+; RV64-NEXT: addiw a1, a1, 2
; RV64-NEXT: add a0, a0, a2
-; RV64-NEXT: srli a1, a1, 30
-; RV64-NEXT: add a1, a0, a1
-; RV64-NEXT: addi a0, a0, 8
-; RV64-NEXT: addi a1, a1, 12
-; RV64-NEXT: li a2, 4
-; RV64-NEXT: li a3, 5
+; RV64-NEXT: li a2, 2
+; RV64-NEXT: addi a3, a0, 4
+; RV64-NEXT: li a4, 4
+; RV64-NEXT: li a5, 5
; RV64-NEXT: .LBB0_2: # %cond_true
; RV64-NEXT: # =>This Inner Loop Header: Depth=1
-; RV64-NEXT: sw a2, -4(a0)
-; RV64-NEXT: sw a3, 0(a0)
-; RV64-NEXT: addi a0, a0, 4
-; RV64-NEXT: bne a0, a1, .LBB0_2
+; RV64-NEXT: sw a4, 0(a3)
+; RV64-NEXT: slli a6, a2, 2
+; RV64-NEXT: add a6, a0, a6
+; RV64-NEXT: addiw a2, a2, 1
+; RV64-NEXT: sw a5, 0(a6)
+; RV64-NEXT: addi a3, a3, 4
+; RV64-NEXT: bne a2, a1, .LBB0_2
; RV64-NEXT: .LBB0_3: # %return
; RV64-NEXT: ret
entry:
diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index f3fe59a31fbbf..9b9bc68ba7ad8 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -60,12 +60,12 @@ define void @f_sadd_overflow(ptr %a) {
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 2147483645, %[[ENTRY]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
; CHECK-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
-; CHECK-NEXT: br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK-NEXT: br i1 true, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
; CHECK: [[TRAP]]:
; CHECK-NEXT: tail call void @llvm.trap(), !nosanitize [[META0]]
; CHECK-NEXT: unreachable, !nosanitize [[META0]]
; CHECK: [[CONT]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
;
entry:
diff --git a/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll b/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
index 25ab339c5d675..9c442710e2191 100644
--- a/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
+++ b/llvm/test/Transforms/IndVarSimplify/range-iter-threshold.ll
@@ -10,12 +10,12 @@ define i32 @test(i1 %c.0, i32 %m) {
; COMMON-NEXT: entry:
; COMMON-NEXT: br label [[OUTER_HEADER:%.*]]
; COMMON: outer.header:
-; COMMON-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
-; COMMON-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_1_NEXT:%.*]], [[OUTER_LATCH]] ]
+; COMMON-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[OUTER_LATCH:%.*]] ]
; COMMON-NEXT: [[MAX_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[MAX_1:%.*]], [[OUTER_LATCH]] ]
+; COMMON-NEXT: [[TMP0:%.*]] = sext i32 [[IV_1]] to i64
; COMMON-NEXT: br label [[INNER_1:%.*]]
; COMMON: inner.1:
-; COMMON-NEXT: [[C_1:%.*]] = icmp slt i64 0, [[INDVARS_IV]]
+; COMMON-NEXT: [[C_1:%.*]] = icmp slt i64 0, [[TMP0]]
; COMMON-NEXT: br i1 [[C_1]], label [[INNER_1]], label [[INNER_2_HEADER_PREHEADER:%.*]]
; COMMON: inner.2.header.preheader:
; COMMON-NEXT: br label [[INNER_2_HEADER:%.*]]
@@ -30,7 +30,6 @@ define i32 @test(i1 %c.0, i32 %m) {
; COMMON-NEXT: [[MAX_1]] = phi i32 [ [[M]], [[INNER_2_LATCH]] ], [ 0, [[INNER_2_HEADER]] ]
; COMMON-NEXT: [[IV_1_NEXT]] = add i32 [[IV_1]], 1
; COMMON-NEXT: [[C_3:%.*]] = icmp ugt i32 [[IV_1]], [[MAX_0]]
-; COMMON-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
; COMMON-NEXT: br i1 [[C_3]], label [[EXIT:%.*]], label [[OUTER_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]
; COMMON: exit:
; COMMON-NEXT: ret i32 0
diff --git a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
index 74efc110bbc17..fb2fdb116f904 100644
--- a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
+++ b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
@@ -83,7 +83,7 @@ define void @test_simplifycompare_rhs_not_constant2(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
; CHECK: [[OUTER_HEADER_LOOPEXIT:.*]]:
-; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 2
+; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[INDVARS_IV:%.*]], 2
; CHECK-NEXT: br label %[[OUTER_HEADER]]
; CHECK: [[OUTER_HEADER]]:
; CHECK-NEXT: [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], %[[OUTER_HEADER_LOOPEXIT]] ], [ 0, %[[ENTRY]] ]
diff --git a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
index 6a889cf4c00b6..4a230b781d2db 100644
--- a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
+++ b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll
@@ -309,7 +309,7 @@ define void @test_infer_nsw(ptr %p) {
; CHECK-NEXT: br i1 [[ICMP]], label [[BB2]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: store i16 1, ptr [[P:%.*]], align 2
-; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[PHI]], 2
+; CHECK-NEXT: [[ADD]] = add nuw i32 [[PHI]], 2
; CHECK-NEXT: br label [[BB1]]
; CHECK: bb3:
; CHECK-NEXT: ret void
@@ -432,7 +432,7 @@ define void @test_shl_nuw_only(ptr %p) {
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[OFF:%.*]] = shl nuw i8 [[IV]], 1
; CHECK-NEXT: store i8 [[OFF]], ptr [[P:%.*]], align 1
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], -128
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
diff --git a/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll b/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
index 96516cbcc0889..406b6ecd944f4 100644
--- a/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
+++ b/llvm/test/Transforms/IndVarSimplify/turn-to-invariant.ll
@@ -1065,7 +1065,7 @@ define i32 @not_invariant_samesign(i32 %unknown_limit, ptr %length_ptr) {
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
; CHECK-NEXT: [[RANGE_CHECK1_FIRST_ITER:%.*]] = icmp samesign ult i32 [[IV_NEXT]], [[UNKNOWN_LIMIT:%.*]]
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[UNKNOWN_LIMIT]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[RANGE_CHECK1_FIRST_ITER]], [[IS_POSITIVE]]
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
index 3c37ee6b6b98a..da14e631f5142 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/2008-08-14-ShadowIV.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -loop-reduce -S -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s
; Provide legal integer types.
@@ -6,201 +5,122 @@ target datalayout = "n8:16:32:64"
define void @foobar(i32 %n) nounwind {
-; CHECK-LABEL: define void @foobar(
-; CHECK-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N]], 0
-; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_NPH:.*]]
-; CHECK: [[BB_NPH]]:
-; CHECK-NEXT: br label %[[BB:.*]]
-; CHECK: [[BB]]:
-; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ 0.000000e+00, %[[BB_NPH]] ], [ [[IV_S_NEXT_:%.*]], %[[BB]] ]
-; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, %[[BB_NPH]] ], [ [[INDVAR_NEXT:%.*]], %[[BB]] ]
-; CHECK-NEXT: tail call void @bar(i32 [[I_03]]) #[[ATTR0]]
-; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
-; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], 1.000000e+00
-; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i32 [[I_03]], 1
-; CHECK-NEXT: [[SCMP:%.*]] = icmp uge i32 [[INDVAR_NEXT]], [[N]]
-; CHECK-NEXT: br i1 [[SCMP]], label %[[RETURN_LOOPEXIT:.*]], label %[[BB]]
-; CHECK: [[RETURN_LOOPEXIT]]:
-; CHECK-NEXT: br label %[[RETURN]]
-; CHECK: [[RETURN]]:
-; CHECK-NEXT: ret void
-;
+
+; CHECK-LABEL: foobar(
+; CHECK: phi double
entry:
- %cond = icmp eq i32 %n, 0 ; <i1>:0 [#uses=2]
- br i1 %cond, label %return, label %bb.nph
+ %cond = icmp eq i32 %n, 0 ; <i1>:0 [#uses=2]
+ br i1 %cond, label %return, label %bb.nph
bb.nph: ; preds = %entry
- %umax = select i1 %cond, i32 1, i32 %n ; <i32> [#uses=1]
- br label %bb
+ %umax = select i1 %cond, i32 1, i32 %n ; <i32> [#uses=1]
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- tail call void @bar( i32 %i.03 ) nounwind
- %tmp1 = uitofp i32 %i.03 to double ; <double>:1 [#uses=1]
- tail call void @foo( double %tmp1 ) nounwind
- %indvar.next = add nsw nuw i32 %i.03, 1 ; <i32> [#uses=2]
- %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ tail call void @bar( i32 %i.03 ) nounwind
+ %tmp1 = uitofp i32 %i.03 to double ; <double>:1 [#uses=1]
+ tail call void @foo( double %tmp1 ) nounwind
+ %indvar.next = add nsw nuw i32 %i.03, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast because the mantissa bits for double are not enough
; to hold all of i64 IV bits.
define void @foobar2(i64 %n) nounwind {
-; CHECK-LABEL: define void @foobar2(
-; CHECK-SAME: i64 [[N:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[N]], 0
-; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_NPH:.*]]
-; CHECK: [[BB_NPH]]:
-; CHECK-NEXT: br label %[[BB:.*]]
-; CHECK: [[BB]]:
-; CHECK-NEXT: [[I_03:%.*]] = phi i64 [ 0, %[[BB_NPH]] ], [ [[INDVAR_NEXT:%.*]], %[[BB]] ]
-; CHECK-NEXT: [[TMP:%.*]] = trunc i64 [[I_03]] to i32
-; CHECK-NEXT: tail call void @bar(i32 [[TMP]]) #[[ATTR0]]
-; CHECK-NEXT: [[TMP2:%.*]] = uitofp i64 [[I_03]] to double
-; CHECK-NEXT: tail call void @foo(double [[TMP2]]) #[[ATTR0]]
-; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i64 [[I_03]], 1
-; CHECK-NEXT: [[SCMP:%.*]] = icmp uge i64 [[INDVAR_NEXT]], [[N]]
-; CHECK-NEXT: br i1 [[SCMP]], label %[[RETURN_LOOPEXIT:.*]], label %[[BB]]
-; CHECK: [[RETURN_LOOPEXIT]]:
-; CHECK-NEXT: br label %[[RETURN]]
-; CHECK: [[RETURN]]:
-; CHECK-NEXT: ret void
-;
+
+; CHECK-LABEL: foobar2(
+; CHECK-NOT: phi double
+; CHECK-NOT: phi float
entry:
- %cond = icmp eq i64 %n, 0 ; <i1>:0 [#uses=2]
- br i1 %cond, label %return, label %bb.nph
+ %cond = icmp eq i64 %n, 0 ; <i1>:0 [#uses=2]
+ br i1 %cond, label %return, label %bb.nph
bb.nph: ; preds = %entry
- %umax = select i1 %cond, i64 1, i64 %n ; <i64> [#uses=1]
- br label %bb
+ %umax = select i1 %cond, i64 1, i64 %n ; <i64> [#uses=1]
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
- %tmp1 = trunc i64 %i.03 to i32 ; <i32>:1 [#uses=1]
- tail call void @bar( i32 %tmp1 ) nounwind
- %tmp2 = uitofp i64 %i.03 to double ; <double>:2 [#uses=1]
- tail call void @foo( double %tmp2 ) nounwind
- %indvar.next = add nsw nuw i64 %i.03, 1 ; <i64> [#uses=2]
- %exitcond = icmp eq i64 %indvar.next, %umax ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
+ %tmp1 = trunc i64 %i.03 to i32 ; <i32>:1 [#uses=1]
+ tail call void @bar( i32 %tmp1 ) nounwind
+ %tmp2 = uitofp i64 %i.03 to double ; <double>:2 [#uses=1]
+ tail call void @foo( double %tmp2 ) nounwind
+ %indvar.next = add nsw nuw i64 %i.03, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %umax ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast due to potentional overflow.
define void @foobar3() nounwind {
-; CHECK-LABEL: define void @foobar3(
-; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 (...) @nn() #[[ATTR0]]
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[TMP0]], 0
-; CHECK-NEXT: br i1 [[COND]], label %[[RETURN:.*]], label %[[BB_PREHEADER:.*]]
-; CHECK: [[BB_PREHEADER]]:
-; CHECK-NEXT: br label %[[BB:.*]]
-; CHECK: [[BB]]:
-; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ [[INDVAR_NEXT:%.*]], %[[BB]] ], [ 0, %[[BB_PREHEADER]] ]
-; CHECK-NEXT: tail call void @bar(i32 [[I_03]]) #[[ATTR0]]
-; CHECK-NEXT: [[TMP2:%.*]] = uitofp i32 [[I_03]] to double
-; CHECK-NEXT: tail call void @foo(double [[TMP2]]) #[[ATTR0]]
-; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw i32 [[I_03]], 1
-; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 (...) @nn() #[[ATTR0]]
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[TMP4]], [[INDVAR_NEXT]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[BB]], label %[[RETURN_LOOPEXIT:.*]]
-; CHECK: [[RETURN_LOOPEXIT]]:
-; CHECK-NEXT: br label %[[RETURN]]
-; CHECK: [[RETURN]]:
-; CHECK-NEXT: ret void
-;
+
+; CHECK-LABEL: foobar3(
+; CHECK-NOT: phi double
+; CHECK-NOT: phi float
entry:
- %tmp0 = tail call i32 (...) @nn( ) nounwind ; <i32>:0 [#uses=1]
- %cond = icmp eq i32 %tmp0, 0 ; <i1>:1 [#uses=1]
- br i1 %cond, label %return, label %bb
+ %tmp0 = tail call i32 (...) @nn( ) nounwind ; <i32>:0 [#uses=1]
+ %cond = icmp eq i32 %tmp0, 0 ; <i1>:1 [#uses=1]
+ br i1 %cond, label %return, label %bb
bb: ; preds = %bb, %entry
- %i.03 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- tail call void @bar( i32 %i.03 ) nounwind
- %tmp2 = uitofp i32 %i.03 to double ; <double>:2 [#uses=1]
- tail call void @foo( double %tmp2 ) nounwind
- %indvar.next = add nuw nsw i32 %i.03, 1 ; <i32>:3 [#uses=2]
- %tmp4 = tail call i32 (...) @nn( ) nounwind ; <i32>:4 [#uses=1]
- %exitcond = icmp ugt i32 %tmp4, %indvar.next ; <i1>:5 [#uses=1]
- br i1 %exitcond, label %bb, label %return
+ %i.03 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ tail call void @bar( i32 %i.03 ) nounwind
+ %tmp2 = uitofp i32 %i.03 to double ; <double>:2 [#uses=1]
+ tail call void @foo( double %tmp2 ) nounwind
+ %indvar.next = add nuw nsw i32 %i.03, 1 ; <i32>:3 [#uses=2]
+ %tmp4 = tail call i32 (...) @nn( ) nounwind ; <i32>:4 [#uses=1]
+ %exitcond = icmp ugt i32 %tmp4, %indvar.next ; <i1>:5 [#uses=1]
+ br i1 %exitcond, label %bb, label %return
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast due to overflow.
define void @foobar4() nounwind {
-; CHECK-LABEL: define void @foobar4(
-; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: br label %[[BB_NPH:.*]]
-; CHECK: [[BB_NPH]]:
-; CHECK-NEXT: br label %[[BB:.*]]
-; CHECK: [[BB]]:
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[BB]] ], [ 0, %[[BB_NPH]] ]
-; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ 0.000000e+00, %[[BB_NPH]] ], [ [[IV_S_NEXT_:%.*]], %[[BB]] ]
-; CHECK-NEXT: tail call void @bar(i32 [[LSR_IV]]) #[[ATTR0]]
-; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
-; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], 1.000000e+00
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 32767
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[RETURN:.*]], label %[[BB]]
-; CHECK: [[RETURN]]:
-; CHECK-NEXT: ret void
-;
+
+; CHECK-LABEL: foobar4(
+; CHECK-NOT: phi double
+; CHECK-NOT: phi float
entry:
- br label %bb.nph
+ br label %bb.nph
bb.nph: ; preds = %entry
- br label %bb
+ br label %bb
bb: ; preds = %bb, %bb.nph
- %i.03 = phi i8 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
- %tmp2 = sext i8 %i.03 to i32 ; <i32>:0 [#uses=1]
- tail call void @bar( i32 %tmp2 ) nounwind
- %tmp3 = uitofp i8 %i.03 to double ; <double>:1 [#uses=1]
- tail call void @foo( double %tmp3 ) nounwind
- %indvar.next = add nsw nuw i8 %i.03, 1 ; <i32> [#uses=2]
- %tmp = sext i8 %indvar.next to i32
- %exitcond = icmp eq i32 %tmp, 32767 ; <i1> [#uses=1]
- br i1 %exitcond, label %return, label %bb
+ %i.03 = phi i8 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
+ %tmp2 = sext i8 %i.03 to i32 ; <i32>:0 [#uses=1]
+ tail call void @bar( i32 %tmp2 ) nounwind
+ %tmp3 = uitofp i8 %i.03 to double ; <double>:1 [#uses=1]
+ tail call void @foo( double %tmp3 ) nounwind
+ %indvar.next = add nsw nuw i8 %i.03, 1 ; <i32> [#uses=2]
+ %tmp = sext i8 %indvar.next to i32
+ %exitcond = icmp eq i32 %tmp, 32767 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
return: ; preds = %bb, %entry
- ret void
+ ret void
}
; Unable to eliminate cast because the integer IV overflows (accum exceeds
; SINT_MAX).
define i32 @foobar5() {
-; CHECK-LABEL: define i32 @foobar5() {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: br label %[[LOOP:.*]]
-; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
-; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = sitofp i32 [[ACCUM]] to double
-; CHECK-NEXT: tail call void @foo(double [[TMP1]]) #[[ATTR0]]
-; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
-; CHECK: [[EXIT]]:
-; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
-;
+; CHECK-LABEL: foobar5(
+; CHECK-NOT: phi double
+; CHECK-NOT: phi float
entry:
br label %loop
@@ -221,22 +141,8 @@ exit: ; preds = %loop
; Can eliminate if we set nsw and, thus, think that we don't overflow SINT_MAX.
define i32 @foobar6() {
-; CHECK-LABEL: define i32 @foobar6() {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: br label %[[LOOP:.*]]
-; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
-; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ -3.220000e+03, %[[ENTRY]] ], [ [[IV_S_NEXT_:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
-; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], f0x41624E65A0000000
-; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
-; CHECK: [[EXIT]]:
-; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
-;
+; CHECK-LABEL: foobar6(
+; CHECK: phi double
entry:
br label %loop
@@ -259,21 +165,9 @@ exit: ; preds = %loop
; UINT_MAX).
define i32 @foobar7() {
-; CHECK-LABEL: define i32 @foobar7() {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: br label %[[LOOP:.*]]
-; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
-; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = uitofp i32 [[ACCUM]] to double
-; CHECK-NEXT: tail call void @foo(double [[TMP1]]) #[[ATTR0]]
-; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
-; CHECK: [[EXIT]]:
-; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
-;
+; CHECK-LABEL: foobar7(
+; CHECK-NOT: phi double
+; CHECK-NOT: phi float
entry:
br label %loop
@@ -294,22 +188,8 @@ exit: ; preds = %loop
; Can eliminate if we set nuw and, thus, think that we don't overflow UINT_MAX.
define i32 @foobar8() {
-; CHECK-LABEL: define i32 @foobar8() {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: br label %[[LOOP:.*]]
-; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 11, %[[ENTRY]] ]
-; CHECK-NEXT: [[IV_S_:%.*]] = phi double [ f0x41EFFFFE6D800000, %[[ENTRY]] ], [ [[IV_S_NEXT_:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[ACCUM:%.*]] = phi i32 [ -3220, %[[ENTRY]] ], [ [[ACCUM_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: tail call void @foo(double [[IV_S_]]) #[[ATTR0]]
-; CHECK-NEXT: [[IV_S_NEXT_]] = fadd double [[IV_S_]], f0x41624E65A0000000
-; CHECK-NEXT: [[ACCUM_NEXT]] = add i32 [[ACCUM]], 9597741
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ugt i32 [[LSR_IV_NEXT]], 235
-; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
-; CHECK: [[EXIT]]:
-; CHECK-NEXT: ret i32 [[ACCUM_NEXT]]
-;
+; CHECK-LABEL: foobar8(
+; CHECK: phi double
entry:
br label %loop
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
index a5300b3fb81e1..f780bee7874cf 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
@@ -108,7 +108,7 @@ define void @test2(i32 %n, i1 %arg) nounwind uwtable {
; CHECK-NEXT: br label [[FOR_INC498:%.*]]
; CHECK: if.then477:
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV]], i64 12
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV1]], 1
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw i32 [[LSR_IV1]], 1
; CHECK-NEXT: br label [[FOR_COND468]]
; CHECK: for.inc498:
; CHECK-NEXT: br label [[FOR_INC498]]
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
index f39d33e77b7a4..a878fc2c39e82 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -loop-reduce -S | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
@@ -8,6 +7,8 @@ target triple = "x86_64-apple-macosx10.9.0"
; expression. In this testcase, the normalized expression was denormalized to
; an expression different from the original, and we were losing sign extension.
+; CHECK: [[TMP:%[a-z]+]] = trunc i32 {{.*}} to i8
+; CHECK: {{%[a-z0-9]+}} = sext i8 [[TMP]] to i32
@j = common global i32 0, align 4
@c = common global i32 0, align 4
@@ -22,41 +23,6 @@ target triple = "x86_64-apple-macosx10.9.0"
; Function Attrs: nounwind optsize ssp uwtable
define i32 @main() #0 {
-; CHECK-LABEL: define i32 @main(
-; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: store i8 0, ptr @h, align 1
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @j, align 4
-; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[TMP0]], 0
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @d, align 4
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[TMP1]], -1
-; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[TMP1]], 31
-; CHECK-NEXT: [[DOTLOBIT_NOT:%.*]] = xor i32 [[DOTLOBIT]], 1
-; CHECK-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK: [[FOR_BODY]]:
-; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i32 [ [[LSR_IV_NEXT2:%.*]], %[[FN3_EXIT:.*]] ], [ 0, %[[ENTRY]] ]
-; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[FN3_EXIT]] ], [ -1, %[[ENTRY]] ]
-; CHECK-NEXT: br i1 [[TOBOOL_I]], label %[[FN3_EXIT]], label %[[LAND_RHS_I:.*]]
-; CHECK: [[LAND_RHS_I]]:
-; CHECK-NEXT: store i32 0, ptr @c, align 4
-; CHECK-NEXT: br label %[[FN3_EXIT]]
-; CHECK: [[FN3_EXIT]]:
-; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], 2
-; CHECK-NEXT: [[LSR_IV_NEXT2]] = add nuw nsw i32 [[LSR_IV1]], 1
-; CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[LSR_IV_NEXT2]] to i8
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[TMP3]], -1
-; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
-; CHECK: [[FOR_END]]:
-; CHECK-NEXT: [[DOTLOBIT_NOT_:%.*]] = select i1 [[CMP3]], i32 [[DOTLOBIT_NOT]], i32 0
-; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[LSR_IV_NEXT2]], -1
-; CHECK-NEXT: store i32 [[TMP2]], ptr @g, align 4
-; CHECK-NEXT: store i32 [[DOTLOBIT_NOT_]], ptr @i, align 4
-; CHECK-NEXT: [[TMP:%.*]] = trunc i32 [[LSR_IV_NEXT2]] to i8
-; CHECK-NEXT: store i8 [[TMP]], ptr @h, align 1
-; CHECK-NEXT: store i32 [[LSR_IV_NEXT]], ptr @e, align 4
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 (ptr, ...) @printf(ptr @.str, i32 [[LSR_IV_NEXT]]) #[[ATTR2:[0-9]+]]
-; CHECK-NEXT: ret i32 0
-;
entry:
store i8 0, ptr @h, align 1
%0 = load i32, ptr @j, align 4
diff --git a/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll b/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
index bfc46c1219716..10b22974080dc 100644
--- a/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/AArch64/apple-unrolling.ll
@@ -313,7 +313,7 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; APPLE: [[EXIT]]:
; APPLE-NEXT: ret void
;
-; OTHER-LABEL: define void @load_op_store_loop_multiblock(
+; ; OTHER-LABEL: define void @load_op_store_loop_multiblock(
; OTHER-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]], i64 [[N:%.*]], i64 [[SCALE:%.*]], float [[K:%.*]]) #[[ATTR0]] {
; OTHER-NEXT: [[ENTRY:.*]]:
; OTHER-NEXT: br label %[[LOOP:.*]]
@@ -321,12 +321,12 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; OTHER-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOPCONT:.*]] ]
; OTHER-NEXT: [[SCALED_IV:%.*]] = mul nuw nsw i64 [[IV]], [[SCALE]]
; OTHER-NEXT: [[GEP_SRC:%.*]] = getelementptr inbounds float, ptr [[SRC]], i64 [[SCALED_IV]]
-; OTHER-NEXT: [[L1:%.*]] = load float, ptr [[GEP_SRC]], align 4
+; OTHER-NEXT: [[L:%.*]] = load float, ptr [[GEP_SRC]], align 4
; OTHER-NEXT: [[AND:%.*]] = and i64 [[IV]], 1
; OTHER-NEXT: [[ODD:%.*]] = icmp eq i64 [[AND]], 1
; OTHER-NEXT: br i1 [[ODD]], label %[[LOOPODD:.*]], label %[[LOOPCONT]]
; OTHER: [[LOOPCONT]]:
-; OTHER-NEXT: [[D:%.*]] = phi float [ [[L2:%.*]], %[[LOOPODD]] ], [ [[L1]], %[[LOOP]] ]
+; OTHER-NEXT: [[D:%.*]] = phi float [ [[L2:%.*]], %[[LOOPODD]] ], [ [[L]], %[[LOOP]] ]
; OTHER-NEXT: [[O:%.*]] = fadd float [[D]], [[K]]
; OTHER-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds float, ptr [[DST]], i64 [[IV]]
; OTHER-NEXT: store float [[O]], ptr [[GEP_DST]], align 4
@@ -334,7 +334,7 @@ define void @load_op_store_loop_multiblock(ptr %src, ptr %dst, i64 %N, i64 %scal
; OTHER-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; OTHER-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
; OTHER: [[LOOPODD]]:
-; OTHER-NEXT: [[L2]] = fneg float [[L1]]
+; OTHER-NEXT: [[L2]] = fneg float [[L]]
; OTHER-NEXT: br label %[[LOOPCONT]]
; OTHER: [[EXIT]]:
; OTHER-NEXT: ret void
@@ -1062,7 +1062,7 @@ define i32 @test_add_reduction_runtime(ptr %a, i64 noundef %n) {
; APPLE-NEXT: [[TMP5:%.*]] = load i32, ptr [[GEP_A_3]], align 2
; APPLE-NEXT: [[RDX_NEXT_3]] = add i32 [[RDX_3]], [[TMP5]]
; APPLE-NEXT: [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4
-; APPLE-NEXT: [[NITER_NEXT_3]] = add nuw nsw i64 [[NITER]], 4
+; APPLE-NEXT: [[NITER_NEXT_3]] = add nuw i64 [[NITER]], 4
; APPLE-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i64 [[NITER_NEXT_3]], [[UNROLL_ITER]]
; APPLE-NEXT: br i1 [[NITER_NCMP_3]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]]
; APPLE: [[EXIT_UNR_LCSSA]]:
diff --git a/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll b/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
index 8060501fc5dd9..c00f744ac3ddf 100644
--- a/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/ARM/loop-unrolling.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -mtriple=armv7 -mcpu=cortex-a57 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
; RUN: opt -mtriple=thumbv7 -mcpu=cortex-a57 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
; RUN: opt -mtriple=thumbv7 -mcpu=cortex-a72 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-NOUNROLL
@@ -6,177 +5,40 @@
; RUN: opt -mtriple=thumbv8m.main -mcpu=cortex-m33 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-UNROLL
; RUN: opt -mtriple=thumbv7em -mcpu=cortex-m7 -passes=loop-unroll -S %s -o - | FileCheck %s --check-prefix=CHECK-UNROLL
+; CHECK-LABEL: partial
define arm_aapcs_vfpcc void @partial(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B) local_unnamed_addr #0 {
-; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @partial(
-; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-; CHECK-NOUNROLL-NEXT: [[ENTRY:.*]]:
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY]]:
-; CHECK-NOUNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC_1:%.*]], %[[FOR_BODY]] ]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_08]], 1
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC_1]] = add nuw nsw i32 [[I_08]], 2
-; CHECK-NOUNROLL-NEXT: [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 1024
-; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND_1]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
-; CHECK-NOUNROLL-NEXT: ret void
-;
-; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @partial(
-; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-; CHECK-UNROLL-NEXT: [[ENTRY:.*]]:
-; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-UNROLL: [[FOR_BODY]]:
-; CHECK-UNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC_15:%.*]], %[[FOR_BODY]] ]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-UNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-UNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_08]], 1
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-UNROLL-NEXT: [[INC_1:%.*]] = add nuw nsw i32 [[I_08]], 2
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_2]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_2:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_2]], ptr [[ARRAYIDX2_2]], align 4
-; CHECK-UNROLL-NEXT: [[INC_2:%.*]] = add nuw nsw i32 [[I_08]], 3
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_3]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_3:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_3]], ptr [[ARRAYIDX2_3]], align 4
-; CHECK-UNROLL-NEXT: [[INC_3:%.*]] = add nuw nsw i32 [[I_08]], 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_3]]
-; CHECK-UNROLL-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_4:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_3]]
-; CHECK-UNROLL-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX1_4]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_4:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_4:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_3]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_4]], ptr [[ARRAYIDX2_4]], align 4
-; CHECK-UNROLL-NEXT: [[INC_4:%.*]] = add nuw nsw i32 [[I_08]], 5
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_4]]
-; CHECK-UNROLL-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_5:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_4]]
-; CHECK-UNROLL-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX1_5]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_5:%.*]] = mul nsw i32 [[TMP11]], [[TMP10]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_5:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_4]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_5]], ptr [[ARRAYIDX2_5]], align 4
-; CHECK-UNROLL-NEXT: [[INC_5:%.*]] = add nuw nsw i32 [[I_08]], 6
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_5]]
-; CHECK-UNROLL-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_6:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_5]]
-; CHECK-UNROLL-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX1_6]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_6:%.*]] = mul nsw i32 [[TMP13]], [[TMP12]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_6:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_5]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_6]], ptr [[ARRAYIDX2_6]], align 4
-; CHECK-UNROLL-NEXT: [[INC_6:%.*]] = add nuw nsw i32 [[I_08]], 7
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_6]]
-; CHECK-UNROLL-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_7:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_6]]
-; CHECK-UNROLL-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX1_7]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_7:%.*]] = mul nsw i32 [[TMP15]], [[TMP14]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_7:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_6]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_7]], ptr [[ARRAYIDX2_7]], align 4
-; CHECK-UNROLL-NEXT: [[INC_7:%.*]] = add nuw nsw i32 [[I_08]], 8
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_8:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_7]]
-; CHECK-UNROLL-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX_8]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_8:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_7]]
-; CHECK-UNROLL-NEXT: [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX1_8]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_8:%.*]] = mul nsw i32 [[TMP17]], [[TMP16]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_8:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_7]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_8]], ptr [[ARRAYIDX2_8]], align 4
-; CHECK-UNROLL-NEXT: [[INC_8:%.*]] = add nuw nsw i32 [[I_08]], 9
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_9:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_8]]
-; CHECK-UNROLL-NEXT: [[TMP18:%.*]] = load i32, ptr [[ARRAYIDX_9]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_9:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_8]]
-; CHECK-UNROLL-NEXT: [[TMP19:%.*]] = load i32, ptr [[ARRAYIDX1_9]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_9:%.*]] = mul nsw i32 [[TMP19]], [[TMP18]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_9:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_8]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_9]], ptr [[ARRAYIDX2_9]], align 4
-; CHECK-UNROLL-NEXT: [[INC_9:%.*]] = add nuw nsw i32 [[I_08]], 10
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_10:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_9]]
-; CHECK-UNROLL-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARRAYIDX_10]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_10:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_9]]
-; CHECK-UNROLL-NEXT: [[TMP21:%.*]] = load i32, ptr [[ARRAYIDX1_10]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_10:%.*]] = mul nsw i32 [[TMP21]], [[TMP20]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_10:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_9]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_10]], ptr [[ARRAYIDX2_10]], align 4
-; CHECK-UNROLL-NEXT: [[INC_10:%.*]] = add nuw nsw i32 [[I_08]], 11
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_11:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_10]]
-; CHECK-UNROLL-NEXT: [[TMP22:%.*]] = load i32, ptr [[ARRAYIDX_11]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_11:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_10]]
-; CHECK-UNROLL-NEXT: [[TMP23:%.*]] = load i32, ptr [[ARRAYIDX1_11]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_11:%.*]] = mul nsw i32 [[TMP23]], [[TMP22]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_11:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_10]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_11]], ptr [[ARRAYIDX2_11]], align 4
-; CHECK-UNROLL-NEXT: [[INC_11:%.*]] = add nuw nsw i32 [[I_08]], 12
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_12:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_11]]
-; CHECK-UNROLL-NEXT: [[TMP24:%.*]] = load i32, ptr [[ARRAYIDX_12]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_12:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_11]]
-; CHECK-UNROLL-NEXT: [[TMP25:%.*]] = load i32, ptr [[ARRAYIDX1_12]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_12:%.*]] = mul nsw i32 [[TMP25]], [[TMP24]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_12:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_11]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_12]], ptr [[ARRAYIDX2_12]], align 4
-; CHECK-UNROLL-NEXT: [[INC_12:%.*]] = add nuw nsw i32 [[I_08]], 13
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_13:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_12]]
-; CHECK-UNROLL-NEXT: [[TMP26:%.*]] = load i32, ptr [[ARRAYIDX_13]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_13:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_12]]
-; CHECK-UNROLL-NEXT: [[TMP27:%.*]] = load i32, ptr [[ARRAYIDX1_13]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_13:%.*]] = mul nsw i32 [[TMP27]], [[TMP26]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_13:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_12]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_13]], ptr [[ARRAYIDX2_13]], align 4
-; CHECK-UNROLL-NEXT: [[INC_13:%.*]] = add nuw nsw i32 [[I_08]], 14
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_14:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_13]]
-; CHECK-UNROLL-NEXT: [[TMP28:%.*]] = load i32, ptr [[ARRAYIDX_14]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_14:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_13]]
-; CHECK-UNROLL-NEXT: [[TMP29:%.*]] = load i32, ptr [[ARRAYIDX1_14]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_14:%.*]] = mul nsw i32 [[TMP29]], [[TMP28]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_14:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_13]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_14]], ptr [[ARRAYIDX2_14]], align 4
-; CHECK-UNROLL-NEXT: [[INC_14:%.*]] = add nuw nsw i32 [[I_08]], 15
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_15:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_14]]
-; CHECK-UNROLL-NEXT: [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX_15]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_15:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_14]]
-; CHECK-UNROLL-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1_15]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_15:%.*]] = mul nsw i32 [[TMP31]], [[TMP30]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_15:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_14]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_15]], ptr [[ARRAYIDX2_15]], align 4
-; CHECK-UNROLL-NEXT: [[INC_15]] = add nuw nsw i32 [[I_08]], 16
-; CHECK-UNROLL-NEXT: [[EXITCOND_15:%.*]] = icmp eq i32 [[INC_15]], 1024
-; CHECK-UNROLL-NEXT: br i1 [[EXITCOND_15]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP]]:
-; CHECK-UNROLL-NEXT: ret void
-;
entry:
br label %for.body
+; CHECK-LABEL: for.body
for.body:
+
+; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV2:%[a-z.0-9]+]], %for.body ]
+; CHECK-NOUNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-NOUNROLL: [[IV2]] = add nuw nsw i32 [[IV0]], 2
+; CHECK-NOUNROLL: [[CMP:%[a-z.0-9]+]] = icmp eq i32 [[IV2]], 1024
+; CHECK-NOUNROLL: br i1 [[CMP]], label [[END:%[a-z.]+]], label %for.body
+
+; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV16:%[a-z.0-9]+]], %for.body ]
+; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
+; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
+; CHECK-UNROLL: [[IV4:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 4
+; CHECK-UNROLL: [[IV5:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 5
+; CHECK-UNROLL: [[IV6:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 6
+; CHECK-UNROLL: [[IV7:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 7
+; CHECK-UNROLL: [[IV8:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 8
+; CHECK-UNROLL: [[IV9:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 9
+; CHECK-UNROLL: [[IV10:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 10
+; CHECK-UNROLL: [[IV11:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 11
+; CHECK-UNROLL: [[IV12:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 12
+; CHECK-UNROLL: [[IV13:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 13
+; CHECK-UNROLL: [[IV14:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 14
+; CHECK-UNROLL: [[IV15:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 15
+; CHECK-UNROLL: [[IV16]] = add nuw nsw i32 [[IV0]], 16
+; CHECK-UNROLL: [[CMP:%[a-z.0-9]+]] = icmp eq i32 [[IV16]], 1024
+; CHECK-UNROLL: br i1 [[CMP]], label [[END:%[a-z.]+]], label %for.body
+
%i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.08
%0 = load i32, ptr %arrayidx, align 4
@@ -193,168 +55,30 @@ for.cond.cleanup:
ret void
}
+; CHECK-LABEL: runtime
define arm_aapcs_vfpcc void @runtime(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B, i32 %N) local_unnamed_addr #0 {
-; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @runtime(
-; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
-; CHECK-NOUNROLL-NEXT: [[CMP8:%.*]] = icmp eq i32 [[N]], 0
-; CHECK-NOUNROLL-NEXT: br i1 [[CMP8]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY_PREHEADER:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY_PREHEADER]]:
-; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
-; CHECK-NOUNROLL-NEXT: [[XTRAITER:%.*]] = and i32 [[N]], 1
-; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 1
-; CHECK-NOUNROLL-NEXT: br i1 [[TMP1]], label %[[FOR_BODY_EPIL_PREHEADER:.*]], label %[[FOR_BODY_PREHEADER_NEW:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY_PREHEADER_NEW]]:
-; CHECK-NOUNROLL-NEXT: [[UNROLL_ITER:%.*]] = sub i32 [[N]], [[XTRAITER]]
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY]]:
-; CHECK-NOUNROLL-NEXT: [[I_09:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1:%.*]], %[[FOR_BODY]] ]
-; CHECK-NOUNROLL-NEXT: [[NITER:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], %[[FOR_BODY]] ]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]]
-; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]]
-; CHECK-NOUNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]]
-; CHECK-NOUNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_09]], 1
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
-; CHECK-NOUNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC_1]] = add nuw nsw i32 [[I_09]], 2
-; CHECK-NOUNROLL-NEXT: [[NITER_NEXT_1]] = add nuw nsw i32 [[NITER]], 2
-; CHECK-NOUNROLL-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]
-; CHECK-NOUNROLL-NEXT: br i1 [[NITER_NCMP_1]], label %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:.*]], label %[[FOR_BODY]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]]:
-; CHECK-NOUNROLL-NEXT: [[I_09_UNR:%.*]] = phi i32 [ [[INC_1]], %[[FOR_BODY]] ]
-; CHECK-NOUNROLL-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
-; CHECK-NOUNROLL-NEXT: br i1 [[LCMP_MOD]], label %[[FOR_BODY_EPIL_PREHEADER]], label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY_EPIL_PREHEADER]]:
-; CHECK-NOUNROLL-NEXT: [[I_09_EPIL_INIT:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[I_09_UNR]], %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]] ]
-; CHECK-NOUNROLL-NEXT: [[LCMP_MOD1:%.*]] = icmp ne i32 [[XTRAITER]], 0
-; CHECK-NOUNROLL-NEXT: call void @llvm.assume(i1 [[LCMP_MOD1]])
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY_EPIL:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY_EPIL]]:
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09_EPIL_INIT]]
-; CHECK-NOUNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09_EPIL_INIT]]
-; CHECK-NOUNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4
-; CHECK-NOUNROLL-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09_EPIL_INIT]]
-; CHECK-NOUNROLL-NEXT: store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT]]:
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
-; CHECK-NOUNROLL-NEXT: ret void
-;
-; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @runtime(
-; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-UNROLL-NEXT: [[ENTRY:.*:]]
-; CHECK-UNROLL-NEXT: [[CMP8:%.*]] = icmp eq i32 [[N]], 0
-; CHECK-UNROLL-NEXT: br i1 [[CMP8]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY_PREHEADER:.*]]
-; CHECK-UNROLL: [[FOR_BODY_PREHEADER]]:
-; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
-; CHECK-UNROLL-NEXT: [[XTRAITER:%.*]] = and i32 [[N]], 3
-; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
-; CHECK-UNROLL-NEXT: br i1 [[TMP1]], label %[[FOR_BODY_EPIL_PREHEADER:.*]], label %[[FOR_BODY_PREHEADER_NEW:.*]]
-; CHECK-UNROLL: [[FOR_BODY_PREHEADER_NEW]]:
-; CHECK-UNROLL-NEXT: [[UNROLL_ITER:%.*]] = sub i32 [[N]], [[XTRAITER]]
-; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-UNROLL: [[FOR_BODY]]:
-; CHECK-UNROLL-NEXT: [[I_09:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_3:%.*]], %[[FOR_BODY]] ]
-; CHECK-UNROLL-NEXT: [[NITER:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], %[[FOR_BODY]] ]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]]
-; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]]
-; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-UNROLL-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], [[TMP2]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-UNROLL-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_09]], 1
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[TMP5]], [[TMP4]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-UNROLL-NEXT: [[INC_1:%.*]] = add nuw nsw i32 [[I_09]], 2
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1_2]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_2:%.*]] = mul nsw i32 [[TMP7]], [[TMP6]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_1]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_2]], ptr [[ARRAYIDX2_2]], align 4
-; CHECK-UNROLL-NEXT: [[INC_2:%.*]] = add nuw nsw i32 [[I_09]], 3
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX1_3]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_3:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_2]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_3]], ptr [[ARRAYIDX2_3]], align 4
-; CHECK-UNROLL-NEXT: [[INC_3]] = add nuw nsw i32 [[I_09]], 4
-; CHECK-UNROLL-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
-; CHECK-UNROLL-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
-; CHECK-UNROLL-NEXT: br i1 [[NITER_NCMP_3]], label %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:.*]], label %[[FOR_BODY]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]]:
-; CHECK-UNROLL-NEXT: [[I_09_UNR:%.*]] = phi i32 [ [[INC_3]], %[[FOR_BODY]] ]
-; CHECK-UNROLL-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
-; CHECK-UNROLL-NEXT: br i1 [[LCMP_MOD]], label %[[FOR_BODY_EPIL_PREHEADER]], label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
-; CHECK-UNROLL: [[FOR_BODY_EPIL_PREHEADER]]:
-; CHECK-UNROLL-NEXT: [[I_09_EPIL_INIT:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[I_09_UNR]], %[[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]] ]
-; CHECK-UNROLL-NEXT: [[LCMP_MOD1:%.*]] = icmp ne i32 [[XTRAITER]], 0
-; CHECK-UNROLL-NEXT: call void @llvm.assume(i1 [[LCMP_MOD1]])
-; CHECK-UNROLL-NEXT: br label %[[FOR_BODY_EPIL:.*]]
-; CHECK-UNROLL: [[FOR_BODY_EPIL]]:
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09_EPIL_INIT]]
-; CHECK-UNROLL-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09_EPIL_INIT]]
-; CHECK-UNROLL-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[TMP11]], [[TMP10]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09_EPIL_INIT]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4
-; CHECK-UNROLL-NEXT: [[INC_EPIL:%.*]] = add nuw i32 [[I_09_EPIL_INIT]], 1
-; CHECK-UNROLL-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
-; CHECK-UNROLL-NEXT: br i1 [[EPIL_ITER_CMP]], label %[[FOR_BODY_EPIL_1:.*]], label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA:.*]]
-; CHECK-UNROLL: [[FOR_BODY_EPIL_1]]:
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_EPIL]]
-; CHECK-UNROLL-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_1]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_EPIL]]
-; CHECK-UNROLL-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL_1]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_EPIL_1:%.*]] = mul nsw i32 [[TMP13]], [[TMP12]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_EPIL]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL_1]], ptr [[ARRAYIDX2_EPIL_1]], align 4
-; CHECK-UNROLL-NEXT: [[INC_EPIL_1:%.*]] = add nuw i32 [[I_09_EPIL_INIT]], 2
-; CHECK-UNROLL-NEXT: [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
-; CHECK-UNROLL-NEXT: br i1 [[EPIL_ITER_CMP_1]], label %[[FOR_BODY_EPIL_2:.*]], label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]
-; CHECK-UNROLL: [[FOR_BODY_EPIL_2]]:
-; CHECK-UNROLL-NEXT: [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC_EPIL_1]]
-; CHECK-UNROLL-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_2]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC_EPIL_1]]
-; CHECK-UNROLL-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL_2]], align 4
-; CHECK-UNROLL-NEXT: [[MUL_EPIL_2:%.*]] = mul nsw i32 [[TMP15]], [[TMP14]]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC_EPIL_1]]
-; CHECK-UNROLL-NEXT: store i32 [[MUL_EPIL_2]], ptr [[ARRAYIDX2_EPIL_2]], align 4
-; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]]:
-; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP_LOOPEXIT]]:
-; CHECK-UNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP]]:
-; CHECK-UNROLL-NEXT: ret void
-;
entry:
%cmp8 = icmp eq i32 %N, 0
br i1 %cmp8, label %for.cond.cleanup, label %for.body
+; CHECK-LABEL: for.body
for.body:
+; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z.0-9]+]] ], [ [[IV2:%[a-z.0-9]+]], %for.body ]
+; CHECK-NOUNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-NOUNROLL: [[IV2]] = add nuw i32 [[IV0]], 2
+; CHECK-NOUNROLL: br
+
+; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z.0-9]+]] ], [ [[IV4:%[a-z.0-9]+]], %for.body ]
+; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
+; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
+; CHECK-UNROLL: [[IV4]] = add nuw i32 [[IV0]], 4
+; CHECK-UNROLL: br
+
+; CHECK-UNROLL: for.body.epil:
+; CHECK-UNROLL: for.body.epil.1:
+; CHECK-UNROLL: for.body.epil.2:
+
%i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.09
%0 = load i32, ptr %arrayidx, align 4
@@ -371,44 +95,8 @@ for.cond.cleanup:
ret void
}
+; CHECK-LABEL: nested_runtime
define arm_aapcs_vfpcc void @nested_runtime(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B, i32 %N) local_unnamed_addr #0 {
-; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @nested_runtime(
-; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
-; CHECK-NOUNROLL-NEXT: [[CMP25:%.*]] = icmp eq i32 [[N]], 0
-; CHECK-NOUNROLL-NEXT: br i1 [[CMP25]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY4_LR_PH_PREHEADER:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY4_LR_PH_PREHEADER]]:
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY4_LR_PH:.*]]
-; CHECK-NOUNROLL: [[FOR_BODY4_LR_PH]]:
-; CHECK-NOUNROLL-NEXT: [[H_026:%.*]] = phi i32 [ [[INC11:%.*]], %[[FOR_COND_CLEANUP3:.*]] ], [ 0, %[[FOR_BODY4_LR_PH_PREHEADER]] ]
-; CHECK-NOUNROLL-NEXT: [[MUL:%.*]] = mul i32 [[H_026]], [[N]]
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY4:.*]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP_LOOPEXIT:.*]]:
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_COND_CLEANUP]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP]]:
-; CHECK-NOUNROLL-NEXT: ret void
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP3]]:
-; CHECK-NOUNROLL-NEXT: [[INC11]] = add nuw i32 [[H_026]], 1
-; CHECK-NOUNROLL-NEXT: [[EXITCOND27:%.*]] = icmp eq i32 [[INC11]], [[N]]
-; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND27]], label %[[FOR_COND_CLEANUP_LOOPEXIT]], label %[[FOR_BODY4_LR_PH]]
-; CHECK-NOUNROLL: [[FOR_BODY4]]:
-; CHECK-NOUNROLL-NEXT: [[W_024:%.*]] = phi i32 [ 0, %[[FOR_BODY4_LR_PH]] ], [ [[INC:%.*]], %[[FOR_BODY4]] ]
-; CHECK-NOUNROLL-NEXT: [[ADD:%.*]] = add i32 [[W_024]], [[MUL]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[A]], i32 [[ADD]]
-; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
-; CHECK-NOUNROLL-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[W_024]]
-; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX5]], align 2
-; CHECK-NOUNROLL-NEXT: [[CONV6:%.*]] = sext i16 [[TMP1]] to i32
-; CHECK-NOUNROLL-NEXT: [[MUL7:%.*]] = mul nsw i32 [[CONV6]], [[CONV]]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[W_024]]
-; CHECK-NOUNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX8]], align 4
-; CHECK-NOUNROLL-NEXT: [[ADD9:%.*]] = add nsw i32 [[MUL7]], [[TMP2]]
-; CHECK-NOUNROLL-NEXT: store i32 [[ADD9]], ptr [[ARRAYIDX8]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC]] = add nuw i32 [[W_024]], 1
-; CHECK-NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]]
-; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]]
-;
entry:
%cmp25 = icmp eq i32 %N, 0
br i1 %cmp25, label %for.cond.cleanup, label %for.body4.lr.ph
@@ -426,7 +114,22 @@ for.cond.cleanup3:
%exitcond27 = icmp eq i32 %inc11, %N
br i1 %exitcond27, label %for.cond.cleanup, label %for.body4.lr.ph
+; CHECK-LABEL: for.body4
for.body4:
+; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z0-9.]+]] ], [ [[IV1:%[a-z.0-9]+]], %for.body4 ]
+; CHECK-NOUNROLL: [[IV1]] = add nuw i32 [[IV0]], 1
+; CHECK-NOUNROLL: br
+
+; CHECK-UNROLL: for.body4.epil:
+; CHECK-UNROLL: for.body4.epil.1:
+; CHECK-UNROLL: for.body4.epil.2:
+; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, [[PRE:%[a-z0-9.]+]] ], [ [[IV4:%[a-z.0-9]+]], %for.body4 ]
+; CHECK-UNROLL: [[IV1:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-UNROLL: [[IV2:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 2
+; CHECK-UNROLL: [[IV3:%[a-z.0-9]+]] = add nuw nsw i32 [[IV0]], 3
+; CHECK-UNROLL: [[IV4]] = add nuw i32 [[IV0]], 4
+; CHECK-UNROLL: br
+
%w.024 = phi i32 [ 0, %for.body4.lr.ph ], [ %inc, %for.body4 ]
%add = add i32 %w.024, %mul
%arrayidx = getelementptr inbounds i16, ptr %A, i32 %add
@@ -445,52 +148,26 @@ for.body4:
br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
}
+; CHECK-LABEL: loop_call
define arm_aapcs_vfpcc void @loop_call(ptr nocapture %C, ptr nocapture readonly %A, ptr nocapture readonly %B) local_unnamed_addr #1 {
-; CHECK-NOUNROLL-LABEL: define arm_aapcs_vfpcc void @loop_call(
-; CHECK-NOUNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NOUNROLL-NEXT: [[ENTRY:.*]]:
-; CHECK-NOUNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-NOUNROLL: [[FOR_COND_CLEANUP:.*]]:
-; CHECK-NOUNROLL-NEXT: ret void
-; CHECK-NOUNROLL: [[FOR_BODY]]:
-; CHECK-NOUNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-NOUNROLL-NEXT: [[CALL:%.*]] = tail call arm_aapcs_vfpcc i32 @some_func(i32 [[TMP0]], i32 [[TMP1]])
-; CHECK-NOUNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
-; CHECK-NOUNROLL-NEXT: store i32 [[CALL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-NOUNROLL-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1
-; CHECK-NOUNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1024
-; CHECK-NOUNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
-;
-; CHECK-UNROLL-LABEL: define arm_aapcs_vfpcc void @loop_call(
-; CHECK-UNROLL-SAME: ptr captures(none) [[C:%.*]], ptr readonly captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-UNROLL-NEXT: [[ENTRY:.*]]:
-; CHECK-UNROLL-NEXT: br label %[[FOR_BODY:.*]]
-; CHECK-UNROLL: [[FOR_COND_CLEANUP:.*]]:
-; CHECK-UNROLL-NEXT: ret void
-; CHECK-UNROLL: [[FOR_BODY]]:
-; CHECK-UNROLL-NEXT: [[I_08:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
-; CHECK-UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-UNROLL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
-; CHECK-UNROLL-NEXT: [[CALL:%.*]] = tail call arm_aapcs_vfpcc i32 @some_func(i32 [[TMP0]], i32 [[TMP1]])
-; CHECK-UNROLL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_08]]
-; CHECK-UNROLL-NEXT: store i32 [[CALL]], ptr [[ARRAYIDX2]], align 4
-; CHECK-UNROLL-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1
-; CHECK-UNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1024
-; CHECK-UNROLL-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
-;
entry:
br label %for.body
for.cond.cleanup:
ret void
+; CHECK-LABEL: for.body
for.body:
+; CHECK-NOUNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV1:%[a-z.0-9]+]], %for.body ]
+; CHECK-NOUNROLL: [[IV1]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-NOUNROLL: icmp eq i32 [[IV1]], 1024
+; CHECK-NOUNROLL: br
+
+; CHECK-UNROLL: [[IV0:%[a-z.0-9]+]] = phi i32 [ 0, %entry ], [ [[IV1:%[a-z.0-9]+]], %for.body ]
+; CHECK-UNROLL: [[IV1]] = add nuw nsw i32 [[IV0]], 1
+; CHECK-UNROLL: icmp eq i32 [[IV1]], 1024
+; CHECK-UNROLL: br
+
%i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.08
%0 = load i32, ptr %arrayidx, align 4
@@ -504,75 +181,27 @@ for.body:
br i1 %exitcond, label %for.cond.cleanup, label %for.body
}
+; CHECK-LABEL: iterate_inc
+; CHECK-NOUNROLL: %n.addr.04 = phi ptr [ %1, %while.body ], [ %n, %while.body.preheader ]
+; CHECK-NOUNROLL: %tobool = icmp eq ptr %1, null
+; CHECK-NOUNROLL: br i1 %tobool
+; CHECK-NOUNROLL-NOT: load
+
+; CHECK-UNROLL: [[CMP0:%[a-z.0-9]+]] = icmp eq ptr [[VAR0:%[a-z.0-9]+]], null
+; CHECK-UNROLL: br i1 [[CMP0]], label [[END:%[a-z.0-9]+]]
+; CHECK-UNROLL: [[CMP1:%[a-z.0-9]+]] = icmp eq ptr [[VAR1:%[a-z.0-9]+]], null
+; CHECK-UNROLL: br i1 [[CMP1]], label [[END]]
+; CHECK-UNROLL: [[CMP2:%[a-z.0-9]+]] = icmp eq ptr [[VAR2:%[a-z.0-9]+]], null
+; CHECK-UNROLL: br i1 [[CMP2]], label [[END]]
+; CHECK-UNROLL: [[CMP3:%[a-z.0-9]+]] = icmp eq ptr [[VAR3:%[a-z.0-9]+]], null
+; CHECK-UNROLL: br i1 [[CMP3]], label [[END]]
+; CHECK-UNROLL: [[CMP4:%[a-z.0-9]+]] = icmp eq ptr [[VAR4:%[a-z.0-9]+]], null
+; CHECK-UNROLL: br i1 [[CMP4]], label [[END]]
+; CHECK-UNROLL-NOT: load
+
%struct.Node = type { ptr, i32 }
define arm_aapcscc void @iterate_inc(ptr %n) local_unnamed_addr #0 {
-; CHECK-NOUNROLL-LABEL: define arm_aapcscc void @iterate_inc(
-; CHECK-NOUNROLL-SAME: ptr [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NOUNROLL-NEXT: [[ENTRY:.*:]]
-; CHECK-NOUNROLL-NEXT: [[TOBOOL3:%.*]] = icmp eq ptr [[N]], null
-; CHECK-NOUNROLL-NEXT: br i1 [[TOBOOL3]], label %[[WHILE_END:.*]], label %[[WHILE_BODY_PREHEADER:.*]]
-; CHECK-NOUNROLL: [[WHILE_BODY_PREHEADER]]:
-; CHECK-NOUNROLL-NEXT: br label %[[WHILE_BODY:.*]]
-; CHECK-NOUNROLL: [[WHILE_BODY]]:
-; CHECK-NOUNROLL-NEXT: [[N_ADDR_04:%.*]] = phi ptr [ [[TMP1:%.*]], %[[WHILE_BODY]] ], [ [[N]], %[[WHILE_BODY_PREHEADER]] ]
-; CHECK-NOUNROLL-NEXT: [[VAL:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[N_ADDR_04]], i32 0, i32 1
-; CHECK-NOUNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4
-; CHECK-NOUNROLL-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 1
-; CHECK-NOUNROLL-NEXT: store i32 [[ADD]], ptr [[VAL]], align 4
-; CHECK-NOUNROLL-NEXT: [[TMP1]] = load ptr, ptr [[N_ADDR_04]], align 4
-; CHECK-NOUNROLL-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[TMP1]], null
-; CHECK-NOUNROLL-NEXT: br i1 [[TOBOOL]], label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY]]
-; CHECK-NOUNROLL: [[WHILE_END_LOOPEXIT]]:
-; CHECK-NOUNROLL-NEXT: br label %[[WHILE_END]]
-; CHECK-NOUNROLL: [[WHILE_END]]:
-; CHECK-NOUNROLL-NEXT: ret void
-;
-; CHECK-UNROLL-LABEL: define arm_aapcscc void @iterate_inc(
-; CHECK-UNROLL-SAME: ptr [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-UNROLL-NEXT: [[ENTRY:.*:]]
-; CHECK-UNROLL-NEXT: [[TOBOOL3:%.*]] = icmp eq ptr [[N]], null
-; CHECK-UNROLL-NEXT: br i1 [[TOBOOL3]], label %[[WHILE_END:.*]], label %[[WHILE_BODY_PREHEADER:.*]]
-; CHECK-UNROLL: [[WHILE_BODY_PREHEADER]]:
-; CHECK-UNROLL-NEXT: br label %[[WHILE_BODY:.*]]
-; CHECK-UNROLL: [[WHILE_BODY]]:
-; CHECK-UNROLL-NEXT: [[N_ADDR_04:%.*]] = phi ptr [ [[N]], %[[WHILE_BODY_PREHEADER]] ], [ [[TMP7:%.*]], %[[WHILE_BODY_3:.*]] ]
-; CHECK-UNROLL-NEXT: [[VAL:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[N_ADDR_04]], i32 0, i32 1
-; CHECK-UNROLL-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4
-; CHECK-UNROLL-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 1
-; CHECK-UNROLL-NEXT: store i32 [[ADD]], ptr [[VAL]], align 4
-; CHECK-UNROLL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[N_ADDR_04]], align 4
-; CHECK-UNROLL-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[TMP1]], null
-; CHECK-UNROLL-NEXT: br i1 [[TOBOOL]], label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY_1:.*]]
-; CHECK-UNROLL: [[WHILE_BODY_1]]:
-; CHECK-UNROLL-NEXT: [[VAL_1:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP1]], i32 0, i32 1
-; CHECK-UNROLL-NEXT: [[TMP2:%.*]] = load i32, ptr [[VAL_1]], align 4
-; CHECK-UNROLL-NEXT: [[ADD_1:%.*]] = add nsw i32 [[TMP2]], 1
-; CHECK-UNROLL-NEXT: store i32 [[ADD_1]], ptr [[VAL_1]], align 4
-; CHECK-UNROLL-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP1]], align 4
-; CHECK-UNROLL-NEXT: [[TOBOOL_1:%.*]] = icmp eq ptr [[TMP3]], null
-; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_1]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY_2:.*]]
-; CHECK-UNROLL: [[WHILE_BODY_2]]:
-; CHECK-UNROLL-NEXT: [[VAL_2:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP3]], i32 0, i32 1
-; CHECK-UNROLL-NEXT: [[TMP4:%.*]] = load i32, ptr [[VAL_2]], align 4
-; CHECK-UNROLL-NEXT: [[ADD_2:%.*]] = add nsw i32 [[TMP4]], 1
-; CHECK-UNROLL-NEXT: store i32 [[ADD_2]], ptr [[VAL_2]], align 4
-; CHECK-UNROLL-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP3]], align 4
-; CHECK-UNROLL-NEXT: [[TOBOOL_2:%.*]] = icmp eq ptr [[TMP5]], null
-; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_2]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY_3]]
-; CHECK-UNROLL: [[WHILE_BODY_3]]:
-; CHECK-UNROLL-NEXT: [[VAL_3:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP5]], i32 0, i32 1
-; CHECK-UNROLL-NEXT: [[TMP6:%.*]] = load i32, ptr [[VAL_3]], align 4
-; CHECK-UNROLL-NEXT: [[ADD_3:%.*]] = add nsw i32 [[TMP6]], 1
-; CHECK-UNROLL-NEXT: store i32 [[ADD_3]], ptr [[VAL_3]], align 4
-; CHECK-UNROLL-NEXT: [[TMP7]] = load ptr, ptr [[TMP5]], align 4
-; CHECK-UNROLL-NEXT: [[TOBOOL_3:%.*]] = icmp eq ptr [[TMP7]], null
-; CHECK-UNROLL-NEXT: br i1 [[TOBOOL_3]], label %[[WHILE_END_LOOPEXIT]], label %[[WHILE_BODY]]
-; CHECK-UNROLL: [[WHILE_END_LOOPEXIT]]:
-; CHECK-UNROLL-NEXT: br label %[[WHILE_END]]
-; CHECK-UNROLL: [[WHILE_END]]:
-; CHECK-UNROLL-NEXT: ret void
-;
entry:
%tobool3 = icmp eq ptr %n, null
br i1 %tobool3, label %while.end, label %while.body.preheader
diff --git a/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll b/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
index e624bd14809b0..066a8b65bfce8 100644
--- a/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
+++ b/llvm/test/Transforms/LoopUnroll/ARM/multi-blocks.ll
@@ -131,8 +131,8 @@ define void @test_three_blocks(ptr nocapture %Output, ptr nocapture readonly %Co
; CHECK-NEXT: br label [[FOR_INC_3]]
; CHECK: for.inc.3:
; CHECK-NEXT: [[TEMP_1_3]] = phi i32 [ [[ADD_3]], [[IF_THEN_3]] ], [ [[TEMP_1_2]], [[FOR_INC_2]] ]
-; CHECK-NEXT: [[INC_3]] = add nuw nsw i32 [[J_010]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
+; CHECK-NEXT: [[INC_3]] = add nuw i32 [[J_010]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
; CHECK-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
; CHECK-NEXT: br i1 [[NITER_NCMP_3]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]]
;
diff --git a/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll b/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
index 91ccde58e33db..d842c4adcb74d 100644
--- a/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll
@@ -148,23 +148,23 @@ define hidden void @runtime(ptr nocapture %a, ptr nocapture readonly %b, ptr noc
; CHECK: for.body:
; CHECK-NEXT: [[I_09:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1]], [[FOR_BODY]] ]
; CHECK-NEXT: [[NITER:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[B]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i8], ptr [[B]], i32 [[I_09]]
; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[C]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [4 x i8], ptr [[C]], i32 [[I_09]]
; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]]
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[A]], i32 [[I_09]]
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [4 x i8], ptr [[A]], i32 [[I_09]]
; CHECK-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
; CHECK-NEXT: [[INC:%.*]] = or disjoint i32 [[I_09]], 1
-; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[B]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[B]], i32 [[INC]]
; CHECK-NEXT: [[I_1:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
-; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[C]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX1_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[C]], i32 [[INC]]
; CHECK-NEXT: [[I1_1:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
; CHECK-NEXT: [[MUL_1:%.*]] = mul nsw i32 [[I1_1]], [[I_1]]
-; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[A]], i32 [[INC]]
+; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds [4 x i8], ptr [[A]], i32 [[INC]]
; CHECK-NEXT: store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
-; CHECK-NEXT: [[INC_1]] = add nuw nsw i32 [[I_09]], 2
-; CHECK-NEXT: [[NITER_NEXT_1]] = add nuw nsw i32 [[NITER]], 2
+; CHECK-NEXT: [[INC_1]] = add nuw i32 [[I_09]], 2
+; CHECK-NEXT: [[NITER_NEXT_1]] = add nuw i32 [[NITER]], 2
; CHECK-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]
; CHECK-NEXT: br i1 [[NITER_NCMP_1]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]]
;
diff --git a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
index 90f4403244630..c763f14b73cb8 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll
@@ -182,7 +182,7 @@ define void @peel_with_guard2(i32 %n) {
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]]
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]
@@ -254,7 +254,7 @@ define void @test_peel_guard_sub_1_btc(i32 %n) {
; CHECK-NEXT: [[CALL136:%.*]] = load volatile ptr, ptr null, align 4294967296
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]]
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP4:![0-9]+]]
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
index 32267cb104d3b..839bdbd541e4b 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll
@@ -10,35 +10,35 @@ target triple = "x86_64-unknown-linux-gnu"
define internal fastcc void @test01(ptr %p0, ptr %p1, ptr %p2) unnamed_addr align 2 {
; CHECK-LABEL: @test01(
; CHECK-NEXT: for.body47.lr.ph:
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0)
; CHECK-NEXT: br label [[FOR_BODY47_PEEL_BEGIN:%.*]]
; CHECK: for.body47.peel.begin:
; CHECK-NEXT: br label [[FOR_BODY47_PEEL:%.*]]
; CHECK: for.body47.peel:
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
-; CHECK-NEXT: store i8 42, ptr [[P0:%.*]], align 1, !alias.scope [[META3]]
-; CHECK-NEXT: store i8 43, ptr [[P1:%.*]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 44, ptr [[P2:%.*]], align 1, !alias.scope [[META5:![0-9]+]]
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias [[META3]]
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias [[META5]]
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-NEXT: store i8 42, ptr [[P0:%.*]], align 1, !alias.scope !3
+; CHECK-NEXT: store i8 43, ptr [[P1:%.*]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 44, ptr [[P2:%.*]], align 1, !alias.scope !5
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !3
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !5
; CHECK-NEXT: [[CMP52_PEEL:%.*]] = icmp eq i32 0, 0
; CHECK-NEXT: br i1 [[CMP52_PEEL]], label [[COND_TRUE_PEEL:%.*]], label [[COND_END_PEEL:%.*]]
; CHECK: cond.true.peel:
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope [[META3]]
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope [[META5]]
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias [[META3]]
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias [[META5]]
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !3
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !5
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !3
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !5
; CHECK-NEXT: br label [[COND_END_PEEL]]
; CHECK: cond.end.peel:
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope [[META3]]
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope [[META5]]
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias [[META3]]
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias [[META5]]
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !3
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !5
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !3
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !5
; CHECK-NEXT: [[INC_PEEL:%.*]] = add nuw i32 0, 1
; CHECK-NEXT: [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], undef
; CHECK-NEXT: br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP46:%.*]], label [[FOR_BODY47_PEEL_NEXT:%.*]]
@@ -54,31 +54,31 @@ define internal fastcc void @test01(ptr %p0, ptr %p1, ptr %p2) unnamed_addr alig
; CHECK-NEXT: ret void
; CHECK: for.body47:
; CHECK-NEXT: [[J_02:%.*]] = phi i32 [ [[INC_PEEL]], [[FOR_BODY47_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[COND_END:%.*]] ]
-; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]])
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !alias.scope [[META6]]
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !alias.scope [[META8:![0-9]+]]
-; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias [[META6]]
-; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias [[META8]]
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !6)
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !alias.scope !6
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !alias.scope !8
+; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !6
+; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !8
; CHECK-NEXT: br i1 false, label [[COND_TRUE:%.*]], label [[COND_END]]
; CHECK: cond.true:
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope [[META6]]
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope [[META8]]
-; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias [[META6]]
-; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias [[META8]]
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !6
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !8
+; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !6
+; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !8
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope [[META6]]
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope [[META0]]
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope [[META8]]
-; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias [[META6]]
-; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias [[META0]]
-; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias [[META8]]
-; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[J_02]], 1
-; CHECK-NEXT: br i1 undef, label [[FOR_COND_CLEANUP46_LOOPEXIT:%.*]], label [[FOR_BODY47]], !llvm.loop [[LOOP9:![0-9]+]]
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !6
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !8
+; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !6
+; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0
+; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !8
+; CHECK-NEXT: [[INC]] = add nuw i32 [[J_02]], 1
+; CHECK-NEXT: br i1 undef, label [[FOR_COND_CLEANUP46_LOOPEXIT:%.*]], label [[FOR_BODY47]], [[LOOP9:!llvm.loop !.*]]
;
for.body47.lr.ph:
call void @llvm.experimental.noalias.scope.decl(metadata !5)
diff --git a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
index 8ec4fa2fdd21a..047360178aa06 100644
--- a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
+++ b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
@@ -95,7 +95,7 @@ define void @pr56282() {
; CHECK: inner.2.preheader:
; CHECK-NEXT: br label [[INNER_2]]
; CHECK: inner.2:
-; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nuw nsw i64 [[OUTER_IV]], 1
+; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nuw i64 [[OUTER_IV]], 1
; CHECK-NEXT: br label [[OUTER_HEADER]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -188,7 +188,7 @@ define void @pr56286(i64 %x, ptr %src, ptr %dst, ptr %ptr.src) !prof !0 {
; CHECK-NEXT: [[L_1_LCSSA_UNR:%.*]] = phi i32 [ poison, [[OUTER_HEADER]] ], [ [[L_1_LCSSA_UNR_PH]], [[INNER_1_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
; CHECK-NEXT: [[INNER_1_IV_UNR:%.*]] = phi i64 [ [[X]], [[OUTER_HEADER]] ], [ [[INNER_1_IV_UNR_PH]], [[INNER_1_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 7
-; CHECK-NEXT: br i1 [[TMP4]], label [[OUTER_MIDDLE:%.*]], label [[OUTER_HEADER_NEW:%.*]], !prof [[PROF3]]
+; CHECK-NEXT: br i1 [[TMP4]], label [[OUTER_MIDDLE:%.*]], label [[OUTER_HEADER_NEW:%.*]], !prof [[PROF6:![0-9]+]]
; CHECK: outer.header.new:
; CHECK-NEXT: br label [[INNER_1_HEADER:%.*]]
; CHECK: inner.1.header:
@@ -232,7 +232,7 @@ define void @pr56286(i64 %x, ptr %src, ptr %dst, ptr %ptr.src) !prof !0 {
; CHECK-NEXT: store i32 [[L_1_7]], ptr [[DST]], align 8
; CHECK-NEXT: [[INNER_1_IV_NEXT_7]] = add i64 [[INNER_1_IV]], 8
; CHECK-NEXT: [[CMP_2_7:%.*]] = icmp sgt i64 [[INNER_1_IV_NEXT_6]], 0
-; CHECK-NEXT: br i1 [[CMP_2_7]], label [[OUTER_MIDDLE_UNR_LCSSA:%.*]], label [[INNER_1_HEADER]], !prof [[PROF6:![0-9]+]], !llvm.loop [[LOOP7:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP_2_7]], label [[OUTER_MIDDLE_UNR_LCSSA:%.*]], label [[INNER_1_HEADER]], !prof [[PROF7:![0-9]+]], !llvm.loop [[LOOP8:![0-9]+]]
; CHECK: outer.middle.unr-lcssa:
; CHECK-NEXT: [[L_1_LCSSA_PH:%.*]] = phi i32 [ [[L_1_7]], [[INNER_1_LATCH_7]] ]
; CHECK-NEXT: br label [[OUTER_MIDDLE]]
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
index dcf6e396cf0e4..351065080119d 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_visit_order.ll
@@ -24,12 +24,13 @@ define void @test1() {
; CHECK-NEXT: [[I4017_3:%.*]] = zext i16 [[I42_2]] to i64
; CHECK-NEXT: [[I13_I_3:%.*]] = add nuw nsw i64 [[I4017_3]], 1
; CHECK-NEXT: [[I42_3]] = trunc i64 [[I13_I_3]] to i16
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i16 [[NITER]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i16 [[NITER]], 4
; CHECK-NEXT: br label [[BB10_PREHEADER:%.*]]
; CHECK: bb10.preheader:
; CHECK-NEXT: br i1 true, label [[BB38]], label [[BB10_PREHEADER]]
; CHECK: bb38:
-; CHECK-NEXT: br i1 false, label [[BB1_BB43_CRIT_EDGE_UNR_LCSSA:%.*]], label [[BB5_PREHEADER]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-NEXT: [[NITER_NCMP_3:%.*]] = icmp eq i16 [[NITER_NEXT_3]], -28
+; CHECK-NEXT: br i1 [[NITER_NCMP_3]], label [[BB1_BB43_CRIT_EDGE_UNR_LCSSA:%.*]], label [[BB5_PREHEADER]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: bb1.bb43_crit_edge.unr-lcssa:
; CHECK-NEXT: [[I10_UNR:%.*]] = phi i16 [ [[I42_3]], [[BB38]] ]
; CHECK-NEXT: br i1 true, label [[BB5_PREHEADER_EPIL_PREHEADER]], label [[BB1_BB43_CRIT_EDGE:%.*]]
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
index 1d740ef0a1cc0..27b4143303692 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll
@@ -27,8 +27,8 @@ define void @test1(i32 %N, i32 %M, ptr noalias nocapture %A, ptr noalias nocaptu
; CHECK-NEXT: [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
; CHECK-NEXT: [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
; CHECK-NEXT: [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
-; CHECK-NEXT: [[ADD8_3]] = add nuw nsw i32 [[I]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
+; CHECK-NEXT: [[ADD8_3]] = add nuw i32 [[I]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
; CHECK-NEXT: br label %[[FOR_INNER:.*]]
; CHECK: [[FOR_INNER]]:
; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_OUTER]] ], [ [[INC:%.*]], %[[FOR_INNER]] ]
@@ -1127,8 +1127,8 @@ define void @test9(i32 %N, i32 %M, ptr nocapture %A, ptr nocapture readonly %B)
; CHECK-NEXT: [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
; CHECK-NEXT: [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
; CHECK-NEXT: [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
-; CHECK-NEXT: [[ADD8_3]] = add nuw nsw i32 [[I]], 4
-; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
+; CHECK-NEXT: [[ADD8_3]] = add nuw i32 [[I]], 4
+; CHECK-NEXT: [[NITER_NEXT_3]] = add nuw i32 [[NITER]], 4
; CHECK-NEXT: br label %[[FOR_INNER:.*]]
; CHECK: [[FOR_INNER]]:
; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_OUTER]] ], [ [[INC:%.*]], %[[FOR_INNER]] ]
diff --git a/llvm/test/Transforms/LoopVectorize/alias-mask.ll b/llvm/test/Transforms/LoopVectorize/alias-mask.ll
index e5acedf8b01b7..47e2cd8f9f3ec 100644
--- a/llvm/test/Transforms/LoopVectorize/alias-mask.ll
+++ b/llvm/test/Transforms/LoopVectorize/alias-mask.ll
@@ -574,11 +574,14 @@ define i64 @any_of_reduction(i64 %a, ptr %src, ptr %dst, i32 %n) {
; CHECK-SAME: i64 [[A:%.*]], ptr [[SRC:%.*]], ptr [[DST:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[DST1:%.*]] = ptrtoaddr ptr [[DST]] to i64
-; CHECK-NEXT: [[TMP0:%.*]] = add nuw i64 [[DST1]], 4
+; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[DST1]], 4
; CHECK-NEXT: [[SRC2:%.*]] = ptrtoaddr ptr [[SRC]] to i64
-; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[SRC2]], 4
+; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[SRC2]], 4
; CHECK-NEXT: br label %[[VECTOR_SCEVCHECK:.*]]
; CHECK: [[VECTOR_SCEVCHECK]]:
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[N]], 1
+; CHECK-NEXT: br i1 [[TMP2]], label %[[SCALAR_PH:.*]], label %[[VECTOR_CLAMPED_VF_CHECK:.*]]
+; CHECK: [[VECTOR_CLAMPED_VF_CHECK]]:
; CHECK-NEXT: [[ALIAS_MASK:%.*]] = call <4 x i1> @llvm.loop.dependence.war.mask.v4i1.i64(i64 [[TMP1]], i64 [[TMP0]], i64 4)
; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i1> [[ALIAS_MASK]] to <4 x i64>
; CHECK-NEXT: [[NUM_ACTIVE_LANES:%.*]] = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> [[TMP4]])
@@ -587,7 +590,7 @@ define i64 @any_of_reduction(i64 %a, ptr %src, ptr %dst, i32 %n) {
; CHECK-NEXT: [[TMP7:%.*]] = sub i32 -1, [[N]]
; CHECK-NEXT: [[VF_STEP_OVERFLOW:%.*]] = icmp ult i32 [[TMP7]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[VF_IS_SCALAR]], [[VF_STEP_OVERFLOW]]
-; CHECK-NEXT: br i1 [[TMP8]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
+; CHECK-NEXT: br i1 [[TMP8]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[N]], 1
; CHECK-NEXT: [[TMP9:%.*]] = sub i32 [[TMP6]], 1
diff --git a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
index e44434d01adf3..db6aa937120c3 100644
--- a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
+++ b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-dead-instructions.ll
@@ -15,10 +15,33 @@ define i8 @recurrence_phi_with_same_incoming_values_after_simplifications(i8 %fo
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 1, [[INDEX]]
+; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[OFFSET_IDX]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[OFFSET_IDX]], 2
+; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[OFFSET_IDX]], 3
+; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[OFFSET_IDX]], 4
+; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[OFFSET_IDX]], 5
+; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[OFFSET_IDX]], 6
+; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[OFFSET_IDX]], 7
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[OFFSET_IDX]]
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP9]], i64 4
-; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[TMP9]], align 1
-; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[TMP3]], align 1
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP2]]
+; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP3]]
+; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP4]]
+; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP5]]
+; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP6]]
+; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP7]]
+; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i8, ptr [[DST]], i32 [[TMP8]]
+; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i8> [[TMP0]], i64 0
+; CHECK-NEXT: store i8 [[TMP17]], ptr [[TMP9]], align 1
+; CHECK-NEXT: [[TMP18:%.*]] = extractelement <4 x i8> [[TMP0]], i64 1
+; CHECK-NEXT: store i8 [[TMP18]], ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i8> [[TMP0]], i64 2
+; CHECK-NEXT: store i8 [[TMP19]], ptr [[TMP11]], align 1
+; CHECK-NEXT: [[TMP20:%.*]] = extractelement <4 x i8> [[TMP0]], i64 3
+; CHECK-NEXT: store i8 [[TMP20]], ptr [[TMP12]], align 1
+; CHECK-NEXT: store i8 [[TMP17]], ptr [[TMP13]], align 1
+; CHECK-NEXT: store i8 [[TMP18]], ptr [[TMP14]], align 1
+; CHECK-NEXT: store i8 [[TMP19]], ptr [[TMP15]], align 1
+; CHECK-NEXT: store i8 [[TMP20]], ptr [[TMP16]], align 1
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 8
; CHECK-NEXT: [[TMP21:%.*]] = icmp eq i32 [[INDEX_NEXT]], -8
; CHECK-NEXT: br i1 [[TMP21]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
index 4122496e99482..0ecc93c8d1cf5 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/peel-multiple-unreachable-exits-for-vectorization.ll
@@ -95,7 +95,7 @@ define i64 @sum_2_at_with_int_conversion(ptr %A, ptr %B, i64 %N) {
; CHECK-NEXT: [[LV_I9:%.*]] = load i64, ptr [[GEP_IDX_I8]], align 8
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[LV_I]], [[SUM]]
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[ADD]], [[LV_I9]]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[SMAX]]
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: error.i:
@@ -241,7 +241,7 @@ define i64 @sum_3_at_with_int_conversion(ptr %A, ptr %B, ptr %C, i64 %N) {
; CHECK-NEXT: [[ADD_1:%.*]] = add i64 [[LV_I]], [[SUM]]
; CHECK-NEXT: [[ADD_2:%.*]] = add i64 [[ADD_1]], [[LV_I9]]
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[ADD_2]], [[LV_I20]]
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[SMAX]]
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
; CHECK: error.i:
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index 95e0215c81fcc..7bba70a97b1bb 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -354,7 +354,7 @@ define void @monkey(ptr noundef %arr, i32 noundef %len) {
; CHECK: [[FOR_COND_CLEANUP]]:
; CHECK-NEXT: ret void
; CHECK: [[FOR_COND_CLEANUP3]]:
-; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_09]], 1
+; CHECK-NEXT: [[INC]] = add nuw i32 [[I_09]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC]], [[LEN]]
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY4_PREHEADER]], label %[[FOR_COND_CLEANUP]]
; CHECK: [[FOR_BODY4]]:
diff --git a/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll b/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
index c5e1973f41bd6..1df51312f7015 100644
--- a/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
+++ b/llvm/test/Transforms/SLPVectorizer/AMDGPU/inst-count-heuristic.ll
@@ -12,21 +12,26 @@ define amdgpu_kernel void @phi5_rotate(
; GFX950-LABEL: define amdgpu_kernel void @phi5_rotate(
; GFX950-SAME: ptr addrspace(1) captures(none) [[OUT:%.*]], i32 [[N:%.*]], i32 [[S0:%.*]], i32 [[S1:%.*]], i32 [[S2:%.*]], i32 [[S3:%.*]], i32 [[S4:%.*]]) {
; GFX950-NEXT: [[ENTRY:.*]]:
+; GFX950-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[S0]], i64 0
+; GFX950-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[S1]], i64 1
+; GFX950-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> poison, i32 [[S4]], i64 0
+; GFX950-NEXT: [[TMP3:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[S0]], i64 1
+; GFX950-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[S3]], i64 0
+; GFX950-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[S4]], i64 1
+; GFX950-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[S2]], i64 0
+; GFX950-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[S3]], i64 1
; GFX950-NEXT: br label %[[LOOP:.*]]
; GFX950: [[LOOP]]:
; GFX950-NEXT: [[I1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[X0:%.*]] = phi i32 [ [[S0]], %[[ENTRY]] ], [ [[X4:%.*]], %[[LOOP]] ]
-; GFX950-NEXT: [[X1:%.*]] = phi i32 [ [[S1]], %[[ENTRY]] ], [ [[X0]], %[[LOOP]] ]
-; GFX950-NEXT: [[X2:%.*]] = phi i32 [ [[S2]], %[[ENTRY]] ], [ [[X1]], %[[LOOP]] ]
-; GFX950-NEXT: [[X3:%.*]] = phi i32 [ [[S3]], %[[ENTRY]] ], [ [[X2]], %[[LOOP]] ]
-; GFX950-NEXT: [[X4]] = phi i32 [ [[S4]], %[[ENTRY]] ], [ [[X3]], %[[LOOP]] ]
+; GFX950-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ [[TMP1]], %[[ENTRY]] ], [ [[TMP9:%.*]], %[[LOOP]] ]
+; GFX950-NEXT: [[TMP9]] = phi <2 x i32> [ [[TMP3]], %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
+; GFX950-NEXT: [[TMP10]] = phi <2 x i32> [ [[TMP5]], %[[ENTRY]] ], [ [[TMP11:%.*]], %[[LOOP]] ]
+; GFX950-NEXT: [[TMP11]] = phi <2 x i32> [ [[TMP7]], %[[ENTRY]] ], [ [[TMP12:%.*]], %[[LOOP]] ]
; GFX950-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I1]]
-; GFX950-NEXT: store i32 [[X0]], ptr addrspace(1) [[GEP1]], align 4
-; GFX950-NEXT: [[I2:%.*]] = or disjoint i32 [[I1]], 1
-; GFX950-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I2]]
-; GFX950-NEXT: store i32 [[X1]], ptr addrspace(1) [[GEP2]], align 4
+; GFX950-NEXT: store <2 x i32> [[TMP8]], ptr addrspace(1) [[GEP1]], align 4
; GFX950-NEXT: [[I_NEXT]] = add nuw i32 [[I1]], 2
; GFX950-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
+; GFX950-NEXT: [[TMP12]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> [[TMP11]], <2 x i32> <i32 1, i32 2>
; GFX950-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
; GFX950: [[EXIT]]:
; GFX950-NEXT: ret void
@@ -34,21 +39,26 @@ define amdgpu_kernel void @phi5_rotate(
; GFX942-LABEL: define amdgpu_kernel void @phi5_rotate(
; GFX942-SAME: ptr addrspace(1) captures(none) [[OUT:%.*]], i32 [[N:%.*]], i32 [[S0:%.*]], i32 [[S1:%.*]], i32 [[S2:%.*]], i32 [[S3:%.*]], i32 [[S4:%.*]]) {
; GFX942-NEXT: [[ENTRY:.*]]:
+; GFX942-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[S0]], i64 0
+; GFX942-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[S1]], i64 1
+; GFX942-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> poison, i32 [[S4]], i64 0
+; GFX942-NEXT: [[TMP3:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[S0]], i64 1
+; GFX942-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[S3]], i64 0
+; GFX942-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[S4]], i64 1
+; GFX942-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[S2]], i64 0
+; GFX942-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[S3]], i64 1
; GFX942-NEXT: br label %[[LOOP:.*]]
; GFX942: [[LOOP]]:
; GFX942-NEXT: [[I1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[X0:%.*]] = phi i32 [ [[S0]], %[[ENTRY]] ], [ [[X4:%.*]], %[[LOOP]] ]
-; GFX942-NEXT: [[X1:%.*]] = phi i32 [ [[S1]], %[[ENTRY]] ], [ [[X0]], %[[LOOP]] ]
-; GFX942-NEXT: [[X2:%.*]] = phi i32 [ [[S2]], %[[ENTRY]] ], [ [[X1]], %[[LOOP]] ]
-; GFX942-NEXT: [[X3:%.*]] = phi i32 [ [[S3]], %[[ENTRY]] ], [ [[X2]], %[[LOOP]] ]
-; GFX942-NEXT: [[X4]] = phi i32 [ [[S4]], %[[ENTRY]] ], [ [[X3]], %[[LOOP]] ]
+; GFX942-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ [[TMP1]], %[[ENTRY]] ], [ [[TMP9:%.*]], %[[LOOP]] ]
+; GFX942-NEXT: [[TMP9]] = phi <2 x i32> [ [[TMP3]], %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
+; GFX942-NEXT: [[TMP10]] = phi <2 x i32> [ [[TMP5]], %[[ENTRY]] ], [ [[TMP11:%.*]], %[[LOOP]] ]
+; GFX942-NEXT: [[TMP11]] = phi <2 x i32> [ [[TMP7]], %[[ENTRY]] ], [ [[TMP12:%.*]], %[[LOOP]] ]
; GFX942-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I1]]
-; GFX942-NEXT: store i32 [[X0]], ptr addrspace(1) [[GEP1]], align 4
-; GFX942-NEXT: [[I2:%.*]] = or disjoint i32 [[I1]], 1
-; GFX942-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[I2]]
-; GFX942-NEXT: store i32 [[X1]], ptr addrspace(1) [[GEP2]], align 4
+; GFX942-NEXT: store <2 x i32> [[TMP8]], ptr addrspace(1) [[GEP1]], align 4
; GFX942-NEXT: [[I_NEXT]] = add nuw i32 [[I1]], 2
; GFX942-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
+; GFX942-NEXT: [[TMP12]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> [[TMP11]], <2 x i32> <i32 1, i32 2>
; GFX942-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
; GFX942: [[EXIT]]:
; GFX942-NEXT: ret void
>From 08765081121767fb9603f97bb91e898f4e3a9ffd Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sat, 22 Aug 2026 19:30:53 +0100
Subject: [PATCH 4/4] [SCEV] Template-deduction build fix
---
llvm/lib/Analysis/ScalarEvolution.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 70891c6d89023..58d2e34dba444 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1471,8 +1471,7 @@ static const SCEV *getExtendAddRecStart(const SCEVAddRecExpr *AR, Type *Ty,
//
// In the current context, S is `Start`, X is `Step`, Ext is `ExtendOpTy` and T
// is `Delta` (defined below).
-template <typename ExtendOpTy,
- SCEVNoWrapFlags WrapType = ExtendOpTraits<ExtendOpTy>::WrapType>
+template <typename ExtendOpTy, SCEVNoWrapFlags WrapType>
bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
const SCEV *Step,
const Loop *L) {
@@ -1784,7 +1783,8 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
}
}
- if (proveNoWrapByVaryingStart<SCEVZeroExtendExpr>(Start, Step, L)) {
+ if (proveNoWrapByVaryingStart<SCEVZeroExtendExpr, SCEV::FlagNUW>(Start,
+ Step, L)) {
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
Start = getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this, Depth + 1);
Step = getZeroExtendExpr(Step, Ty, Depth + 1);
@@ -2048,7 +2048,8 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
inferNoWrapViaConstantRanges(AR);
auto NewFlags = proveNoSignedWrapViaInduction(AR);
if (!hasFlags(NewFlags, SCEV::FlagNSW) &&
- proveNoWrapByVaryingStart<SCEVSignExtendExpr>(Start, Step, L))
+ proveNoWrapByVaryingStart<SCEVSignExtendExpr, SCEV::FlagNSW>(Start,
+ Step, L))
NewFlags |= SCEV::FlagNSW;
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
More information about the llvm-commits
mailing list