[llvm] [RISCV] Add macro fusions for Xiangshan (PR #72362)
Wang Pengcheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 30 04:37:01 PST 2024
https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/72362
>From 35de0b952cabd5b1f5da83906d47e7088615fe32 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Wed, 15 Nov 2023 16:10:07 +0800
Subject: [PATCH] [RISCV] Add macro fusions for Xiangshan
Doc: https://xiangshan-doc.readthedocs.io/zh-cn/latest/frontend/decode/
This PR is to show the usage of TableGen-based macro fusions.
Some instrcution pairs can be folded into one MacroFusion definition
but I leave them standalone to show the different ways to define a
macro fusion.
This PR is stacked on #72219, #72222, #72223, #72224, #72227
---
llvm/lib/Target/RISCV/RISCVMacroFusion.td | 213 ++++++++++++++++++++++
1 file changed, 213 insertions(+)
diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusion.td b/llvm/lib/Target/RISCV/RISCVMacroFusion.td
index 875a93d09a2c..2c364a68fe6b 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusion.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusion.td
@@ -91,3 +91,216 @@ def TuneLDADDFusion
CheckIsImmOperand<2>,
CheckImmOperand<2, 0>
]>>;
+
+// Get lower 16 bits:
+// slliw r1, r0, 16
+// srliw r1, r1, 16
+def GetLower16BitsFusion
+ : SimpleFusion<"get-lower-16bits-fusion", "HasGetLower16BitsFusion",
+ "Enable SLLIW+SRLIW to be fused to get lower 16 bits",
+ CheckAll<[
+ CheckOpcode<[SLLIW]>,
+ CheckImmOperand<2, 16>
+ ]>,
+ CheckAll<[
+ CheckOpcode<[SRLIW]>,
+ CheckImmOperand<2, 16>
+ ]>>;
+
+// Sign-extend a 16-bit number:
+// slliw r1, r0, 16
+// sraiw r1, r1, 16
+def SExtHFusion
+ : SimpleFusion<"sign-extend-16bits-fusion","HasSExtHFusion",
+ "Enable SLLIW+SRAIW to be fused to sign-extend a 16-bit number",
+ CheckAll<[
+ CheckOpcode<[SLLIW]>,
+ CheckImmOperand<2, 16>
+ ]>,
+ CheckAll<[
+ CheckOpcode<[SRAIW]>,
+ CheckImmOperand<2, 16>
+ ]>>;
+
+// These should be covered by Zba extension.
+// * shift left by one and add:
+// slli r1, r0, 1
+// add r1, r1, r2
+// * shift left by two and add:
+// slli r1, r0, 2
+// add r1, r1, r2
+// * shift left by three and add:
+// slli r1, r0, 3
+// add r1, r1, r2
+def ShiftNAddFusion
+ : SimpleFusion<"shift-n-add-fusion", "HasShiftNAddFusion",
+ "Enable SLLI+ADD to be fused to shift left by 1/2/3 and add",
+ CheckAll<[
+ CheckOpcode<[SLLI]>,
+ CheckAny<[CheckImmOperand<2, 1>,
+ CheckImmOperand<2, 2>,
+ CheckImmOperand<2, 3>]>
+ ]>,
+ CheckOpcode<[ADD]>>;
+
+// * Shift zero-extended word left by 1:
+// slli r1, r0, 32
+// srli r1, r0, 31
+// * Shift zero-extended word left by 2:
+// slli r1, r0, 32
+// srli r1, r0, 30
+// * Shift zero-extended word left by 3:
+// slli r1, r0, 32
+// srli r1, r0, 29
+def ShiftZExtByNFusion
+ : SimpleFusion<"shift-zext-by-n-fusion", "HasShiftZExtByNFusion",
+ "Enable SLLI+SRLI to be fused to shift zero-extended word left by 1/2/3",
+ CheckAll<[
+ CheckOpcode<[SLLI]>,
+ CheckImmOperand<2, 32>
+ ]>,
+ CheckAll<[
+ CheckOpcode<[SRLI]>,
+ CheckAny<[CheckImmOperand<2, 29>,
+ CheckImmOperand<2, 30>,
+ CheckImmOperand<2, 31>]>
+ ]>>;
+
+// Get the second byte:
+// srli r1, r0, 8
+// andi r1, r1, 255
+def GetSecondByteFusion
+ : SimpleFusion<"get-second-byte-fusion", "HasGetSecondByteFusion",
+ "Enable SRLI+ANDI to be fused to get the second byte",
+ CheckAll<[
+ CheckOpcode<[SRLI]>,
+ CheckImmOperand<2, 8>
+ ]>,
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckImmOperand<2, 255>
+ ]>>;
+
+// Shift left by four and add:
+// slli r1, r0, 4
+// add r1, r1, r2
+def ShiftLeft4AddFusion
+ : SimpleFusion<"shift-left-four-add-fusion", "HasShiftLeft4AddFusion",
+ "Enable SLLI+ADD to be fused to shift left by four and add",
+ CheckAll<[
+ CheckOpcode<[SLLI]>,
+ CheckImmOperand<2, 4>
+ ]>,
+ CheckOpcode<[ADD]>>;
+
+// * Shift right by 29 and add:
+// srli r1, r0, 29
+// add r1, r1, r2
+// * Shift right by 30 and add:
+// srli r1, r0, 30
+// add r1, r1, r2
+// * Shift right by 31 and add:
+// srli r1, r0, 31
+// add r1, r1, r2
+// * Shift right by 32 and add:
+// srli r1, r0, 32
+// add r1, r1, r2
+def ShiftRightNAddFusion
+ : SimpleFusion<"shift-right-n-add-fusion", "HasShiftRightNAddFusion",
+ "Enable SRLI+add to be fused to shift right by 29/30/31/32 and add",
+ CheckAll<[
+ CheckOpcode<[SRLI]>,
+ CheckAny<[CheckImmOperand<2, 29>,
+ CheckImmOperand<2, 30>,
+ CheckImmOperand<2, 31>,
+ CheckImmOperand<2, 32>]>
+ ]>,
+ CheckOpcode<[ADD]>>;
+
+// Add one if odd, otherwise unchanged:
+// andi r1, r0, 1
+// add r1, r1, r2
+// Add one if odd (in word format), otherwise unchanged:
+// andi r1, r0, 1
+// addw r1, r1, r2
+def AddOneIfOddFusion
+ : SimpleFusion<"add-one-if-odd-fusion", "HasAddOneIfOddFusion",
+ "Enable ANDI+ADDW to be fused to add one if odd",
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckImmOperand<2, 1>
+ ]>,
+ CheckOpcode<[ADD, ADDW]>>;
+
+// * Add word and extract its lower 1 bit:
+// andw r1, r1, r0
+// andi r1, r1, 1
+// * Add word and extract its lower 8 bits:
+// andw r1, r1, r0
+// andi r1, r1, 255
+def AddAndExtractNBitsFusion
+ : SimpleFusion<"add-and-extract-n-bits-fusion", "HasAddAndExtractNBitsFusion",
+ "Enable ADDW+ANDI to be fused to get lower 16 bits",
+ CheckOpcode<[ADDW]>,
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckAny<[CheckImmOperand<2, 1>,
+ CheckImmOperand<2, 255>]>
+ ]>>;
+
+// * Add word and zext.h:
+// andw r1, r1, r0
+// zext.h r1, r1
+// * Add word and sext.h:
+// andw r1, r1, r0
+// sext.h r1, r1
+def AddwAndExtFusion
+ : SimpleFusion<"addw-and-ext-fusion", "HasAddwAndExtFusion",
+ "Enable ADDW+ZEXT_H/SEXT_H to be fused",
+ CheckOpcode<[ADDW]>,
+ CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64, SEXT_H]>>;
+
+// Logic operation and extract its LSB:
+// <logic op> r1, r1, r0
+// andi r1, r1, 1
+def LogicOpAndExtractLSBFusion
+ : SimpleFusion<"logic-op-and-extract-lsb-fusion", "HasLogicOpAndExtractLSBFusion",
+ "Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ANDI to be fused to logic operation and extract its LSB",
+ CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckImmOperand<2, 1>
+ ]>>;
+
+// Logic operation and extract its lower 16 bits:
+// <logic op> r1, r1, r0
+// zext.h r1, r1, 1
+def LogicOpAndExtractLow16BitsFusion
+ : SimpleFusion<"logic-op-and-extract-low-16bits-fusion", "HasLogicOpAndExtractLow16BitsFusion",
+ "Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ANDI to be fused to logic operation and extract its lower 16 bits",
+ CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
+ CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64]>>;
+
+// OR(Cat(src1(63, 8), 0.U(8.W)), src2):
+// andi r1, r0, -256
+// or r1, r1, r2
+def OrCatFusion
+ : SimpleFusion<"or-cat-fusion", "HasOrCatFusion",
+ "Enable SLLIW+SRLIW to be fused to get lower 16 bits",
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckImmOperand<2, -256>
+ ]>,
+ CheckOpcode<[OR]>>;
+
+// Multiply 7-bit data with 32-bit data:
+// andi r1, r0, 127
+// mulw r1, r1, r2
+def Mul7BitsWith32BitsFusion
+ : SimpleFusion<"mul-7bits-with-32bit-fusion", "HasMul7BitsWith32BitsFusion",
+ "Enable ANDI+MULW to be fused to multiply 7-bit data with 32-bit data",
+ CheckAll<[
+ CheckOpcode<[ANDI]>,
+ CheckImmOperand<2, 127>
+ ]>,
+ CheckOpcode<[MULW]>>;
More information about the llvm-commits
mailing list