Skip to content

Commit d732965

Browse files
author
Evgeniy Brevnov
committed
[VPlan] Allow sinking of instructions with no defs
We started seeing new failure after D142886. Looks like it enabled new cases and we hit an assert: assert(Current->getNumDefinedValues() == 1 && "only recipes with a single defined value expected"); When we do instruction sinking for the first order recurrence we hit an assert if instruction doesn't have single def. In case instruction doesn't produce any new def there is no new users and nothing to sink. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D151204
1 parent 1f082d2 commit d732965

File tree

3 files changed

+43
-42
lines changed

3 files changed

+43
-42
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,9 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
664664
properlyDominates(Previous, SinkCandidate, VPDT))
665665
return true;
666666

667+
if (SinkCandidate->mayHaveSideEffects())
668+
return false;
669+
667670
WorkList.push_back(SinkCandidate);
668671
return true;
669672
};
@@ -674,6 +677,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
674677
VPRecipeBase *Current = WorkList[I];
675678
assert(Current->getNumDefinedValues() == 1 &&
676679
"only recipes with a single defined value expected");
680+
677681
for (VPUser *User : Current->getVPSingleValue()->users()) {
678682
if (auto *R = dyn_cast<VPRecipeBase>(User))
679683
if (!TryToPushSinkCandidate(R))

llvm/test/Transforms/LoopVectorize/first-order-recurrence-chains-vplan.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,33 @@ loop:
108108
exit:
109109
ret void
110110
}
111+
112+
; This test has two FORs (for.x and for.y) where incoming value from the previous
113+
; iteration (for.x.prev) of one FOR (for.y) depends on another FOR (for.x). Due to
114+
; this dependency all uses of the former FOR (for.y) should be sunk after
115+
; incoming value from the previous iteration (for.x.prev) of te latter FOR (for.y).
116+
; That means side-effecting user (store i64 %for.y.i64, ptr %gep) of the latter
117+
; FOR (for.y) should be moved which is not currently supported.
118+
define i32 @test_chained_first_order_recurrences_4(ptr %base) {
119+
; CHECK-LABEL: 'test_chained_first_order_recurrences_4'
120+
; CHECK: No VPlan could be built for
121+
122+
entry:
123+
br label %loop
124+
125+
ret:
126+
ret i32 0
127+
128+
loop:
129+
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
130+
%for.x = phi i64 [ %for.x.next, %loop ], [ 0, %entry ]
131+
%for.y = phi i32 [ %for.x.prev, %loop ], [ 0, %entry ]
132+
%iv.next = add i64 %iv, 1
133+
%gep = getelementptr i64, ptr %base, i64 %iv
134+
%for.x.prev = trunc i64 %for.x to i32
135+
%for.y.i64 = sext i32 %for.y to i64
136+
store i64 %for.y.i64, ptr %gep
137+
%for.x.next = mul i64 0, 0
138+
%icmp = icmp ugt i64 %iv, 4096
139+
br i1 %icmp, label %ret, label %loop
140+
}

llvm/test/Transforms/LoopVectorize/first-order-recurrence-multiply-recurrences.ll

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -221,55 +221,22 @@ exit:
221221
define void @test_pr54233_for_depend_on_each_other(ptr noalias %a, ptr noalias %b) {
222222
; CHECK-LABEL: @test_pr54233_for_depend_on_each_other(
223223
; CHECK-NEXT: entry:
224-
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
225-
; CHECK: vector.ph:
226-
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
227-
; CHECK: vector.body:
228-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
229-
; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 0>, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
230-
; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 0>, [[VECTOR_PH]] ], [ [[BROADCAST_SPLAT:%.*]], [[VECTOR_BODY]] ]
231-
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
232-
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B:%.*]], align 4
233-
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[TMP1]], i64 0
234-
; CHECK-NEXT: [[BROADCAST_SPLAT]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
235-
; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR1]], <4 x i32> [[BROADCAST_SPLAT]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
236-
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP2]], <i32 10, i32 10, i32 10, i32 10>
237-
; CHECK-NEXT: [[TMP4]] = xor <4 x i32> <i32 12, i32 12, i32 12, i32 12>, [[TMP2]]
238-
; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR]], <4 x i32> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
239-
; CHECK-NEXT: [[TMP6:%.*]] = shl <4 x i32> [[TMP2]], [[TMP5]]
240-
; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i32> [[TMP6]], <i32 255, i32 255, i32 255, i32 255>
241-
; CHECK-NEXT: [[TMP8:%.*]] = and <4 x i32> [[TMP7]], [[TMP3]]
242-
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]]
243-
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i32, ptr [[TMP9]], i32 0
244-
; CHECK-NEXT: store <4 x i32> [[TMP8]], ptr [[TMP10]], align 4
245-
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
246-
; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
247-
; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
248-
; CHECK: middle.block:
249-
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1001, 1000
250-
; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i32> [[TMP4]], i32 3
251-
; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT2:%.*]] = extractelement <4 x i32> [[BROADCAST_SPLAT]], i32 3
252-
; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
253-
; CHECK: scalar.ph:
254-
; CHECK-NEXT: [[SCALAR_RECUR_INIT3:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VECTOR_RECUR_EXTRACT2]], [[MIDDLE_BLOCK]] ]
255-
; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ]
256-
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
257224
; CHECK-NEXT: br label [[LOOP:%.*]]
258225
; CHECK: loop:
259-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
260-
; CHECK-NEXT: [[SCALAR_RECUR:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[FOR_1_NEXT:%.*]], [[LOOP]] ]
261-
; CHECK-NEXT: [[SCALAR_RECUR4:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT3]], [[SCALAR_PH]] ], [ [[FOR_2_NEXT:%.*]], [[LOOP]] ]
262-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SCALAR_RECUR4]], 10
263-
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[SCALAR_RECUR4]], [[SCALAR_RECUR]]
226+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
227+
; CHECK-NEXT: [[FOR_1:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_1_NEXT:%.*]], [[LOOP]] ]
228+
; CHECK-NEXT: [[FOR_2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_2_NEXT:%.*]], [[LOOP]] ]
229+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[FOR_2]], 10
230+
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[FOR_2]], [[FOR_1]]
264231
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], 255
265232
; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[OR]]
266-
; CHECK-NEXT: [[FOR_1_NEXT]] = xor i32 12, [[SCALAR_RECUR4]]
267-
; CHECK-NEXT: [[FOR_2_NEXT]] = load i32, ptr [[B]], align 4
268-
; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]
233+
; CHECK-NEXT: [[FOR_1_NEXT]] = xor i32 12, [[FOR_2]]
234+
; CHECK-NEXT: [[FOR_2_NEXT]] = load i32, ptr [[B:%.*]], align 4
235+
; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IV]]
269236
; CHECK-NEXT: store i32 [[AND]], ptr [[A_GEP]], align 4
270237
; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
271238
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[IV]], 1000
272-
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
239+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]
273240
; CHECK: exit:
274241
; CHECK-NEXT: ret void
275242
;

0 commit comments

Comments
 (0)