Files
TheRock/compiler/amd-llvm/llvm/lib/Target/RISCV/RISCVMacroFusion.td
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

258 lines
9.3 KiB
TableGen

//==----- RISCVMacroFusion.td - Macro Fusion Definitions -----*- tablegen -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// ===---------------------------------------------------------------------===//
// The following definitions describe the macro fusion predicators.
// Fuse LUI followed by ADDI or ADDIW:
// rd = imm[31:0] which decomposes to
// lui rd, imm[31:12]
// addi(w) rd, rd, imm[11:0]
def TuneLUIADDIFusion
: SimpleFusion<"lui-addi", "HasLUIADDIFusion",
"Enable LUI+ADDI macro fusion",
CheckOpcode<[LUI]>,
CheckOpcode<[ADDI, ADDIW]>>;
// Fuse AUIPC followed by ADDI:
// auipc rd, imm20
// addi rd, rd, imm12
def TuneAUIPCADDIFusion
: SimpleFusion<"auipc-addi", "HasAUIPCADDIFusion",
"Enable AUIPC+ADDI macrofusion",
CheckOpcode<[AUIPC]>,
CheckOpcode<[ADDI]>>;
// Fuse zero extension of halfword:
// slli rd, rs1, 48
// srli rd, rd, 48
def TuneZExtHFusion
: SimpleFusion<"zexth", "HasZExtHFusion",
"Enable SLLI+SRLI to be fused to zero extension of halfword",
CheckAll<[
CheckOpcode<[SLLI]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 48>
]>,
CheckAll<[
CheckOpcode<[SRLI]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 48>
]>>;
// Fuse zero extension of word:
// slli rd, rs1, 32
// srli rd, rd, 32
def TuneZExtWFusion
: SimpleFusion<"zextw", "HasZExtWFusion",
"Enable SLLI+SRLI to be fused to zero extension of word",
CheckAll<[
CheckOpcode<[SLLI]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 32>
]>,
CheckAll<[
CheckOpcode<[SRLI]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 32>
]>>;
// Fuse shifted zero extension of word:
// slli rd, rs1, 32
// srli rd, rd, x
// where 0 <= x < 32
def TuneShiftedZExtWFusion
: SimpleFusion<"shifted-zextw", "HasShiftedZExtWFusion",
"Enable SLLI+SRLI to be fused when computing (shifted) word zero extension",
CheckAll<[
CheckOpcode<[SLLI]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 32>
]>,
CheckAll<[
CheckOpcode<[SRLI]>,
CheckIsImmOperand<2>,
CheckImmOperandRange<2, 0, 31>
]>>;
// Fuse load with add:
// add rd, rs1, rs2
// ld rd, 0(rd)
def TuneLDADDFusion
: SimpleFusion<"ld-add", "HasLDADDFusion", "Enable LD+ADD macrofusion",
CheckOpcode<[ADD]>,
CheckAll<[
CheckOpcode<[LD]>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 0>
]>>;
defvar Load = [LB, LH, LW, LD, LBU, LHU, LWU];
defvar LoadStore = [LB, LBU, LH, LHU, LW, LWU, LD,
FLH, FLW, FLD,
SB, SH, SW, SD,
FSH, FSW, FSD];
defvar LogicOp = [AND, OR, XOR];
defvar LogicImmOp = [ANDI, ORI, XORI];
defvar ShiftLeft = [SLLI, SLLIW];
defvar ShiftRight = [SRLI, SRLIW, SRAI, SRAIW];
// Fuse add(.uw) followed by a load (lb, lh, lw, ld, lbu, lhu, lwu):
// add(.uw) rd, rs1, rs2
// load rd, imm12(rd)
def TuneADDLoadFusion
: SimpleFusion<"add-load", "HasADDLoadFusion", "Enable ADD(.UW) + load macrofusion",
CheckOpcode<[ADD, ADD_UW]>,
CheckOpcode<Load>>;
// Fuse AUIPC followed by by a load (lb, lh, lw, ld, lbu, lhu, lwu)
// auipc rd, imm20
// load rd, imm12(rd)
def TuneAUIPCLoadFusion
: SimpleFusion<"auipc-load", "HasAUIPCLoadFusion",
"Enable AUIPC + load macrofusion",
CheckOpcode<[AUIPC]>,
CheckOpcode<Load>>;
// Fuse LUI followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
// lui rd, imm[31:12]
// load rd, imm12(rd)
def TuneLUILoadFusion
: SimpleFusion<"lui-load", "HasLUILoadFusion",
"Enable LUI + load macrofusion",
CheckOpcode<[LUI]>,
CheckOpcode<Load>>;
// Bitfield extract fusion: similar to TuneShiftedZExtWFusion
// but without the immediate restriction
// slli rd, rs1, imm12
// srli rd, rd, imm12
def TuneBFExtFusion
: SimpleFusion<"bfext", "HasBFExtFusion",
"Enable SLLI+SRLI (bitfield extract) macrofusion",
CheckOpcode<[SLLI]>,
CheckOpcode<[SRLI]>>;
// Fuse ADDI followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
// addi rd, rs1, imm12
// load rd, imm12(rd)
def TuneADDILoadFusion
: SimpleFusion<"addi-load", "HasADDILoadFusion",
"Enable ADDI + load macrofusion",
CheckOpcode<[ADDI]>,
CheckOpcode<Load>>;
// Fuse shXadd(.uw) followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
// shXadd(.uw) rd, rs1, rs2
// load rd, imm12(rd)
def TuneSHXADDLoadFusion
: SimpleFusion<"shxadd-load", "HasSHXADDLoadFusion",
"Enable SH(1|2|3)ADD(.UW) + load macrofusion",
CheckOpcode<[SH1ADD, SH2ADD, SH3ADD, SH1ADD_UW, SH2ADD_UW, SH3ADD_UW]>,
CheckOpcode<Load>>;
// Fuse logic operation followed by another logic operation:
// and/or/xor rd, rs1, rs2
// and/or/xor rd, rd, rs3
let IsCommutable = 1 in
def TuneFusionLogicRegReg
: SimpleFusion<"logic-reg-reg", "HasFusionLogicRegReg",
"Enable AND/OR/XOR+AND/OR/XOR macrofusion",
CheckOpcode<LogicOp>,
CheckOpcode<LogicOp>>;
// Fuse logic operation followed by logic immediate operation:
// and/or/xor rd, rs1, rs2
// andi/ori/xori rd, rd, imm
def TuneFusionLogicRegImm
: SimpleFusion<"logic-reg-imm", "HasFusionLogicRegImm",
"Enable AND/OR/XOR+ANDI/ORI/XORI macrofusion",
CheckOpcode<LogicOp>,
CheckOpcode<LogicImmOp>>;
// Fuse logic immediate operation followed by logic operation:
// andi/ori/xori rd, rs1, imm
// and/or/xor rd, rd, rs2
let IsCommutable = 1 in
def TuneFusionLogicImmReg
: SimpleFusion<"logic-imm-reg", "HasFusionLogicImmReg",
"Enable ANDI/ORI/XORI+AND/OR/XOR macrofusion",
CheckOpcode<LogicImmOp>,
CheckOpcode<LogicOp>>;
// Fuse multiply followed by add:
// mul(w) rd, rs1, rs2
// add(w) rd, rd, rs3
def TuneFusionMulAdd
: SimpleFusion<"mul-add", "HasFusionMulAdd",
"Enable MUL+ADD macrofusion",
CheckOpcode<[MUL, MULW]>,
CheckOpcode<[ADD, ADDW]>,
epilog = [
// Check that both instructions have the same width
FusionPredicateWithCode<[{
if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
(SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
return false;
}]>,
SecondFusionPredicateWithMCInstPredicate<
CheckNot<CheckSameRegOperand<0, 2>>
>
]>;
// Fuse add with load or store with zero offset:
// add rd, rs1, rs2
// load/store rt, 0(rd)
def TuneFusionAddMem
: Fusion<"add-mem", "HasFusionAddMem",
"Enable ADD+LOAD/STORE macrofusion",
[
SecondFusionPredicateWithMCInstPredicate<
CheckAll<[
CheckOpcode<LoadStore>,
CheckIsImmOperand<2>,
CheckImmOperand<2, 0>
]>
>,
WildcardTrue,
FirstFusionPredicateWithMCInstPredicate<
CheckAll<[
CheckOpcode<[ADD]>,
CheckNot<CheckSameRegOperand<0, 1>>,
CheckNot<CheckSameRegOperand<0, 2>>
]>
>,
TieReg<0, 1>
]>;
// Fuse shift left followed by shift right for bit extraction:
// slli(w) rd, rs1, imm1
// srli(w)/srai(w) rd, rd, imm2
// where imm1 <= imm2
def TuneFusionShiftBitExtract
: SimpleFusion<"shift-bit-extract", "HasFusionShiftBitExtract",
"Enable SLLI+SRLI/SRAI macrofusion",
CheckOpcode<ShiftLeft>,
CheckOpcode<ShiftRight>,
epilog = [
// Check that both instructions have the same width
FusionPredicateWithCode<[{
if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
(SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
return false;
}]>,
// Check that FirstMI's immediate <= SecondMI's immediate
FusionPredicateWithCode<[{
if (!(FirstMI->getOperand(2).isImm() &&
SecondMI.getOperand(2).isImm() &&
FirstMI->getOperand(2).getImm() <=
SecondMI.getOperand(2).getImm()))
return false;
}]>,
]>;