From aaca871d95a372531249dd489fbdb9ea850f4c50 Mon Sep 17 00:00:00 2001 From: wangpc Date: Wed, 20 Dec 2023 17:29:45 +0800 Subject: [PATCH 1/2] [RISCV] Split TuneShiftedZExtFusion We split `TuneShiftedZExtFusion` into three fusions to make them reusable and match the GCC implementation[1]. The zexth/zextw fusions can be reused by XiangShan[2] and others commercial processors, but shifted zero extension is not so common. Besides, `TuneVeyronFusions` is changed back to `TuneVentanaVeyron` and fusion features are added to processor definition. `macro-fusions-veyron-v1.mir` is renamed so it's not relevant to specific processor. References: [1] https://gcc.gnu.org/pipermail/gcc-patches/2023-November/637303.html [2] https://xiangshan-doc.readthedocs.io/zh_CN/latest/frontend/decode --- llvm/lib/Target/RISCV/RISCVFeatures.td | 16 +++- llvm/lib/Target/RISCV/RISCVMacroFusion.cpp | 82 +++++++++++++++---- llvm/lib/Target/RISCV/RISCVProcessors.td | 4 +- llvm/lib/Target/RISCV/RISCVSubtarget.h | 4 +- ...usions-veyron-v1.mir => macro-fusions.mir} | 4 +- 5 files changed, 87 insertions(+), 23 deletions(-) rename llvm/test/CodeGen/RISCV/{macro-fusions-veyron-v1.mir => macro-fusions.mir} (94%) diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 5048e28545a3c..a66dd135ae5f8 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -977,9 +977,19 @@ def TuneLUIADDIFusion def TuneAUIPCADDIFusion : SubtargetFeature<"auipc-addi-fusion", "HasAUIPCADDIFusion", "true", "Enable AUIPC+ADDI macrofusion">; -def TuneShiftedZExtFusion - : SubtargetFeature<"shifted-zext-fusion", "HasShiftedZExtFusion", - "true", "Enable SLLI+SRLI to be fused when computing (shifted) zero extension">; + +def TuneZExtHFusion + : SubtargetFeature<"zexth-fusion", "HasZExtHFusion", + "true", "Enable SLLI+SRLI to be fused to zero extension of halfword">; + +def TuneZExtWFusion + : SubtargetFeature<"zextw-fusion", "HasZExtWFusion", + "true", "Enable SLLI+SRLI to be fused to zero extension of word">; + +def TuneShiftedZExtWFusion + : SubtargetFeature<"shifted-zextw-fusion", "HasShiftedZExtWFusion", + "true", "Enable SLLI+SRLI to be fused when computing (shifted) zero extension of word">; + def TuneLDADDFusion : SubtargetFeature<"ld-add-fusion", "HasLDADDFusion", "true", "Enable LD+ADD macrofusion.">; diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp b/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp index 02ea5270823d8..f948f05b22f77 100644 --- a/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp +++ b/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp @@ -58,18 +58,66 @@ static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI) { return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI); } -// Fuse these patterns: -// -// slli rd, rs1, 32 -// srli rd, rd, x -// where 0 <= x <= 32 -// -// and -// +// Fuse zero extension of halfword: // slli rd, rs1, 48 +// srli rd, rd, 48 +static bool isZExtH(const MachineInstr *FirstMI, const MachineInstr &SecondMI) { + if (SecondMI.getOpcode() != RISCV::SRLI) + return false; + + if (!SecondMI.getOperand(2).isImm()) + return false; + + if (SecondMI.getOperand(2).getImm() != 48) + return false; + + // Given SecondMI, when FirstMI is unspecified, we must return + // if SecondMI may be part of a fused pair at all. + if (!FirstMI) + return true; + + if (FirstMI->getOpcode() != RISCV::SLLI) + return false; + + if (FirstMI->getOperand(2).getImm() != 48) + return false; + + return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI); +} + +// Fuse zero extension of word: +// slli rd, rs1, 32 +// srli rd, rd, 32 +static bool isZExtW(const MachineInstr *FirstMI, const MachineInstr &SecondMI) { + if (SecondMI.getOpcode() != RISCV::SRLI) + return false; + + if (!SecondMI.getOperand(2).isImm()) + return false; + + if (SecondMI.getOperand(2).getImm() != 32) + return false; + + // Given SecondMI, when FirstMI is unspecified, we must return + // if SecondMI may be part of a fused pair at all. + if (!FirstMI) + return true; + + if (FirstMI->getOpcode() != RISCV::SLLI) + return false; + + if (FirstMI->getOperand(2).getImm() != 32) + return false; + + return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI); +} + +// Fuse shifted zero extension of word: +// slli rd, rs1, 32 // srli rd, rd, x -static bool isShiftedZExt(const MachineInstr *FirstMI, - const MachineInstr &SecondMI) { +// where 0 <= x < 32 +static bool isShiftedZExtW(const MachineInstr *FirstMI, + const MachineInstr &SecondMI) { if (SecondMI.getOpcode() != RISCV::SRLI) return false; @@ -77,8 +125,7 @@ static bool isShiftedZExt(const MachineInstr *FirstMI, return false; unsigned SRLIImm = SecondMI.getOperand(2).getImm(); - bool IsShiftBy48 = SRLIImm == 48; - if (SRLIImm > 32 && !IsShiftBy48) + if (SRLIImm >= 32) return false; // Given SecondMI, when FirstMI is unspecified, we must return @@ -89,8 +136,7 @@ static bool isShiftedZExt(const MachineInstr *FirstMI, if (FirstMI->getOpcode() != RISCV::SLLI) return false; - unsigned SLLIImm = FirstMI->getOperand(2).getImm(); - if (IsShiftBy48 ? (SLLIImm != 48) : (SLLIImm != 32)) + if (FirstMI->getOperand(2).getImm() != 32) return false; return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI); @@ -144,7 +190,13 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, if (ST.hasAUIPCADDIFusion() && isAUIPCADDI(FirstMI, SecondMI)) return true; - if (ST.hasShiftedZExtFusion() && isShiftedZExt(FirstMI, SecondMI)) + if (ST.hasZExtHFusion() && isZExtH(FirstMI, SecondMI)) + return true; + + if (ST.hasZExtWFusion() && isZExtW(FirstMI, SecondMI)) + return true; + + if (ST.hasShiftedZExtWFusion() && isShiftedZExtW(FirstMI, SecondMI)) return true; if (ST.hasLDADDFusion() && isLDADD(FirstMI, SecondMI)) diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td index 71c250634cfc9..6362a3bef6f28 100644 --- a/llvm/lib/Target/RISCV/RISCVProcessors.td +++ b/llvm/lib/Target/RISCV/RISCVProcessors.td @@ -276,7 +276,9 @@ def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1", [TuneVentanaVeyron, TuneLUIADDIFusion, TuneAUIPCADDIFusion, - TuneShiftedZExtFusion, + TuneZExtHFusion, + TuneZExtWFusion, + TuneShiftedZExtWFusion, TuneLDADDFusion]>; def XIANGSHAN_NANHU : RISCVProcessorModel<"xiangshan-nanhu", diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 7540218633bfc..26320b05d9be2 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -190,8 +190,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { } bool hasMacroFusion() const { - return hasLUIADDIFusion() || hasAUIPCADDIFusion() || - hasShiftedZExtFusion() || hasLDADDFusion(); + return hasLUIADDIFusion() || hasAUIPCADDIFusion() || hasZExtHFusion() || + hasZExtWFusion() || hasShiftedZExtWFusion() || hasLDADDFusion(); } // Vector codegen related methods. diff --git a/llvm/test/CodeGen/RISCV/macro-fusions-veyron-v1.mir b/llvm/test/CodeGen/RISCV/macro-fusions.mir similarity index 94% rename from llvm/test/CodeGen/RISCV/macro-fusions-veyron-v1.mir rename to llvm/test/CodeGen/RISCV/macro-fusions.mir index 6d1e92e997b32..dfcd53e36d66d 100644 --- a/llvm/test/CodeGen/RISCV/macro-fusions-veyron-v1.mir +++ b/llvm/test/CodeGen/RISCV/macro-fusions.mir @@ -1,7 +1,7 @@ # REQUIRES: asserts -# RUN: llc -mtriple=riscv64-linux-gnu -mcpu=veyron-v1 -x=mir < %s \ +# RUN: llc -mtriple=riscv64-linux-gnu -x=mir < %s \ # RUN: -debug-only=machine-scheduler -start-before=machine-scheduler 2>&1 \ -# RUN: -mattr=+lui-addi-fusion,+auipc-addi-fusion,+shifted-zext-fusion,+ld-add-fusion \ +# RUN: -mattr=+lui-addi-fusion,+auipc-addi-fusion,+zexth-fusion,+zextw-fusion,+shifted-zextw-fusion,+ld-add-fusion \ # RUN: | FileCheck %s # CHECK: lui_addi:%bb.0 From 65473de225d53e613554c51fd95d13dd7e8d093a Mon Sep 17 00:00:00 2001 From: wangpc Date: Fri, 22 Dec 2023 12:07:40 +0800 Subject: [PATCH 2/2] Rename tests --- llvm/test/CodeGen/RISCV/macro-fusions.mir | 25 +++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/macro-fusions.mir b/llvm/test/CodeGen/RISCV/macro-fusions.mir index dfcd53e36d66d..b7568ae6f0f69 100644 --- a/llvm/test/CodeGen/RISCV/macro-fusions.mir +++ b/llvm/test/CodeGen/RISCV/macro-fusions.mir @@ -38,10 +38,10 @@ body: | PseudoRET ... -# CHECK: slli_srli +# CHECK: slli_srli_shifted_zext # CHECK: Macro fuse: {{.*}}SLLI - SRLI --- -name: slli_srli +name: shifted_zext tracksRegLiveness: true body: | bb.0.entry: @@ -55,10 +55,10 @@ body: | PseudoRET ... -# CHECK: slli_srli_48 +# CHECK: slli_srli_zexth # CHECK: Macro fuse: {{.*}}SLLI - SRLI --- -name: slli_srli_48 +name: zexth tracksRegLiveness: true body: | bb.0.entry: @@ -72,6 +72,23 @@ body: | PseudoRET ... +# CHECK: slli_srli_zextw +# CHECK: Macro fuse: {{.*}}SLLI - SRLI +--- +name: zextw +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10 + %1:gpr = COPY $x10 + %2:gpr = SLLI %1, 32 + %3:gpr = XORI %1, 3 + %4:gpr = SRLI %2, 32 + $x10 = COPY %3 + $x11 = COPY %4 + PseudoRET +... + # CHECK: slli_srli_no_fusion_0 # CHECK-NOT: Macro fuse: {{.*}}SLLI - SRLI ---