[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