[llvm] [X86] Use the Divider resource consistently for scalar integer division (PR #204972)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 21 20:39:11 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Adam Scott (as4230)
<details>
<summary>Changes</summary>
The Intel scheduler models from Haswell through Ice Lake model scalar integer division inconsistently. The Divider resource is used by some forms but not others with no consistent rule and on most of these models the 16/32/64-bit register forms just put one flat latency across the issue ports with no divider at all.
On Skylake, for example, the register form of DIV32 is given a latency of 76 with 32 uops, and IDIV32 a latency of 102 with 66 uops, when the real numbers are closer to 28 cycles and 10 uops. The same flat latency is used for every width so DIV stays 76 whether it is 16, 32 or 64 bit and IDIV stays 102, even though a 64-bit divide is slower than a 16-bit one.
Every WriteDiv and WriteIDiv form now goes through the Divider. The latency, throughput and uop counts come from uops.info.
## Data sources:
- DIV:
https://uops.info/html-instr/DIV_R8l.html
https://uops.info/html-instr/DIV_R16.html
https://uops.info/html-instr/DIV_R32.html
https://uops.info/html-instr/DIV_R64.html
- IDIV:
https://uops.info/html-instr/IDIV_R8l.html
https://uops.info/html-instr/IDIV_R16.html
https://uops.info/html-instr/IDIV_R32.html
https://uops.info/html-instr/IDIV_R64.html
## Changes:
Format below is latency / divider / uops, where divider is the number of cycles the Divider resource is held or ports if that form didn't use the Divider and latency is worst-case max across all operand paths.
### Haswell
| Class | Before | After |
|--------|------------------|---------------|
| DIV8 | 22 / ports / 9 | 24 / 9 / 9 |
| DIV16 | 98 / ports / 32 | 25 / 9 / 11 |
| DIV32 | 98 / ports / 32 | 28 / 9 / 10 |
| DIV64 | 98 / ports / 32 | 94 / 21 / 36 |
| IDIV8 | 23 / ports / 9 | 24 / 8 / 9 |
| IDIV16 | 112 / ports / 66 | 25 / 8 / 10 |
| IDIV32 | 112 / ports / 66 | 28 / 8 / 9 |
| IDIV64 | 112 / ports / 66 | 101 / 24 / 59 |
### Broadwell
| Class | Before | After |
|--------|-----------------|---------------|
| DIV8 | 25 / 10 / 1 | 24 / 9 / 9 |
| DIV16 | 80 / ports / 32 | 25 / 9 / 11 |
| DIV32 | 80 / ports / 32 | 28 / 9 / 10 |
| DIV64 | 80 / ports / 32 | 92 / 21 / 36 |
| IDIV8 | 25 / 10 / 1 | 24 / 6 / 9 |
| IDIV16 | 25 / 10 / 1 | 26 / 6 / 10 |
| IDIV32 | 25 / 10 / 1 | 28 / 6 / 9 |
| IDIV64 | 25 / 10 / 1 | 100 / 24 / 59 |
### Skylake
| Class | Before | After |
|--------|------------------|--------------|
| DIV8 | 25 / 10 / 1 | 25 / 6 / 10 |
| DIV16 | 76 / ports / 32 | 24 / 6 / 10 |
| DIV32 | 76 / ports / 32 | 28 / 6 / 10 |
| DIV64 | 76 / ports / 32 | 90 / 21 / 36 |
| IDIV8 | 25 / 10 / 1 | 25 / 6 / 11 |
| IDIV16 | 102 / ports / 66 | 24 / 6 / 10 |
| IDIV32 | 102 / ports / 66 | 28 / 6 / 10 |
| IDIV64 | 102 / ports / 66 | 96 / 24 / 57 |
### Ice Lake
| Class | Before | After |
|--------|------------------|-------------|
| DIV8 | 25 / 10 / 1 | 15 / 6 / 4 |
| DIV16 | 76 / ports / 32 | 16 / 6 / 6 |
| DIV32 | 76 / ports / 32 | 15 / 6 / 4 |
| DIV64 | 76 / ports / 32 | 18 / 10 / 4 |
| IDIV8 | 25 / 10 / 1 | 15 / 6 / 4 |
| IDIV16 | 102 / ports / 66 | 16 / 6 / 6 |
| IDIV32 | 102 / ports / 66 | 15 / 6 / 4 |
| IDIV64 | 102 / ports / 66 | 18 / 10 / 4 |
Fixes #<!-- -->201568.
---
Patch is 108.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/204972.diff
14 Files Affected:
- (modified) llvm/lib/Target/X86/X86SchedBroadwell.td (+9-18)
- (modified) llvm/lib/Target/X86/X86SchedHaswell.td (+9-18)
- (modified) llvm/lib/Target/X86/X86SchedIceLake.td (+9-17)
- (modified) llvm/lib/Target/X86/X86SchedSkylakeClient.td (+9-17)
- (modified) llvm/lib/Target/X86/X86SchedSkylakeServer.td (+9-17)
- (modified) llvm/test/CodeGen/X86/masked-sdiv.ll (+88-101)
- (modified) llvm/test/CodeGen/X86/masked-srem.ll (+89-103)
- (modified) llvm/test/CodeGen/X86/masked-udiv.ll (+94-94)
- (modified) llvm/test/CodeGen/X86/masked-urem.ll (+94-94)
- (modified) llvm/test/tools/llvm-mca/X86/Broadwell/resources-x86_64.s (+33-33)
- (modified) llvm/test/tools/llvm-mca/X86/Haswell/resources-x86_64.s (+33-33)
- (modified) llvm/test/tools/llvm-mca/X86/IceLakeServer/resources-x86_64.s (+32-32)
- (modified) llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x86_64.s (+33-33)
- (modified) llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x86_64.s (+33-33)
``````````diff
diff --git a/llvm/lib/Target/X86/X86SchedBroadwell.td b/llvm/lib/Target/X86/X86SchedBroadwell.td
index 4b697c4336341..da0fa935c7567 100644
--- a/llvm/lib/Target/X86/X86SchedBroadwell.td
+++ b/llvm/lib/Target/X86/X86SchedBroadwell.td
@@ -212,24 +212,15 @@ defm : BWWriteResPair<WriteBEXTR, [BWPort06,BWPort15], 2, [1,1], 2>;
defm : BWWriteResPair<WriteBLS, [BWPort15], 1>;
defm : BWWriteResPair<WriteBZHI, [BWPort15], 1>;
-// TODO: Why isn't the BWDivider used consistently?
-defm : X86WriteRes<WriteDiv8, [BWPort0, BWDivider], 25, [1, 10], 1>;
-defm : X86WriteRes<WriteDiv16, [BWPort0,BWPort1,BWPort5,BWPort6,BWPort01,BWPort0156], 80, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv32, [BWPort0,BWPort1,BWPort5,BWPort6,BWPort01,BWPort0156], 80, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv64, [BWPort0,BWPort1,BWPort5,BWPort6,BWPort01,BWPort0156], 80, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv8Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 34, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteDiv16Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 34, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteDiv32Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 34, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteDiv64Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 34, [2,2,2,1,1], 8>;
-
-defm : X86WriteRes<WriteIDiv8, [BWPort0, BWDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv16, [BWPort0, BWDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv32, [BWPort0, BWDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv64, [BWPort0, BWDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv8Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 35, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteIDiv16Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 35, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteIDiv32Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 35, [2,2,2,1,1], 8>;
-defm : X86WriteRes<WriteIDiv64Ld, [BWPort0,BWPort1,BWPort5,BWPort23,BWPort0156], 35, [2,2,2,1,1], 8>;
+defm : BWWriteResPair<WriteDiv8, [BWPort0, BWDivider], 24, [1,9], 9>;
+defm : BWWriteResPair<WriteDiv16, [BWPort0, BWDivider], 25, [1,9], 11>;
+defm : BWWriteResPair<WriteDiv32, [BWPort0, BWDivider], 28, [1,9], 10>;
+defm : BWWriteResPair<WriteDiv64, [BWPort0, BWDivider], 92, [1,21], 36>;
+
+defm : BWWriteResPair<WriteIDiv8, [BWPort0, BWDivider], 24, [1,6], 9>;
+defm : BWWriteResPair<WriteIDiv16, [BWPort0, BWDivider], 26, [1,6], 10>;
+defm : BWWriteResPair<WriteIDiv32, [BWPort0, BWDivider], 28, [1,6], 9>;
+defm : BWWriteResPair<WriteIDiv64, [BWPort0, BWDivider], 100, [1,24], 59>;
// Floating point. This covers both scalar and vector operations.
defm : X86WriteRes<WriteFLD0, [BWPort01], 1, [1], 1>;
diff --git a/llvm/lib/Target/X86/X86SchedHaswell.td b/llvm/lib/Target/X86/X86SchedHaswell.td
index dd1e1c3a6cb53..d6f0d3f4e179f 100644
--- a/llvm/lib/Target/X86/X86SchedHaswell.td
+++ b/llvm/lib/Target/X86/X86SchedHaswell.td
@@ -214,24 +214,15 @@ defm : HWWriteResPair<WriteBEXTR, [HWPort06,HWPort15], 2, [1,1], 2>;
defm : HWWriteResPair<WriteBLS, [HWPort15], 1>;
defm : HWWriteResPair<WriteBZHI, [HWPort15], 1>;
-// TODO: Why isn't the HWDivider used?
-defm : X86WriteRes<WriteDiv8, [HWPort0,HWPort1,HWPort5,HWPort6], 22, [], 9>;
-defm : X86WriteRes<WriteDiv16, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort01,HWPort0156], 98, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv32, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort01,HWPort0156], 98, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv64, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort01,HWPort0156], 98, [7,7,3,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv8Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv16Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv32Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv64Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-
-defm : X86WriteRes<WriteIDiv8, [HWPort0,HWPort1,HWPort5,HWPort6], 23, [], 9>;
-defm : X86WriteRes<WriteIDiv16, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort06,HWPort0156], 112, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv32, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort06,HWPort0156], 112, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv64, [HWPort0,HWPort1,HWPort5,HWPort6,HWPort06,HWPort0156], 112, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv8Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteIDiv16Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteIDiv32Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteIDiv64Ld, [HWPort0,HWPort23,HWDivider], 29, [1,1,10], 2>;
+defm : HWWriteResPair<WriteDiv8, [HWPort0, HWDivider], 24, [1,9], 9>;
+defm : HWWriteResPair<WriteDiv16, [HWPort0, HWDivider], 25, [1,9], 11>;
+defm : HWWriteResPair<WriteDiv32, [HWPort0, HWDivider], 28, [1,9], 10>;
+defm : HWWriteResPair<WriteDiv64, [HWPort0, HWDivider], 94, [1,21], 36>;
+
+defm : HWWriteResPair<WriteIDiv8, [HWPort0, HWDivider], 24, [1,8], 9>;
+defm : HWWriteResPair<WriteIDiv16, [HWPort0, HWDivider], 25, [1,8], 10>;
+defm : HWWriteResPair<WriteIDiv32, [HWPort0, HWDivider], 28, [1,8], 9>;
+defm : HWWriteResPair<WriteIDiv64, [HWPort0, HWDivider], 101, [1,24], 59>;
// Floating point. This covers both scalar and vector operations.
defm : X86WriteRes<WriteFLD0, [HWPort01], 1, [1], 1>;
diff --git a/llvm/lib/Target/X86/X86SchedIceLake.td b/llvm/lib/Target/X86/X86SchedIceLake.td
index 1c57093c89796..594296355592a 100644
--- a/llvm/lib/Target/X86/X86SchedIceLake.td
+++ b/llvm/lib/Target/X86/X86SchedIceLake.td
@@ -148,23 +148,15 @@ defm : X86WriteRes<WriteCMPXCHG,[ICXPort06, ICXPort0156], 5, [2,3], 5>;
defm : X86WriteRes<WriteCMPXCHGRMW,[ICXPort23,ICXPort06,ICXPort0156,ICXPort78,ICXPort49], 8, [1,2,1,1,1], 6>;
defm : X86WriteRes<WriteXCHG, [ICXPort0156], 2, [3], 3>;
-// TODO: Why isn't the ICXDivider used?
-defm : ICXWriteResPair<WriteDiv8, [ICXPort0, ICXDivider], 25, [1,10], 1, 4>;
-defm : X86WriteRes<WriteDiv16, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort05,ICXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv32, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort05,ICXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv64, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort05,ICXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv16Ld, [ICXPort0,ICXPort23,ICXDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv32Ld, [ICXPort0,ICXPort23,ICXDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv64Ld, [ICXPort0,ICXPort23,ICXDivider], 29, [1,1,10], 2>;
-
-defm : X86WriteRes<WriteIDiv8, [ICXPort0, ICXDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv16, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort06,ICXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv32, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort06,ICXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv64, [ICXPort0,ICXPort1,ICXPort5,ICXPort6,ICXPort06,ICXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv8Ld, [ICXPort0,ICXPort5,ICXPort23,ICXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv16Ld, [ICXPort0,ICXPort5,ICXPort23,ICXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv32Ld, [ICXPort0,ICXPort5,ICXPort23,ICXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv64Ld, [ICXPort0,ICXPort5,ICXPort23,ICXPort0156], 28, [2,4,1,1], 8>;
+defm : ICXWriteResPair<WriteDiv8, [ICXPort0, ICXDivider], 15, [1,6], 4>;
+defm : ICXWriteResPair<WriteDiv16, [ICXPort0, ICXDivider], 16, [1,6], 6>;
+defm : ICXWriteResPair<WriteDiv32, [ICXPort0, ICXDivider], 15, [1,6], 4>;
+defm : ICXWriteResPair<WriteDiv64, [ICXPort0, ICXDivider], 18, [1,10], 4>;
+
+defm : ICXWriteResPair<WriteIDiv8, [ICXPort0, ICXDivider], 15, [1,6], 4>;
+defm : ICXWriteResPair<WriteIDiv16, [ICXPort0, ICXDivider], 16, [1,6], 6>;
+defm : ICXWriteResPair<WriteIDiv32, [ICXPort0, ICXDivider], 15, [1,6], 4>;
+defm : ICXWriteResPair<WriteIDiv64, [ICXPort0, ICXDivider], 18, [1,10], 4>;
defm : ICXWriteResPair<WriteCRC32, [ICXPort1], 3>;
diff --git a/llvm/lib/Target/X86/X86SchedSkylakeClient.td b/llvm/lib/Target/X86/X86SchedSkylakeClient.td
index f15a7c7076414..2d2e5d0daa634 100644
--- a/llvm/lib/Target/X86/X86SchedSkylakeClient.td
+++ b/llvm/lib/Target/X86/X86SchedSkylakeClient.td
@@ -146,23 +146,15 @@ defm : X86WriteRes<WriteCMPXCHG,[SKLPort06, SKLPort0156], 5, [2,3], 5>;
defm : X86WriteRes<WriteCMPXCHGRMW,[SKLPort23,SKLPort06,SKLPort0156,SKLPort237,SKLPort4], 8, [1,2,1,1,1], 6>;
defm : X86WriteRes<WriteXCHG, [SKLPort0156], 2, [3], 3>;
-// TODO: Why isn't the SKLDivider used?
-defm : SKLWriteResPair<WriteDiv8, [SKLPort0,SKLDivider], 25, [1,10], 1, 4>;
-defm : X86WriteRes<WriteDiv16, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort05,SKLPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv32, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort05,SKLPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv64, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort05,SKLPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv16Ld, [SKLPort0,SKLPort23,SKLDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv32Ld, [SKLPort0,SKLPort23,SKLDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv64Ld, [SKLPort0,SKLPort23,SKLDivider], 29, [1,1,10], 2>;
-
-defm : X86WriteRes<WriteIDiv8, [SKLPort0,SKLDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv16, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort06,SKLPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv32, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort06,SKLPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv64, [SKLPort0,SKLPort1,SKLPort5,SKLPort6,SKLPort06,SKLPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv8Ld, [SKLPort0,SKLPort5,SKLPort23,SKLPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv16Ld, [SKLPort0,SKLPort5,SKLPort23,SKLPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv32Ld, [SKLPort0,SKLPort5,SKLPort23,SKLPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv64Ld, [SKLPort0,SKLPort5,SKLPort23,SKLPort0156], 28, [2,4,1,1], 8>;
+defm : SKLWriteResPair<WriteDiv8, [SKLPort0, SKLDivider], 25, [1,6], 10>;
+defm : SKLWriteResPair<WriteDiv16, [SKLPort0, SKLDivider], 24, [1,6], 10>;
+defm : SKLWriteResPair<WriteDiv32, [SKLPort0, SKLDivider], 28, [1,6], 10>;
+defm : SKLWriteResPair<WriteDiv64, [SKLPort0, SKLDivider], 90, [1,21], 36>;
+
+defm : SKLWriteResPair<WriteIDiv8, [SKLPort0, SKLDivider], 25, [1,6], 11>;
+defm : SKLWriteResPair<WriteIDiv16, [SKLPort0, SKLDivider], 24, [1,6], 10>;
+defm : SKLWriteResPair<WriteIDiv32, [SKLPort0, SKLDivider], 28, [1,6], 10>;
+defm : SKLWriteResPair<WriteIDiv64, [SKLPort0, SKLDivider], 96, [1,24], 57>;
defm : SKLWriteResPair<WriteCRC32, [SKLPort1], 3>;
diff --git a/llvm/lib/Target/X86/X86SchedSkylakeServer.td b/llvm/lib/Target/X86/X86SchedSkylakeServer.td
index 2a793d0205986..fb726b44e57d0 100644
--- a/llvm/lib/Target/X86/X86SchedSkylakeServer.td
+++ b/llvm/lib/Target/X86/X86SchedSkylakeServer.td
@@ -147,23 +147,15 @@ defm : X86WriteRes<WriteCMPXCHG,[SKXPort06, SKXPort0156], 5, [2,3], 5>;
defm : X86WriteRes<WriteCMPXCHGRMW,[SKXPort23,SKXPort06,SKXPort0156,SKXPort237,SKXPort4], 8, [1,2,1,1,1], 6>;
defm : X86WriteRes<WriteXCHG, [SKXPort0156], 2, [3], 3>;
-// TODO: Why isn't the SKXDivider used?
-defm : SKXWriteResPair<WriteDiv8, [SKXPort0, SKXDivider], 25, [1,10], 1, 4>;
-defm : X86WriteRes<WriteDiv16, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort05,SKXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv32, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort05,SKXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv64, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort05,SKXPort0156], 76, [7,2,8,3,1,11], 32>;
-defm : X86WriteRes<WriteDiv16Ld, [SKXPort0,SKXPort23,SKXDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv32Ld, [SKXPort0,SKXPort23,SKXDivider], 29, [1,1,10], 2>;
-defm : X86WriteRes<WriteDiv64Ld, [SKXPort0,SKXPort23,SKXDivider], 29, [1,1,10], 2>;
-
-defm : X86WriteRes<WriteIDiv8, [SKXPort0, SKXDivider], 25, [1,10], 1>;
-defm : X86WriteRes<WriteIDiv16, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort06,SKXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv32, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort06,SKXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv64, [SKXPort0,SKXPort1,SKXPort5,SKXPort6,SKXPort06,SKXPort0156], 102, [4,2,4,8,14,34], 66>;
-defm : X86WriteRes<WriteIDiv8Ld, [SKXPort0,SKXPort5,SKXPort23,SKXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv16Ld, [SKXPort0,SKXPort5,SKXPort23,SKXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv32Ld, [SKXPort0,SKXPort5,SKXPort23,SKXPort0156], 28, [2,4,1,1], 8>;
-defm : X86WriteRes<WriteIDiv64Ld, [SKXPort0,SKXPort5,SKXPort23,SKXPort0156], 28, [2,4,1,1], 8>;
+defm : SKXWriteResPair<WriteDiv8, [SKXPort0, SKXDivider], 25, [1,6], 10>;
+defm : SKXWriteResPair<WriteDiv16, [SKXPort0, SKXDivider], 24, [1,6], 10>;
+defm : SKXWriteResPair<WriteDiv32, [SKXPort0, SKXDivider], 28, [1,6], 10>;
+defm : SKXWriteResPair<WriteDiv64, [SKXPort0, SKXDivider], 89, [1,21], 36>;
+
+defm : SKXWriteResPair<WriteIDiv8, [SKXPort0, SKXDivider], 25, [1,6], 11>;
+defm : SKXWriteResPair<WriteIDiv16, [SKXPort0, SKXDivider], 24, [1,6], 10>;
+defm : SKXWriteResPair<WriteIDiv32, [SKXPort0, SKXDivider], 28, [1,6], 10>;
+defm : SKXWriteResPair<WriteIDiv64, [SKXPort0, SKXDivider], 96, [1,24], 57>;
defm : SKXWriteResPair<WriteCRC32, [SKXPort1], 3>;
diff --git a/llvm/test/CodeGen/X86/masked-sdiv.ll b/llvm/test/CodeGen/X86/masked-sdiv.ll
index 30d7f116dcb47..5f7366ccd9ebe 100644
--- a/llvm/test/CodeGen/X86/masked-sdiv.ll
+++ b/llvm/test/CodeGen/X86/masked-sdiv.ll
@@ -91,47 +91,47 @@ define <4 x i32> @sdiv_v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m) {
; AVX2-NEXT: cltd
; AVX2-NEXT: idivl %esi
; AVX2-NEXT: vmovd %eax, %xmm2
-; AVX2-NEXT: vpinsrd $1, %ecx, %xmm2, %xmm2
-; AVX2-NEXT: vpextrd $2, %xmm1, %ecx
+; AVX2-NEXT: vpextrd $2, %xmm1, %esi
; AVX2-NEXT: vpextrd $2, %xmm0, %eax
; AVX2-NEXT: cltd
-; AVX2-NEXT: idivl %ecx
-; AVX2-NEXT: movl %eax, %ecx
-; AVX2-NEXT: vpextrd $3, %xmm1, %esi
+; AVX2-NEXT: idivl %esi
+; AVX2-NEXT: movl %eax, %esi
+; AVX2-NEXT: vpinsrd $1, %ecx, %xmm2, %xmm2
+; AVX2-NEXT: vpextrd $3, %xmm1, %ecx
; AVX2-NEXT: vpextrd $3, %xmm0, %eax
; AVX2-NEXT: cltd
-; AVX2-NEXT: idivl %esi
-; AVX2-NEXT: vpinsrd $2, %ecx, %xmm2, %xmm0
+; AVX2-NEXT: idivl %ecx
+; AVX2-NEXT: vpinsrd $2, %esi, %xmm2, %xmm0
; AVX2-NEXT: vpinsrd $3, %eax, %xmm0, %xmm0
; AVX2-NEXT: retq
;
; AVX512-LABEL: sdiv_v4i32:
; AVX512: # %bb.0:
; AVX512-NEXT: vpslld $31, %xmm2, %xmm2
+; AVX512-NEXT: vpbroadcastd {{.*#+}} xmm3 = [1,1,1,1]
; AVX512-NEXT: vpmovd2m %xmm2, %k1
-; AVX512-NEXT: vpbroadcastd {{.*#+}} xmm2 = [1,1,1,1]
-; AVX512-NEXT: vmovdqa32 %xmm1, %xmm2 {%k1}
-; AVX512-NEXT: vpextrd $1, %xmm2, %ecx
+; AVX512-NEXT: vmovdqa32 %xmm1, %xmm3 {%k1}
+; AVX512-NEXT: vpextrd $1, %xmm3, %ecx
; AVX512-NEXT: vpextrd $1, %xmm0, %eax
; AVX512-NEXT: cltd
; AVX512-NEXT: idivl %ecx
; AVX512-NEXT: movl %eax, %ecx
-; AVX512-NEXT: vmovd %xmm2, %esi
+; AVX512-NEXT: vmovd %xmm3, %esi
; AVX512-NEXT: vmovd %xmm0, %eax
; AVX512-NEXT: cltd
; AVX512-NEXT: idivl %esi
; AVX512-NEXT: movl %eax, %esi
-; AVX512-NEXT: vpextrd $2, %xmm2, %edi
+; AVX512-NEXT: vpextrd $2, %xmm3, %edi
; AVX512-NEXT: vpextrd $2, %xmm0, %eax
; AVX512-NEXT: cltd
; AVX512-NEXT: idivl %edi
; AVX512-NEXT: movl %eax, %edi
-; AVX512-NEXT: vmovd %esi, %xmm1
-; AVX512-NEXT: vpextrd $3, %xmm2, %esi
+; AVX512-NEXT: vpextrd $3, %xmm3, %r8d
; AVX512-NEXT: vpextrd $3, %xmm0, %eax
+; AVX512-NEXT: vmovd %esi, %xmm0
; AVX512-NEXT: cltd
-; AVX512-NEXT: idivl %esi
-; AVX512-NEXT: vpinsrd $1, %ecx, %xmm1, %xmm0
+; AVX512-NEXT: idivl %r8d
+; AVX512-NEXT: vpinsrd $1, %ecx, %xmm0, %xmm0
; AVX512-NEXT: vpinsrd $2, %edi, %xmm0, %xmm0
; AVX512-NEXT: vpinsrd $3, %eax, %xmm0, %xmm0
; AVX512-NEXT: retq
@@ -323,25 +323,24 @@ define <4 x i64> @sdiv_v4i64(<4 x i64> %x, <4 x i64> %y, <4 x i1> %m) {
; AVX2-NEXT: vpextrq $1, %xmm3, %rax
; AVX2-NEXT: cqto
; AVX2-NEXT: idivq %rcx
-; AVX2-NEXT: movq %rax, %rcx
-; AVX2-NEXT: vmovq %xmm2, %rsi
+; AVX2-NEXT: vmovq %rax, %xmm4
+; AVX2-NEXT: vmovq %xmm2, %rcx
; AVX2-NEXT: vmovq %xmm3, %rax
; AVX2-NEXT: cqto
-; AVX2-NEXT: idivq %rsi
-; AVX2-NEXT: movq %rax, %rsi
-; AVX2-NEXT: vpextrq $1, %xmm1, %rdi
+; AVX2-NEXT: idivq %rcx
+; AVX2-NEXT: movq %rax, %rcx
+; AVX2-NEXT: vpextrq $1, %xmm1, %rsi
; AVX2-NEXT: vpextrq $1, %xmm0, %rax
; AVX2-NEXT: cqto
-; AVX2-NEXT: idivq %rdi
-; AVX2-NEXT: movq %rax, %rdi
+; AVX2-NEXT: idivq %rsi
+; AVX2-NEXT: movq %rax, %rsi
; AVX2-NEXT: vmovq %rcx, %xmm2
-; AVX2-NEXT: vmovq %rsi, %xmm3
-; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm3[0],xmm2[0]
+; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm4[0]
; AVX2-NEXT: vmovq %xmm1, %rcx
; AVX2-NEXT: vmovq %xmm0, %rax
; AVX2-NEXT: cqto
; AVX2-NEXT: idivq %rcx
-; AVX2-NEXT: vmovq %rdi, %xmm0
+; AVX2-NEXT: vmovq %rsi, %xmm0
; AVX2-NEXT: vmovq %rax, %xmm1
; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
; AVX2-NEXT: vinserti128 $1, %xmm2, %ymm0, %ymm0
@@ -350,34 +349,34 @@ define <4 x i64> @sdiv_v4i64(<4 x i64> %x, <4 x i64> %y, <4 x i1> %m) {
; AVX512-LABEL: sdiv_v4i64:
; AVX512: # %bb.0:
; AVX512-NEXT: vpslld $31, %xmm2, %xmm2
+; AVX512-NEXT: vpbroadcastq {{.*#+}} ymm3 = [1,1,1,1]
; AVX512-NEXT: vpmovd2m %xmm2, %k1
-; AVX512-NEXT: vpbroadcastq {{.*#+}} ymm2 = [1,1,1,1]
-; AVX512-NEXT: vmovdqa64 %ymm1, %ymm2 {%k1}
-; AVX512-NEXT: vextracti128 $1, %ymm2, %xmm1
+; AVX512-NEXT: vmovdqa64 %ymm1, %ymm3 {%k1}
+; AVX512-NEXT: vextracti128 $1, %ymm3, %xmm1
; AVX512-NEXT: vpextrq $1, %xmm1, %rcx
-; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm3
-; AVX512-NEXT: vpextrq $1, %xmm3, %rax
+; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2
+; AVX512-NEXT: vpextrq $1, %xmm2, %rax
; AVX512-NEXT: cqto
; AVX512-NEXT: idivq %rcx
; AVX512-NEXT: movq %rax, %rcx
; AVX512-NEXT: vmovq %xmm1, %rsi
-; AVX512-NEXT: vmovq %xmm3, %rax
+; AVX512-NEXT: vmovq %xmm2, %rax
; AVX512-NEXT: cqto
; AVX512-NEXT: idivq %rsi
; AVX512-NEXT: movq %rax, %rsi
-; AVX512-NEXT: vpextrq $1, %xmm2, %rdi
+; AVX512-NEXT: vmovq %rcx, %xmm1
+; AVX512-NEXT: vpextrq $1, %xmm3, %rcx
; AVX512-NEXT: vpextrq $1, %xmm0, %rax
; AVX512-NEXT: cqto
-; AVX512-NEXT: idivq %rdi
-; AVX512-NEXT: movq %rax, %rdi
-; AVX512-NEXT: vmovq %rcx, %xmm1
-; AVX512-NEXT: vmovq %xmm2, %rcx
+; AVX512-NEXT: idivq %rcx
+; AVX512-NEXT: movq %rax, %rcx
+; AVX512-NEXT: vmovq %xmm3, %rdi
; AVX512-NEXT: vmovq %xmm0, %rax
; AVX512-NEXT: cqto
-; AVX512-NEXT: idivq %rcx
+; AVX512-NEXT: idivq %rdi
; AVX512-NEXT: vmovq %rsi, %xmm0
; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
-; AVX512-NEXT: vmovq %rdi, %xmm1
+; AVX512-NEXT: vmovq %rcx, %xmm1
; AVX512-NEXT: vmovq %rax, %xmm2
; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0
@@ -477,47 +476,47 @@ define <2 x i32> @sdiv_v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i1> %m) {
; AVX2-NEXT: cltd
; AVX2-NEXT: idivl %esi
; AVX2-NEXT: vmovd %eax, %xmm2
-; AVX2-NEXT: vpinsrd $1, %ecx, %xmm2, %xmm2
-; AVX2-NEXT: vpextrd $2, %xmm1, %ecx
+; AVX2-NEXT: vpextrd $2, %xmm1, %esi
; AVX2-NEXT: vpextrd $2, %xmm0, %eax
; AVX2-NEXT: cltd
-; AVX2-NEXT: idivl %ecx
-; AVX2-NEXT: movl %eax, %ecx
-; AVX2-NEXT: vpextrd $3, %xmm1, %esi
+; AVX2-NEXT: idivl %esi
+; AVX2-NEXT: movl %eax, %esi
+; AVX2-NEXT: vpinsrd $1, %ecx, %xmm2, %xmm2
+; AVX2-NEXT: vpextrd $3, %xmm1, %ecx
; AVX2-NEXT: vpextrd $3, %xmm0, %eax
; AVX2-NEXT: cltd
-; AVX2-NEXT: idivl %esi
-; AVX2-NEXT: vpinsrd $2, %ecx, %xmm2, %xmm0
+; AVX2-NEXT: idivl %ecx
+; AVX2-NEXT: vpinsrd $2, %esi, %xmm2, %x...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/204972
More information about the llvm-commits
mailing list