[llvm] [LoongArch] Optimize codegen for ISD::ROTL (PR #100344)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 24 03:48:14 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: hev (heiher)
<details>
<summary>Changes</summary>
The LoongArch rotr.{w,d} instruction ignores the high bits of the shift operand, allowing it to generate more efficient code using the constant zero register.
---
Full diff: https://github.com/llvm/llvm-project/pull/100344.diff
2 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+14-2)
- (modified) llvm/test/CodeGen/LoongArch/rotl-rotr.ll (+6-12)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index d80509cf39849..185a1b9d52e5b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -78,7 +78,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SRA_PARTS, GRLenVT, Custom);
setOperationAction(ISD::SRL_PARTS, GRLenVT, Custom);
setOperationAction(ISD::FP_TO_SINT, GRLenVT, Custom);
- setOperationAction(ISD::ROTL, GRLenVT, Expand);
+ setOperationAction(ISD::ROTL, GRLenVT, Custom);
setOperationAction(ISD::CTPOP, GRLenVT, Expand);
setOperationAction({ISD::GlobalAddress, ISD::BlockAddress, ISD::ConstantPool,
@@ -2661,7 +2661,8 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
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);
+ SDValue TmpOp = DAG.getConstant(
+ isa<ConstantSDNode>(NewOp1.getNode()) ? 32 : 0, DL, MVT::i64);
NewOp1 = DAG.getNode(ISD::SUB, DL, MVT::i64, TmpOp, NewOp1);
}
NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
@@ -2833,6 +2834,17 @@ void LoongArchTargetLowering::ReplaceNodeResults(
}
break;
case ISD::ROTL:
+ if (VT == MVT::i32 && Subtarget.is64Bit()) {
+ Results.push_back(customLegalizeToWOp(N, DAG, 2));
+ } else {
+ SDValue Op0 = N->getOperand(0);
+ SDValue TmpOp = DAG.getConstant(
+ isa<ConstantSDNode>(Op0.getNode()) ? Subtarget.getGRLen() : 0, DL,
+ VT);
+ SDValue NewOp1 = DAG.getNode(ISD::SUB, DL, VT, TmpOp, N->getOperand(1));
+ Results.push_back(DAG.getNode(ISD::ROTR, DL, VT, Op0, NewOp1));
+ }
+ break;
case ISD::ROTR:
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
"Unexpected custom legalisation");
diff --git a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll b/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
index 75461f5820984..774cf614f6099 100644
--- a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
+++ b/llvm/test/CodeGen/LoongArch/rotl-rotr.ll
@@ -5,15 +5,13 @@
define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
; LA32-LABEL: rotl_32:
; LA32: # %bb.0:
-; LA32-NEXT: ori $a2, $zero, 32
-; LA32-NEXT: sub.w $a1, $a2, $a1
+; LA32-NEXT: sub.w $a1, $zero, $a1
; LA32-NEXT: rotr.w $a0, $a0, $a1
; LA32-NEXT: ret
;
; LA64-LABEL: rotl_32:
; LA64: # %bb.0:
-; LA64-NEXT: ori $a2, $zero, 32
-; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: sub.d $a1, $zero, $a1
; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%z = sub i32 32, %y
@@ -80,8 +78,7 @@ define i64 @rotl_64(i64 %x, i64 %y) nounwind {
;
; LA64-LABEL: rotl_64:
; LA64: # %bb.0:
-; LA64-NEXT: ori $a2, $zero, 64
-; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: sub.d $a1, $zero, $a1
; LA64-NEXT: rotr.d $a0, $a0, $a1
; LA64-NEXT: ret
%z = sub i64 64, %y
@@ -149,8 +146,7 @@ define signext i32 @rotl_32_mask(i32 signext %x, i32 signext %y) nounwind {
;
; LA64-LABEL: rotl_32_mask:
; LA64: # %bb.0:
-; LA64-NEXT: ori $a2, $zero, 32
-; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: sub.d $a1, $zero, $a1
; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%z = sub i32 0, %y
@@ -170,8 +166,7 @@ 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: ori $a2, $zero, 32
-; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: sub.d $a1, $zero, $a1
; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%a = and i32 %y, 63
@@ -192,8 +187,7 @@ 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: ori $a2, $zero, 32
-; LA64-NEXT: sub.d $a1, $a2, $a1
+; LA64-NEXT: sub.d $a1, $zero, $a1
; LA64-NEXT: rotr.w $a0, $a0, $a1
; LA64-NEXT: ret
%a = or i32 %y, 64
``````````
</details>
https://github.com/llvm/llvm-project/pull/100344
More information about the llvm-commits
mailing list