Skip to content

Commit 5a8d182

Browse files
committed
[VPlan] Don't build recipes for unconditional switches
In #157322 we crash because we try to infer a type for a VPReplicate switch recipe. My understanding was that these switches should be removed by VPlanPredicator, but this switch survived through it because it was unconditional, i.e. had no cases other than the default case. This fixes #157322 by not emitting any recipes for unconditional switches to begin with, similar to how we treat unconditional branches.
1 parent 8704e55 commit 5a8d182

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
193193
}
194194

195195
if (auto *SI = dyn_cast<SwitchInst>(Inst)) {
196+
// Don't emit recipes for unconditional switch instructions.
197+
if (SI->getNumCases() == 0)
198+
continue;
196199
SmallVector<VPValue *> Ops = {getOrCreateVPOperand(SI->getCondition())};
197200
for (auto Case : SI->cases())
198201
Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));

llvm/test/Transforms/LoopVectorize/predicate-switch.ll

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,18 +490,106 @@ loop.latch:
490490
exit:
491491
ret void
492492
}
493+
494+
define void @switch_unconditional(ptr %start) {
495+
; IC1-LABEL: define void @switch_unconditional(
496+
; IC1-SAME: ptr [[START:%.*]]) {
497+
; IC1-NEXT: [[ENTRY:.*:]]
498+
; IC1-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
499+
; IC1: [[VECTOR_PH]]:
500+
; IC1-NEXT: br label %[[VECTOR_BODY:.*]]
501+
; IC1: [[VECTOR_BODY]]:
502+
; IC1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
503+
; IC1-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
504+
; IC1-NEXT: [[TMP0:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
505+
; IC1-NEXT: br i1 [[TMP0]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
506+
; IC1: [[MIDDLE_BLOCK]]:
507+
; IC1-NEXT: br label %[[EXIT:.*]]
508+
; IC1: [[SCALAR_PH]]:
509+
; IC1-NEXT: br label %[[LOOP:.*]]
510+
; IC1: [[LOOP]]:
511+
; IC1-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]
512+
; IC1-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[START]], i64 [[IV]]
513+
; IC1-NEXT: [[X:%.*]] = load i32, ptr [[GEP]], align 4
514+
; IC1-NEXT: switch i32 [[X]], label %[[FOO:.*]] [
515+
; IC1-NEXT: ]
516+
; IC1: [[FOO]]:
517+
; IC1-NEXT: br label %[[LATCH]]
518+
; IC1: [[LATCH]]:
519+
; IC1-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
520+
; IC1-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], 100
521+
; IC1-NEXT: br i1 [[CMP]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]
522+
; IC1: [[EXIT]]:
523+
; IC1-NEXT: ret void
524+
;
525+
; IC2-LABEL: define void @switch_unconditional(
526+
; IC2-SAME: ptr [[START:%.*]]) {
527+
; IC2-NEXT: [[ENTRY:.*:]]
528+
; IC2-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
529+
; IC2: [[VECTOR_PH]]:
530+
; IC2-NEXT: br label %[[VECTOR_BODY:.*]]
531+
; IC2: [[VECTOR_BODY]]:
532+
; IC2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
533+
; IC2-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
534+
; IC2-NEXT: [[TMP0:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
535+
; IC2-NEXT: br i1 [[TMP0]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
536+
; IC2: [[MIDDLE_BLOCK]]:
537+
; IC2-NEXT: br label %[[EXIT:.*]]
538+
; IC2: [[SCALAR_PH]]:
539+
; IC2-NEXT: br label %[[LOOP:.*]]
540+
; IC2: [[LOOP]]:
541+
; IC2-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]
542+
; IC2-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[START]], i64 [[IV]]
543+
; IC2-NEXT: [[X:%.*]] = load i32, ptr [[GEP]], align 4
544+
; IC2-NEXT: switch i32 [[X]], label %[[FOO:.*]] [
545+
; IC2-NEXT: ]
546+
; IC2: [[FOO]]:
547+
; IC2-NEXT: br label %[[LATCH]]
548+
; IC2: [[LATCH]]:
549+
; IC2-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
550+
; IC2-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], 100
551+
; IC2-NEXT: br i1 [[CMP]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]
552+
; IC2: [[EXIT]]:
553+
; IC2-NEXT: ret void
554+
;
555+
entry:
556+
br label %loop
557+
558+
loop:
559+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
560+
%gep = getelementptr i32, ptr %start, i64 %iv
561+
%x = load i32, ptr %gep
562+
switch i32 %x, label %foo []
563+
564+
foo:
565+
br label %latch
566+
567+
latch:
568+
%iv.next = add i64 %iv, 1
569+
%cmp = icmp eq i64 %iv.next, 100
570+
br i1 %cmp, label %exit, label %loop
571+
572+
exit:
573+
ret void
574+
}
575+
576+
493577
;.
494578
; IC1: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
495579
; IC1: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
496580
; IC1: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
497581
; IC1: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
498582
; IC1: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
499583
; IC1: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
584+
; IC1: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
585+
; IC1: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]}
500586
;.
501587
; IC2: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
502588
; IC2: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
503589
; IC2: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
504590
; IC2: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
505591
; IC2: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
506592
; IC2: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
593+
; IC2: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
594+
; IC2: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]}
507595
;.

0 commit comments

Comments
 (0)