diff --git a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td index 8851ee44ac93..4d6fc05b7316 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td +++ b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td @@ -23,6 +23,10 @@ def VLDSX0Pred // is enabled. def SingleElementVecFP64SchedPred : FeatureSchedPredicate; +// This scheduling predicate is true when the subtarget is RV32 (i.e. Feature64Bit +// is not enabled). +def RV32SchedPred : NotSchedPred>; + // Returns true if this is the sext.w pattern, addiw rd, rs1, 0. def isSEXT_W : TIIPredicate<"isSEXT_W", diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td index 329827b7eefa..545916168fd0 100644 --- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td +++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td @@ -346,21 +346,30 @@ multiclass SiFive7WriteResBase; } - // Integer division - def : WriteRes { + // IDiv / IRem in a 32-bit core should have the same latency and throughput + // as IDiv32 / IRem32 in a 64-bit core. + def SiFive7RV64IDivRemSchedWriteRes : SchedWriteRes<[PipeB, IDiv]> { let Latency = 66; let ReleaseAtCycles = [1, 65]; } + def SiFive7RV32IDivRemSchedWriteRes : SchedWriteRes<[PipeB, IDiv]> { + let Latency = 34; + let ReleaseAtCycles = [1, 33]; + } + def SiFive7IDivRemSchedWriteVariant : SchedWriteVariant<[ + SchedVar(NAME # "SiFive7RV32IDivRemSchedWriteRes")]>, + SchedVar(NAME # "SiFive7RV64IDivRemSchedWriteRes")]> + ]>; + + // Integer division + def : SchedAlias(NAME # "SiFive7IDivRemSchedWriteVariant")>; def : WriteRes { let Latency = 34; let ReleaseAtCycles = [1, 33]; } // Integer remainder - def : WriteRes { - let Latency = 66; - let ReleaseAtCycles = [1, 65]; - } + def : SchedAlias(NAME # "SiFive7IDivRemSchedWriteVariant")>; def : WriteRes { let Latency = 34; let ReleaseAtCycles = [1, 33]; diff --git a/llvm/test/tools/llvm-mca/RISCV/Inputs/mul-div-rv32.s b/llvm/test/tools/llvm-mca/RISCV/Inputs/mul-div-rv32.s new file mode 100644 index 000000000000..577646b25750 --- /dev/null +++ b/llvm/test/tools/llvm-mca/RISCV/Inputs/mul-div-rv32.s @@ -0,0 +1,10 @@ +# Input instructions for the 'M' extension. + +mul a0, a0, a0 +mulh a0, a0, a0 +mulhu a0, a0, a0 +mulhsu a0, a0, a0 +div a0, a1, a2 +divu a0, a1, a2 +rem a0, a1, a2 +remu a0, a1, a2 diff --git a/llvm/test/tools/llvm-mca/RISCV/SiFive7/mul-div-rv32.test b/llvm/test/tools/llvm-mca/RISCV/SiFive7/mul-div-rv32.test new file mode 100644 index 000000000000..ee7796dbd739 --- /dev/null +++ b/llvm/test/tools/llvm-mca/RISCV/SiFive7/mul-div-rv32.test @@ -0,0 +1,59 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -mtriple=riscv32 -mcpu=sifive-e76 -iterations=1 -instruction-tables=full %p/../Inputs/mul-div-rv32.s | FileCheck %s + +# CHECK: Resources: +# CHECK-NEXT: [0] - VLEN512SiFive7FDiv:1 +# CHECK-NEXT: [1] - VLEN512SiFive7IDiv:1 +# CHECK-NEXT: [2] - VLEN512SiFive7PipeA:1 +# CHECK-NEXT: [3] - VLEN512SiFive7PipeAB:2 VLEN512SiFive7PipeA, VLEN512SiFive7PipeB +# CHECK-NEXT: [4] - VLEN512SiFive7PipeB:1 +# CHECK-NEXT: [5] - VLEN512SiFive7VA1:1 +# CHECK-NEXT: [6] - VLEN512SiFive7VCQ:1 +# CHECK-NEXT: [7] - VLEN512SiFive7VL:1 +# CHECK-NEXT: [8] - VLEN512SiFive7VS:1 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) +# CHECK-NEXT: [7]: Bypass Latency +# CHECK-NEXT: [8]: Resources ( | [] | [,