[llvm] [SCEV] Generalize A + zext(-A + B) fold to A + zext(C + X) (PR #209160)
Aleksandr Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 07:08:13 PDT 2026
https://github.com/aleks-tmb updated https://github.com/llvm/llvm-project/pull/209160
>From d8566d6a4ba2798d26dd96ff74a4f482a1ec5d21 Mon Sep 17 00:00:00 2001
From: Aleksandr Popov <apopov at azul.com>
Date: Mon, 13 Jul 2026 13:44:29 +0000
Subject: [PATCH 1/3] [SCEV][NFC] Add tests for generalized A + zext(C + X)
fold
---
.../ScalarEvolution/zext-add-nsw-fold.ll | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
index 06e1f48a5f2c4..95c652470b987 100644
--- a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
+++ b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
@@ -283,3 +283,82 @@ define i64 @mul_zext_fold_positive_c(i8 %x) {
%ext = zext i32 %add to i64
ret i64 %ext
}
+
+; A = -5 with min(mul) = 12. The generalized fold pushes the constant out of
+; the ZExt even though A != -C_min, leaving a non-zero wide constant survivor.
+; The old A + zext(-A + B) shape could not fold this.
+define i64 @mul_umax_fold_negative_a_non_cancelling(i8 %x) {
+; CHECK-LABEL: 'mul_umax_fold_negative_a_non_cancelling'
+; CHECK-NEXT: Classifying expressions for: @mul_umax_fold_negative_a_non_cancelling
+; CHECK-NEXT: %zx = zext i8 %x to i32
+; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256)
+; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3)
+; CHECK-NEXT: --> (3 umax (zext i8 %x to i32)) U: [3,256) S: [3,256)
+; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax
+; CHECK-NEXT: --> (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw> U: [12,1021) S: [12,1021)
+; CHECK-NEXT: %add = add nsw i32 -5, %mul
+; CHECK-NEXT: --> (-5 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [7,1016) S: [7,1016)
+; CHECK-NEXT: %ext = zext i32 %add to i64
+; CHECK-NEXT: --> (3 + (zext i32 (-8 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64))<nuw><nsw> U: [7,1016) S: [7,1016)
+; CHECK-NEXT: Determining loop execution counts for: @mul_umax_fold_negative_a_non_cancelling
+;
+ %zx = zext i8 %x to i32
+ %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3)
+ %mul = mul nuw nsw i32 4, %umax
+ %add = add nsw i32 -5, %mul
+ %ext = zext i32 %add to i64
+ ret i64 %ext
+}
+
+; A = -900 with min(mul) = 800: the narrow sum can be as low as -100, so NUW
+; on `-C + (C + X) = X` cannot be proved and the fold must not fire.
+define i64 @mul_umax_no_fold_underflow_possible(i8 %x) {
+; CHECK-LABEL: 'mul_umax_no_fold_underflow_possible'
+; CHECK-NEXT: Classifying expressions for: @mul_umax_no_fold_underflow_possible
+; CHECK-NEXT: %zx = zext i8 %x to i32
+; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256)
+; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 200)
+; CHECK-NEXT: --> (200 umax (zext i8 %x to i32)) U: [200,256) S: [200,256)
+; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax
+; CHECK-NEXT: --> (4 * (200 umax (zext i8 %x to i32)))<nuw><nsw> U: [800,1021) S: [800,1021)
+; CHECK-NEXT: %add = add nsw i32 -900, %mul
+; CHECK-NEXT: --> (-900 + (4 * (200 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [0,-3) S: [-100,121)
+; CHECK-NEXT: %ext = zext i32 %add to i64
+; CHECK-NEXT: --> (zext i32 (-900 + (4 * (200 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64) U: [0,4294967293) S: [0,4294967296)
+; CHECK-NEXT: Determining loop execution counts for: @mul_umax_no_fold_underflow_possible
+;
+ %zx = zext i8 %x to i32
+ %umax = call i32 @llvm.umax.i32(i32 %zx, i32 200)
+ %mul = mul nuw nsw i32 4, %umax
+ %add = add nsw i32 -900, %mul
+ %ext = zext i32 %add to i64
+ ret i64 %ext
+}
+
+; Two chained zexts (i32 -> i64 -> i128). The fold composes: the constant is
+; pushed all the way out to the widest type.
+define i128 @cascading_zext_fold(i8 %x) {
+; CHECK-LABEL: 'cascading_zext_fold'
+; CHECK-NEXT: Classifying expressions for: @cascading_zext_fold
+; CHECK-NEXT: %zx = zext i8 %x to i32
+; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256)
+; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3)
+; CHECK-NEXT: --> (3 umax (zext i8 %x to i32)) U: [3,256) S: [3,256)
+; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax
+; CHECK-NEXT: --> (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw> U: [12,1021) S: [12,1021)
+; CHECK-NEXT: %add32 = add nsw i32 -10, %mul
+; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: %ext64 = zext i32 %add32 to i64
+; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64))<nuw><nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: %ext128 = zext i64 %ext64 to i128
+; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i128))<nuw><nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: Determining loop execution counts for: @cascading_zext_fold
+;
+ %zx = zext i8 %x to i32
+ %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3)
+ %mul = mul nuw nsw i32 4, %umax
+ %add32 = add nsw i32 -10, %mul
+ %ext64 = zext i32 %add32 to i64
+ %ext128 = zext i64 %ext64 to i128
+ ret i128 %ext128
+}
>From a6032b01e8825e9942404d12b8d5963cc8caec49 Mon Sep 17 00:00:00 2001
From: Aleksandr Popov <apopov at azul.com>
Date: Mon, 13 Jul 2026 11:40:29 +0000
Subject: [PATCH 2/3] [SCEV] Generalize A + zext(-A + B) fold to A + zext(C +
X)
Extend the existing fold `A + zext(-A + B) -> zext(B)` to the more
general form `A + zext(C + X) -> (A + sext(C)) + zext(X)`, where C is
any negative constant and A is a constant so that `A + sext(C)` folds
to a single wide constant.
Correctness still relies on NUW of `(-C) + (C + X)`, which proves that
`C + X` does not wrap below zero, so `zext(C + X) == sext(C) + zext(X)`.
Related to #208778
---
llvm/lib/Analysis/ScalarEvolution.cpp | 33 ++++++++++------
.../ScalarEvolution/zext-add-nsw-fold.ll | 2 +-
.../single_early_exit_zext_trip_count.ll | 38 ++++++++++++++++---
3 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 134be6ac097e0..c3b2693fe0373 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2809,17 +2809,28 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
}
- // Try to push the constant operand into a ZExt: A + zext (-A + B) -> zext
- // (B), if trunc (A) + -A + B does not unsigned-wrap.
- const SCEVAddExpr *InnerAdd;
- if (match(B, m_scev_ZExt(m_scev_Add(InnerAdd)))) {
- const SCEV *NarrowA = getTruncateExpr(A, InnerAdd->getType());
- if (NarrowA == getNegativeSCEV(InnerAdd->getOperand(0)) &&
- getZeroExtendExpr(NarrowA, B->getType()) == A &&
- hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
- SCEV::FlagAnyWrap),
- SCEV::FlagNUW)) {
- return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd), B->getType());
+ // Push a negative constant addend out of a ZExt when the inner add is
+ // provably non-negative in the narrow type:
+ //
+ // A + zext(C + X) -> WideAC + zext(X) [WideAC = A + sext(C)]
+ //
+ // Require A to be a constant so that `A + sext(C)` folds into a single wide
+ // constant, actually simplifying the expression.
+ const SCEVAddExpr *Add;
+ if (isa<SCEVConstant>(A) && match(B, m_scev_ZExt(m_scev_Add(Add)))) {
+ const APInt *C;
+ const SCEV *X;
+ if (match(Add, m_scev_Add(m_scev_APInt(C), m_SCEV(X))) &&
+ C->isNegative() &&
+ // NUW on `(-C) + (C + X) = X` proves that `C + X` did not wrap
+ // below zero, so `zext(C + X) == sext(C) + zext(X)`.
+ hasFlags(StrengthenNoWrapFlags(this, scAddExpr,
+ {getConstant(-*C), Add},
+ SCEV::FlagAnyWrap),
+ SCEV::FlagNUW)) {
+ return getAddExpr(
+ A, getSignExtendExpr(getConstant(*C), B->getType()),
+ getZeroExtendExpr(X, B->getType()));
}
}
}
diff --git a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
index 95c652470b987..b433cfe7e5d8c 100644
--- a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
+++ b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
@@ -107,7 +107,7 @@ define i64 @mul_umax_fold_round_up(i8 %x) {
; CHECK-NEXT: %add = add nsw i32 -10, %mul
; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
; CHECK-NEXT: %ext = zext i32 %add to i64
-; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64))<nuw><nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i64)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
; CHECK-NEXT: Determining loop execution counts for: @mul_umax_fold_round_up
;
%zx = zext i8 %x to i32
diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit_zext_trip_count.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit_zext_trip_count.ll
index 59fe0321c0112..fb591fc3787b8 100644
--- a/llvm/test/Transforms/LoopVectorize/single_early_exit_zext_trip_count.ll
+++ b/llvm/test/Transforms/LoopVectorize/single_early_exit_zext_trip_count.ll
@@ -28,17 +28,43 @@ define void @test1(ptr %p) {
; CHECK: [[PREHEADER]]:
; CHECK-NEXT: [[EXIT_32:%.*]] = add nsw i32 [[LEN]], -1
; CHECK-NEXT: [[EXIT:%.*]] = zext i32 [[EXIT_32]] to i64
+; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[EXIT]], 1
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
+; CHECK: [[VECTOR_PH]]:
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ 0, %[[PREHEADER]] ]
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ]
; CHECK-NEXT: [[ELEM_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[BASE]], i64 [[IV]]
-; CHECK-NEXT: [[ELEM:%.*]] = load i8, ptr [[ELEM_PTR]], align 1
+; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[ELEM_PTR]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
+; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP3]])
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV]], 4
+; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP4]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]]
+; CHECK: [[VECTOR_BODY_INTERIM]]:
+; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[LOOP]], !llvm.loop [[LOOP1:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label %[[RET_LOOPEXIT:.*]], label %[[SCALAR_PH]]
+; CHECK: [[VECTOR_EARLY_EXIT]]:
+; CHECK-NEXT: br label %[[RET_LOOPEXIT]]
+; CHECK: [[SCALAR_PH]]:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[PREHEADER]] ]
+; CHECK-NEXT: br label %[[LOOP2:.*]]
+; CHECK: [[LOOP2]]:
+; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]
+; CHECK-NEXT: [[ELEM_PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[BASE]], i64 [[IV1]]
+; CHECK-NEXT: [[ELEM:%.*]] = load i8, ptr [[ELEM_PTR1]], align 1
; CHECK-NEXT: [[IS_TARGET:%.*]] = icmp eq i8 [[ELEM]], 0
-; CHECK-NEXT: br i1 [[IS_TARGET]], label %[[RET_LOOPEXIT:.*]], label %[[LATCH]]
+; CHECK-NEXT: br i1 [[IS_TARGET]], label %[[RET_LOOPEXIT]], label %[[LATCH]]
; CHECK: [[LATCH]]:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
-; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i64 [[IV]], [[EXIT]]
-; CHECK-NEXT: br i1 [[LOOP_COND]], label %[[LOOP]], label %[[RET_LOOPEXIT]]
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
+; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i64 [[IV1]], [[EXIT]]
+; CHECK-NEXT: br i1 [[LOOP_COND]], label %[[LOOP2]], label %[[RET_LOOPEXIT]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: [[RET_LOOPEXIT]]:
; CHECK-NEXT: br label %[[RET]]
; CHECK: [[RET]]:
>From 71688311862010cb3609ceb8fd94c9480a1c77e7 Mon Sep 17 00:00:00 2001
From: Aleksandr Popov <apopov at azul.com>
Date: Mon, 13 Jul 2026 12:23:57 +0000
Subject: [PATCH 3/3] Update tests, apply clang-format
---
llvm/lib/Analysis/ScalarEvolution.cpp | 11 +++++------
.../Analysis/ScalarEvolution/zext-add-nsw-fold.ll | 6 +++---
.../Transforms/IndVarSimplify/scev-update-loop-opt.ll | 6 +++---
3 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index c3b2693fe0373..25bea2180b31d 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2825,12 +2825,11 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
// NUW on `(-C) + (C + X) = X` proves that `C + X` did not wrap
// below zero, so `zext(C + X) == sext(C) + zext(X)`.
hasFlags(StrengthenNoWrapFlags(this, scAddExpr,
- {getConstant(-*C), Add},
- SCEV::FlagAnyWrap),
- SCEV::FlagNUW)) {
- return getAddExpr(
- A, getSignExtendExpr(getConstant(*C), B->getType()),
- getZeroExtendExpr(X, B->getType()));
+ {getConstant(-*C), Add},
+ SCEV::FlagAnyWrap),
+ SCEV::FlagNUW)) {
+ return getAddExpr(A, getSignExtendExpr(getConstant(*C), B->getType()),
+ getZeroExtendExpr(X, B->getType()));
}
}
}
diff --git a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
index b433cfe7e5d8c..b353eb210bfa3 100644
--- a/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
+++ b/llvm/test/Analysis/ScalarEvolution/zext-add-nsw-fold.ll
@@ -299,7 +299,7 @@ define i64 @mul_umax_fold_negative_a_non_cancelling(i8 %x) {
; CHECK-NEXT: %add = add nsw i32 -5, %mul
; CHECK-NEXT: --> (-5 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [7,1016) S: [7,1016)
; CHECK-NEXT: %ext = zext i32 %add to i64
-; CHECK-NEXT: --> (3 + (zext i32 (-8 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64))<nuw><nsw> U: [7,1016) S: [7,1016)
+; CHECK-NEXT: --> (-5 + (4 * (3 umax (zext i8 %x to i64)))<nuw><nsw>)<nsw> U: [7,1016) S: [7,1016)
; CHECK-NEXT: Determining loop execution counts for: @mul_umax_fold_negative_a_non_cancelling
;
%zx = zext i8 %x to i32
@@ -349,9 +349,9 @@ define i128 @cascading_zext_fold(i8 %x) {
; CHECK-NEXT: %add32 = add nsw i32 -10, %mul
; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
; CHECK-NEXT: %ext64 = zext i32 %add32 to i64
-; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i64))<nuw><nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i64)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
; CHECK-NEXT: %ext128 = zext i64 %ext64 to i128
-; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))<nuw><nsw>)<nsw> to i128))<nuw><nsw> U: [2,1011) S: [2,1011)
+; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i128)))<nuw><nsw>)<nsw> U: [2,1011) S: [2,1011)
; CHECK-NEXT: Determining loop execution counts for: @cascading_zext_fold
;
%zx = zext i8 %x to i32
diff --git a/llvm/test/Transforms/IndVarSimplify/scev-update-loop-opt.ll b/llvm/test/Transforms/IndVarSimplify/scev-update-loop-opt.ll
index f716796745fb7..01060490bb0f3 100644
--- a/llvm/test/Transforms/IndVarSimplify/scev-update-loop-opt.ll
+++ b/llvm/test/Transforms/IndVarSimplify/scev-update-loop-opt.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
; RUN: opt %s -passes="loop(loop-idiom,indvars,loop-deletion,loop-unroll-full)" -S | FileCheck %s
; REQUIRES: asserts
@@ -10,15 +10,15 @@ define void @loop_limit_test(i32 %conv5, i1 %cmp13, i1 %cmp20, i1 %cmp27, i1 %cm
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[CONV5]], 1
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
-; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[CONV5]] to i64
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND_LOOPEXIT:.*]]:
; CHECK-NEXT: br label %[[FOR_COND]]
; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[CONV5]] to i64
; CHECK-NEXT: br label %[[FOR_COND2:.*]]
; CHECK: [[FOR_COND2]]:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_COND_CLEANUP14:.*]] ], [ 0, %[[FOR_COND]] ]
-; CHECK-NEXT: [[CMP6:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], [[TMP2]]
+; CHECK-NEXT: [[CMP6:%.*]] = icmp ne i64 [[INDVARS_IV]], [[TMP2]]
; CHECK-NEXT: br i1 [[CMP6]], label %[[FOR_COND9_PREHEADER:.*]], label %[[FOR_COND_LOOPEXIT]]
; CHECK: [[FOR_COND9_PREHEADER]]:
; CHECK-NEXT: br label %[[FOR_COND9:.*]]
More information about the llvm-commits
mailing list