Skip to content

Commit f2bbb4c

Browse files
authored
[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: 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.
1 parent f203cb0 commit f2bbb4c

File tree

3 files changed

+183
-0
lines changed

3 files changed

+183
-0
lines changed

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
349349
.widenScalarToNextPow2(0);
350350
}
351351

352+
// TODO: Use libcall for sDoubleXLen.
353+
getActionDefinitionsBuilder({G_UDIVREM, G_SDIVREM}).lower();
354+
352355
auto &AbsActions = getActionDefinitionsBuilder(G_ABS);
353356
if (ST.hasStdExtZbb())
354357
AbsActions.customFor({s32, sXLen}).minScalar(0, sXLen);

llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv32.mir

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,93 @@ body: |
555555
PseudoRET implicit $x10, implicit $x11
556556
557557
...
558+
---
559+
name: udivrem_i32
560+
body: |
561+
bb.1.entry:
562+
liveins: $x10, $x11
563+
564+
; CHECK-I-LABEL: name: udivrem_i32
565+
; CHECK-I: liveins: $x10, $x11
566+
; CHECK-I-NEXT: {{ $}}
567+
; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
568+
; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
569+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
570+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
571+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
572+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
573+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
574+
; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
575+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
576+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
577+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
578+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
579+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
580+
; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
581+
; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[COPY3]]
582+
; CHECK-I-NEXT: $x10 = COPY [[ADD]](s32)
583+
; CHECK-I-NEXT: PseudoRET implicit $x10
584+
;
585+
; CHECK-M-LABEL: name: udivrem_i32
586+
; CHECK-M: liveins: $x10, $x11
587+
; CHECK-M-NEXT: {{ $}}
588+
; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
589+
; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
590+
; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[COPY]], [[COPY1]]
591+
; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[COPY]], [[COPY1]]
592+
; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[UDIV]], [[UREM]]
593+
; CHECK-M-NEXT: $x10 = COPY [[ADD]](s32)
594+
; CHECK-M-NEXT: PseudoRET implicit $x10
595+
%0:_(s32) = COPY $x10
596+
%1:_(s32) = COPY $x11
597+
%2:_(s32), %3:_(s32) = G_UDIVREM %0, %1
598+
%4:_(s32) = G_ADD %2, %3
599+
$x10 = COPY %4(s32)
600+
PseudoRET implicit $x10
601+
602+
...
603+
---
604+
name: sdivrem_i32
605+
body: |
606+
bb.1.entry:
607+
liveins: $x10, $x11
608+
609+
; CHECK-I-LABEL: name: sdivrem_i32
610+
; CHECK-I: liveins: $x10, $x11
611+
; CHECK-I-NEXT: {{ $}}
612+
; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
613+
; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
614+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
615+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
616+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
617+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
618+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
619+
; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
620+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
621+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
622+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
623+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
624+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
625+
; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
626+
; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[COPY3]]
627+
; CHECK-I-NEXT: $x10 = COPY [[ADD]](s32)
628+
; CHECK-I-NEXT: PseudoRET implicit $x10
629+
;
630+
; CHECK-M-LABEL: name: sdivrem_i32
631+
; CHECK-M: liveins: $x10, $x11
632+
; CHECK-M-NEXT: {{ $}}
633+
; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
634+
; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
635+
; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
636+
; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[COPY]], [[COPY1]]
637+
; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[SDIV]], [[SREM]]
638+
; CHECK-M-NEXT: $x10 = COPY [[ADD]](s32)
639+
; CHECK-M-NEXT: PseudoRET implicit $x10
640+
%0:_(s32) = COPY $x10
641+
%1:_(s32) = COPY $x11
642+
%2:_(s32), %3:_(s32) = G_SDIVREM %0, %1
643+
%4:_(s32) = G_ADD %2, %3
644+
$x10 = COPY %4(s32)
645+
PseudoRET implicit $x10
646+
647+
...

llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,93 @@ body: |
655655
PseudoRET implicit $x10, implicit $x11
656656
657657
...
658+
---
659+
name: udivrem_i64
660+
body: |
661+
bb.1.entry:
662+
liveins: $x10, $x11
663+
664+
; CHECK-I-LABEL: name: udivrem_i64
665+
; CHECK-I: liveins: $x10, $x11
666+
; CHECK-I-NEXT: {{ $}}
667+
; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
668+
; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
669+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
670+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
671+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
672+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
673+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
674+
; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
675+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
676+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
677+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
678+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
679+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
680+
; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x10
681+
; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY2]], [[COPY3]]
682+
; CHECK-I-NEXT: $x10 = COPY [[ADD]](s64)
683+
; CHECK-I-NEXT: PseudoRET implicit $x10
684+
;
685+
; CHECK-M-LABEL: name: udivrem_i64
686+
; CHECK-M: liveins: $x10, $x11
687+
; CHECK-M-NEXT: {{ $}}
688+
; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
689+
; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
690+
; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[COPY]], [[COPY1]]
691+
; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[COPY]], [[COPY1]]
692+
; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[UDIV]], [[UREM]]
693+
; CHECK-M-NEXT: $x10 = COPY [[ADD]](s64)
694+
; CHECK-M-NEXT: PseudoRET implicit $x10
695+
%0:_(s64) = COPY $x10
696+
%1:_(s64) = COPY $x11
697+
%2:_(s64), %3:_(s64) = G_UDIVREM %0, %1
698+
%4:_(s64) = G_ADD %2, %3
699+
$x10 = COPY %4(s64)
700+
PseudoRET implicit $x10
701+
702+
...
703+
---
704+
name: sdivrem_i64
705+
body: |
706+
bb.1.entry:
707+
liveins: $x10, $x11
708+
709+
; CHECK-I-LABEL: name: sdivrem_i64
710+
; CHECK-I: liveins: $x10, $x11
711+
; CHECK-I-NEXT: {{ $}}
712+
; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
713+
; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
714+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
715+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
716+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
717+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
718+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
719+
; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
720+
; CHECK-I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
721+
; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
722+
; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
723+
; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
724+
; CHECK-I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
725+
; CHECK-I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x10
726+
; CHECK-I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY2]], [[COPY3]]
727+
; CHECK-I-NEXT: $x10 = COPY [[ADD]](s64)
728+
; CHECK-I-NEXT: PseudoRET implicit $x10
729+
;
730+
; CHECK-M-LABEL: name: sdivrem_i64
731+
; CHECK-M: liveins: $x10, $x11
732+
; CHECK-M-NEXT: {{ $}}
733+
; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
734+
; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
735+
; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[COPY]], [[COPY1]]
736+
; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[COPY]], [[COPY1]]
737+
; CHECK-M-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[SDIV]], [[SREM]]
738+
; CHECK-M-NEXT: $x10 = COPY [[ADD]](s64)
739+
; CHECK-M-NEXT: PseudoRET implicit $x10
740+
%0:_(s64) = COPY $x10
741+
%1:_(s64) = COPY $x11
742+
%2:_(s64), %3:_(s64) = G_SDIVREM %0, %1
743+
%4:_(s64) = G_ADD %2, %3
744+
$x10 = COPY %4(s64)
745+
PseudoRET implicit $x10
746+
747+
...

0 commit comments

Comments
 (0)