[llvm] [SCEV] Try to fold ZExt/SExt of AddRec before existing lookup. (PR #208805)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 04:08:33 PDT 2026
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/208805
>From 0c7f2f5622e3697d8c7996e7130048cfc7d24157 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 16 Jul 2026 16:37:36 +0100
Subject: [PATCH 1/2] Add tests
---
.../iv-widen-addrec-flag-inferred-late.ll | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
diff --git a/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll b/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
new file mode 100644
index 0000000000000..4bfd088d22720
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
@@ -0,0 +1,92 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=indvars -S %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-n8:16:32:64-S128"
+
+define i32 @f(ptr %a, i32 %k) {
+; CHECK-LABEL: define i32 @f(
+; CHECK-SAME: ptr [[A:%.*]], i32 [[K:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[CHECK:.*]] ]
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = zext i32 [[IV]] to i64
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
+; CHECK-NEXT: [[DONE:%.*]] = icmp ne i32 [[V]], 0
+; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[IV]], [[K]]
+; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[DONE]], i1 [[LT]], i1 false
+; CHECK-NEXT: br i1 [[OR_COND]], label %[[CHECK]], label %[[EXIT:.*]]
+; CHECK: [[CHECK]]:
+; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
+; CHECK-NEXT: br label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[IV]], %[[LOOP]] ]
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %check ]
+ %idx = zext i32 %iv to i64
+ %gep = getelementptr i32, ptr %a, i64 %idx
+ %v = load i32, ptr %gep, align 4
+ %done = icmp eq i32 %v, 0
+ br i1 %done, label %exit, label %guard
+
+guard:
+ %lt = icmp ult i32 %iv, %k
+ br i1 %lt, label %check, label %exit
+
+check:
+ %iv.next = add i32 %iv, 1
+ br label %loop
+
+exit:
+ ret i32 %iv
+}
+
+define i32 @f_sext(ptr %a, i32 %k) {
+; CHECK-LABEL: define i32 @f_sext(
+; CHECK-SAME: ptr [[A:%.*]], i32 [[K:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[CHECK:.*]] ]
+; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[IV]] to i64
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[IDX]]
+; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
+; CHECK-NEXT: [[DONE:%.*]] = icmp ne i32 [[V]], 0
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[IV]], [[K]]
+; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[DONE]], i1 [[LT]], i1 false
+; CHECK-NEXT: br i1 [[OR_COND]], label %[[CHECK]], label %[[EXIT:.*]]
+; CHECK: [[CHECK]]:
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT: br label %[[LOOP]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], %[[LOOP]] ]
+; CHECK-NEXT: ret i32 [[IV_LCSSA]]
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %check ]
+ %idx = sext i32 %iv to i64
+ %gep = getelementptr i32, ptr %a, i64 %idx
+ %v = load i32, ptr %gep, align 4
+ %done = icmp eq i32 %v, 0
+ br i1 %done, label %exit, label %guard
+
+guard:
+ %lt = icmp slt i32 %iv, %k
+ br i1 %lt, label %check, label %exit
+
+check:
+ %iv.next = add i32 %iv, 1
+ br label %loop
+
+exit:
+ ret i32 %iv
+}
>From d1e1095256a4da03c9fd7d2eedeae3de4a3353e7 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Fri, 10 Jul 2026 14:00:38 +0100
Subject: [PATCH 2/2] [SCEV] Try to fold ZExt/SExt of AddRec before existing
lookup.
Move AddRec fold for ZExt & SExt before existing SCEV lookup. This can
improve results, when we constructed SCEV for a ZExt/SExt during earlier
analysis and flags on the operand AddRec have not been
refined/strengthend yet.
This improves results in some cases and fixes the regression here
https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/654#discussion_r3554885279.
On a large C/C++ corpus with 32k bitcode files, ~2% more IVs get
widened, removing a large number of ZExt instructions.
Compile-time impact in the noise
https://llvm-compile-time-tracker.com/compare.php?from=167d65906cc3c636221158abe8289ab4a03dfc7d&to=381abca0d5ead4443d86287d754f47c21396a9be&stat=instructions:u
---
llvm/lib/Analysis/ScalarEvolution.cpp | 42 ++-
.../ScalarEvolution/exit-count-non-strict.ll | 5 -
.../ScalarEvolution/incorrect-exit-count.ll | 8 +-
...vergence-divergent-i1-used-outside-loop.ll | 82 ++---
.../GlobalISel/divergence-structurizer.ll | 316 ++++++++----------
llvm/test/CodeGen/AMDGPU/memset-pattern.ll | 23 +-
llvm/test/CodeGen/ARM/select-imm.ll | 45 ++-
.../iv-widen-addrec-flag-inferred-late.ll | 22 +-
8 files changed, 249 insertions(+), 294 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 134be6ac097e0..af27a7897865b 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1701,6 +1701,18 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(const SCEV *Op, Type *Ty,
if (const SCEVZeroExtendExpr *SZ = dyn_cast<SCEVZeroExtendExpr>(Op))
return getZeroExtendExpr(SZ->getOperand(), Ty, Depth + 1);
+ // If the operand is an affine AddRec with the no-unsigned-wrap flag, the
+ // zero-extension distributes over the recurrence.
+ if (Depth <= MaxCastDepth)
+ if (const auto *AR = dyn_cast<SCEVAddRecExpr>(Op))
+ if (AR->isAffine() && AR->hasNoUnsignedWrap()) {
+ const SCEV *Start =
+ getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this, Depth + 1);
+ const SCEV *Step =
+ getZeroExtendExpr(AR->getStepRecurrence(*this), Ty, Depth + 1);
+ return getAddRecExpr(Start, Step, AR->getLoop(), AR->getNoWrapFlags());
+ }
+
// Before doing any expensive analysis, check to see if we've already
// computed a SCEV for this Op and Ty.
FoldingSetNodeID ID;
@@ -1742,14 +1754,7 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(const SCEV *Op, Type *Ty,
unsigned BitWidth = getTypeSizeInBits(AR->getType());
const Loop *L = AR->getLoop();
- // If we have special knowledge that this addrec won't overflow,
- // we don't need to do any further analysis.
- if (AR->hasNoUnsignedWrap()) {
- Start =
- getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getZeroExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, AR->getNoWrapFlags());
- }
+ // The no-unsigned-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
@@ -2054,6 +2059,18 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(const SCEV *Op, Type *Ty,
if (const SCEVZeroExtendExpr *SZ = dyn_cast<SCEVZeroExtendExpr>(Op))
return getZeroExtendExpr(SZ->getOperand(), Ty, Depth + 1);
+ // If the operand is an affine AddRec with the no-signed-wrap flag, the
+ // sign-extension distributes over the recurrence.
+ if (Depth <= MaxCastDepth)
+ if (const auto *AR = dyn_cast<SCEVAddRecExpr>(Op))
+ if (AR->isAffine() && AR->hasNoSignedWrap()) {
+ const SCEV *Start =
+ getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
+ const SCEV *Step =
+ getSignExtendExpr(AR->getStepRecurrence(*this), Ty, Depth + 1);
+ return getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagNSW);
+ }
+
// Before doing any expensive analysis, check to see if we've already
// computed a SCEV for this Op and Ty.
FoldingSetNodeID ID;
@@ -2128,14 +2145,7 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(const SCEV *Op, Type *Ty,
unsigned BitWidth = getTypeSizeInBits(AR->getType());
const Loop *L = AR->getLoop();
- // If we have special knowledge that this addrec won't overflow,
- // we don't need to do any further analysis.
- if (AR->hasNoSignedWrap()) {
- Start =
- getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1);
- Step = getSignExtendExpr(Step, Ty, Depth + 1);
- return getAddRecExpr(Start, Step, L, SCEV::FlagNSW);
- }
+ // 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
diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
index 3fde1dfb963c4..023f51265d08e 100644
--- a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
@@ -407,7 +407,6 @@ define void @sle_from_int_min_no_nsw(i32 %M, i32 %N) {
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: predicated exit count for loop: (2147483649 + (sext i32 %M to i64))<nsw>
; CHECK-NEXT: Predicates:
-; CHECK-NEXT: {-2147483648,+,1}<nsw><%loop> Added Flags: <nssw>
; CHECK-EMPTY:
; CHECK-NEXT: exit count for latch: (-2147483648 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1
@@ -415,18 +414,14 @@ define void @sle_from_int_min_no_nsw(i32 %M, i32 %N) {
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: predicated symbolic max exit count for loop: (2147483649 + (sext i32 %M to i64))<nsw>
; CHECK-NEXT: Predicates:
-; CHECK-NEXT: {-2147483648,+,1}<nsw><%loop> Added Flags: <nssw>
; CHECK-EMPTY:
; CHECK-NEXT: symbolic max exit count for latch: (-2147483648 + %N)
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 (-2147483648 + %N) to i64) umin (2147483649 + (sext i32 %M to i64))<nsw>)
; CHECK-NEXT: Predicates:
-; CHECK-NEXT: {-2147483648,+,1}<nsw><%loop> Added Flags: <nssw>
; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295
; CHECK-NEXT: Predicates:
-; CHECK-NEXT: {-2147483648,+,1}<nsw><%loop> Added Flags: <nssw>
; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 (-2147483648 + %N) to i64) umin (2147483649 + (sext i32 %M to i64))<nsw>)
; CHECK-NEXT: Predicates:
-; CHECK-NEXT: {-2147483648,+,1}<nsw><%loop> Added Flags: <nssw>
;
entry:
br label %loop
diff --git a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
index b00c26d472eaf..4daa22b0ba54d 100644
--- a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
+++ b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
@@ -19,9 +19,9 @@ define dso_local i32 @f() {
; CHECK-NEXT: %storemerge1921 = phi i32 [ 3, %outer.loop ], [ %dec, %for.end ]
; CHECK-NEXT: --> {3,+,-1}<nuw><nsw><%for.cond6> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %idxprom20 = zext i32 %storemerge1921 to i64
-; CHECK-NEXT: --> (zext i32 {3,+,-1}<nuw><nsw><%for.cond6> to i64) U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
+; CHECK-NEXT: --> {3,+,4294967295}<nuw><nsw><%for.cond6> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %arrayidx7 = getelementptr inbounds [1 x [4 x i16]], ptr @__const.f.g, i64 0, i64 0, i64 %idxprom20
-; CHECK-NEXT: --> ((2 * (zext i32 {3,+,-1}<nuw><nsw><%for.cond6> to i64))<nuw><nsw> + @__const.f.g)<nuw> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
+; CHECK-NEXT: --> {(6 + @__const.f.g)<nuw>,+,8589934590}<nuw><%for.cond6> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %i = load i16, ptr %arrayidx7, align 2
; CHECK-NEXT: --> %i U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond6: Variant, %outer.loop: Variant }
; CHECK-NEXT: %storemerge1822.lcssa.ph = phi i32 [ 0, %for.cond6 ]
@@ -43,9 +43,9 @@ define dso_local i32 @f() {
; CHECK-NEXT: %storemerge1921.3 = phi i32 [ 3, %for.end ], [ %dec.3, %for.end.3 ]
; CHECK-NEXT: --> {3,+,-1}<nuw><nsw><%inner.loop> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %idxprom20.3 = zext i32 %storemerge1921.3 to i64
-; CHECK-NEXT: --> (zext i32 {3,+,-1}<nuw><nsw><%inner.loop> to i64) U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
+; CHECK-NEXT: --> {3,+,4294967295}<nuw><nsw><%inner.loop> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %arrayidx7.3 = getelementptr inbounds [1 x [4 x i16]], ptr @__const.f.g, i64 0, i64 0, i64 %idxprom20.3
-; CHECK-NEXT: --> ((2 * (zext i32 {3,+,-1}<nuw><nsw><%inner.loop> to i64))<nuw><nsw> + @__const.f.g)<nuw> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
+; CHECK-NEXT: --> {(6 + @__const.f.g)<nuw>,+,8589934590}<nuw><%inner.loop> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
; CHECK-NEXT: %i7 = load i16, ptr %arrayidx7.3, align 2
; CHECK-NEXT: --> %i7 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %inner.loop: Variant, %outer.loop: Variant }
; CHECK-NEXT: %i8 = load volatile i32, ptr @b, align 4
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-used-outside-loop.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-used-outside-loop.ll
index 0709f8b0129c1..ac93b626bce90 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-used-outside-loop.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-used-outside-loop.ll
@@ -536,67 +536,59 @@ exit:
define amdgpu_cs void @loop_with_1break(ptr addrspace(1) %x, ptr addrspace(1) %a, ptr addrspace(1) %a.break) {
; GFX10-LABEL: loop_with_1break:
; GFX10: ; %bb.0: ; %entry
+; GFX10-NEXT: s_mov_b32 s1, -1
; GFX10-NEXT: s_mov_b32 s0, 0
-; GFX10-NEXT: s_mov_b32 s4, 0
-; GFX10-NEXT: ; implicit-def: $sgpr6
-; GFX10-NEXT: ; implicit-def: $sgpr7
-; GFX10-NEXT: ; implicit-def: $sgpr5
+; GFX10-NEXT: ; implicit-def: $sgpr3
+; GFX10-NEXT: ; implicit-def: $sgpr4
+; GFX10-NEXT: ; implicit-def: $sgpr2
; GFX10-NEXT: s_branch .LBB7_2
; GFX10-NEXT: .LBB7_1: ; %Flow
; GFX10-NEXT: ; in Loop: Header=BB7_2 Depth=1
-; GFX10-NEXT: s_waitcnt_depctr depctr_vm_vsrc(0)
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s1
-; GFX10-NEXT: s_and_b32 s1, exec_lo, s6
-; GFX10-NEXT: s_or_b32 s4, s1, s4
-; GFX10-NEXT: s_andn2_b32 s1, s5, exec_lo
-; GFX10-NEXT: s_and_b32 s2, exec_lo, s7
-; GFX10-NEXT: s_or_b32 s5, s1, s2
-; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s5
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s3
+; GFX10-NEXT: s_or_b32 s0, s5, s0
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s4
+; GFX10-NEXT: s_or_b32 s2, s2, s5
+; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s0
; GFX10-NEXT: s_cbranch_execz .LBB7_4
; GFX10-NEXT: .LBB7_2: ; %A
; GFX10-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX10-NEXT: s_ashr_i32 s1, s0, 31
-; GFX10-NEXT: s_mov_b32 s8, exec_lo
-; GFX10-NEXT: s_lshl_b64 s[2:3], s[0:1], 2
-; GFX10-NEXT: s_andn2_b32 s1, s7, exec_lo
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_and_b32 s7, exec_lo, s8
-; GFX10-NEXT: s_andn2_b32 s6, s6, exec_lo
-; GFX10-NEXT: s_and_b32 s8, exec_lo, exec_lo
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v2, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v3, v7, vcc_lo
-; GFX10-NEXT: s_or_b32 s7, s1, s7
-; GFX10-NEXT: s_or_b32 s6, s6, s8
-; GFX10-NEXT: global_load_dword v6, v[6:7], off
+; GFX10-NEXT: global_load_dword v6, v[2:3], off
+; GFX10-NEXT: s_mov_b32 s5, exec_lo
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s5
+; GFX10-NEXT: s_andn2_b32 s3, s3, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, exec_lo
+; GFX10-NEXT: s_or_b32 s4, s4, s5
+; GFX10-NEXT: s_or_b32 s3, s3, s6
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v6
-; GFX10-NEXT: s_and_saveexec_b32 s1, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s5, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB7_1
; GFX10-NEXT: ; %bb.3: ; %loop.body
; GFX10-NEXT: ; in Loop: Header=BB7_2 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_add_i32 s2, s0, 1
-; GFX10-NEXT: s_cmpk_lt_u32 s0, 0x64
-; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v0, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v1, v7, vcc_lo
-; GFX10-NEXT: s_andn2_b32 s3, s7, exec_lo
+; GFX10-NEXT: global_load_dword v6, v[0:1], off
+; GFX10-NEXT: s_add_i32 s1, s1, 1
+; GFX10-NEXT: v_add_co_u32 v2, vcc_lo, v2, 4
+; GFX10-NEXT: s_cmpk_lt_u32 s1, 0x64
+; GFX10-NEXT: v_add_co_ci_u32_e32 v3, vcc_lo, 0, v3, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s6, exec_lo, 0
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
; GFX10-NEXT: s_and_b32 s7, exec_lo, 0
-; GFX10-NEXT: s_andn2_b32 s6, s6, exec_lo
-; GFX10-NEXT: global_load_dword v8, v[6:7], off
-; GFX10-NEXT: s_and_b32 s0, exec_lo, s0
-; GFX10-NEXT: s_or_b32 s7, s3, s7
-; GFX10-NEXT: s_or_b32 s6, s6, s0
-; GFX10-NEXT: s_mov_b32 s0, s2
+; GFX10-NEXT: s_andn2_b32 s3, s3, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, s6
+; GFX10-NEXT: s_or_b32 s4, s4, s7
+; GFX10-NEXT: s_or_b32 s3, s3, s6
; GFX10-NEXT: s_waitcnt vmcnt(0)
-; GFX10-NEXT: v_add_nc_u32_e32 v8, 1, v8
-; GFX10-NEXT: global_store_dword v[6:7], v8, off
+; GFX10-NEXT: v_add_nc_u32_e32 v6, 1, v6
+; GFX10-NEXT: global_store_dword v[0:1], v6, off
+; GFX10-NEXT: v_add_co_u32 v0, vcc_lo, v0, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
; GFX10-NEXT: s_branch .LBB7_1
; GFX10-NEXT: .LBB7_4: ; %loop.exit.guard
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s4
-; GFX10-NEXT: s_and_saveexec_b32 s0, s5
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s0
+; GFX10-NEXT: s_and_saveexec_b32 s0, s2
; GFX10-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX10-NEXT: s_cbranch_execz .LBB7_6
; GFX10-NEXT: ; %bb.5: ; %break.body
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-structurizer.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-structurizer.ll
index 421d385107cae..7575a7a72209c 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-structurizer.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-structurizer.ll
@@ -106,51 +106,43 @@ exit:
define amdgpu_cs void @loop_with_1break(ptr addrspace(1) %x, ptr addrspace(1) %a) {
; GFX10-LABEL: loop_with_1break:
; GFX10: ; %bb.0: ; %entry
-; GFX10-NEXT: s_mov_b32 s0, 0
-; GFX10-NEXT: s_mov_b32 s4, 0
-; GFX10-NEXT: ; implicit-def: $sgpr5
+; GFX10-NEXT: s_mov_b32 s0, -1
+; GFX10-NEXT: s_mov_b32 s1, 0
+; GFX10-NEXT: ; implicit-def: $sgpr2
; GFX10-NEXT: s_branch .LBB2_2
; GFX10-NEXT: .LBB2_1: ; %Flow
; GFX10-NEXT: ; in Loop: Header=BB2_2 Depth=1
-; GFX10-NEXT: s_waitcnt_depctr depctr_vm_vsrc(0)
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s1
-; GFX10-NEXT: s_and_b32 s1, exec_lo, s5
-; GFX10-NEXT: s_or_b32 s4, s1, s4
-; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s3
+; GFX10-NEXT: s_and_b32 s3, exec_lo, s2
+; GFX10-NEXT: s_or_b32 s1, s3, s1
+; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s1
; GFX10-NEXT: s_cbranch_execz .LBB2_4
; GFX10-NEXT: .LBB2_2: ; %A
; GFX10-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX10-NEXT: s_ashr_i32 s1, s0, 31
-; GFX10-NEXT: s_lshl_b64 s[2:3], s[0:1], 2
-; GFX10-NEXT: s_andn2_b32 s1, s5, exec_lo
-; GFX10-NEXT: v_mov_b32_e32 v4, s2
-; GFX10-NEXT: v_mov_b32_e32 v5, s3
-; GFX10-NEXT: s_and_b32 s5, exec_lo, exec_lo
-; GFX10-NEXT: s_or_b32 s5, s1, s5
-; GFX10-NEXT: v_add_co_u32 v4, vcc_lo, v2, v4
-; GFX10-NEXT: v_add_co_ci_u32_e32 v5, vcc_lo, v3, v5, vcc_lo
-; GFX10-NEXT: global_load_dword v4, v[4:5], off
+; GFX10-NEXT: global_load_dword v4, v[2:3], off
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s3, exec_lo, exec_lo
+; GFX10-NEXT: s_or_b32 s2, s2, s3
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v4
-; GFX10-NEXT: s_and_saveexec_b32 s1, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s3, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB2_1
; GFX10-NEXT: ; %bb.3: ; %loop.body
; GFX10-NEXT: ; in Loop: Header=BB2_2 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v4, s2
-; GFX10-NEXT: v_mov_b32_e32 v5, s3
-; GFX10-NEXT: s_add_i32 s2, s0, 1
+; GFX10-NEXT: global_load_dword v4, v[0:1], off
+; GFX10-NEXT: s_add_i32 s0, s0, 1
+; GFX10-NEXT: v_add_co_u32 v2, vcc_lo, v2, 4
; GFX10-NEXT: s_cmpk_lt_u32 s0, 0x64
-; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
-; GFX10-NEXT: v_add_co_u32 v4, vcc_lo, v0, v4
-; GFX10-NEXT: v_add_co_ci_u32_e32 v5, vcc_lo, v1, v5, vcc_lo
-; GFX10-NEXT: s_andn2_b32 s3, s5, exec_lo
-; GFX10-NEXT: s_and_b32 s0, exec_lo, s0
-; GFX10-NEXT: global_load_dword v6, v[4:5], off
-; GFX10-NEXT: s_or_b32 s5, s3, s0
-; GFX10-NEXT: s_mov_b32 s0, s2
+; GFX10-NEXT: v_add_co_ci_u32_e32 v3, vcc_lo, 0, v3, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s4, exec_lo, 0
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s4, exec_lo, s4
+; GFX10-NEXT: s_or_b32 s2, s2, s4
; GFX10-NEXT: s_waitcnt vmcnt(0)
-; GFX10-NEXT: v_add_nc_u32_e32 v6, 1, v6
-; GFX10-NEXT: global_store_dword v[4:5], v6, off
+; GFX10-NEXT: v_add_nc_u32_e32 v4, 1, v4
+; GFX10-NEXT: global_store_dword v[0:1], v4, off
+; GFX10-NEXT: v_add_co_u32 v0, vcc_lo, v0, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
; GFX10-NEXT: s_branch .LBB2_1
; GFX10-NEXT: .LBB2_4: ; %exit
; GFX10-NEXT: s_endpgm
@@ -180,69 +172,59 @@ exit:
define amdgpu_cs void @loop_with_2breaks(ptr addrspace(1) %x, ptr addrspace(1) %a, ptr addrspace(1) %b) {
; GFX10-LABEL: loop_with_2breaks:
; GFX10: ; %bb.0: ; %entry
-; GFX10-NEXT: s_mov_b32 s0, 0
-; GFX10-NEXT: s_mov_b32 s4, 0
-; GFX10-NEXT: ; implicit-def: $sgpr5
+; GFX10-NEXT: s_mov_b32 s0, -1
+; GFX10-NEXT: s_mov_b32 s1, 0
+; GFX10-NEXT: ; implicit-def: $sgpr2
; GFX10-NEXT: s_branch .LBB3_3
-; GFX10-NEXT: .LBB3_1: ; %Flow3
+; GFX10-NEXT: .LBB3_1: ; %Flow8
; GFX10-NEXT: ; in Loop: Header=BB3_3 Depth=1
-; GFX10-NEXT: s_waitcnt_depctr depctr_vm_vsrc(0)
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s7
-; GFX10-NEXT: s_andn2_b32 s2, s5, exec_lo
-; GFX10-NEXT: s_and_b32 s3, exec_lo, s6
-; GFX10-NEXT: s_or_b32 s5, s2, s3
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s5
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s4, exec_lo, s4
+; GFX10-NEXT: s_or_b32 s2, s2, s4
; GFX10-NEXT: .LBB3_2: ; %Flow
; GFX10-NEXT: ; in Loop: Header=BB3_3 Depth=1
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s1
-; GFX10-NEXT: s_and_b32 s1, exec_lo, s5
-; GFX10-NEXT: s_or_b32 s4, s1, s4
-; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s3
+; GFX10-NEXT: s_and_b32 s3, exec_lo, s2
+; GFX10-NEXT: s_or_b32 s1, s3, s1
+; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s1
; GFX10-NEXT: s_cbranch_execz .LBB3_6
; GFX10-NEXT: .LBB3_3: ; %A
; GFX10-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX10-NEXT: s_ashr_i32 s1, s0, 31
-; GFX10-NEXT: s_lshl_b64 s[2:3], s[0:1], 2
-; GFX10-NEXT: s_andn2_b32 s1, s5, exec_lo
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_and_b32 s5, exec_lo, exec_lo
-; GFX10-NEXT: s_or_b32 s5, s1, s5
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v2, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v3, v7, vcc_lo
-; GFX10-NEXT: global_load_dword v6, v[6:7], off
+; GFX10-NEXT: global_load_dword v6, v[2:3], off
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s3, exec_lo, exec_lo
+; GFX10-NEXT: s_or_b32 s2, s2, s3
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v6
-; GFX10-NEXT: s_and_saveexec_b32 s1, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s3, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB3_2
; GFX10-NEXT: ; %bb.4: ; %B
; GFX10-NEXT: ; in Loop: Header=BB3_3 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_mov_b32 s6, exec_lo
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v4, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v5, v7, vcc_lo
-; GFX10-NEXT: global_load_dword v6, v[6:7], off
+; GFX10-NEXT: global_load_dword v6, v[4:5], off
+; GFX10-NEXT: s_mov_b32 s4, exec_lo
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v6
-; GFX10-NEXT: s_and_saveexec_b32 s7, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s5, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB3_1
; GFX10-NEXT: ; %bb.5: ; %loop.body
; GFX10-NEXT: ; in Loop: Header=BB3_3 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_add_i32 s2, s0, 1
+; GFX10-NEXT: global_load_dword v6, v[0:1], off
+; GFX10-NEXT: v_add_co_u32 v4, vcc_lo, v4, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v5, vcc_lo, 0, v5, vcc_lo
+; GFX10-NEXT: s_add_i32 s0, s0, 1
+; GFX10-NEXT: v_add_co_u32 v2, vcc_lo, v2, 4
; GFX10-NEXT: s_cmpk_lt_u32 s0, 0x64
-; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v0, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v1, v7, vcc_lo
-; GFX10-NEXT: s_andn2_b32 s3, s6, exec_lo
-; GFX10-NEXT: s_and_b32 s0, exec_lo, s0
-; GFX10-NEXT: global_load_dword v8, v[6:7], off
-; GFX10-NEXT: s_or_b32 s6, s3, s0
-; GFX10-NEXT: s_mov_b32 s0, s2
+; GFX10-NEXT: v_add_co_ci_u32_e32 v3, vcc_lo, 0, v3, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s6, exec_lo, 0
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, s6
+; GFX10-NEXT: s_or_b32 s4, s4, s6
; GFX10-NEXT: s_waitcnt vmcnt(0)
-; GFX10-NEXT: v_add_nc_u32_e32 v8, 1, v8
-; GFX10-NEXT: global_store_dword v[6:7], v8, off
+; GFX10-NEXT: v_add_nc_u32_e32 v6, 1, v6
+; GFX10-NEXT: global_store_dword v[0:1], v6, off
+; GFX10-NEXT: v_add_co_u32 v0, vcc_lo, v0, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
; GFX10-NEXT: s_branch .LBB3_1
; GFX10-NEXT: .LBB3_6: ; %exit
; GFX10-NEXT: s_endpgm
@@ -278,87 +260,75 @@ exit:
define amdgpu_cs void @loop_with_3breaks(ptr addrspace(1) %x, ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c) {
; GFX10-LABEL: loop_with_3breaks:
; GFX10: ; %bb.0: ; %entry
-; GFX10-NEXT: s_mov_b32 s0, 0
-; GFX10-NEXT: s_mov_b32 s4, 0
-; GFX10-NEXT: ; implicit-def: $sgpr5
+; GFX10-NEXT: s_mov_b32 s0, -1
+; GFX10-NEXT: s_mov_b32 s1, 0
+; GFX10-NEXT: ; implicit-def: $sgpr2
; GFX10-NEXT: s_branch .LBB4_4
-; GFX10-NEXT: .LBB4_1: ; %Flow5
-; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
-; GFX10-NEXT: s_waitcnt_depctr depctr_vm_vsrc(0)
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s9
-; GFX10-NEXT: s_andn2_b32 s2, s6, exec_lo
-; GFX10-NEXT: s_and_b32 s3, exec_lo, s8
-; GFX10-NEXT: s_or_b32 s6, s2, s3
-; GFX10-NEXT: .LBB4_2: ; %Flow4
+; GFX10-NEXT: .LBB4_1: ; %Flow12
; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s7
-; GFX10-NEXT: s_andn2_b32 s2, s5, exec_lo
-; GFX10-NEXT: s_and_b32 s3, exec_lo, s6
-; GFX10-NEXT: s_or_b32 s5, s2, s3
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, s6
+; GFX10-NEXT: s_or_b32 s4, s4, s6
+; GFX10-NEXT: .LBB4_2: ; %Flow11
+; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s5
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s4, exec_lo, s4
+; GFX10-NEXT: s_or_b32 s2, s2, s4
; GFX10-NEXT: .LBB4_3: ; %Flow
; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s1
-; GFX10-NEXT: s_and_b32 s1, exec_lo, s5
-; GFX10-NEXT: s_or_b32 s4, s1, s4
-; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s3
+; GFX10-NEXT: s_and_b32 s3, exec_lo, s2
+; GFX10-NEXT: s_or_b32 s1, s3, s1
+; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s1
; GFX10-NEXT: s_cbranch_execz .LBB4_8
; GFX10-NEXT: .LBB4_4: ; %A
; GFX10-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX10-NEXT: s_ashr_i32 s1, s0, 31
-; GFX10-NEXT: s_lshl_b64 s[2:3], s[0:1], 2
-; GFX10-NEXT: s_andn2_b32 s1, s5, exec_lo
-; GFX10-NEXT: v_mov_b32_e32 v8, s2
-; GFX10-NEXT: v_mov_b32_e32 v9, s3
-; GFX10-NEXT: s_and_b32 s5, exec_lo, exec_lo
-; GFX10-NEXT: s_or_b32 s5, s1, s5
-; GFX10-NEXT: v_add_co_u32 v8, vcc_lo, v2, v8
-; GFX10-NEXT: v_add_co_ci_u32_e32 v9, vcc_lo, v3, v9, vcc_lo
-; GFX10-NEXT: global_load_dword v8, v[8:9], off
+; GFX10-NEXT: global_load_dword v8, v[2:3], off
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s3, exec_lo, exec_lo
+; GFX10-NEXT: s_or_b32 s2, s2, s3
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v8
-; GFX10-NEXT: s_and_saveexec_b32 s1, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s3, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB4_3
; GFX10-NEXT: ; %bb.5: ; %B
; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v8, s2
-; GFX10-NEXT: v_mov_b32_e32 v9, s3
-; GFX10-NEXT: s_mov_b32 s6, exec_lo
-; GFX10-NEXT: v_add_co_u32 v8, vcc_lo, v4, v8
-; GFX10-NEXT: v_add_co_ci_u32_e32 v9, vcc_lo, v5, v9, vcc_lo
-; GFX10-NEXT: global_load_dword v8, v[8:9], off
+; GFX10-NEXT: global_load_dword v8, v[4:5], off
+; GFX10-NEXT: s_mov_b32 s4, exec_lo
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v8
-; GFX10-NEXT: s_and_saveexec_b32 s7, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s5, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB4_2
; GFX10-NEXT: ; %bb.6: ; %C
; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v8, s2
-; GFX10-NEXT: v_mov_b32_e32 v9, s3
-; GFX10-NEXT: s_mov_b32 s8, exec_lo
-; GFX10-NEXT: v_add_co_u32 v8, vcc_lo, v6, v8
-; GFX10-NEXT: v_add_co_ci_u32_e32 v9, vcc_lo, v7, v9, vcc_lo
-; GFX10-NEXT: global_load_dword v8, v[8:9], off
+; GFX10-NEXT: global_load_dword v8, v[6:7], off
+; GFX10-NEXT: s_mov_b32 s6, exec_lo
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v8
-; GFX10-NEXT: s_and_saveexec_b32 s9, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s7, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB4_1
; GFX10-NEXT: ; %bb.7: ; %loop.body
; GFX10-NEXT: ; in Loop: Header=BB4_4 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v8, s2
-; GFX10-NEXT: v_mov_b32_e32 v9, s3
-; GFX10-NEXT: s_add_i32 s2, s0, 1
+; GFX10-NEXT: global_load_dword v8, v[0:1], off
+; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v6, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, 0, v7, vcc_lo
+; GFX10-NEXT: v_add_co_u32 v4, vcc_lo, v4, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v5, vcc_lo, 0, v5, vcc_lo
+; GFX10-NEXT: s_add_i32 s0, s0, 1
+; GFX10-NEXT: v_add_co_u32 v2, vcc_lo, v2, 4
; GFX10-NEXT: s_cmpk_lt_u32 s0, 0x64
-; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
-; GFX10-NEXT: v_add_co_u32 v8, vcc_lo, v0, v8
-; GFX10-NEXT: v_add_co_ci_u32_e32 v9, vcc_lo, v1, v9, vcc_lo
-; GFX10-NEXT: s_andn2_b32 s3, s8, exec_lo
-; GFX10-NEXT: s_and_b32 s0, exec_lo, s0
-; GFX10-NEXT: global_load_dword v10, v[8:9], off
-; GFX10-NEXT: s_or_b32 s8, s3, s0
-; GFX10-NEXT: s_mov_b32 s0, s2
+; GFX10-NEXT: v_add_co_ci_u32_e32 v3, vcc_lo, 0, v3, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s8, exec_lo, 0
+; GFX10-NEXT: s_andn2_b32 s6, s6, exec_lo
+; GFX10-NEXT: s_and_b32 s8, exec_lo, s8
+; GFX10-NEXT: s_or_b32 s6, s6, s8
; GFX10-NEXT: s_waitcnt vmcnt(0)
-; GFX10-NEXT: v_add_nc_u32_e32 v10, 1, v10
-; GFX10-NEXT: global_store_dword v[8:9], v10, off
+; GFX10-NEXT: v_add_nc_u32_e32 v8, 1, v8
+; GFX10-NEXT: global_store_dword v[0:1], v8, off
+; GFX10-NEXT: v_add_co_u32 v0, vcc_lo, v0, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
; GFX10-NEXT: s_branch .LBB4_1
; GFX10-NEXT: .LBB4_8: ; %exit
; GFX10-NEXT: s_endpgm
@@ -404,67 +374,59 @@ exit:
define amdgpu_cs void @loop_with_div_break_with_body(ptr addrspace(1) %x, ptr addrspace(1) %a, ptr addrspace(1) %a.break) {
; GFX10-LABEL: loop_with_div_break_with_body:
; GFX10: ; %bb.0: ; %entry
+; GFX10-NEXT: s_mov_b32 s1, -1
; GFX10-NEXT: s_mov_b32 s0, 0
-; GFX10-NEXT: s_mov_b32 s4, 0
-; GFX10-NEXT: ; implicit-def: $sgpr6
-; GFX10-NEXT: ; implicit-def: $sgpr7
-; GFX10-NEXT: ; implicit-def: $sgpr5
+; GFX10-NEXT: ; implicit-def: $sgpr3
+; GFX10-NEXT: ; implicit-def: $sgpr4
+; GFX10-NEXT: ; implicit-def: $sgpr2
; GFX10-NEXT: s_branch .LBB5_2
; GFX10-NEXT: .LBB5_1: ; %Flow
; GFX10-NEXT: ; in Loop: Header=BB5_2 Depth=1
-; GFX10-NEXT: s_waitcnt_depctr depctr_vm_vsrc(0)
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s1
-; GFX10-NEXT: s_and_b32 s1, exec_lo, s6
-; GFX10-NEXT: s_or_b32 s4, s1, s4
-; GFX10-NEXT: s_andn2_b32 s1, s5, exec_lo
-; GFX10-NEXT: s_and_b32 s2, exec_lo, s7
-; GFX10-NEXT: s_or_b32 s5, s1, s2
-; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s5
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s3
+; GFX10-NEXT: s_or_b32 s0, s5, s0
+; GFX10-NEXT: s_andn2_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s4
+; GFX10-NEXT: s_or_b32 s2, s2, s5
+; GFX10-NEXT: s_andn2_b32 exec_lo, exec_lo, s0
; GFX10-NEXT: s_cbranch_execz .LBB5_4
; GFX10-NEXT: .LBB5_2: ; %A
; GFX10-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX10-NEXT: s_ashr_i32 s1, s0, 31
-; GFX10-NEXT: s_mov_b32 s8, exec_lo
-; GFX10-NEXT: s_lshl_b64 s[2:3], s[0:1], 2
-; GFX10-NEXT: s_andn2_b32 s1, s7, exec_lo
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_and_b32 s7, exec_lo, s8
-; GFX10-NEXT: s_andn2_b32 s6, s6, exec_lo
-; GFX10-NEXT: s_and_b32 s8, exec_lo, exec_lo
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v2, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v3, v7, vcc_lo
-; GFX10-NEXT: s_or_b32 s7, s1, s7
-; GFX10-NEXT: s_or_b32 s6, s6, s8
-; GFX10-NEXT: global_load_dword v6, v[6:7], off
+; GFX10-NEXT: global_load_dword v6, v[2:3], off
+; GFX10-NEXT: s_mov_b32 s5, exec_lo
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
+; GFX10-NEXT: s_and_b32 s5, exec_lo, s5
+; GFX10-NEXT: s_andn2_b32 s3, s3, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, exec_lo
+; GFX10-NEXT: s_or_b32 s4, s4, s5
+; GFX10-NEXT: s_or_b32 s3, s3, s6
; GFX10-NEXT: s_waitcnt vmcnt(0)
; GFX10-NEXT: v_cmp_ne_u32_e32 vcc_lo, 0, v6
-; GFX10-NEXT: s_and_saveexec_b32 s1, vcc_lo
+; GFX10-NEXT: s_and_saveexec_b32 s5, vcc_lo
; GFX10-NEXT: s_cbranch_execz .LBB5_1
; GFX10-NEXT: ; %bb.3: ; %loop.body
; GFX10-NEXT: ; in Loop: Header=BB5_2 Depth=1
-; GFX10-NEXT: v_mov_b32_e32 v6, s2
-; GFX10-NEXT: v_mov_b32_e32 v7, s3
-; GFX10-NEXT: s_add_i32 s2, s0, 1
-; GFX10-NEXT: s_cmpk_lt_u32 s0, 0x64
-; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
-; GFX10-NEXT: v_add_co_u32 v6, vcc_lo, v0, v6
-; GFX10-NEXT: v_add_co_ci_u32_e32 v7, vcc_lo, v1, v7, vcc_lo
-; GFX10-NEXT: s_andn2_b32 s3, s7, exec_lo
+; GFX10-NEXT: global_load_dword v6, v[0:1], off
+; GFX10-NEXT: s_add_i32 s1, s1, 1
+; GFX10-NEXT: v_add_co_u32 v2, vcc_lo, v2, 4
+; GFX10-NEXT: s_cmpk_lt_u32 s1, 0x64
+; GFX10-NEXT: v_add_co_ci_u32_e32 v3, vcc_lo, 0, v3, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s6, exec_lo, 0
+; GFX10-NEXT: s_andn2_b32 s4, s4, exec_lo
; GFX10-NEXT: s_and_b32 s7, exec_lo, 0
-; GFX10-NEXT: s_andn2_b32 s6, s6, exec_lo
-; GFX10-NEXT: global_load_dword v8, v[6:7], off
-; GFX10-NEXT: s_and_b32 s0, exec_lo, s0
-; GFX10-NEXT: s_or_b32 s7, s3, s7
-; GFX10-NEXT: s_or_b32 s6, s6, s0
-; GFX10-NEXT: s_mov_b32 s0, s2
+; GFX10-NEXT: s_andn2_b32 s3, s3, exec_lo
+; GFX10-NEXT: s_and_b32 s6, exec_lo, s6
+; GFX10-NEXT: s_or_b32 s4, s4, s7
+; GFX10-NEXT: s_or_b32 s3, s3, s6
; GFX10-NEXT: s_waitcnt vmcnt(0)
-; GFX10-NEXT: v_add_nc_u32_e32 v8, 1, v8
-; GFX10-NEXT: global_store_dword v[6:7], v8, off
+; GFX10-NEXT: v_add_nc_u32_e32 v6, 1, v6
+; GFX10-NEXT: global_store_dword v[0:1], v6, off
+; GFX10-NEXT: v_add_co_u32 v0, vcc_lo, v0, 4
+; GFX10-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
; GFX10-NEXT: s_branch .LBB5_1
; GFX10-NEXT: .LBB5_4: ; %loop.exit.guard
-; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s4
-; GFX10-NEXT: s_and_saveexec_b32 s0, s5
+; GFX10-NEXT: s_or_b32 exec_lo, exec_lo, s0
+; GFX10-NEXT: s_and_saveexec_b32 s0, s2
; GFX10-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX10-NEXT: s_cbranch_execz .LBB5_6
; GFX10-NEXT: ; %bb.5: ; %break.body
diff --git a/llvm/test/CodeGen/AMDGPU/memset-pattern.ll b/llvm/test/CodeGen/AMDGPU/memset-pattern.ll
index dfd0f4533b410..661025a2a9282 100644
--- a/llvm/test/CodeGen/AMDGPU/memset-pattern.ll
+++ b/llvm/test/CodeGen/AMDGPU/memset-pattern.ll
@@ -90,19 +90,20 @@ define void @memset_pattern_i128_constlen_mainloop_and_residual_taken(ptr addrsp
; GFX942-SDAG-NEXT: ; %bb.2: ; %memset.pattern-expansion-residual-body.preheader
; GFX942-SDAG-NEXT: s_mov_b64 s[0:1], 0x100
; GFX942-SDAG-NEXT: v_lshl_add_u64 v[4:5], v[0:1], 0, s[0:1]
-; GFX942-SDAG-NEXT: s_mov_b32 s0, 1
+; GFX942-SDAG-NEXT: s_mov_b64 s[0:1], 0
; GFX942-SDAG-NEXT: v_mov_b32_e32 v0, 0xdddddddd
; GFX942-SDAG-NEXT: v_mov_b32_e32 v1, 0xcccccccc
; GFX942-SDAG-NEXT: v_mov_b32_e32 v2, 0xbbbbbbbb
; GFX942-SDAG-NEXT: v_mov_b32_e32 v3, 0xaaaaaaaa
; GFX942-SDAG-NEXT: .LBB3_3: ; %memset.pattern-expansion-residual-body
; GFX942-SDAG-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX942-SDAG-NEXT: s_add_i32 s1, s0, 1
+; GFX942-SDAG-NEXT: s_add_u32 s0, s0, 1
+; GFX942-SDAG-NEXT: s_addc_u32 s1, s1, 0
+; GFX942-SDAG-NEXT: v_cmp_lt_u64_e64 s[2:3], s[0:1], 3
; GFX942-SDAG-NEXT: global_store_dwordx4 v[4:5], v[0:3], off
-; GFX942-SDAG-NEXT: s_cmp_lt_u32 s0, 3
; GFX942-SDAG-NEXT: v_lshl_add_u64 v[4:5], v[4:5], 0, 16
-; GFX942-SDAG-NEXT: s_mov_b32 s0, s1
-; GFX942-SDAG-NEXT: s_cbranch_scc1 .LBB3_3
+; GFX942-SDAG-NEXT: s_and_b64 vcc, exec, s[2:3]
+; GFX942-SDAG-NEXT: s_cbranch_vccnz .LBB3_3
; GFX942-SDAG-NEXT: ; %bb.4: ; %memset.pattern-post-expansion
; GFX942-SDAG-NEXT: s_waitcnt vmcnt(0)
; GFX942-SDAG-NEXT: s_setpc_b64 s[30:31]
@@ -153,20 +154,18 @@ define void @memset_pattern_i128_constlen_mainloop_and_residual_taken(ptr addrsp
; GFX942-GISEL-NEXT: s_mov_b32 s6, 0xbbbbbbbb
; GFX942-GISEL-NEXT: s_mov_b32 s7, 0xaaaaaaaa
; GFX942-GISEL-NEXT: v_addc_co_u32_e32 v5, vcc, 0, v1, vcc
-; GFX942-GISEL-NEXT: s_mov_b32 s0, 1
+; GFX942-GISEL-NEXT: s_mov_b64 s[0:1], 0
; GFX942-GISEL-NEXT: v_mov_b64_e32 v[0:1], s[4:5]
; GFX942-GISEL-NEXT: v_mov_b64_e32 v[2:3], s[6:7]
-; GFX942-GISEL-NEXT: s_mov_b32 s1, 0
; GFX942-GISEL-NEXT: .LBB3_3: ; %memset.pattern-expansion-residual-body
; GFX942-GISEL-NEXT: ; =>This Inner Loop Header: Depth=1
-; GFX942-GISEL-NEXT: v_cmp_lt_u64_e64 s[2:3], s[0:1], 3
-; GFX942-GISEL-NEXT: s_cmp_lg_u64 s[2:3], 0
+; GFX942-GISEL-NEXT: s_add_u32 s0, s0, 1
+; GFX942-GISEL-NEXT: s_addc_u32 s1, s1, 0
; GFX942-GISEL-NEXT: global_store_dwordx4 v[4:5], v[0:3], off
; GFX942-GISEL-NEXT: v_add_co_u32_e32 v4, vcc, 16, v4
-; GFX942-GISEL-NEXT: s_cselect_b32 s2, 1, 0
-; GFX942-GISEL-NEXT: s_add_i32 s0, s0, 1
+; GFX942-GISEL-NEXT: v_cmp_lt_u64_e64 s[2:3], s[0:1], 3
+; GFX942-GISEL-NEXT: s_cmp_lg_u64 s[2:3], 0
; GFX942-GISEL-NEXT: v_addc_co_u32_e32 v5, vcc, 0, v5, vcc
-; GFX942-GISEL-NEXT: s_cmp_lg_u32 s2, 0
; GFX942-GISEL-NEXT: s_cbranch_scc1 .LBB3_3
; GFX942-GISEL-NEXT: ; %bb.4: ; %memset.pattern-post-expansion
; GFX942-GISEL-NEXT: s_waitcnt vmcnt(0)
diff --git a/llvm/test/CodeGen/ARM/select-imm.ll b/llvm/test/CodeGen/ARM/select-imm.ll
index 186276b50ceeb..690f5410f5ce7 100644
--- a/llvm/test/CodeGen/ARM/select-imm.ll
+++ b/llvm/test/CodeGen/ARM/select-imm.ll
@@ -431,14 +431,13 @@ define void @t9(ptr %a, i8 %b) {
; ARM-NEXT: cmp r0, r0
; ARM-NEXT: bne .LBB8_3
; ARM-NEXT: @ %bb.1: @ %while.body.preheader
-; ARM-NEXT: add r1, r4, #1
-; ARM-NEXT: mov r2, r0
+; ARM-NEXT: mov r1, r0
; ARM-NEXT: .LBB8_2: @ %while.body
; ARM-NEXT: @ =>This Inner Loop Header: Depth=1
-; ARM-NEXT: add r2, r2, #1
; ARM-NEXT: add r1, r1, #1
-; ARM-NEXT: and r3, r2, #255
-; ARM-NEXT: cmp r3, r0
+; ARM-NEXT: add r4, r4, #1
+; ARM-NEXT: and r2, r1, #255
+; ARM-NEXT: cmp r2, r0
; ARM-NEXT: blt .LBB8_2
; ARM-NEXT: .LBB8_3: @ %while.end
; ARM-NEXT: pop {r4, lr}
@@ -455,14 +454,13 @@ define void @t9(ptr %a, i8 %b) {
; ARMT2-NEXT: cmp r0, r0
; ARMT2-NEXT: popne {r4, pc}
; ARMT2-NEXT: .LBB8_1: @ %while.body.preheader
-; ARMT2-NEXT: add r1, r4, #1
-; ARMT2-NEXT: mov r2, r0
+; ARMT2-NEXT: mov r1, r0
; ARMT2-NEXT: .LBB8_2: @ %while.body
; ARMT2-NEXT: @ =>This Inner Loop Header: Depth=1
-; ARMT2-NEXT: add r2, r2, #1
; ARMT2-NEXT: add r1, r1, #1
-; ARMT2-NEXT: uxtb r3, r2
-; ARMT2-NEXT: cmp r3, r0
+; ARMT2-NEXT: add r4, r4, #1
+; ARMT2-NEXT: uxtb r2, r1
+; ARMT2-NEXT: cmp r2, r0
; ARMT2-NEXT: blt .LBB8_2
; ARMT2-NEXT: @ %bb.3: @ %while.end
; ARMT2-NEXT: pop {r4, pc}
@@ -479,14 +477,13 @@ define void @t9(ptr %a, i8 %b) {
; THUMB1-NEXT: cmp r0, r0
; THUMB1-NEXT: bne .LBB8_3
; THUMB1-NEXT: @ %bb.1: @ %while.body.preheader
-; THUMB1-NEXT: adds r1, r4, #1
-; THUMB1-NEXT: mov r2, r0
+; THUMB1-NEXT: mov r1, r0
; THUMB1-NEXT: .LBB8_2: @ %while.body
; THUMB1-NEXT: @ =>This Inner Loop Header: Depth=1
+; THUMB1-NEXT: adds r4, r4, #1
; THUMB1-NEXT: adds r1, r1, #1
-; THUMB1-NEXT: adds r2, r2, #1
-; THUMB1-NEXT: uxtb r3, r2
-; THUMB1-NEXT: cmp r3, r0
+; THUMB1-NEXT: uxtb r2, r1
+; THUMB1-NEXT: cmp r2, r0
; THUMB1-NEXT: blt .LBB8_2
; THUMB1-NEXT: .LBB8_3: @ %while.end
; THUMB1-NEXT: pop {r4, pc}
@@ -503,14 +500,13 @@ define void @t9(ptr %a, i8 %b) {
; THUMB2-NEXT: it ne
; THUMB2-NEXT: popne {r4, pc}
; THUMB2-NEXT: .LBB8_1: @ %while.body.preheader
-; THUMB2-NEXT: adds r1, r4, #1
-; THUMB2-NEXT: mov r2, r0
+; THUMB2-NEXT: mov r1, r0
; THUMB2-NEXT: .LBB8_2: @ %while.body
; THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1
-; THUMB2-NEXT: adds r2, #1
; THUMB2-NEXT: adds r1, #1
-; THUMB2-NEXT: uxtb r3, r2
-; THUMB2-NEXT: cmp r3, r0
+; THUMB2-NEXT: adds r4, #1
+; THUMB2-NEXT: uxtb r2, r1
+; THUMB2-NEXT: cmp r2, r0
; THUMB2-NEXT: blt .LBB8_2
; THUMB2-NEXT: @ %bb.3: @ %while.end
; THUMB2-NEXT: pop {r4, pc}
@@ -527,14 +523,13 @@ define void @t9(ptr %a, i8 %b) {
; V8MBASE-NEXT: cmp r0, r0
; V8MBASE-NEXT: bne .LBB8_3
; V8MBASE-NEXT: @ %bb.1: @ %while.body.preheader
-; V8MBASE-NEXT: adds r1, r4, #1
-; V8MBASE-NEXT: mov r2, r0
+; V8MBASE-NEXT: mov r1, r0
; V8MBASE-NEXT: .LBB8_2: @ %while.body
; V8MBASE-NEXT: @ =>This Inner Loop Header: Depth=1
+; V8MBASE-NEXT: adds r4, r4, #1
; V8MBASE-NEXT: adds r1, r1, #1
-; V8MBASE-NEXT: adds r2, r2, #1
-; V8MBASE-NEXT: uxtb r3, r2
-; V8MBASE-NEXT: cmp r3, r0
+; V8MBASE-NEXT: uxtb r2, r1
+; V8MBASE-NEXT: cmp r2, r0
; V8MBASE-NEXT: blt .LBB8_2
; V8MBASE-NEXT: .LBB8_3: @ %while.end
; V8MBASE-NEXT: pop {r4, pc}
diff --git a/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll b/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
index 4bfd088d22720..982590d408d5a 100644
--- a/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
+++ b/llvm/test/Transforms/IndVarSimplify/iv-widen-addrec-flag-inferred-late.ll
@@ -7,21 +7,22 @@ define i32 @f(ptr %a, i32 %k) {
; CHECK-LABEL: define i32 @f(
; CHECK-SAME: ptr [[A:%.*]], i32 [[K:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[K]] to i64
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[CHECK:.*]] ]
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = zext i32 [[IV]] to i64
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CHECK:.*]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
; CHECK-NEXT: [[DONE:%.*]] = icmp ne i32 [[V]], 0
-; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[IV]], [[K]]
+; CHECK-NEXT: [[LT:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], [[TMP0]]
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[DONE]], i1 [[LT]], i1 false
; CHECK-NEXT: br i1 [[OR_COND]], label %[[CHECK]], label %[[EXIT:.*]]
; CHECK: [[CHECK]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[IV]], %[[LOOP]] ]
+; CHECK-NEXT: [[IV_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], %[[LOOP]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[IV_LCSSA_WIDE]] to i32
; CHECK-NEXT: ret i32 [[TMP1]]
;
entry:
@@ -51,21 +52,22 @@ define i32 @f_sext(ptr %a, i32 %k) {
; CHECK-LABEL: define i32 @f_sext(
; CHECK-SAME: ptr [[A:%.*]], i32 [[K:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[K]] to i64
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[CHECK:.*]] ]
-; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[IV]] to i64
+; CHECK-NEXT: [[IDX:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CHECK:.*]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[IDX]]
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
; CHECK-NEXT: [[DONE:%.*]] = icmp ne i32 [[V]], 0
-; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[IV]], [[K]]
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[IDX]], [[TMP0]]
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[DONE]], i1 [[LT]], i1 false
; CHECK-NEXT: br i1 [[OR_COND]], label %[[CHECK]], label %[[EXIT:.*]]
; CHECK: [[CHECK]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[IDX]], 1
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], %[[LOOP]] ]
+; CHECK-NEXT: [[IV_LCSSA_WIDE:%.*]] = phi i64 [ [[IDX]], %[[LOOP]] ]
+; CHECK-NEXT: [[IV_LCSSA:%.*]] = trunc nuw nsw i64 [[IV_LCSSA_WIDE]] to i32
; CHECK-NEXT: ret i32 [[IV_LCSSA]]
;
entry:
More information about the llvm-commits
mailing list