Skip to content

[RISCV] Add macro fusions for Xiangshan #72362

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions llvm/lib/Target/RISCV/RISCVMacroFusion.td
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,179 @@ def TuneLDADDFusion
CheckIsImmOperand<2>,
CheckImmOperand<2, 0>
]>>;

// Get lower 16 bits:
// slliw r1, r0, 16
// srliw r1, r1, 16
def GetLower16BitsFusion
: SingleFusion<"get-lower-16bits-fusion", "HasGetLower16BitsFusion",
"Enable SLLIW+SRLIW to be fused to get lower 16 bits",
SLLIW, SRLIW,
CheckImmOperand<2, 16>,
CheckImmOperand<2, 16>>;

// Sign-extend a 16-bit number:
// slliw r1, r0, 16
// sraiw r1, r1, 16
def SExtHFusion
: SingleFusion<"sign-extend-16bits-fusion","HasSExtHFusion",
"Enable SLLIW+SRAIW to be fused to sign-extend a 16-bit number",
SLLIW, SRAIW,
CheckImmOperand<2, 16>,
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
: SingleFusion<"shift-n-add-fusion", "HasShiftNAddFusion",
"Enable SLLI+ADD to be fused to shift left by 1/2/3 and add",
SLLI, ADD,
CheckAny<[CheckImmOperand<2, 1>,
CheckImmOperand<2, 2>,
CheckImmOperand<2, 3>]>>;

// * 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
: SingleFusion<"shift-zext-by-n-fusion", "HasShiftZExtByNFusion",
"Enable SLLI+SRLI to be fused to shift zero-extended word left by 1/2/3",
SLLI, SRLI,
CheckImmOperand<2, 32>,
CheckAny<[CheckImmOperand<2, 29>,
CheckImmOperand<2, 30>,
CheckImmOperand<2, 31>]>>;

// Get the second byte:
// srli r1, r0, 8
// andi r1, r1, 255
def GetSecondByteFusion
: SingleFusion<"get-second-byte-fusion", "HasGetSecondByteFusion",
"Enable SRLI+ANDI to be fused to get the second byte",
SRLI, ANDI,
CheckImmOperand<2, 8>,
CheckImmOperand<2, 255>>;

// Shift left by four and add:
// slli r1, r0, 4
// add r1, r1, r2
def ShiftLeft4AddFusion
: SingleFusion<"shift-left-four-add-fusion", "HasShiftLeft4AddFusion",
"Enable SLLI+ADD to be fused to shift left by four and add",
SLLI, ADD,
CheckImmOperand<2, 4>>;

// * 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
: SingleFusion<"shift-right-n-add-fusion", "HasShiftRightNAddFusion",
"Enable SRLI+add to be fused to shift right by 29/30/31/32 and add",
SRLI, ADD,
CheckAny<[CheckImmOperand<2, 29>,
CheckImmOperand<2, 30>,
CheckImmOperand<2, 31>,
CheckImmOperand<2, 32>]>>;

// 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
let IsCommutable = 1 in
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
: SingleFusion<"add-and-extract-n-bits-fusion", "HasAddAndExtractNBitsFusion",
"Enable ADDW+ANDI to be fused to get lower 16 bits",
ADDW, ANDI,
secondInstPred = 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
def LogicOpAndExtractLow16BitsFusion
: SimpleFusion<"logic-op-and-extract-low-16bits-fusion", "HasLogicOpAndExtractLow16BitsFusion",
"Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ZEXT_H 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
: SingleFusion<"or-cat-fusion", "HasOrCatFusion",
"Enable SLLIW+SRLIW to be fused to get lower 16 bits",
ANDI, OR,
CheckImmOperand<2, -256>>;

// Multiply 7-bit data with 32-bit data:
// andi r1, r0, 127
// mulw r1, r1, r2
def Mul7BitsWith32BitsFusion
: SingleFusion<"mul-7bits-with-32bit-fusion", "HasMul7BitsWith32BitsFusion",
"Enable ANDI+MULW to be fused to multiply 7-bit data with 32-bit data",
ANDI, MULW,
CheckImmOperand<2, 127>>;
Loading
Loading