Skip to content

Commit 4e98944

Browse files
committed
[VPlan] Truncate VFxUF if needed in VPWidenPointerInduction::execute.
Create truncate if needed after 56b05a0. Note that this preserves the original behavior pre 56b05a0. If truncate would strip any set bits, then the explicit computation in the narrower type would wrap.
1 parent dc9a183 commit 4e98944

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,8 +3366,10 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
33663366

33673367
Value *InductionGEP = GetElementPtrInst::Create(
33683368
State.Builder.getInt8Ty(), NewPointerPhi,
3369-
State.Builder.CreateMul(ScalarStepValue, NumUnrolledElems), "ptr.ind",
3370-
InductionLoc);
3369+
State.Builder.CreateMul(
3370+
ScalarStepValue,
3371+
State.Builder.CreateTrunc(NumUnrolledElems, PhiType)),
3372+
"ptr.ind", InductionLoc);
33713373

33723374
NewPointerPhi->addIncoming(InductionGEP, VectorPH);
33733375
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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 -S %s | FileCheck %s
3+
4+
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
5+
6+
; Test case where the pointer index with is 32 bits, but the main IV is 64 bit.
7+
; Make sure VFxUF is adjusted accordingly.
8+
define void @wide_ptr_induction_index_width_smaller_than_iv_width(ptr noalias %src, ptr noalias %dst.0, ptr noalias %dst.1) {
9+
; CHECK-LABEL: define void @wide_ptr_induction_index_width_smaller_than_iv_width(
10+
; CHECK-SAME: ptr noalias [[SRC:%.*]], ptr noalias [[DST_0:%.*]], ptr noalias [[DST_1:%.*]]) {
11+
; CHECK-NEXT: [[ENTRY:.*]]:
12+
; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
13+
; CHECK: [[VECTOR_PH]]:
14+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[SRC]], i32 800
15+
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
16+
; CHECK: [[VECTOR_BODY]]:
17+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
18+
; CHECK-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[SRC]], %[[VECTOR_PH]] ], [ [[PTR_IND:%.*]], %[[VECTOR_BODY]] ]
19+
; CHECK-NEXT: [[VECTOR_GEP:%.*]] = getelementptr i8, ptr [[POINTER_PHI]], <4 x i32> <i32 0, i32 8, i32 16, i32 24>
20+
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 0
21+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[INDEX]], 1
22+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[INDEX]], 2
23+
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 3
24+
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x ptr> [[VECTOR_GEP]], i32 0
25+
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i64, ptr [[TMP5]], i32 0
26+
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP6]], align 1
27+
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[DST_0]], i64 [[TMP1]]
28+
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[DST_0]], i64 [[TMP2]]
29+
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, ptr [[DST_0]], i64 [[TMP3]]
30+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, ptr [[DST_0]], i64 [[TMP4]]
31+
; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
32+
; CHECK-NEXT: store <4 x i64> [[WIDE_LOAD]], ptr [[TMP11]], align 8
33+
; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP7]], align 8
34+
; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x ptr> [[VECTOR_GEP]], i32 1
35+
; CHECK-NEXT: store ptr [[TMP12]], ptr [[TMP8]], align 8
36+
; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x ptr> [[VECTOR_GEP]], i32 2
37+
; CHECK-NEXT: store ptr [[TMP13]], ptr [[TMP9]], align 8
38+
; CHECK-NEXT: [[TMP14:%.*]] = extractelement <4 x ptr> [[VECTOR_GEP]], i32 3
39+
; CHECK-NEXT: store ptr [[TMP14]], ptr [[TMP10]], align 8
40+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
41+
; CHECK-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i32 32
42+
; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
43+
; CHECK-NEXT: br i1 [[TMP15]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
44+
; CHECK: [[MIDDLE_BLOCK]]:
45+
; CHECK-NEXT: br i1 false, label %[[EXIT:.*]], label %[[SCALAR_PH]]
46+
; CHECK: [[SCALAR_PH]]:
47+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 100, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
48+
; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi ptr [ [[TMP0]], %[[MIDDLE_BLOCK]] ], [ [[SRC]], %[[ENTRY]] ]
49+
; CHECK-NEXT: br label %[[LOOP:.*]]
50+
; CHECK: [[LOOP]]:
51+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
52+
; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[BC_RESUME_VAL1]], %[[SCALAR_PH]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
53+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[PTR_IV]], align 1
54+
; CHECK-NEXT: [[GEP_DST_1:%.*]] = getelementptr inbounds i64, ptr [[DST_0]], i64 [[IV]]
55+
; CHECK-NEXT: store i64 [[L]], ptr [[GEP_DST_1]], align 8
56+
; CHECK-NEXT: [[GEP_DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST_1]], i64 [[IV]]
57+
; CHECK-NEXT: store ptr [[PTR_IV]], ptr [[GEP_DST_1]], align 8
58+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
59+
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr i8, ptr [[PTR_IV]], i32 8
60+
; CHECK-NEXT: [[EC:%.*]] = icmp ult i64 [[IV]], 100
61+
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
62+
; CHECK: [[EXIT]]:
63+
; CHECK-NEXT: ret void
64+
;
65+
entry:
66+
br label %loop
67+
68+
loop:
69+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
70+
%ptr.iv = phi ptr [ %src, %entry ], [ %ptr.iv.next, %loop ]
71+
%l = load i64, ptr %ptr.iv, align 1
72+
%gep.dst.1 = getelementptr inbounds i64, ptr %dst.0, i64 %iv
73+
store i64 %l, ptr %gep.dst.1, align 8
74+
%gep.dst.0 = getelementptr inbounds ptr, ptr %dst.1, i64 %iv
75+
store ptr %ptr.iv, ptr %gep.dst.1, align 8
76+
%iv.next = add i64 %iv, 1
77+
%ptr.iv.next = getelementptr i8, ptr %ptr.iv, i32 8
78+
%ec = icmp ult i64 %iv, 100
79+
br i1 %ec, label %loop, label %exit
80+
81+
exit:
82+
ret void
83+
}
84+
;.
85+
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
86+
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
87+
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
88+
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
89+
;.

0 commit comments

Comments
 (0)