[llvm] [LoongArch] Make rotl/rotr custom for lsx/lasx (PR #161154)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 27 18:22:33 PST 2025
================
@@ -827,6 +834,59 @@ SDValue LoongArchTargetLowering::lowerPREFETCH(SDValue Op,
return Op;
}
+SDValue LoongArchTargetLowering::lowerRotate(SDValue Op,
+ SelectionDAG &DAG) const {
+ MVT VT = Op.getSimpleValueType();
+ if (!VT.isVector())
+ return Op;
+
+ SDLoc DL(Op);
+ SDValue R = Op.getOperand(0);
+ SDValue Amt = Op.getOperand(1);
+ unsigned Opcode = Op.getOpcode();
+ unsigned EltSizeInBits = VT.getScalarSizeInBits();
+
+ auto checkCstSplat = [](SDValue V, APInt &CstSplatValue) {
+ if (V.getOpcode() != ISD::BUILD_VECTOR)
+ return false;
+ if (SDValue SplatValue =
+ cast<BuildVectorSDNode>(V.getNode())->getSplatValue()) {
+ if (auto *C = dyn_cast<ConstantSDNode>(SplatValue)) {
+ CstSplatValue = C->getAPIntValue();
+ return true;
+ }
+ }
+ return false;
+ };
+
+ // Check for constant splat rotation amount.
+ APInt CstSplatValue;
+ bool IsCstSplat = checkCstSplat(Amt, CstSplatValue);
+ bool isROTL = Opcode == ISD::ROTL;
+
+ // Check for splat rotate by zero.
+ if (IsCstSplat && CstSplatValue.urem(EltSizeInBits) == 0)
+ return R;
+
+ // LoongArch tagets always prefers ISD::ROTR.
+ if (isROTL) {
+ SDValue Zero = DAG.getConstant(0, DL, VT);
+ return DAG.getNode(ISD::ROTR, DL, VT, R,
+ DAG.getNode(ISD::SUB, DL, VT, Zero, Amt));
+ }
+
+ // Rotate by a immediate.
+ if (IsCstSplat) {
+ // ISD::ROTR: Attemp to rotate by a positive immediate.
+ SDValue Bits = DAG.getConstant(EltSizeInBits, DL, VT);
+ if (SDValue Urem =
+ DAG.FoldConstantArithmetic(ISD::UREM, DL, VT, {Amt, Bits}))
+ return DAG.getNode(Op.getOpcode(), DL, VT, R, Urem);
----------------
zhaoqi5 wrote:
```suggestion
return DAG.getNode(Opcode, DL, VT, R, Urem);
```
https://github.com/llvm/llvm-project/pull/161154
More information about the llvm-commits
mailing list