Skip to content

Commit 53c0a25

Browse files
authored
[LoongArch] Use div.w/mod.w to eliminate unnecessary sign-extend for sdiv/srem i32. (#117298)
1 parent b4a16a7 commit 53c0a25

File tree

5 files changed

+34
-25
lines changed

5 files changed

+34
-25
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
141141

142142
setOperationAction(ISD::BITREVERSE, MVT::i32, Custom);
143143
setOperationAction(ISD::BSWAP, MVT::i32, Custom);
144-
setOperationAction({ISD::UDIV, ISD::UREM}, MVT::i32, Custom);
144+
setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM}, MVT::i32,
145+
Custom);
145146
setOperationAction(ISD::LROUND, MVT::i32, Custom);
146147
}
147148

@@ -2631,8 +2632,12 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
26312632
switch (Opcode) {
26322633
default:
26332634
llvm_unreachable("Unexpected opcode");
2635+
case ISD::SDIV:
2636+
return LoongArchISD::DIV_W;
26342637
case ISD::UDIV:
26352638
return LoongArchISD::DIV_WU;
2639+
case ISD::SREM:
2640+
return LoongArchISD::MOD_W;
26362641
case ISD::UREM:
26372642
return LoongArchISD::MOD_WU;
26382643
case ISD::SHL:
@@ -2829,7 +2834,9 @@ void LoongArchTargetLowering::ReplaceNodeResults(
28292834
"Unexpected custom legalisation");
28302835
Results.push_back(customLegalizeToWOpWithSExt(N, DAG));
28312836
break;
2837+
case ISD::SDIV:
28322838
case ISD::UDIV:
2839+
case ISD::SREM:
28332840
case ISD::UREM:
28342841
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
28352842
"Unexpected custom legalisation");
@@ -4672,7 +4679,9 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
46724679
NODE_NAME_CASE(BITREV_W)
46734680
NODE_NAME_CASE(ROTR_W)
46744681
NODE_NAME_CASE(ROTL_W)
4682+
NODE_NAME_CASE(DIV_W)
46754683
NODE_NAME_CASE(DIV_WU)
4684+
NODE_NAME_CASE(MOD_W)
46764685
NODE_NAME_CASE(MOD_WU)
46774686
NODE_NAME_CASE(CLZ_W)
46784687
NODE_NAME_CASE(CTZ_W)

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ enum NodeType : unsigned {
4444
ROTR_W,
4545

4646
// unsigned 32-bit integer division
47+
DIV_W,
48+
MOD_W,
4749
DIV_WU,
4850
MOD_WU,
4951

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
8585
def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
8686
def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
8787
def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
88+
def loongarch_div_w : SDNode<"LoongArchISD::DIV_W", SDT_LoongArchIntBinOpW>;
8889
def loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>;
90+
def loongarch_mod_w : SDNode<"LoongArchISD::MOD_W", SDT_LoongArchIntBinOpW>;
8991
def loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>;
9092
def loongarch_crc_w_b_w
9193
: SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
@@ -1156,10 +1158,12 @@ def : PatGprGpr<sub, SUB_D>;
11561158
def : PatGprGpr<sdiv, DIV_D>;
11571159
def : PatGprGpr_32<sdiv, DIV_W>;
11581160
def : PatGprGpr<udiv, DIV_DU>;
1161+
def : PatGprGpr<loongarch_div_w, DIV_W>;
11591162
def : PatGprGpr<loongarch_div_wu, DIV_WU>;
11601163
def : PatGprGpr<srem, MOD_D>;
11611164
def : PatGprGpr_32<srem, MOD_W>;
11621165
def : PatGprGpr<urem, MOD_DU>;
1166+
def : PatGprGpr<loongarch_mod_w, MOD_W>;
11631167
def : PatGprGpr<loongarch_mod_wu, MOD_WU>;
11641168
def : PatGprGpr<shiftop<rotr>, ROTR_D>;
11651169
def : PatGprGpr<shiftopw<loongarch_rotr_w>, ROTR_W>;

llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem-div32.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,17 @@
22
; RUN: llc --mtriple=loongarch64 -mattr=+d,-div32 < %s | FileCheck %s --check-prefix=LA64
33
; RUN: llc --mtriple=loongarch64 -mattr=+d,+div32 < %s | FileCheck %s --check-prefix=LA64-DIV32
44

5-
; TODO: Use div.w/mod.w for sdiv/srem i32
6-
75
define i32 @divw(i64 %a, i64 %b) {
86
; LA64-LABEL: divw:
97
; LA64: # %bb.0:
10-
; LA64-NEXT: addi.w $a0, $a0, 0
118
; LA64-NEXT: addi.w $a1, $a1, 0
12-
; LA64-NEXT: div.d $a0, $a0, $a1
9+
; LA64-NEXT: addi.w $a0, $a0, 0
10+
; LA64-NEXT: div.w $a0, $a0, $a1
1311
; LA64-NEXT: ret
1412
;
1513
; LA64-DIV32-LABEL: divw:
1614
; LA64-DIV32: # %bb.0:
17-
; LA64-DIV32-NEXT: addi.w $a0, $a0, 0
18-
; LA64-DIV32-NEXT: addi.w $a1, $a1, 0
19-
; LA64-DIV32-NEXT: div.d $a0, $a0, $a1
15+
; LA64-DIV32-NEXT: div.w $a0, $a0, $a1
2016
; LA64-DIV32-NEXT: ret
2117
%conv1 = trunc i64 %a to i32
2218
%conv2 = trunc i64 %b to i32
@@ -45,16 +41,14 @@ define i32 @divwu(i64 %a, i64 %b) {
4541
define i32 @modw(i64 %a, i64 %b) {
4642
; LA64-LABEL: modw:
4743
; LA64: # %bb.0:
48-
; LA64-NEXT: addi.w $a0, $a0, 0
4944
; LA64-NEXT: addi.w $a1, $a1, 0
50-
; LA64-NEXT: mod.d $a0, $a0, $a1
45+
; LA64-NEXT: addi.w $a0, $a0, 0
46+
; LA64-NEXT: mod.w $a0, $a0, $a1
5147
; LA64-NEXT: ret
5248
;
5349
; LA64-DIV32-LABEL: modw:
5450
; LA64-DIV32: # %bb.0:
55-
; LA64-DIV32-NEXT: addi.w $a0, $a0, 0
56-
; LA64-DIV32-NEXT: addi.w $a1, $a1, 0
57-
; LA64-DIV32-NEXT: mod.d $a0, $a0, $a1
51+
; LA64-DIV32-NEXT: mod.w $a0, $a0, $a1
5852
; LA64-DIV32-NEXT: ret
5953
%conv1 = trunc i64 %a to i32
6054
%conv2 = trunc i64 %b to i32

llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ define i32 @sdiv_i32(i32 %a, i32 %b) {
121121
; LA64: # %bb.0: # %entry
122122
; LA64-NEXT: addi.w $a1, $a1, 0
123123
; LA64-NEXT: addi.w $a0, $a0, 0
124-
; LA64-NEXT: div.d $a0, $a0, $a1
124+
; LA64-NEXT: div.w $a0, $a0, $a1
125125
; LA64-NEXT: ret
126126
;
127127
; LA32-TRAP-LABEL: sdiv_i32:
@@ -137,7 +137,7 @@ define i32 @sdiv_i32(i32 %a, i32 %b) {
137137
; LA64-TRAP: # %bb.0: # %entry
138138
; LA64-TRAP-NEXT: addi.w $a1, $a1, 0
139139
; LA64-TRAP-NEXT: addi.w $a0, $a0, 0
140-
; LA64-TRAP-NEXT: div.d $a0, $a0, $a1
140+
; LA64-TRAP-NEXT: div.w $a0, $a0, $a1
141141
; LA64-TRAP-NEXT: bnez $a1, .LBB3_2
142142
; LA64-TRAP-NEXT: # %bb.1: # %entry
143143
; LA64-TRAP-NEXT: break 7
@@ -156,7 +156,7 @@ define i32 @sdiv_ui32_si32_si32(i32 signext %a, i32 signext %b) {
156156
;
157157
; LA64-LABEL: sdiv_ui32_si32_si32:
158158
; LA64: # %bb.0: # %entry
159-
; LA64-NEXT: div.d $a0, $a0, $a1
159+
; LA64-NEXT: div.w $a0, $a0, $a1
160160
; LA64-NEXT: ret
161161
;
162162
; LA32-TRAP-LABEL: sdiv_ui32_si32_si32:
@@ -170,7 +170,7 @@ define i32 @sdiv_ui32_si32_si32(i32 signext %a, i32 signext %b) {
170170
;
171171
; LA64-TRAP-LABEL: sdiv_ui32_si32_si32:
172172
; LA64-TRAP: # %bb.0: # %entry
173-
; LA64-TRAP-NEXT: div.d $a0, $a0, $a1
173+
; LA64-TRAP-NEXT: div.w $a0, $a0, $a1
174174
; LA64-TRAP-NEXT: bnez $a1, .LBB4_2
175175
; LA64-TRAP-NEXT: # %bb.1: # %entry
176176
; LA64-TRAP-NEXT: break 7
@@ -693,7 +693,7 @@ define i32 @srem_i32(i32 %a, i32 %b) {
693693
; LA64: # %bb.0: # %entry
694694
; LA64-NEXT: addi.w $a1, $a1, 0
695695
; LA64-NEXT: addi.w $a0, $a0, 0
696-
; LA64-NEXT: mod.d $a0, $a0, $a1
696+
; LA64-NEXT: mod.w $a0, $a0, $a1
697697
; LA64-NEXT: ret
698698
;
699699
; LA32-TRAP-LABEL: srem_i32:
@@ -709,7 +709,7 @@ define i32 @srem_i32(i32 %a, i32 %b) {
709709
; LA64-TRAP: # %bb.0: # %entry
710710
; LA64-TRAP-NEXT: addi.w $a1, $a1, 0
711711
; LA64-TRAP-NEXT: addi.w $a0, $a0, 0
712-
; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1
712+
; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1
713713
; LA64-TRAP-NEXT: bnez $a1, .LBB19_2
714714
; LA64-TRAP-NEXT: # %bb.1: # %entry
715715
; LA64-TRAP-NEXT: break 7
@@ -728,7 +728,7 @@ define i32 @srem_ui32_si32_si32(i32 signext %a, i32 signext %b) {
728728
;
729729
; LA64-LABEL: srem_ui32_si32_si32:
730730
; LA64: # %bb.0: # %entry
731-
; LA64-NEXT: mod.d $a0, $a0, $a1
731+
; LA64-NEXT: mod.w $a0, $a0, $a1
732732
; LA64-NEXT: ret
733733
;
734734
; LA32-TRAP-LABEL: srem_ui32_si32_si32:
@@ -742,7 +742,7 @@ define i32 @srem_ui32_si32_si32(i32 signext %a, i32 signext %b) {
742742
;
743743
; LA64-TRAP-LABEL: srem_ui32_si32_si32:
744744
; LA64-TRAP: # %bb.0: # %entry
745-
; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1
745+
; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1
746746
; LA64-TRAP-NEXT: bnez $a1, .LBB20_2
747747
; LA64-TRAP-NEXT: # %bb.1: # %entry
748748
; LA64-TRAP-NEXT: break 7
@@ -763,7 +763,7 @@ define signext i32 @srem_si32_ui32_ui32(i32 %a, i32 %b) {
763763
; LA64: # %bb.0: # %entry
764764
; LA64-NEXT: addi.w $a1, $a1, 0
765765
; LA64-NEXT: addi.w $a0, $a0, 0
766-
; LA64-NEXT: mod.d $a0, $a0, $a1
766+
; LA64-NEXT: mod.w $a0, $a0, $a1
767767
; LA64-NEXT: ret
768768
;
769769
; LA32-TRAP-LABEL: srem_si32_ui32_ui32:
@@ -779,7 +779,7 @@ define signext i32 @srem_si32_ui32_ui32(i32 %a, i32 %b) {
779779
; LA64-TRAP: # %bb.0: # %entry
780780
; LA64-TRAP-NEXT: addi.w $a1, $a1, 0
781781
; LA64-TRAP-NEXT: addi.w $a0, $a0, 0
782-
; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1
782+
; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1
783783
; LA64-TRAP-NEXT: bnez $a1, .LBB21_2
784784
; LA64-TRAP-NEXT: # %bb.1: # %entry
785785
; LA64-TRAP-NEXT: break 7
@@ -798,7 +798,7 @@ define signext i32 @srem_si32_si32_si32(i32 signext %a, i32 signext %b) {
798798
;
799799
; LA64-LABEL: srem_si32_si32_si32:
800800
; LA64: # %bb.0: # %entry
801-
; LA64-NEXT: mod.d $a0, $a0, $a1
801+
; LA64-NEXT: mod.w $a0, $a0, $a1
802802
; LA64-NEXT: ret
803803
;
804804
; LA32-TRAP-LABEL: srem_si32_si32_si32:
@@ -812,7 +812,7 @@ define signext i32 @srem_si32_si32_si32(i32 signext %a, i32 signext %b) {
812812
;
813813
; LA64-TRAP-LABEL: srem_si32_si32_si32:
814814
; LA64-TRAP: # %bb.0: # %entry
815-
; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1
815+
; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1
816816
; LA64-TRAP-NEXT: bnez $a1, .LBB22_2
817817
; LA64-TRAP-NEXT: # %bb.1: # %entry
818818
; LA64-TRAP-NEXT: break 7

0 commit comments

Comments
 (0)