[llvm] [LoongArch] Add scheduler definitions for LoongArch with schedule model for LA464/LA664 (PR #226064)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 01:16:12 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: lrzlin
<details>
<summary>Changes</summary>
This patch adds full scheduler definitions for LoongArch backend and schedule models for LA464/LA664, covering basic instructions and LSX/LASX SIMD instructions, along with a series of `llvm-mca` tests.
The model are base on a Chip and Cheese microarchitecture analysis article, [Loongson 3A6000: A Star among Chinese CPUs](https://chipsandcheese.com/p/loongson-3a6000-a-star-among-chinese-cpus/), which has a detailed analysis for LA464/LA664 microarchitecture. The latency/throughput numbers were measured from actual machine, so many of them depend on estimate.
`PostRAScheduler` was not set because we found that it will cause regression on SPEC CPU2006 470.lbm testcase. `MispredictPenalty` is also based on a raw guess. Besides, even if `LoopMicroOpBufferSize` will have a positive impact on performance due to loop unrolling, these microarchitecture details is still unknown, so I would perfer override the `getUnrollingPreferences` in future TTI patches, or waiting for more informations about this.
For the performance metrics, we run SPEC CPU2006 with `-mtune=la664 -O3 -mlsx` on a Loongson 3B6000, which has 16 LA664 cores running on 2.1GHz, here are the results.
## CINT2006
| benchmark | sched time (s) | nosched time (s) | sched ratio | nosched ratio | delta |
|---|---:|---:|---:|---:|---:|
| 400.perlbench | 358 | 374 | 27.3 | 26.1 | **+4.6 %** |
| 401.bzip2 | 521 | 519 | 18.5 | 18.6 | -0.5 % |
| 403.gcc | 314 | 315 | 25.6 | 25.5 | +0.4 % |
| 429.mcf | 256 | 254 | 35.6 | 35.9 | -0.8 % |
| 445.gobmk | 461 | 464 | 22.8 | 22.6 | +0.9 % |
| 456.hmmer | 456 | 456 | 20.5 | 20.5 | +0.0 % |
| 458.sjeng | 512 | 515 | 23.6 | 23.5 | +0.4 % |
| 462.libquantum | 630 | 642 | 32.9 | 32.3 | **+1.9 %** |
| 464.h264ref | 597 | 598 | 37.1 | 37.0 | +0.3 % |
| 471.omnetpp | 178 | 180 | 35.0 | 34.7 | +0.9 % |
| 473.astar | 365 | 363 | 19.3 | 19.4 | -0.5 % |
| 483.xalancbmk | 219 | 218 | 31.5 | 31.6 | -0.3 % |
| **SPECint_base2006** | | | **26.7** | **26.6** | **+0.58 %** |
## CFP2006
| benchmark | sched time (s) | nosched time (s) | sched ratio | nosched ratio | delta |
|---|---:|---:|---:|---:|---:|
| 410.bwaves | 341 | 343 | 39.9 | 39.7 | +0.5 % |
| 416.gamess | 605 | 613 | 32.4 | 31.9 | **+1.6 %** |
| 433.milc | 362 | 361 | 25.3 | 25.5 | -0.8 % |
| 434.zeusmp | 257 | 257 | 35.4 | 35.4 | +0.0 % |
| 435.gromacs | 467 | 469 | 15.3 | 15.2 | +0.7 % |
| 436.cactusADM | 206 | 205 | 58.0 | 58.3 | -0.5 % |
| 437.leslie3d | 269 | 278 | 35.0 | 33.8 | **+3.6 %** |
| 444.namd | 342 | 351 | 23.5 | 22.8 | **+3.1 %** |
| 447.dealII | 317 | 314 | 36.1 | 36.4 | -0.8 % |
| 450.soplex | 237 | 279 | 35.2 | 29.9 | **+17.7 %** |
| 453.povray | 153 | 154 | 34.8 | 34.6 | +0.6 % |
| 454.calculix | 912 | 907 | 9.1 | 9.1 | -0.5 % |
| 459.GemsFDTD | 323 | 321 | 32.8 | 33.1 | -0.9 % |
| 465.tonto | 312 | 313 | 31.5 | 31.5 | +0.0 % |
| 470.lbm | 305 | 304 | 45.1 | 45.2 | -0.2 % |
| 481.wrf | 237 | 237 | 47.2 | 47.2 | +0.0 % |
| 482.sphinx3 | 561 | 551 | 34.7 | 35.4 | **-2.0 %** |
| **SPECfp_base2006** | | | **31.2** | **30.9** | **+1.20 %** |
The SPEC CPU2006 results show a slightly improment on both CINT and CFP, consider it introducing possibilities for optimization passes like `MachineCombiner` and `EarlyIfConvertion`, the performance could futher improve IMO.
---
Patch is 531.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/226064.diff
29 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArch.td (+11-3)
- (modified) llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td (+154-77)
- (modified) llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td (+165-82)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+347-214)
- (modified) llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td (+1460-832)
- (modified) llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td (+1397-805)
- (added) llvm/lib/Target/LoongArch/LoongArchSchedLA464.td (+1080)
- (added) llvm/lib/Target/LoongArch/LoongArchSchedLA664.td (+1138)
- (added) llvm/lib/Target/LoongArch/LoongArchSchedule.td (+520)
- (added) llvm/lib/Target/LoongArch/LoongArchScheduleV.td (+1291)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/floating-point.s (+27)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/integer.s (+22)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/lasx.s (+27)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/lsx.s (+41)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/memory.s (+22)
- (added) llvm/test/tools/llvm-mca/LoongArch/Inputs/mul-div.s (+9)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/floating-point.test (+88)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/integer.test (+78)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/lasx.test (+88)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/lsx.test (+116)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/memory.test (+78)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA464/mul-div.test (+52)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/floating-point.test (+93)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/integer.test (+83)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/lasx.test (+93)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/lsx.test (+121)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/memory.test (+83)
- (added) llvm/test/tools/llvm-mca/LoongArch/LA664/mul-div.test (+57)
- (added) llvm/test/tools/llvm-mca/LoongArch/lit.local.cfg (+2)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 577dcbed48eea..0514e36a96563 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -155,13 +155,21 @@ def TunePreferWInst
"Prefer instructions with W suffix">;
//===----------------------------------------------------------------------===//
-// Registers, instruction descriptions ...
+// Schedule, Registers, instruction descriptions ...
//===----------------------------------------------------------------------===//
+include "LoongArchSchedule.td"
include "LoongArchRegisterInfo.td"
include "LoongArchCallingConv.td"
include "LoongArchInstrInfo.td"
+//===----------------------------------------------------------------------===//
+// LoongArch Scheduling Models.
+//===----------------------------------------------------------------------===//
+
+include "LoongArchSchedLA464.td"
+include "LoongArchSchedLA664.td"
+
//===----------------------------------------------------------------------===//
// LoongArch processors supported.
//===----------------------------------------------------------------------===//
@@ -183,13 +191,13 @@ def : ProcessorModel<"loongarch64", NoSchedModel, [Feature64Bit,
// to change to the appropriate la32/la64 version.
def : ProcessorModel<"generic", NoSchedModel, []>;
-def : ProcessorModel<"la464", NoSchedModel, [Feature64Bit,
+def : ProcessorModel<"la464", LA464Model, [Feature64Bit,
FeatureUAL,
FeatureExtLASX,
FeatureExtLVZ,
FeatureExtLBT]>;
-def : ProcessorModel<"la664", NoSchedModel, [Feature64Bit,
+def : ProcessorModel<"la664", LA664Model, [Feature64Bit,
FeatureUAL,
FeatureExtLASX,
FeatureExtLVZ,
diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
index 27d5fa1fab62a..3c5635942ca8c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
@@ -54,112 +54,189 @@ def loongarch_sitof : SDNode<"LoongArchISD::SITOF", SDT_LoongArchITOF>;
let Predicates = [HasBasicF] in {
// Arithmetic Operation Instructions
-def FADD_S : FP_ALU_3R<0x01008000>;
-def FSUB_S : FP_ALU_3R<0x01028000>;
-def FMUL_S : FP_ALU_3R<0x01048000>;
-def FDIV_S : FP_ALU_3R<0x01068000>;
-def FMADD_S : FP_ALU_4R<0x08100000>;
-def FMSUB_S : FP_ALU_4R<0x08500000>;
-def FNMADD_S : FP_ALU_4R<0x08900000>;
-def FNMSUB_S : FP_ALU_4R<0x08d00000>;
-def FMAX_S : FP_ALU_3R<0x01088000>;
-def FMIN_S : FP_ALU_3R<0x010a8000>;
-def FMAXA_S : FP_ALU_3R<0x010c8000>;
-def FMINA_S : FP_ALU_3R<0x010e8000>;
-def FABS_S : FP_ALU_2R<0x01140400>;
-def FNEG_S : FP_ALU_2R<0x01141400>;
-def FSQRT_S : FP_ALU_2R<0x01144400>;
-def FRECIP_S : FP_ALU_2R<0x01145400>;
-def FRSQRT_S : FP_ALU_2R<0x01146400>;
-def FRECIPE_S : FP_ALU_2R<0x01147400>;
-def FRSQRTE_S : FP_ALU_2R<0x01148400>;
-def FSCALEB_S : FP_ALU_3R<0x01108000>;
-def FLOGB_S : FP_ALU_2R<0x01142400>;
-def FCOPYSIGN_S : FP_ALU_3R<0x01128000>;
-def FCLASS_S : FP_ALU_2R<0x01143400>;
+def FADD_S : FP_ALU_3R<0x01008000>,
+ Sched<[WriteFADD, ReadFADD, ReadFADD]>;
+def FSUB_S : FP_ALU_3R<0x01028000>,
+ Sched<[WriteFADD, ReadFADD, ReadFADD]>;
+def FMUL_S : FP_ALU_3R<0x01048000>,
+ Sched<[WriteFMUL, ReadFMUL, ReadFMUL]>;
+def FDIV_S : FP_ALU_3R<0x01068000>,
+ Sched<[WriteFDIV32, ReadFDIV32, ReadFDIV32]>;
+def FMADD_S : FP_ALU_4R<0x08100000>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FMSUB_S : FP_ALU_4R<0x08500000>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FNMADD_S : FP_ALU_4R<0x08900000>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FNMSUB_S : FP_ALU_4R<0x08d00000>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FMAX_S : FP_ALU_3R<0x01088000>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMIN_S : FP_ALU_3R<0x010a8000>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMAXA_S : FP_ALU_3R<0x010c8000>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMINA_S : FP_ALU_3R<0x010e8000>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FABS_S : FP_ALU_2R<0x01140400>,
+ Sched<[WriteFABS, ReadFABS]>;
+def FNEG_S : FP_ALU_2R<0x01141400>,
+ Sched<[WriteFNEG, ReadFNEG]>;
+def FSQRT_S : FP_ALU_2R<0x01144400>,
+ Sched<[WriteFSQRT32, ReadFSQRT32]>;
+def FRECIP_S : FP_ALU_2R<0x01145400>,
+ Sched<[WriteFRECIP32, ReadFRECIP32]>;
+def FRSQRT_S : FP_ALU_2R<0x01146400>,
+ Sched<[WriteFRSQRT32, ReadFRSQRT32]>;
+def FRECIPE_S : FP_ALU_2R<0x01147400>,
+ Sched<[WriteFRECIPE, ReadFRECIPE]>;
+def FRSQRTE_S : FP_ALU_2R<0x01148400>,
+ Sched<[WriteFRSQRTE, ReadFRSQRTE]>;
+def FSCALEB_S : FP_ALU_3R<0x01108000>,
+ Sched<[WriteFSCALEB, ReadFSCALEB, ReadFSCALEB]>;
+def FLOGB_S : FP_ALU_2R<0x01142400>,
+ Sched<[WriteFLOGB, ReadFLOGB]>;
+def FCOPYSIGN_S : FP_ALU_3R<0x01128000>,
+ Sched<[WriteFCOPYSIGN, ReadFCOPYSIGN, ReadFCOPYSIGN]>;
+def FCLASS_S : FP_ALU_2R<0x01143400>,
+ Sched<[WriteFCLASS, ReadFCLASS]>;
// Comparison Instructions
-def FCMP_CAF_S : FP_CMP<0x0c100000>;
-def FCMP_CUN_S : FP_CMP<0x0c140000>;
-def FCMP_CEQ_S : FP_CMP<0x0c120000>;
-def FCMP_CUEQ_S : FP_CMP<0x0c160000>;
-def FCMP_CLT_S : FP_CMP<0x0c110000>;
-def FCMP_CULT_S : FP_CMP<0x0c150000>;
-def FCMP_CLE_S : FP_CMP<0x0c130000>;
-def FCMP_CULE_S : FP_CMP<0x0c170000>;
-def FCMP_CNE_S : FP_CMP<0x0c180000>;
-def FCMP_COR_S : FP_CMP<0x0c1a0000>;
-def FCMP_CUNE_S : FP_CMP<0x0c1c0000>;
-def FCMP_SAF_S : FP_CMP<0x0c108000>;
-def FCMP_SUN_S : FP_CMP<0x0c148000>;
-def FCMP_SEQ_S : FP_CMP<0x0c128000>;
-def FCMP_SUEQ_S : FP_CMP<0x0c168000>;
-def FCMP_SLT_S : FP_CMP<0x0c118000>;
-def FCMP_SULT_S : FP_CMP<0x0c158000>;
-def FCMP_SLE_S : FP_CMP<0x0c138000>;
-def FCMP_SULE_S : FP_CMP<0x0c178000>;
-def FCMP_SNE_S : FP_CMP<0x0c188000>;
-def FCMP_SOR_S : FP_CMP<0x0c1a8000>;
-def FCMP_SUNE_S : FP_CMP<0x0c1c8000>;
+def FCMP_CAF_S : FP_CMP<0x0c100000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUN_S : FP_CMP<0x0c140000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CEQ_S : FP_CMP<0x0c120000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUEQ_S : FP_CMP<0x0c160000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CLT_S : FP_CMP<0x0c110000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CULT_S : FP_CMP<0x0c150000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CLE_S : FP_CMP<0x0c130000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CULE_S : FP_CMP<0x0c170000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CNE_S : FP_CMP<0x0c180000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_COR_S : FP_CMP<0x0c1a0000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUNE_S : FP_CMP<0x0c1c0000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SAF_S : FP_CMP<0x0c108000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SUN_S : FP_CMP<0x0c148000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SEQ_S : FP_CMP<0x0c128000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SUEQ_S : FP_CMP<0x0c168000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SLT_S : FP_CMP<0x0c118000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SULT_S : FP_CMP<0x0c158000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SLE_S : FP_CMP<0x0c138000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SULE_S : FP_CMP<0x0c178000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SNE_S : FP_CMP<0x0c188000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SOR_S : FP_CMP<0x0c1a8000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SUNE_S : FP_CMP<0x0c1c8000>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
// Conversion Instructions
-def FFINT_S_W : FP_CONV<0x011d1000>;
-def FTINT_W_S : FP_CONV<0x011b0400>;
-def FTINTRM_W_S : FP_CONV<0x011a0400>;
-def FTINTRP_W_S : FP_CONV<0x011a4400>;
-def FTINTRZ_W_S : FP_CONV<0x011a8400>;
-def FTINTRNE_W_S : FP_CONV<0x011ac400>;
-def FRINT_S : FP_CONV<0x011e4400>;
+def FFINT_S_W : FP_CONV<0x011d1000>,
+ Sched<[WriteFCvtStoW, ReadFCvtStoW]>;
+def FTINT_W_S : FP_CONV<0x011b0400>,
+ Sched<[WriteFCvtWtoS, ReadFCvtWtoS]>;
+def FTINTRM_W_S : FP_CONV<0x011a0400>,
+ Sched<[WriteFCvtWtoS_RM, ReadFCvtWtoS_RM]>;
+def FTINTRP_W_S : FP_CONV<0x011a4400>,
+ Sched<[WriteFCvtWtoS_RP, ReadFCvtWtoS_RP]>;
+def FTINTRZ_W_S : FP_CONV<0x011a8400>,
+ Sched<[WriteFCvtWtoS_RZ, ReadFCvtWtoS_RZ]>;
+def FTINTRNE_W_S : FP_CONV<0x011ac400>,
+ Sched<[WriteFCvtWtoS_RNE, ReadFCvtWtoS_RNE]>;
+def FRINT_S : FP_CONV<0x011e4400>,
+ Sched<[WriteFCvtFStoIS, ReadFCvtFStoIS]>;
// Move Instructions
-def FSEL_xS : FP_SEL<0x0d000000>;
-def FMOV_S : FP_MOV<0x01149400>;
-def MOVGR2FR_W : FP_MOV<0x0114a400, FPR32, GPR>;
-def MOVFR2GR_S : FP_MOV<0x0114b400, GPR, FPR32>;
+def FSEL_xS : FP_SEL<0x0d000000>,
+ Sched<[WriteFSEL, ReadFSEL, ReadFSEL, ReadFSEL]>;
+def FMOV_S : FP_MOV<0x01149400>,
+ Sched<[WriteFMovS, ReadFMovS]>;
+def MOVGR2FR_W : FP_MOV<0x0114a400, FPR32, GPR>,
+ Sched<[WriteFMovGRtoFRW, ReadFMovGRtoFRW]>;
+def MOVFR2GR_S : FP_MOV<0x0114b400, GPR, FPR32>,
+ Sched<[WriteFMovFRtoGRS, ReadFMovFRtoGRS]>;
let hasSideEffects = 1 in {
-def MOVGR2FCSR : FP_MOV<0x0114c000, FCSR, GPR>;
-def MOVFCSR2GR : FP_MOV<0x0114c800, GPR, FCSR>;
+def MOVGR2FCSR : FP_MOV<0x0114c000, FCSR, GPR>,
+ Sched<[WriteFMovGRtoFCSR, ReadFMovGRtoFCSR]>;
+def MOVFCSR2GR : FP_MOV<0x0114c800, GPR, FCSR>,
+ Sched<[WriteFMovFCSRtoGR, ReadFMovFCSRtoGR]>;
} // hasSideEffects = 1
-def MOVFR2CF_xS : FP_MOV<0x0114d000, CFR, FPR32>;
-def MOVCF2FR_xS : FP_MOV<0x0114d400, FPR32, CFR>;
-def MOVGR2CF : FP_MOV<0x0114d800, CFR, GPR>;
-def MOVCF2GR : FP_MOV<0x0114dc00, GPR, CFR>;
+def MOVFR2CF_xS : FP_MOV<0x0114d000, CFR, FPR32>,
+ Sched<[WriteFMoveFRtoCF, ReadFMoveFRtoCF]>;
+def MOVCF2FR_xS : FP_MOV<0x0114d400, FPR32, CFR>,
+ Sched<[WriteFMoveCFtoFR, ReadFMoveCFtoFR]>;
+def MOVGR2CF : FP_MOV<0x0114d800, CFR, GPR>,
+ Sched<[WriteFMoveGRtoCF, ReadFMoveGRtoCF]>;
+def MOVCF2GR : FP_MOV<0x0114dc00, GPR, CFR>,
+ Sched<[WriteFMoveCFtoGR, ReadFMoveCFtoGR]>;
// Branch Instructions
-def BCEQZ : FP_BRANCH<0x48000000>;
-def BCNEZ : FP_BRANCH<0x48000100>;
+def BCEQZ : FP_BRANCH<0x48000000>,
+ Sched<[WriteFJump, ReadFJump]>;
+def BCNEZ : FP_BRANCH<0x48000100>,
+ Sched<[WriteFJump, ReadFJump]>;
// Common Memory Access Instructions
-def FLD_S : FP_LOAD_2RI12<0x2b000000>;
-def FST_S : FP_STORE_2RI12<0x2b400000>;
-def FLDX_S : FP_LOAD_3R<0x38300000>;
-def FSTX_S : FP_STORE_3R<0x38380000>;
+def FLD_S : FP_LOAD_2RI12<0x2b000000>,
+ Sched<[WriteFLD, ReadFMemBase]>;
+def FST_S : FP_STORE_2RI12<0x2b400000>,
+ Sched<[WriteFST, ReadFSTData, ReadFMemBase]>;
+def FLDX_S : FP_LOAD_3R<0x38300000>,
+ Sched<[WriteFLDX, ReadFMemBase, ReadFMemOffset]>;
+def FSTX_S : FP_STORE_3R<0x38380000>,
+ Sched<[WriteFSTX, ReadFSTData, ReadFMemBase, ReadFMemOffset]>;
// Bound Check Memory Access Instructions
-def FLDGT_S : FP_LOAD_3R<0x38740000>;
-def FLDLE_S : FP_LOAD_3R<0x38750000>;
-def FSTGT_S : FP_STORE_3R<0x38760000>;
-def FSTLE_S : FP_STORE_3R<0x38770000>;
+def FLDGT_S : FP_LOAD_3R<0x38740000>,
+ Sched<[WriteFLDGT, ReadFMemBase, ReadFMemCmp]>;
+def FLDLE_S : FP_LOAD_3R<0x38750000>,
+ Sched<[WriteFLDLE, ReadFMemBase, ReadFMemCmp]>;
+def FSTGT_S : FP_STORE_3R<0x38760000>,
+ Sched<[WriteFSTGT, ReadFSTData, ReadFMemBase, ReadFMemCmp]>;
+def FSTLE_S : FP_STORE_3R<0x38770000>,
+ Sched<[WriteFSTLE, ReadFSTData, ReadFMemBase, ReadFMemCmp]>;
// Pseudo instructions for spill/reload CFRs.
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def PseudoST_CFR : Pseudo<(outs),
- (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>;
+ (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>,
+ Sched<[WritePseudo, ReadPseudo, ReadPseudo]>;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def PseudoLD_CFR : Pseudo<(outs CFR:$ccd),
- (ins GPR:$rj, grlenimm:$imm)>;
+ (ins GPR:$rj, grlenimm:$imm)>,
+ Sched<[WritePseudo, ReadPseudo]>;
// SET_CFR_{FALSE,TRUE}
// These instructions are defined in order to avoid expensive check error if
// regular instruction patterns are used.
// fcmp.caf.s $dst, $fa0, $fa0
-def SET_CFR_FALSE : SET_CFR<0x0c100000, "fcmp.caf.s">;
+def SET_CFR_FALSE : SET_CFR<0x0c100000, "fcmp.caf.s">,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
// fcmp.cueq.s $dst, $fa0, $fa0
-def SET_CFR_TRUE : SET_CFR<0x0c160000, "fcmp.cueq.s">;
+def SET_CFR_TRUE : SET_CFR<0x0c160000, "fcmp.cueq.s">,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
// Pseudo instruction for copying CFRs.
-def PseudoCopyCFR : Pseudo<(outs CFR:$dst), (ins CFR:$src)> {
+def PseudoCopyCFR : Pseudo<(outs CFR:$dst), (ins CFR:$src)>,
+ Sched<[WritePseudo, ReadPseudo]> {
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
index 6eb9398b4d34a..398884397469f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
@@ -33,113 +33,196 @@ def loongarch_movgr2fr_d_lo_hi
let Predicates = [HasBasicD] in {
// Arithmetic Operation Instructions
-def FADD_D : FP_ALU_3R<0x01010000, FPR64>;
-def FSUB_D : FP_ALU_3R<0x01030000, FPR64>;
-def FMUL_D : FP_ALU_3R<0x01050000, FPR64>;
-def FDIV_D : FP_ALU_3R<0x01070000, FPR64>;
-def FMADD_D : FP_ALU_4R<0x08200000, FPR64>;
-def FMSUB_D : FP_ALU_4R<0x08600000, FPR64>;
-def FNMADD_D : FP_ALU_4R<0x08a00000, FPR64>;
-def FNMSUB_D : FP_ALU_4R<0x08e00000, FPR64>;
-def FMAX_D : FP_ALU_3R<0x01090000, FPR64>;
-def FMIN_D : FP_ALU_3R<0x010b0000, FPR64>;
-def FMAXA_D : FP_ALU_3R<0x010d0000, FPR64>;
-def FMINA_D : FP_ALU_3R<0x010f0000, FPR64>;
-def FABS_D : FP_ALU_2R<0x01140800, FPR64>;
-def FNEG_D : FP_ALU_2R<0x01141800, FPR64>;
-def FSQRT_D : FP_ALU_2R<0x01144800, FPR64>;
-def FRECIP_D : FP_ALU_2R<0x01145800, FPR64>;
-def FRSQRT_D : FP_ALU_2R<0x01146800, FPR64>;
-def FRECIPE_D : FP_ALU_2R<0x01147800, FPR64>;
-def FRSQRTE_D : FP_ALU_2R<0x01148800, FPR64>;
-def FSCALEB_D : FP_ALU_3R<0x01110000, FPR64>;
-def FLOGB_D : FP_ALU_2R<0x01142800, FPR64>;
-def FCOPYSIGN_D : FP_ALU_3R<0x01130000, FPR64>;
-def FCLASS_D : FP_ALU_2R<0x01143800, FPR64>;
+def FADD_D : FP_ALU_3R<0x01010000, FPR64>,
+ Sched<[WriteFADD, ReadFADD, ReadFADD]>;
+def FSUB_D : FP_ALU_3R<0x01030000, FPR64>,
+ Sched<[WriteFADD, ReadFADD, ReadFADD]>;
+def FMUL_D : FP_ALU_3R<0x01050000, FPR64>,
+ Sched<[WriteFMUL, ReadFMUL, ReadFMUL]>;
+def FDIV_D : FP_ALU_3R<0x01070000, FPR64>,
+ Sched<[WriteFDIV, ReadFDIV, ReadFDIV]>;
+def FMADD_D : FP_ALU_4R<0x08200000, FPR64>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FMSUB_D : FP_ALU_4R<0x08600000, FPR64>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FNMADD_D : FP_ALU_4R<0x08a00000, FPR64>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FNMSUB_D : FP_ALU_4R<0x08e00000, FPR64>,
+ Sched<[WriteFMADD, ReadFMADD, ReadFMADD, ReadFMADD]>;
+def FMAX_D : FP_ALU_3R<0x01090000, FPR64>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMIN_D : FP_ALU_3R<0x010b0000, FPR64>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMAXA_D : FP_ALU_3R<0x010d0000, FPR64>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FMINA_D : FP_ALU_3R<0x010f0000, FPR64>,
+ Sched<[WriteFMinMax, ReadFMinMax, ReadFMinMax]>;
+def FABS_D : FP_ALU_2R<0x01140800, FPR64>,
+ Sched<[WriteFABS, ReadFABS]>;
+def FNEG_D : FP_ALU_2R<0x01141800, FPR64>,
+ Sched<[WriteFNEG, ReadFNEG]>;
+def FSQRT_D : FP_ALU_2R<0x01144800, FPR64>,
+ Sched<[WriteFSQRT, ReadFSQRT]>;
+def FRECIP_D : FP_ALU_2R<0x01145800, FPR64>,
+ Sched<[WriteFRECIP, ReadFRECIP]>;
+def FRSQRT_D : FP_ALU_2R<0x01146800, FPR64>,
+ Sched<[WriteFRSQRT, ReadFRSQRT]>;
+def FRECIPE_D : FP_ALU_2R<0x01147800, FPR64>,
+ Sched<[WriteFRECIPE, ReadFRECIPE]>;
+def FRSQRTE_D : FP_ALU_2R<0x01148800, FPR64>,
+ Sched<[WriteFRSQRTE, ReadFRSQRTE]>;
+def FSCALEB_D : FP_ALU_3R<0x01110000, FPR64>,
+ Sched<[WriteFSCALEB, ReadFSCALEB, ReadFSCALEB]>;
+def FLOGB_D : FP_ALU_2R<0x01142800, FPR64>,
+ Sched<[WriteFLOGB, ReadFLOGB]>;
+def FCOPYSIGN_D : FP_ALU_3R<0x01130000, FPR64>,
+ Sched<[WriteFCOPYSIGN, ReadFCOPYSIGN, ReadFCOPYSIGN]>;
+def FCLASS_D : FP_ALU_2R<0x01143800, FPR64>,
+ Sched<[WriteFCLASS, ReadFCLASS]>;
// Comparison Instructions
-def FCMP_CAF_D : FP_CMP<0x0c200000, FPR64>;
-def FCMP_CUN_D : FP_CMP<0x0c240000, FPR64>;
-def FCMP_CEQ_D : FP_CMP<0x0c220000, FPR64>;
-def FCMP_CUEQ_D : FP_CMP<0x0c260000, FPR64>;
-def FCMP_CLT_D : FP_CMP<0x0c210000, FPR64>;
-def FCMP_CULT_D : FP_CMP<0x0c250000, FPR64>;
-def FCMP_CLE_D : FP_CMP<0x0c230000, FPR64>;
-def FCMP_CULE_D : FP_CMP<0x0c270000, FPR64>;
-def FCMP_CNE_D : FP_CMP<0x0c280000, FPR64>;
-def FCMP_COR_D : FP_CMP<0x0c2a0000, FPR64>;
-def FCMP_CUNE_D : FP_CMP<0x0c2c0000, FPR64>;
-def FCMP_SAF_D : FP_CMP<0x0c208000, FPR64>;
-def FCMP_SUN_D : FP_CMP<0x0c248000, FPR64>;
-def FCMP_SEQ_D : FP_CMP<0x0c228000, FPR64>;
-def FCMP_SUEQ_D : FP_CMP<0x0c268000, FPR64>;
-def FCMP_SLT_D : FP_CMP<0x0c218000, FPR64>;
-def FCMP_SULT_D : FP_CMP<0x0c258000, FPR64>;
-def FCMP_SLE_D : FP_CMP<0x0c238000, FPR64>;
-def FCMP_SULE_D : FP_CMP<0x0c278000, FPR64>;
-def FCMP_SNE_D : FP_CMP<0x0c288000, FPR64>;
-def FCMP_SOR_D : FP_CMP<0x0c2a8000, FPR64>;
-def FCMP_SUNE_D : FP_CMP<0x0c2c8000, FPR64>;
+def FCMP_CAF_D : FP_CMP<0x0c200000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUN_D : FP_CMP<0x0c240000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CEQ_D : FP_CMP<0x0c220000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUEQ_D : FP_CMP<0x0c260000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CLT_D : FP_CMP<0x0c210000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CULT_D : FP_CMP<0x0c250000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CLE_D : FP_CMP<0x0c230000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CULE_D : FP_CMP<0x0c270000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CNE_D : FP_CMP<0x0c280000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_COR_D : FP_CMP<0x0c2a0000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_CUNE_D : FP_CMP<0x0c2c0000, FPR64>,
+ Sched<[WriteFCMP, ReadFCMP, ReadFCMP]>;
+def FCMP_SAF_D : FP_CMP<0x0c208000, FPR64>,
+ S...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/226064
More information about the llvm-commits
mailing list