[llvm] [VPlan] Create edge mask for single-destination switch (PR #179107)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 1 19:47:48 PST 2026
================
@@ -508,19 +508,88 @@ define void @switch_unconditional(ptr %start) {
; IC2: [[EXIT]]:
; IC2-NEXT: ret void
;
+entry:
+ br label %loop.header
+
+loop.header:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
+ %gep = getelementptr i32, ptr %start, i64 %iv
+ %x = load i32, ptr %gep
+ switch i32 %x, label %foo []
+
+foo:
+ br label %loop.latch
+
+loop.latch:
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp eq i64 %iv.next, 100
+ br i1 %cmp, label %exit, label %loop.header
+
+exit:
+ ret void
+}
+
+define void @switch_unconditional_duplicate_target(ptr %start) {
+; IC1-LABEL: define void @switch_unconditional_duplicate_target(
+; IC1-SAME: ptr [[START:%.*]]) {
+; IC1-NEXT: [[ENTRY:.*:]]
+; IC1-NEXT: br label %[[VECTOR_PH:.*]]
+; IC1: [[VECTOR_PH]]:
+; IC1-NEXT: br label %[[VECTOR_BODY:.*]]
+; IC1: [[VECTOR_BODY]]:
+; IC1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; IC1-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; IC1-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[START]], <2 x i64> [[VEC_IND]]
+; IC1-NEXT: [[TMP1:%.*]] = extractelement <2 x ptr> [[TMP0]], i32 0
+; IC1-NEXT: store <2 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; IC1-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
+; IC1-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
+; IC1-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
+; IC1-NEXT: br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
+; IC1: [[MIDDLE_BLOCK]]:
+; IC1-NEXT: br label %[[EXIT:.*]]
+; IC1: [[EXIT]]:
+; IC1-NEXT: ret void
+;
+; IC2-LABEL: define void @switch_unconditional_duplicate_target(
+; IC2-SAME: ptr [[START:%.*]]) {
+; IC2-NEXT: [[ENTRY:.*:]]
+; IC2-NEXT: br label %[[VECTOR_PH:.*]]
+; IC2: [[VECTOR_PH]]:
+; IC2-NEXT: br label %[[VECTOR_BODY:.*]]
+; IC2: [[VECTOR_BODY]]:
+; IC2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; IC2-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; IC2-NEXT: [[STEP_ADD:%.*]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
+; IC2-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[START]], <2 x i64> [[VEC_IND]]
+; IC2-NEXT: [[TMP1:%.*]] = extractelement <2 x ptr> [[TMP0]], i32 0
+; IC2-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[TMP1]], i64 2
+; IC2-NEXT: store <2 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; IC2-NEXT: store <2 x i32> zeroinitializer, ptr [[TMP2]], align 4
+; IC2-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; IC2-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[STEP_ADD]], splat (i64 2)
+; IC2-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
+; IC2-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
+; IC2: [[MIDDLE_BLOCK]]:
+; IC2-NEXT: br label %[[EXIT:.*]]
+; IC2: [[EXIT]]:
+; IC2-NEXT: ret void
+;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
%gep = getelementptr i32, ptr %start, i64 %iv
%x = load i32, ptr %gep
- switch i32 %x, label %foo []
+ br i1 0, label %forward, label %latch
-foo:
- br label %latch
+forward:
+ switch i32 %x, label %latch [ i32 0, label %latch ]
latch:
+ %gep.1 = phi ptr [ %gep, %loop ], [ null, %forward ], [ null, %forward ]
----------------
lukel97 wrote:
Might be good to replace the nulls with an ptr type argument since stores to null in the default address space are UB IIRC
https://github.com/llvm/llvm-project/pull/179107
More information about the llvm-commits
mailing list