[llvm] [InstCombine] Fold `switch(rol(x, C1)) case C2:` to `switch(x) case rol(C2, -C1):` (PR #86307)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 24 09:49:15 PDT 2024
https://github.com/YanWQ-monad updated https://github.com/llvm/llvm-project/pull/86307
>From 87a72040a928d602a06040f6090295639c10125a Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Sat, 23 Mar 2024 00:47:03 +0800
Subject: [PATCH 1/3] Pre-commit: add test
---
.../test/Transforms/InstCombine/switch-rol.ll | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/switch-rol.ll
diff --git a/llvm/test/Transforms/InstCombine/switch-rol.ll b/llvm/test/Transforms/InstCombine/switch-rol.ll
new file mode 100644
index 0000000000000..cd0d066e3e0ce
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/switch-rol.ll
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+declare void @dummy()
+
+define i32 @switch_rol(i32 %a) #0 {
+; CHECK-LABEL: define i32 @switch_rol(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ROL:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[A]], i32 30)
+; CHECK-NEXT: switch i32 [[ROL]], label [[DEFAULT:%.*]] [
+; CHECK-NEXT: i32 0, label [[TRAP_EXIT:%.*]]
+; CHECK-NEXT: i32 5, label [[TRAP_EXIT]]
+; CHECK-NEXT: ]
+; CHECK: default:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: br label [[TRAP_EXIT]]
+; CHECK: trap.exit:
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ %rol = call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 30)
+ switch i32 %rol, label %default [
+ i32 0, label %trap.exit
+ i32 5, label %trap.exit
+ ]
+
+default:
+ call void @dummy()
+ br label %trap.exit
+
+trap.exit:
+ ret i32 0
+}
+
+define i32 @switch_rol_2(i32 %a) #0 {
+; CHECK-LABEL: define i32 @switch_rol_2(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[A]], -7
+; CHECK-NEXT: [[ROL:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP0]], i32 [[TMP0]], i32 30)
+; CHECK-NEXT: switch i32 [[ROL]], label [[DEFAULT:%.*]] [
+; CHECK-NEXT: i32 0, label [[TRAP_EXIT:%.*]]
+; CHECK-NEXT: i32 5, label [[TRAP_EXIT]]
+; CHECK-NEXT: ]
+; CHECK: default:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: br label [[TRAP_EXIT]]
+; CHECK: trap.exit:
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ %1 = sub i32 %a, 7
+ %rol = call i32 @llvm.fshl.i32(i32 %1, i32 %1, i32 30)
+ switch i32 %rol, label %default [
+ i32 0, label %trap.exit
+ i32 5, label %trap.exit
+ ]
+
+default:
+ call void @dummy()
+ br label %trap.exit
+
+trap.exit:
+ ret i32 0
+}
>From e52ac48b2563ad5d1c41b5f4f6ad5861345cbf6d Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Sat, 23 Mar 2024 00:47:45 +0800
Subject: [PATCH 2/3] Fold 'switch(rol(x, C1))'
---
.../Transforms/InstCombine/InstructionCombining.cpp | 10 ++++++++++
llvm/test/Transforms/InstCombine/switch-rol.ll | 13 +++++--------
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7c40fb4fc8608..b6611cfbbfc1f 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3645,6 +3645,16 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
}
}
+ // Fold 'switch(rol(x, C1)) case C2:' to 'switch(x) case rol(C2, -C1):'
+ if (match(Cond,
+ m_FShl(m_Value(Op0), m_Deferred(Op0), m_ConstantInt(ShiftAmt)))) {
+ for (auto &Case : SI.cases()) {
+ const APInt NewCase = Case.getCaseValue()->getValue().rotr(ShiftAmt);
+ Case.setValue(ConstantInt::get(SI.getContext(), NewCase));
+ }
+ return replaceOperand(SI, 0, Op0);
+ }
+
KnownBits Known = computeKnownBits(Cond, 0, &SI);
unsigned LeadingKnownZeros = Known.countMinLeadingZeros();
unsigned LeadingKnownOnes = Known.countMinLeadingOnes();
diff --git a/llvm/test/Transforms/InstCombine/switch-rol.ll b/llvm/test/Transforms/InstCombine/switch-rol.ll
index cd0d066e3e0ce..7557ad5dfe276 100644
--- a/llvm/test/Transforms/InstCombine/switch-rol.ll
+++ b/llvm/test/Transforms/InstCombine/switch-rol.ll
@@ -7,10 +7,9 @@ define i32 @switch_rol(i32 %a) #0 {
; CHECK-LABEL: define i32 @switch_rol(
; CHECK-SAME: i32 [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ROL:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[A]], i32 30)
-; CHECK-NEXT: switch i32 [[ROL]], label [[DEFAULT:%.*]] [
+; CHECK-NEXT: switch i32 [[A]], label [[DEFAULT:%.*]] [
; CHECK-NEXT: i32 0, label [[TRAP_EXIT:%.*]]
-; CHECK-NEXT: i32 5, label [[TRAP_EXIT]]
+; CHECK-NEXT: i32 20, label [[TRAP_EXIT]]
; CHECK-NEXT: ]
; CHECK: default:
; CHECK-NEXT: call void @dummy()
@@ -37,11 +36,9 @@ define i32 @switch_rol_2(i32 %a) #0 {
; CHECK-LABEL: define i32 @switch_rol_2(
; CHECK-SAME: i32 [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[A]], -7
-; CHECK-NEXT: [[ROL:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP0]], i32 [[TMP0]], i32 30)
-; CHECK-NEXT: switch i32 [[ROL]], label [[DEFAULT:%.*]] [
-; CHECK-NEXT: i32 0, label [[TRAP_EXIT:%.*]]
-; CHECK-NEXT: i32 5, label [[TRAP_EXIT]]
+; CHECK-NEXT: switch i32 [[A]], label [[DEFAULT:%.*]] [
+; CHECK-NEXT: i32 7, label [[TRAP_EXIT:%.*]]
+; CHECK-NEXT: i32 27, label [[TRAP_EXIT]]
; CHECK-NEXT: ]
; CHECK: default:
; CHECK-NEXT: call void @dummy()
>From 365b36d06d79a5b53e37e3d42a01d7be0f3c855e Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Sat, 25 May 2024 00:48:33 +0800
Subject: [PATCH 3/3] [InstCombine] Only fold switches with no more than 3
cases
---
.../InstCombine/InstructionCombining.cpp | 4 +--
.../test/Transforms/InstCombine/switch-rol.ll | 36 +++++++++++++++++++
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index b6611cfbbfc1f..ba14ea2915b38 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3646,8 +3646,8 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
}
// Fold 'switch(rol(x, C1)) case C2:' to 'switch(x) case rol(C2, -C1):'
- if (match(Cond,
- m_FShl(m_Value(Op0), m_Deferred(Op0), m_ConstantInt(ShiftAmt)))) {
+ if (SI.getNumCases() < 4 && match(Cond, m_FShl(m_Value(Op0), m_Deferred(Op0),
+ m_ConstantInt(ShiftAmt)))) {
for (auto &Case : SI.cases()) {
const APInt NewCase = Case.getCaseValue()->getValue().rotr(ShiftAmt);
Case.setValue(ConstantInt::get(SI.getContext(), NewCase));
diff --git a/llvm/test/Transforms/InstCombine/switch-rol.ll b/llvm/test/Transforms/InstCombine/switch-rol.ll
index 7557ad5dfe276..33e556e85445a 100644
--- a/llvm/test/Transforms/InstCombine/switch-rol.ll
+++ b/llvm/test/Transforms/InstCombine/switch-rol.ll
@@ -61,3 +61,39 @@ default:
trap.exit:
ret i32 0
}
+
+define i32 @switch_rol_negative_dense_switch(i32 %a) #0 {
+; CHECK-LABEL: define i32 @switch_rol_negative_dense_switch(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[A]], -7
+; CHECK-NEXT: [[ROL:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP0]], i32 [[TMP0]], i32 30)
+; CHECK-NEXT: switch i32 [[ROL]], label [[DEFAULT:%.*]] [
+; CHECK-NEXT: i32 0, label [[TRAP_EXIT:%.*]]
+; CHECK-NEXT: i32 1, label [[TRAP_EXIT]]
+; CHECK-NEXT: i32 2, label [[TRAP_EXIT]]
+; CHECK-NEXT: i32 3, label [[TRAP_EXIT]]
+; CHECK-NEXT: ]
+; CHECK: default:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: br label [[TRAP_EXIT]]
+; CHECK: trap.exit:
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ %1 = sub i32 %a, 7
+ %rol = call i32 @llvm.fshl.i32(i32 %1, i32 %1, i32 30)
+ switch i32 %rol, label %default [
+ i32 0, label %trap.exit
+ i32 1, label %trap.exit
+ i32 2, label %trap.exit
+ i32 3, label %trap.exit
+ ]
+
+default:
+ call void @dummy()
+ br label %trap.exit
+
+trap.exit:
+ ret i32 0
+}
More information about the llvm-commits
mailing list