[GISel][RISCV] Legalize G_{U|S}DIVREM (#93067)
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:
4ea21a0261/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.
This commit is contained in:
parent
f203cb03d9
commit
f2bbb4cb3e
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
...
|
||||
|
||||
@ -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
|
||||
|
||||
...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user