[llvm] [GISel][RISCV] Legalize `G_{U|S}DIVREM` (PR #93067)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 22 09:43:01 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
This patch expands `G_{U|S}DIVREM` into `G_{U|S}DIV + G_{U|S}REM`. `G_{U|S}DIVREM` is generated by the following fold:
https://github.com/llvm/llvm-project/blob/4ea21a0261cd8599a9ffa15f5c554ab0d4bbbe27/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp#L1410-L1471
It always folds `div + rem` pairs into `divrem` during pre-legalization. I tried to change `isLegalOrBeforeLegalizer` to `isLegal` but it produced worse codegen on AArch64.
I am not sure whether this patch is useful since `DivRemPairsPass` always converts `div + rem` pairs into `div + mul` on RISCV.
---
Full diff: https://github.com/llvm/llvm-project/pull/93067.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+3)
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir (+90)
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir (+90)
``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index a1d3aadb816ab..c6d11b8a8bd7e 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -349,6 +349,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.widenScalarToNextPow2(0);
}
+ // TODO: Use libcall for sDoubleXLen.
+ getActionDefinitionsBuilder({G_UDIVREM, G_SDIVREM}).lower();
+
auto &AbsActions = getActionDefinitionsBuilder(G_ABS);
if (ST.hasStdExtZbb())
AbsActions.customFor({s32, sXLen}).minScalar(0, sXLen);
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir
index 4177a40e3826c..26d8785afb470 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir
@@ -555,3 +555,93 @@ body: |
PseudoRET implicit $x10, implicit $x11
...
+---
+name: udivrem_i32
+body: |
+ bb.1.entry:
+ liveins: $x10, $x11
+
+ ; CHECK-I-LABEL: name: udivrem_i32
+ ; CHECK-I: liveins: $x10, $x11
+ ; CHECK-I-NEXT: {{ $}}
+ ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[COPY3]]
+ ; CHECK-I-NEXT: $x10 = COPY [[ADD]](s32)
+ ; CHECK-I-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-M-LABEL: name: udivrem_i32
+ ; CHECK-M: liveins: $x10, $x11
+ ; CHECK-M-NEXT: {{ $}}
+ ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[UDIV]], [[UREM]]
+ ; CHECK-M-NEXT: $x10 = COPY [[ADD]](s32)
+ ; CHECK-M-NEXT: PseudoRET implicit $x10
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32), %3:_(s32) = G_UDIVREM %0, %1
+ %4:_(s32) = G_ADD %2, %3
+ $x10 = COPY %4(s32)
+ PseudoRET implicit $x10
+
+...
+---
+name: sdivrem_i32
+body: |
+ bb.1.entry:
+ liveins: $x10, $x11
+
+ ; CHECK-I-LABEL: name: sdivrem_i32
+ ; CHECK-I: liveins: $x10, $x11
+ ; CHECK-I-NEXT: {{ $}}
+ ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[COPY3]]
+ ; CHECK-I-NEXT: $x10 = COPY [[ADD]](s32)
+ ; CHECK-I-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-M-LABEL: name: sdivrem_i32
+ ; CHECK-M: liveins: $x10, $x11
+ ; CHECK-M-NEXT: {{ $}}
+ ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[SDIV]], [[SREM]]
+ ; CHECK-M-NEXT: $x10 = COPY [[ADD]](s32)
+ ; CHECK-M-NEXT: PseudoRET implicit $x10
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32), %3:_(s32) = G_SDIVREM %0, %1
+ %4:_(s32) = G_ADD %2, %3
+ $x10 = COPY %4(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
index 492f9530997c9..bbbe38f695d2e 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
@@ -655,3 +655,93 @@ body: |
PseudoRET implicit $x10, implicit $x11
...
+---
+name: udivrem_i64
+body: |
+ bb.1.entry:
+ liveins: $x10, $x11
+
+ ; CHECK-I-LABEL: name: udivrem_i64
+ ; CHECK-I: liveins: $x10, $x11
+ ; CHECK-I-NEXT: {{ $}}
+ ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY2]], [[COPY3]]
+ ; CHECK-I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; CHECK-I-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-M-LABEL: name: udivrem_i64
+ ; CHECK-M: liveins: $x10, $x11
+ ; CHECK-M-NEXT: {{ $}}
+ ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[UDIV]], [[UREM]]
+ ; CHECK-M-NEXT: $x10 = COPY [[ADD]](s64)
+ ; CHECK-M-NEXT: PseudoRET implicit $x10
+ %0:_(s64) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(s64), %3:_(s64) = G_UDIVREM %0, %1
+ %4:_(s64) = G_ADD %2, %3
+ $x10 = COPY %4(s64)
+ PseudoRET implicit $x10
+
+...
+---
+name: sdivrem_i64
+body: |
+ bb.1.entry:
+ liveins: $x10, $x11
+
+ ; CHECK-I-LABEL: name: sdivrem_i64
+ ; CHECK-I: liveins: $x10, $x11
+ ; CHECK-I-NEXT: {{ $}}
+ ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+ ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+ ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY2]], [[COPY3]]
+ ; CHECK-I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; CHECK-I-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-M-LABEL: name: sdivrem_i64
+ ; CHECK-M: liveins: $x10, $x11
+ ; CHECK-M-NEXT: {{ $}}
+ ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[SDIV]], [[SREM]]
+ ; CHECK-M-NEXT: $x10 = COPY [[ADD]](s64)
+ ; CHECK-M-NEXT: PseudoRET implicit $x10
+ %0:_(s64) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(s64), %3:_(s64) = G_SDIVREM %0, %1
+ %4:_(s64) = G_ADD %2, %3
+ $x10 = COPY %4(s64)
+ PseudoRET implicit $x10
+
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/93067
More information about the llvm-commits
mailing list