Skip to content

Commit ad59967

Browse files
authored
[LoongArch] Optimize codegen for ISD::{ROTL,ROTR} (#91174)
1 parent ebde770 commit ad59967

File tree

3 files changed

+24
-35
lines changed

3 files changed

+24
-35
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,10 +1671,9 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
16711671
return LoongArchISD::SRA_W;
16721672
case ISD::SRL:
16731673
return LoongArchISD::SRL_W;
1674+
case ISD::ROTL:
16741675
case ISD::ROTR:
16751676
return LoongArchISD::ROTR_W;
1676-
case ISD::ROTL:
1677-
return LoongArchISD::ROTL_W;
16781677
case ISD::CTTZ:
16791678
return LoongArchISD::CTZ_W;
16801679
case ISD::CTLZ:
@@ -1704,6 +1703,10 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
17041703
case 2: {
17051704
NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
17061705
SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1));
1706+
if (N->getOpcode() == ISD::ROTL) {
1707+
SDValue TmpOp = DAG.getConstant(32, DL, MVT::i64);
1708+
NewOp1 = DAG.getNode(ISD::SUB, DL, MVT::i64, TmpOp, NewOp1);
1709+
}
17071710
NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
17081711
break;
17091712
}
@@ -1841,7 +1844,6 @@ void LoongArchTargetLowering::ReplaceNodeResults(
18411844
case ISD::SHL:
18421845
case ISD::SRA:
18431846
case ISD::SRL:
1844-
case ISD::ROTR:
18451847
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
18461848
"Unexpected custom legalisation");
18471849
if (N->getOperand(1).getOpcode() != ISD::Constant) {
@@ -1850,11 +1852,10 @@ void LoongArchTargetLowering::ReplaceNodeResults(
18501852
}
18511853
break;
18521854
case ISD::ROTL:
1853-
ConstantSDNode *CN;
1854-
if ((CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))) {
1855-
Results.push_back(customLegalizeToWOp(N, DAG, 2));
1856-
break;
1857-
}
1855+
case ISD::ROTR:
1856+
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
1857+
"Unexpected custom legalisation");
1858+
Results.push_back(customLegalizeToWOp(N, DAG, 2));
18581859
break;
18591860
case ISD::FP_TO_SINT: {
18601861
assert(VT == MVT::i32 && Subtarget.is64Bit() &&

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ 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_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>;
8988
def loongarch_crc_w_b_w
9089
: SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
9190
def loongarch_crc_w_h_w
@@ -1116,12 +1115,10 @@ def : PatGprGpr<srem, MOD_D>;
11161115
def : PatGprGpr<urem, MOD_DU>;
11171116
def : PatGprGpr<rotr, ROTR_D>;
11181117
def : PatGprGpr<loongarch_rotr_w, ROTR_W>;
1118+
def : PatGprGpr_32<rotr, ROTR_W>;
11191119
def : PatGprImm<rotr, ROTRI_D, uimm6>;
11201120
def : PatGprImm_32<rotr, ROTRI_W, uimm5>;
1121-
def : Pat<(loongarch_rotl_w GPR:$rj, uimm5:$imm),
1122-
(ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
1123-
def : Pat<(sext_inreg (loongarch_rotl_w GPR:$rj, uimm5:$imm), i32),
1124-
(ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
1121+
def : PatGprImm<loongarch_rotr_w, ROTRI_W, uimm5>;
11251122
// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the
11261123
// product are used.
11271124
def : PatGprGpr<mul, MUL_D>;

llvm/test/CodeGen/LoongArch/rotl-rotr.ll

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32
33
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64
44

5-
;; TODO: Add optimization to ISD::ROTL
6-
75
define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
86
; LA32-LABEL: rotl_32:
97
; LA32: # %bb.0:
@@ -14,10 +12,9 @@ define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
1412
;
1513
; LA64-LABEL: rotl_32:
1614
; LA64: # %bb.0:
17-
; LA64-NEXT: sll.w $a2, $a0, $a1
18-
; LA64-NEXT: sub.d $a1, $zero, $a1
19-
; LA64-NEXT: srl.w $a0, $a0, $a1
20-
; LA64-NEXT: or $a0, $a2, $a0
15+
; LA64-NEXT: ori $a2, $zero, 32
16+
; LA64-NEXT: sub.d $a1, $a2, $a1
17+
; LA64-NEXT: rotr.w $a0, $a0, $a1
2118
; LA64-NEXT: ret
2219
%z = sub i32 32, %y
2320
%b = shl i32 %x, %y
@@ -152,10 +149,9 @@ define signext i32 @rotl_32_mask(i32 signext %x, i32 signext %y) nounwind {
152149
;
153150
; LA64-LABEL: rotl_32_mask:
154151
; LA64: # %bb.0:
155-
; LA64-NEXT: sll.w $a2, $a0, $a1
156-
; LA64-NEXT: sub.d $a1, $zero, $a1
157-
; LA64-NEXT: srl.w $a0, $a0, $a1
158-
; LA64-NEXT: or $a0, $a2, $a0
152+
; LA64-NEXT: ori $a2, $zero, 32
153+
; LA64-NEXT: sub.d $a1, $a2, $a1
154+
; LA64-NEXT: rotr.w $a0, $a0, $a1
159155
; LA64-NEXT: ret
160156
%z = sub i32 0, %y
161157
%and = and i32 %z, 31
@@ -174,10 +170,9 @@ define signext i32 @rotl_32_mask_and_63_and_31(i32 signext %x, i32 signext %y) n
174170
;
175171
; LA64-LABEL: rotl_32_mask_and_63_and_31:
176172
; LA64: # %bb.0:
177-
; LA64-NEXT: sll.w $a2, $a0, $a1
178-
; LA64-NEXT: sub.d $a1, $zero, $a1
179-
; LA64-NEXT: srl.w $a0, $a0, $a1
180-
; LA64-NEXT: or $a0, $a2, $a0
173+
; LA64-NEXT: ori $a2, $zero, 32
174+
; LA64-NEXT: sub.d $a1, $a2, $a1
175+
; LA64-NEXT: rotr.w $a0, $a0, $a1
181176
; LA64-NEXT: ret
182177
%a = and i32 %y, 63
183178
%b = shl i32 %x, %a
@@ -197,10 +192,9 @@ define signext i32 @rotl_32_mask_or_64_or_32(i32 signext %x, i32 signext %y) nou
197192
;
198193
; LA64-LABEL: rotl_32_mask_or_64_or_32:
199194
; LA64: # %bb.0:
200-
; LA64-NEXT: sll.w $a2, $a0, $a1
201-
; LA64-NEXT: sub.d $a1, $zero, $a1
202-
; LA64-NEXT: srl.w $a0, $a0, $a1
203-
; LA64-NEXT: or $a0, $a2, $a0
195+
; LA64-NEXT: ori $a2, $zero, 32
196+
; LA64-NEXT: sub.d $a1, $a2, $a1
197+
; LA64-NEXT: rotr.w $a0, $a0, $a1
204198
; LA64-NEXT: ret
205199
%a = or i32 %y, 64
206200
%b = shl i32 %x, %a
@@ -591,10 +585,7 @@ define signext i32 @rotr_i32_fshr(i32 signext %a) nounwind {
591585
;
592586
; LA64-LABEL: rotr_i32_fshr:
593587
; LA64: # %bb.0:
594-
; LA64-NEXT: slli.d $a1, $a0, 20
595-
; LA64-NEXT: bstrpick.d $a0, $a0, 31, 12
596-
; LA64-NEXT: or $a0, $a0, $a1
597-
; LA64-NEXT: addi.w $a0, $a0, 0
588+
; LA64-NEXT: rotri.w $a0, $a0, 12
598589
; LA64-NEXT: ret
599590
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 12)
600591
ret i32 %or

0 commit comments

Comments
 (0)