[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
Thu Jul 16 09:13:17 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