[llvm] [SimplifyCFG] Do not run `simplifySwitchOfPowersOfTwo` in early invocations (PR #145477)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 24 07:16:51 PDT 2025
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/145477
>From f2b8ed3854e691bae94d737ca61b1b44233d8203 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Tue, 24 Jun 2025 15:55:00 +0200
Subject: [PATCH 1/2] [PhaseOrdering] Introduce test for PR145477 (NFC)
---
.../X86/simplifycfg-switch-powers-two-late.ll | 76 +++++++++++++++++++
1 file changed, 76 insertions(+)
create mode 100644 llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll b/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
new file mode 100644
index 0000000000000..d31621536e289
--- /dev/null
+++ b/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
@@ -0,0 +1,76 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes="default<O2>" -S < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @simplifycfg_switch_power_two_late_optimized(i64 %x, ptr noalias dereferenceable(8) %y, ptr %z) {
+; CHECK-LABEL: define void @simplifycfg_switch_power_two_late_optimized(
+; CHECK-SAME: i64 [[X:%.*]], ptr noalias readonly captures(none) dereferenceable(8) [[Y:%.*]], ptr [[Z:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[ALLOC1:%.*]] = alloca [24 x i8], align 8
+; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[X]], 1
+; CHECK-NEXT: [[SWITCH_NOT:%.*]] = icmp eq i64 [[TMP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[Z]], null
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH_NOT]], i1 undef, i1 [[TMP1]]
+; CHECK-NEXT: br i1 [[SPEC_SELECT]], label %[[EXIT:.*]], label %[[OPAQUE_CALL:.*]]
+; CHECK: [[OPAQUE_CALL]]:
+; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[Y]], align 8
+; CHECK-NEXT: store i64 [[TMP2]], ptr [[ALLOC1]], align 8
+; CHECK-NEXT: [[PTR_IDX:%.*]] = getelementptr inbounds nuw i8, ptr [[ALLOC1]], i64 16
+; CHECK-NEXT: store ptr [[Z]], ptr [[PTR_IDX]], align 8
+; CHECK-NEXT: call void @opaque(ptr nonnull [[ALLOC1]])
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ %alloc1 = alloca [24 x i8], align 8
+ %alloc2 = alloca [8 x i8], align 8
+ %alloc3 = alloca [8 x i8], align 8
+ store i64 %x, ptr %alloc3, align 8
+ %val = load i64, ptr %alloc3, align 8
+ switch i64 %val, label %bb.default [
+ i64 1, label %bb.1
+ i64 2, label %bb.2
+ i64 4, label %bb.3
+ i64 8, label %bb.4
+ ]
+
+bb.default: ; preds = %continue, %entry
+ unreachable
+
+bb.1: ; preds = %entry
+ store ptr %z, ptr %alloc2, align 8
+ br label %continue
+
+bb.2: ; preds = %entry
+ br label %continue
+
+bb.3: ; preds = %entry
+ br label %continue
+
+bb.4: ; preds = %entry
+ br label %continue
+
+continue: ; preds = %bb.4, %bb.3, %bb.2, %bb.1
+ %val2 = load ptr, ptr %alloc2, align 8
+ %cast = ptrtoint ptr %val2 to i64
+ %icmp = icmp eq i64 %cast, 0
+ %cond = select i1 %icmp, i64 0, i64 1
+ switch i64 %cond, label %bb.default [
+ i64 0, label %exit
+ i64 1, label %opaque.call
+ ]
+
+opaque.call: ; preds = %continue
+ call void @llvm.memcpy.p0.p0.i64(ptr %alloc1, ptr align 8 %y, i64 8, i1 false)
+ %ptr.idx = getelementptr inbounds i8, ptr %alloc1, i64 16
+ store ptr %z, ptr %ptr.idx, align 8
+ call void @opaque(ptr %alloc1)
+ br label %exit
+
+exit: ; preds = %opaque.call
+ ret void
+}
+
+declare void @opaque(ptr)
>From 319ccfbd107206f6bda516adb291b3f150643edf Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Tue, 24 Jun 2025 15:59:29 +0200
Subject: [PATCH 2/2] [SimplifyCFG] Do not run `simplifySwitchOfPowersOfTwo` in
early invocations
It may be desirable not to carry out `simplifySwitchOfPowersOfTwo`
transform during early pipeline invocations, so as to let other
optimizations occur first.
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 5 ++++-
.../PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll | 5 ++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index e205551658aa5..4f3bfcff03d1c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -7604,7 +7604,10 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
switchToLookupTable(SI, Builder, DTU, DL, TTI))
return requestResimplify();
- if (simplifySwitchOfPowersOfTwo(SI, Builder, DL, TTI))
+ // Do not transform the switch into a `cttz` and a reduced table on early
+ // invocations.
+ if (Options.ConvertSwitchToLookupTable &&
+ simplifySwitchOfPowersOfTwo(SI, Builder, DL, TTI))
return requestResimplify();
if (reduceSwitchRange(SI, Builder, DL, TTI))
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll b/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
index d31621536e289..20f82fb7d980e 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-switch-powers-two-late.ll
@@ -8,10 +8,9 @@ define void @simplifycfg_switch_power_two_late_optimized(i64 %x, ptr noalias der
; CHECK-SAME: i64 [[X:%.*]], ptr noalias readonly captures(none) dereferenceable(8) [[Y:%.*]], ptr [[Z:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ALLOC1:%.*]] = alloca [24 x i8], align 8
-; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[X]], 1
-; CHECK-NEXT: [[SWITCH_NOT:%.*]] = icmp eq i64 [[TMP0]], 0
+; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i64 [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[Z]], null
-; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH_NOT]], i1 undef, i1 [[TMP1]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 [[TMP1]], i1 undef
; CHECK-NEXT: br i1 [[SPEC_SELECT]], label %[[EXIT:.*]], label %[[OPAQUE_CALL:.*]]
; CHECK: [[OPAQUE_CALL]]:
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[Y]], align 8
More information about the llvm-commits
mailing list