Skip to content

Commit 4f7f71b

Browse files
committed
[VPlan] Compare APInt instead of getSExtValue to fix crash in unroll.
getSExtValue assumes the result fits in 64 bits, but this may not be the case for indcutions with wider types. Instead, directly perform the compare on the APInt for the ConstantInt. Fixes llvm#118850.
1 parent 9ad22cf commit 4f7f71b

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void UnrollState::unrollWidenInductionByUF(
168168
auto *ConstStep = ScalarStep->isLiveIn()
169169
? dyn_cast<ConstantInt>(ScalarStep->getLiveInIRValue())
170170
: nullptr;
171-
if (!ConstStep || ConstStep->getZExtValue() != 1) {
171+
if (!ConstStep || ConstStep->getValue() != 1) {
172172
if (TypeInfo.inferScalarType(ScalarStep) != IVTy) {
173173
ScalarStep =
174174
Builder.createWidenCast(Instruction::Trunc, ScalarStep, IVTy);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=2 -S %s | FileCheck %s
3+
4+
; Test case for https://github.com/llvm/llvm-project/issues/118850.
5+
define void @i65_induction_with_negative_step(ptr %dst) {
6+
; CHECK-LABEL: define void @i65_induction_with_negative_step(
7+
; CHECK-SAME: ptr [[DST:%.*]]) {
8+
; CHECK-NEXT: [[ENTRY:.*]]:
9+
; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
10+
; CHECK: [[VECTOR_PH]]:
11+
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
12+
; CHECK: [[VECTOR_BODY]]:
13+
; CHECK-NEXT: [[INDEX:%.*]] = phi i65 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
14+
; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 0>, %[[VECTOR_PH]] ], [ [[STEP_ADD:%.*]], %[[VECTOR_BODY]] ]
15+
; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 -1, i64 -2, i64 -3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
16+
; CHECK-NEXT: [[STEP_ADD]] = add <4 x i64> [[VEC_IND]], splat (i64 -4)
17+
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = sub i65 0, [[INDEX]]
18+
; CHECK-NEXT: [[TMP0:%.*]] = trunc i65 [[OFFSET_IDX]] to i64
19+
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 0
20+
; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i64> [[VECTOR_RECUR]], <4 x i64> [[VEC_IND]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
21+
; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i64> [[VEC_IND]], <4 x i64> [[STEP_ADD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
22+
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[TMP1]]
23+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[TMP4]], i32 0
24+
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[TMP5]], i32 -3
25+
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[TMP4]], i32 -4
26+
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 -3
27+
; CHECK-NEXT: [[REVERSE:%.*]] = shufflevector <4 x i64> [[TMP2]], <4 x i64> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
28+
; CHECK-NEXT: store <4 x i64> [[REVERSE]], ptr [[TMP6]], align 8
29+
; CHECK-NEXT: [[REVERSE1:%.*]] = shufflevector <4 x i64> [[TMP3]], <4 x i64> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
30+
; CHECK-NEXT: store <4 x i64> [[REVERSE1]], ptr [[TMP8]], align 8
31+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i65 [[INDEX]], 8
32+
; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[STEP_ADD]], splat (i64 -4)
33+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i65 [[INDEX_NEXT]], 1000
34+
; CHECK-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
35+
; CHECK: [[MIDDLE_BLOCK]]:
36+
; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i64> [[STEP_ADD]], i32 3
37+
; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
38+
; CHECK: [[SCALAR_PH]]:
39+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
40+
; CHECK-NEXT: [[BC_RESUME_VAL2:%.*]] = phi i65 [ -1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
41+
; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[VECTOR_RECUR_EXTRACT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
42+
; CHECK-NEXT: br label %[[LOOP:.*]]
43+
; CHECK: [[LOOP]]:
44+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
45+
; CHECK-NEXT: [[IV_I65:%.*]] = phi i65 [ [[BC_RESUME_VAL2]], %[[SCALAR_PH]] ], [ [[IV_I65_NEXT:%.*]], %[[LOOP]] ]
46+
; CHECK-NEXT: [[FOR:%.*]] = phi i64 [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[TRUNC:%.*]], %[[LOOP]] ]
47+
; CHECK-NEXT: [[TRUNC]] = trunc i65 [[IV_I65]] to i64
48+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[TRUNC]]
49+
; CHECK-NEXT: store i64 [[FOR]], ptr [[GEP]], align 8
50+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
51+
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
52+
; CHECK-NEXT: [[IV_I65_NEXT]] = add i65 [[IV_I65]], -1
53+
; CHECK-NEXT: br i1 [[ICMP]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
54+
; CHECK: [[EXIT]]:
55+
; CHECK-NEXT: ret void
56+
;
57+
entry:
58+
br label %loop
59+
60+
loop:
61+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
62+
%iv.i65 = phi i65 [ 0, %entry ], [ %iv.i65.next, %loop ]
63+
%for = phi i64 [ 0, %entry ], [ %trunc, %loop ]
64+
%trunc = trunc i65 %iv.i65 to i64
65+
%gep = getelementptr inbounds i64, ptr %dst, i64 %trunc
66+
store i64 %for, ptr %gep, align 8
67+
%iv.next = add i64 %iv, 1
68+
%icmp = icmp eq i64 %iv.next, 1000
69+
%iv.i65.next = add i65 %iv.i65, -1
70+
br i1 %icmp, label %exit, label %loop
71+
72+
exit:
73+
ret void
74+
}
75+
;.
76+
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
77+
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
78+
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
79+
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
80+
;.

0 commit comments

Comments
 (0)