Skip to content

Commit f8742b8

Browse files
authored
[SCEV] Teach SCEVExpander to use zext nneg when possible (#70815)
zext nneg was recently added to the IR in #67982. Teaching SCEVExpander to emit nneg when possible is valuable since SCEV may have proved non-trivial facts about loop bounds which would otherwise be lost when materializing the value.
1 parent 6be0e97 commit f8742b8

File tree

8 files changed

+19
-16
lines changed

8 files changed

+19
-16
lines changed

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,10 @@ Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
12931293

12941294
Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
12951295
Value *V = expand(S->getOperand());
1296-
return Builder.CreateZExt(V, S->getType());
1296+
auto *Res = Builder.CreateZExt(V, S->getType());
1297+
if (auto *I = dyn_cast<Instruction>(Res))
1298+
I->setNonNeg(SE.isKnownNonNegative(S->getOperand()));
1299+
return Res;
12971300
}
12981301

12991302
Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) {

llvm/test/Transforms/IRCE/iv-plus-offset-range-check.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ define i8 @test_overflow_check_runtime(i8 %limit, ptr %p) {
10881088
; CHECK-NEXT: [[SMAX2:%.*]] = call i8 @llvm.smax.i8(i8 [[SMIN]], i8 -1)
10891089
; CHECK-NEXT: [[TMP4:%.*]] = add nsw i8 [[SMAX2]], 1
10901090
; CHECK-NEXT: [[TMP5:%.*]] = mul i8 [[TMP2]], [[TMP4]]
1091-
; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[N]] to i16
1091+
; CHECK-NEXT: [[TMP6:%.*]] = zext nneg i8 [[N]] to i16
10921092
; CHECK-NEXT: [[TMP7:%.*]] = sub i16 124, [[TMP6]]
10931093
; CHECK-NEXT: [[SMIN3:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP7]], i16 0)
10941094
; CHECK-NEXT: [[TMP8:%.*]] = trunc i16 [[SMIN3]] to i8

llvm/test/Transforms/IRCE/wide_indvar.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ define i32 @test_increasing_slt_slt_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
125125
; CHECK-NEXT: entry:
126126
; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6:![0-9]+]]
127127
; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7:![0-9]+]]
128-
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
128+
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64
129129
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 [[TMP0]])
130130
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
131131
; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
@@ -217,7 +217,7 @@ define i32 @test_increasing_slt_slt_wide_general(ptr %n_ptr, ptr %m_ptr) {
217217
; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
218218
; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1
219219
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
220-
; CHECK-NEXT: [[TMP4:%.*]] = zext i32 [[N]] to i64
220+
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64
221221
; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
222222
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 0)
223223
; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
@@ -309,7 +309,7 @@ define i32 @test_increasing_slt_slt_wide_general_preloop(ptr %n_ptr, ptr %m_ptr)
309309
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M]], [[SMAX1]]
310310
; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX]], 1
311311
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
312-
; CHECK-NEXT: [[TMP4:%.*]] = zext i32 [[N]] to i64
312+
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64
313313
; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
314314
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 -1)
315315
; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 -1, [[EXIT_PRELOOP_AT]]
@@ -456,7 +456,7 @@ define i32 @test_increasing_slt_slt_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr
456456
; CHECK-NEXT: [[TMP14:%.*]] = add nsw i64 [[SMAX12]], 1
457457
; CHECK-NEXT: [[TMP15:%.*]] = mul i64 [[TMP13]], [[TMP14]]
458458
; CHECK-NEXT: [[SMIN13:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN9]], i64 [[TMP15]])
459-
; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[N]] to i64
459+
; CHECK-NEXT: [[TMP16:%.*]] = zext nneg i32 [[N]] to i64
460460
; CHECK-NEXT: [[SMIN14:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN13]], i64 [[TMP16]])
461461
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN14]], i64 0)
462462
; CHECK-NEXT: [[TMP17:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
@@ -719,7 +719,7 @@ define i32 @test_increasing_ult_ult_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
719719
; CHECK-NEXT: entry:
720720
; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
721721
; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7]]
722-
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
722+
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64
723723
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[M]], i64 [[TMP0]])
724724
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
725725
; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
@@ -809,7 +809,7 @@ define i32 @test_increasing_ult_ult_wide_general(ptr %n_ptr, ptr %m_ptr) {
809809
; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
810810
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1
811811
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]
812-
; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[N]] to i64
812+
; CHECK-NEXT: [[TMP3:%.*]] = zext nneg i32 [[N]] to i64
813813
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP3]])
814814
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
815815
; CHECK-NEXT: br i1 [[TMP4]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
@@ -918,7 +918,7 @@ define i32 @test_increasing_ult_ult_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr
918918
; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[SMAX7]], 1
919919
; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
920920
; CHECK-NEXT: [[UMIN8:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN5]], i64 [[TMP11]])
921-
; CHECK-NEXT: [[TMP12:%.*]] = zext i32 [[N]] to i64
921+
; CHECK-NEXT: [[TMP12:%.*]] = zext nneg i32 [[N]] to i64
922922
; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN8]], i64 [[TMP12]])
923923
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
924924
; CHECK-NEXT: br i1 [[TMP13]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]

llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ define void @promote_latch_condition_decrementing_loop_02(ptr %p, ptr %a) {
230230
; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0
231231
; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]]
232232
; CHECK: preheader:
233-
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[LEN]] to i64
233+
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[LEN]] to i64
234234
; CHECK-NEXT: br label [[LOOP:%.*]]
235235
; CHECK: loopexit.loopexit:
236236
; CHECK-NEXT: br label [[LOOPEXIT]]
@@ -273,7 +273,7 @@ define void @promote_latch_condition_decrementing_loop_03(ptr %p, ptr %a) {
273273
; CHECK-NEXT: [[ZERO_CHECK:%.*]] = icmp eq i32 [[LEN]], 0
274274
; CHECK-NEXT: br i1 [[ZERO_CHECK]], label [[LOOPEXIT:%.*]], label [[PREHEADER:%.*]]
275275
; CHECK: preheader:
276-
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[LEN]] to i64
276+
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[LEN]] to i64
277277
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1
278278
; CHECK-NEXT: br label [[LOOP:%.*]]
279279
; CHECK: loopexit.loopexit:

llvm/test/Transforms/IndVarSimplify/zext-nuw.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ define void @_Z3fn1v() {
1616
; CHECK-NEXT: br label [[DOTPREHEADER4_LR_PH:%.*]]
1717
; CHECK: .preheader4.lr.ph:
1818
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X4]], -1
19-
; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
19+
; CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64
2020
; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 1
2121
; CHECK-NEXT: [[TMP4:%.*]] = sext i8 [[J_SROA_0_0_COPYLOAD]] to i64
2222
; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP3]], [[TMP4]]

llvm/test/Transforms/LoopIdiom/X86/memset-size-compute.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define void @test(ptr %ptr) {
1717
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 8
1818
; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LIM_0]], i32 2)
1919
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[UMAX]], -1
20-
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
20+
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TMP0]] to i64
2121
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP1]], 3
2222
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[SCEVGEP]], i8 0, i64 [[TMP2]], i1 false)
2323
; CHECK-NEXT: br label [[FOR_BODY:%.*]]

llvm/test/Transforms/LoopVectorize/reduction.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,7 @@ define i64 @reduction_with_phi_with_one_incoming_on_backedge(i16 %n, ptr %A) {
12001200
; CHECK-NEXT: entry:
12011201
; CHECK-NEXT: [[SMAX:%.*]] = call i16 @llvm.smax.i16(i16 [[N]], i16 2)
12021202
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i16 [[SMAX]], -1
1203-
; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32
1203+
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i16 [[TMP0]] to i32
12041204
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i16 [[SMAX]], 5
12051205
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12061206
; CHECK: vector.ph:
@@ -1278,7 +1278,7 @@ define i64 @reduction_with_phi_with_two_incoming_on_backedge(i16 %n, ptr %A) {
12781278
; CHECK-NEXT: entry:
12791279
; CHECK-NEXT: [[SMAX:%.*]] = call i16 @llvm.smax.i16(i16 [[N]], i16 2)
12801280
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i16 [[SMAX]], -1
1281-
; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32
1281+
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i16 [[TMP0]] to i32
12821282
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i16 [[SMAX]], 5
12831283
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12841284
; CHECK: vector.ph:

polly/test/CodeGen/partial_write_in_region_with_loop.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
; CHECK:polly.stmt.bb3:
1010
; CHECK-NEXT: %polly.subregion.iv = phi i32 [ %polly.subregion.iv.inc, %polly.stmt.bb5.cont ], [ 0, %polly.stmt.bb3.entry ]
1111
; CHECK-NEXT: %polly.j.0 = phi i64 [ %j.0.phiops.reload, %polly.stmt.bb3.entry ], [ %p_tmp10, %polly.stmt.bb5.cont ]
12-
; CHECK-NEXT: %8 = zext i64 %polly.indvar to i65
12+
; CHECK-NEXT: %8 = zext nneg i64 %polly.indvar to i65
1313
; CHECK-NEXT: %9 = add nsw i64 %polly.indvar, -1
1414
; CHECK-NEXT: %10 = zext i64 %9 to i65
1515
; CHECK-NEXT: %11 = mul i65 %8, %10

0 commit comments

Comments
 (0)