[llvm] ad59967 - [LoongArch] Optimize codegen for ISD::{ROTL, ROTR} (#91174)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 7 00:46:14 PDT 2024
Author: hev
Date: 2024-05-07T15:46:11+08:00
New Revision: ad59967336d2279eee77fff3a92e52ec87010aae
URL: https://github.com/llvm/llvm-project/commit/ad59967336d2279eee77fff3a92e52ec87010aae
DIFF: https://github.com/llvm/llvm-project/commit/ad59967336d2279eee77fff3a92e52ec87010aae.diff
LOG: [LoongArch] Optimize codegen for ISD::{ROTL,ROTR} (#91174)
Added:
Modified:
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
llvm/test/CodeGen/LoongArch/rotl-rotr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 46a6703f29d500..21d520656091c9 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -1671,10 +1671,9 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
return LoongArchISD::SRA_W;
case ISD::SRL:
return LoongArchISD::SRL_W;
+ case ISD::ROTL:
case ISD::ROTR:
return LoongArchISD::ROTR_W;
- case ISD::ROTL:
- return LoongArchISD::ROTL_W;
case ISD::CTTZ:
return LoongArchISD::CTZ_W;
case ISD::CTLZ:
@@ -1704,6 +1703,10 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
case 2: {
NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1));
+ if (N->getOpcode() == ISD::ROTL) {
+ SDValue TmpOp = DAG.getConstant(32, DL, MVT::i64);
+ NewOp1 = DAG.getNode(ISD::SUB, DL, MVT::i64, TmpOp, NewOp1);
+ }
NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
break;
}
@@ -1841,7 +1844,6 @@ void LoongArchTargetLowering::ReplaceNodeResults(
case ISD::SHL:
case ISD::SRA:
case ISD::SRL:
- case ISD::ROTR:
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
"Unexpected custom legalisation");
if (N->getOperand(1).getOpcode() != ISD::Constant) {
@@ -1850,11 +1852,10 @@ void LoongArchTargetLowering::ReplaceNodeResults(
}
break;
case ISD::ROTL:
- ConstantSDNode *CN;
- if ((CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))) {
- Results.push_back(customLegalizeToWOp(N, DAG, 2));
- break;
- }
+ case ISD::ROTR:
+ assert(VT == MVT::i32 && Subtarget.is64Bit() &&
+ "Unexpected custom legalisation");
+ Results.push_back(customLegalizeToWOp(N, DAG, 2));
break;
case ISD::FP_TO_SINT: {
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index a7f6eb9a79ebc0..f56f8f7e1179c2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -85,7 +85,6 @@ def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
-def loongarch_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>;
def loongarch_crc_w_b_w
: SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crc_w_h_w
@@ -1116,12 +1115,10 @@ def : PatGprGpr<srem, MOD_D>;
def : PatGprGpr<urem, MOD_DU>;
def : PatGprGpr<rotr, ROTR_D>;
def : PatGprGpr<loongarch_rotr_w, ROTR_W>;
+def : PatGprGpr_32<rotr, ROTR_W>;
def : PatGprImm<rotr, ROTRI_D, uimm6>;
def : PatGprImm_32<rotr, ROTRI_W, uimm5>;
-def : Pat<(loongarch_rotl_w GPR:$rj, uimm5:$imm),
- (ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
-def : Pat<(sext_inreg (loongarch_rotl_w GPR:$rj, uimm5:$imm), i32),
- (ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
+def : PatGprImm<loongarch_rotr_w, ROTRI_W, uimm5>;
// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the
// product are used.
def : PatGprGpr<mul, MUL_D>;
diff --git a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll b/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
index 8646771e5d48a1..b9fbd962e6bbf6 100644
--- a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
+++ b/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
@@ -2,8 +2,6 @@
; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64
-;; TODO: Add optimization to ISD::ROTL
-
define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
; LA32-LABEL: rotl_32:
; LA32: # %bb.0:
@@ -14,10 +12,9 @@ define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
;
; LA64-LABEL: rotl_32:
; LA64: # %bb.0:
-; LA64-NEXT: sll.w $a2, $a0, $a1
-; LA64-NEXT: sub.d $a1, $zero, $a1
-; LA64-NEXT: srl.w $a0, $a0, $a1
-; LA64-NEXT: or $a0, $a2, $a0
+; LA64-NEXT: ori $a2, $zero, 32
+; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%z = sub i32 32, %y
%b = shl i32 %x, %y
@@ -152,10 +149,9 @@ define signext i32 @rotl_32_mask(i32 signext %x, i32 signext %y) nounwind {
;
; LA64-LABEL: rotl_32_mask:
; LA64: # %bb.0:
-; LA64-NEXT: sll.w $a2, $a0, $a1
-; LA64-NEXT: sub.d $a1, $zero, $a1
-; LA64-NEXT: srl.w $a0, $a0, $a1
-; LA64-NEXT: or $a0, $a2, $a0
+; LA64-NEXT: ori $a2, $zero, 32
+; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%z = sub i32 0, %y
%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
;
; LA64-LABEL: rotl_32_mask_and_63_and_31:
; LA64: # %bb.0:
-; LA64-NEXT: sll.w $a2, $a0, $a1
-; LA64-NEXT: sub.d $a1, $zero, $a1
-; LA64-NEXT: srl.w $a0, $a0, $a1
-; LA64-NEXT: or $a0, $a2, $a0
+; LA64-NEXT: ori $a2, $zero, 32
+; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%a = and i32 %y, 63
%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
;
; LA64-LABEL: rotl_32_mask_or_64_or_32:
; LA64: # %bb.0:
-; LA64-NEXT: sll.w $a2, $a0, $a1
-; LA64-NEXT: sub.d $a1, $zero, $a1
-; LA64-NEXT: srl.w $a0, $a0, $a1
-; LA64-NEXT: or $a0, $a2, $a0
+; LA64-NEXT: ori $a2, $zero, 32
+; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%a = or i32 %y, 64
%b = shl i32 %x, %a
@@ -591,10 +585,7 @@ define signext i32 @rotr_i32_fshr(i32 signext %a) nounwind {
;
; LA64-LABEL: rotr_i32_fshr:
; LA64: # %bb.0:
-; LA64-NEXT: slli.d $a1, $a0, 20
-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 12
-; LA64-NEXT: or $a0, $a0, $a1
-; LA64-NEXT: addi.w $a0, $a0, 0
+; LA64-NEXT: rotri.w $a0, $a0, 12
; LA64-NEXT: ret
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 12)
ret i32 %or
More information about the llvm-commits
mailing list