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 83% rename from llvm/test/CodeGen/RISCV/macro-fusions-veyron-v1.mir rename to llvm/test/CodeGen/RISCV/macro-fusions.mir index 6d1e92e997b32..b7568ae6f0f69 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 @@ -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 ---