[llvm-branch-commits] [llvm] [LoongArch] Combine rounded vector shifts to VSRLR/VSRAR (PR #192921)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Apr 20 01:48:32 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: hev (heiher)
<details>
<summary>Changes</summary>
Add DAG combines to recognize canonical rounded shift patterns and lower them to target-specific vector rounded shift instructions.
The combines match vector arithmetic and logical right shifts with rounding implemented as:
```
add (srl/sra X, shift),
(and (srl X, shift-1), 1)
```
and the shift-by-1 variant:
```
add (srl/sra X, 1),
(and X, 1)
```
Additionally, handle the guarded form generated when shift may be zero:
```
vselect (setcc shift, 0, seteq),
X,
rounded_shift
```
and fold it to the corresponding rounded shift instruction.
Define new target DAG nodes VSRLR and VSRAR and add instruction selection patterns for both LSX and LASX, including register and immediate shift forms.
---
Patch is 33.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192921.diff
7 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+272)
- (modified) llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td (+8)
- (modified) llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td (+12)
- (modified) llvm/test/CodeGen/LoongArch/lasx/srar.ll (+12-65)
- (modified) llvm/test/CodeGen/LoongArch/lasx/srlr.ll (+12-65)
- (modified) llvm/test/CodeGen/LoongArch/lsx/srar.ll (+12-65)
- (modified) llvm/test/CodeGen/LoongArch/lsx/srlr.ll (+12-65)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 446d27805fb35..71edc58ff7640 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -482,8 +482,10 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
// Set DAG combine for 'LSX' feature.
if (Subtarget.hasExtLSX()) {
+ setTargetDAGCombine(ISD::ADD);
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
setTargetDAGCombine(ISD::BITCAST);
+ setTargetDAGCombine(ISD::VSELECT);
}
// Set DAG combine for 'LASX' feature.
@@ -5439,6 +5441,139 @@ static SDValue combineAndNotIntoVANDN(SDNode *N, const SDLoc &DL,
return DAG.getNode(LoongArchISD::VANDN, DL, VT, X, Y);
}
+static bool isConstantSplatVector(SDValue N, APInt &SplatValue,
+ unsigned MinSizeInBits) {
+ if (N->getOpcode() == ISD::BITCAST)
+ N = N->getOperand(0);
+
+ BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(N);
+
+ if (!Node)
+ return false;
+
+ APInt SplatUndef;
+ unsigned SplatBitSize;
+ bool HasAnyUndefs;
+
+ return Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
+ HasAnyUndefs, MinSizeInBits,
+ /*IsBigEndian=*/false);
+}
+
+static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const LoongArchSubtarget &Subtarget) {
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
+ EVT VT = N->getValueType(0);
+ if (!VT.isVector())
+ return SDValue();
+
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
+ return SDValue();
+
+ EVT EltVT = VT.getVectorElementType();
+ if (!EltVT.isInteger())
+ return SDValue();
+
+ // match:
+ //
+ // add
+ // (and
+ // (srl X, shift-1) / X
+ // 1)
+ // (srl/sra X, shift)
+
+ SDValue Add0 = N->getOperand(0);
+ SDValue Add1 = N->getOperand(1);
+ SDValue And;
+ SDValue Shr;
+
+ if (Add0.getOpcode() == ISD::AND) {
+ And = Add0;
+ Shr = Add1;
+ } else if (Add1.getOpcode() == ISD::AND) {
+ And = Add1;
+ Shr = Add0;
+ } else {
+ return SDValue();
+ }
+
+ // match:
+ //
+ // srl/sra X, shift
+
+ if (Shr.getOpcode() != ISD::SRL && Shr.getOpcode() != ISD::SRA)
+ return SDValue();
+
+ SDValue X = Shr.getOperand(0);
+ SDValue Shift = Shr.getOperand(1);
+ APInt ShiftVal;
+
+ if (!isConstantSplatVector(Shift, ShiftVal, EltVT.getSizeInBits()))
+ return SDValue();
+
+ if (ShiftVal == 0)
+ return SDValue();
+
+ // match:
+ //
+ // and
+ // (srl X, shift-1) / X
+ // 1
+
+ SDValue One = And.getOperand(1);
+ APInt SplatVal;
+
+ if (!isConstantSplatVector(One, SplatVal, EltVT.getSizeInBits()))
+ return SDValue();
+
+ if (SplatVal != 1)
+ return SDValue();
+
+ if (And.getOperand(0) == X) {
+ // match:
+ //
+ // shift == 1
+
+ if (ShiftVal != 1)
+ return SDValue();
+ } else {
+ // match:
+ //
+ // srl X, shift-1
+
+ SDValue Srl = And.getOperand(0);
+
+ if (Srl.getOpcode() != ISD::SRL)
+ return SDValue();
+
+ if (Srl.getOperand(0) != X)
+ return SDValue();
+
+ // match:
+ //
+ // shift-1
+
+ SDValue ShiftMinus1 = Srl.getOperand(1);
+
+ if (!isConstantSplatVector(ShiftMinus1, SplatVal, EltVT.getSizeInBits()))
+ return SDValue();
+
+ if (ShiftVal != (SplatVal + 1))
+ return SDValue();
+ }
+
+ // We matched a rounded right shift pattern and can lower it
+ // to a single vector rounded shift instruction.
+
+ SDLoc DL(N);
+ return DAG.getNode(Shr.getOpcode() == ISD::SRL ? LoongArchISD::VSRLR
+ : LoongArchISD::VSRAR,
+ DL, VT, X, Shift);
+}
+
static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const LoongArchSubtarget &Subtarget) {
@@ -7332,12 +7467,147 @@ performCONCAT_VECTORSCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const LoongArchSubtarget &Subtarget) {
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
+ EVT VT = N->getValueType(0);
+ if (!VT.isVector())
+ return SDValue();
+
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
+ return SDValue();
+
+ EVT EltVT = VT.getVectorElementType();
+ if (!EltVT.isInteger())
+ return SDValue();
+
+ SDValue Cond = N->getOperand(0);
+ SDValue TrueVal = N->getOperand(1);
+ SDValue FalseVal = N->getOperand(2);
+
+ // match:
+ //
+ // vselect (setcc shift, 0, seteq),
+ // x,
+ // rounded_shift
+
+ if (Cond.getOpcode() != ISD::SETCC)
+ return SDValue();
+
+ if (!ISD::isConstantSplatVectorAllZeros(Cond.getOperand(1).getNode()))
+ return SDValue();
+
+ auto *CC = cast<CondCodeSDNode>(Cond.getOperand(2));
+ if (CC->get() != ISD::SETEQ)
+ return SDValue();
+
+ SDValue Shift = Cond.getOperand(0);
+
+ // True branch must be original value:
+ //
+ // vselect cond, x, ...
+
+ SDValue X = TrueVal;
+
+ // Now match rounded shift pattern:
+ //
+ // add
+ // (and
+ // (srl X, shift-1)
+ // 1)
+ // (srl/sra X, shift)
+
+ if (FalseVal.getOpcode() != ISD::ADD)
+ return SDValue();
+
+ SDValue Add0 = FalseVal.getOperand(0);
+ SDValue Add1 = FalseVal.getOperand(1);
+ SDValue And;
+ SDValue Shr;
+
+ if (Add0.getOpcode() == ISD::AND) {
+ And = Add0;
+ Shr = Add1;
+ } else if (Add1.getOpcode() == ISD::AND) {
+ And = Add1;
+ Shr = Add0;
+ } else {
+ return SDValue();
+ }
+
+ // match:
+ //
+ // srl/sra X, shift
+
+ if (Shr.getOpcode() != ISD::SRL && Shr.getOpcode() != ISD::SRA)
+ return SDValue();
+
+ if (Shr.getOperand(0) != X)
+ return SDValue();
+
+ if (Shr.getOperand(1) != Shift)
+ return SDValue();
+
+ // match:
+ //
+ // and
+ // (srl X, shift-1)
+ // 1
+
+ SDValue Srl = And.getOperand(0);
+ SDValue One = And.getOperand(1);
+ APInt SplatVal;
+
+ if (Srl.getOpcode() != ISD::SRL)
+ return SDValue();
+
+ if (One.getOpcode() == ISD::BITCAST)
+ One = One.getOperand(0);
+
+ if (!isConstantSplatVector(One, SplatVal, EltVT.getSizeInBits()))
+ return SDValue();
+
+ if (SplatVal != 1)
+ return SDValue();
+
+ if (Srl.getOperand(0) != X)
+ return SDValue();
+
+ // match:
+ //
+ // shift-1
+
+ SDValue ShiftMinus1 = Srl.getOperand(1);
+
+ if (ShiftMinus1.getOpcode() != ISD::ADD)
+ return SDValue();
+
+ if (ShiftMinus1.getOperand(0) != Shift)
+ return SDValue();
+
+ if (!ISD::isConstantSplatVectorAllOnes(ShiftMinus1.getOperand(1).getNode()))
+ return SDValue();
+
+ // We matched a rounded right shift pattern and can lower it
+ // to a single vector rounded shift instruction.
+
+ SDLoc DL(N);
+ return DAG.getNode(Shr.getOpcode() == ISD::SRL ? LoongArchISD::VSRLR
+ : LoongArchISD::VSRAR,
+ DL, VT, X, Shift);
+}
+
SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
switch (N->getOpcode()) {
default:
break;
+ case ISD::ADD:
+ return performADDCombine(N, DAG, DCI, Subtarget);
case ISD::AND:
return performANDCombine(N, DAG, DCI, Subtarget);
case ISD::OR:
@@ -7375,6 +7645,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
return performVANDNCombine(N, DAG, DCI, Subtarget);
case ISD::CONCAT_VECTORS:
return performCONCAT_VECTORSCombine(N, DAG, DCI, Subtarget);
+ case ISD::VSELECT:
+ return performVSELECTCombine(N, DAG, DCI, Subtarget);
case LoongArchISD::VPACKEV:
if (SDValue Result =
combineFP_ROUND(SDValue(N, 0), SDLoc(N), DAG, Subtarget))
diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index b807b5927585b..133226e474f62 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1469,11 +1469,19 @@ defm : PatShiftXrXr<srl, "XVSRL">;
defm : PatShiftXrSplatUimm<srl, "XVSRLI">;
defm : PatShiftXrUimm<loongarch_vsrli, "XVSRLI">;
+// XVSRLR[I]_{B/H/W/D}
+defm : PatXrXr<loongarch_vsrlr, "XVSRLR">;
+defm : PatShiftXrSplatUimm<loongarch_vsrlr, "XVSRLRI">;
+
// XVSRA[I]_{B/H/W/D}
defm : PatXrXr<sra, "XVSRA">;
defm : PatShiftXrXr<sra, "XVSRA">;
defm : PatShiftXrSplatUimm<sra, "XVSRAI">;
+// XVSRAR[I]_{B/H/W/D}
+defm : PatXrXr<loongarch_vsrar, "XVSRAR">;
+defm : PatShiftXrSplatUimm<loongarch_vsrar, "XVSRARI">;
+
// XVROTR[I]_{B/H/W/D}
defm : PatXrXr<rotr, "XVROTR">;
defm : PatShiftXrXr<rotr, "XVROTR">;
diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
index 92d3214363f7b..b7539730e7524 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -98,6 +98,10 @@ def loongarch_vmsknez: SDNode<"LoongArchISD::VMSKNEZ", SDT_LoongArchVMSKCOND>;
def loongarch_vfcvt_s_d: SDNode<"LoongArchISD::VFCVT", SDT_LoongArchVFCVT_S_D>;
+// Vector rounded shift
+def loongarch_vsrlr: SDNode<"LoongArchISD::VSRLR", SDT_LoongArchV2R>;
+def loongarch_vsrar: SDNode<"LoongArchISD::VSRAR", SDT_LoongArchV2R>;
+
def immZExt1 : ImmLeaf<GRLenVT, [{return isUInt<1>(Imm);}]>;
def immZExt2 : ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]>;
def immZExt3 : ImmLeaf<GRLenVT, [{return isUInt<3>(Imm);}]>;
@@ -1690,11 +1694,19 @@ defm : PatShiftVrVr<srl, "VSRL">;
defm : PatShiftVrSplatUimm<srl, "VSRLI">;
defm : PatShiftVrUimm<loongarch_vsrli, "VSRLI">;
+// VSRLR[I]_{B/H/W/D}
+defm : PatVrVr<loongarch_vsrlr, "VSRLR">;
+defm : PatShiftVrSplatUimm<loongarch_vsrlr, "VSRLRI">;
+
// VSRA[I]_{B/H/W/D}
defm : PatVrVr<sra, "VSRA">;
defm : PatShiftVrVr<sra, "VSRA">;
defm : PatShiftVrSplatUimm<sra, "VSRAI">;
+// VSRAR[I]_{B/H/W/D}
+defm : PatVrVr<loongarch_vsrar, "VSRAR">;
+defm : PatShiftVrSplatUimm<loongarch_vsrar, "VSRARI">;
+
// VROTR[I]_{B/H/W/D}
defm : PatVrVr<rotr, "VROTR">;
defm : PatShiftVrVr<rotr, "VROTR">;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/srar.ll b/llvm/test/CodeGen/LoongArch/lasx/srar.ll
index 289b2296a3d88..4fb641020e74c 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/srar.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/srar.ll
@@ -5,13 +5,7 @@
define <32 x i8> @srar_b(<32 x i8> %a, <32 x i8> %b) nounwind {
; CHECK-LABEL: srar_b:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsra.b $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.bu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.b $xr3, $xr0, $xr3
-; CHECK-NEXT: xvandi.b $xr3, $xr3, 1
-; CHECK-NEXT: xvadd.b $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.b $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrar.b $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = ashr <32 x i8> %a, %b
@@ -27,14 +21,7 @@ entry:
define <16 x i16> @srar_h(<16 x i16> %a, <16 x i16> %b) nounwind {
; CHECK-LABEL: srar_h:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsra.h $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.hu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.h $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.h $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.h $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.h $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrar.h $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = ashr <16 x i16> %a, %b
@@ -50,14 +37,7 @@ entry:
define <8 x i32> @srar_w(<8 x i32> %a, <8 x i32> %b) nounwind {
; CHECK-LABEL: srar_w:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsra.w $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.wu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.w $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.w $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.w $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.w $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrar.w $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = ashr <8 x i32> %a, %b
@@ -73,14 +53,7 @@ entry:
define <4 x i64> @srar_d(<4 x i64> %a, <4 x i64> %b) nounwind {
; CHECK-LABEL: srar_d:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsra.d $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.du $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.d $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.d $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.d $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.d $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrar.d $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = ashr <4 x i64> %a, %b
@@ -96,9 +69,7 @@ entry:
define <32 x i8> @srar_b_1(<32 x i8> %a) nounwind {
; CHECK-LABEL: srar_b_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.b $xr1, $xr0, 1
-; CHECK-NEXT: xvandi.b $xr0, $xr0, 1
-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.b $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = ashr <32 x i8> %a, splat (i8 1)
@@ -110,10 +81,7 @@ entry:
define <32 x i8> @srar_b_7(<32 x i8> %a) nounwind {
; CHECK-LABEL: srar_b_7:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.b $xr1, $xr0, 7
-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 6
-; CHECK-NEXT: xvandi.b $xr0, $xr0, 1
-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.b $xr0, $xr0, 7
; CHECK-NEXT: ret
entry:
%0 = ashr <32 x i8> %a, splat (i8 7)
@@ -126,10 +94,7 @@ entry:
define <16 x i16> @srar_h_1(<16 x i16> %a) nounwind {
; CHECK-LABEL: srar_h_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.h $xr1, $xr0, 1
-; CHECK-NEXT: xvrepli.h $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.h $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = ashr <16 x i16> %a, splat (i16 1)
@@ -141,11 +106,7 @@ entry:
define <16 x i16> @srar_h_15(<16 x i16> %a) nounwind {
; CHECK-LABEL: srar_h_15:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.h $xr1, $xr0, 15
-; CHECK-NEXT: xvsrli.h $xr0, $xr0, 14
-; CHECK-NEXT: xvrepli.h $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.h $xr0, $xr0, 15
; CHECK-NEXT: ret
entry:
%0 = ashr <16 x i16> %a, splat (i16 15)
@@ -158,10 +119,7 @@ entry:
define <8 x i32> @srar_w_1(<8 x i32> %a) nounwind {
; CHECK-LABEL: srar_w_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.w $xr1, $xr0, 1
-; CHECK-NEXT: xvrepli.w $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.w $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = ashr <8 x i32> %a, splat (i32 1)
@@ -173,11 +131,7 @@ entry:
define <8 x i32> @srar_w_31(<8 x i32> %a) nounwind {
; CHECK-LABEL: srar_w_31:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.w $xr1, $xr0, 31
-; CHECK-NEXT: xvsrli.w $xr0, $xr0, 30
-; CHECK-NEXT: xvrepli.w $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.w $xr0, $xr0, 31
; CHECK-NEXT: ret
entry:
%0 = ashr <8 x i32> %a, splat (i32 31)
@@ -190,10 +144,7 @@ entry:
define <4 x i64> @srar_d_1(<4 x i64> %a) nounwind {
; CHECK-LABEL: srar_d_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.d $xr1, $xr0, 1
-; CHECK-NEXT: xvrepli.d $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.d $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = ashr <4 x i64> %a, splat (i64 1)
@@ -205,11 +156,7 @@ entry:
define <4 x i64> @srar_d_63(<4 x i64> %a) nounwind {
; CHECK-LABEL: srar_d_63:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrai.d $xr1, $xr0, 63
-; CHECK-NEXT: xvsrli.d $xr0, $xr0, 62
-; CHECK-NEXT: xvrepli.d $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrari.d $xr0, $xr0, 63
; CHECK-NEXT: ret
entry:
%0 = ashr <4 x i64> %a, splat (i64 63)
diff --git a/llvm/test/CodeGen/LoongArch/lasx/srlr.ll b/llvm/test/CodeGen/LoongArch/lasx/srlr.ll
index 3087ceb928451..cadbf154201d5 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/srlr.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/srlr.ll
@@ -5,13 +5,7 @@
define <32 x i8> @srlr_b(<32 x i8> %a, <32 x i8> %b) nounwind {
; CHECK-LABEL: srlr_b:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrl.b $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.bu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.b $xr3, $xr0, $xr3
-; CHECK-NEXT: xvandi.b $xr3, $xr3, 1
-; CHECK-NEXT: xvadd.b $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.b $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrlr.b $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = lshr <32 x i8> %a, %b
@@ -27,14 +21,7 @@ entry:
define <16 x i16> @srlr_h(<16 x i16> %a, <16 x i16> %b) nounwind {
; CHECK-LABEL: srlr_h:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrl.h $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.hu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.h $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.h $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.h $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.h $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrlr.h $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = lshr <16 x i16> %a, %b
@@ -50,14 +37,7 @@ entry:
define <8 x i32> @srlr_w(<8 x i32> %a, <8 x i32> %b) nounwind {
; CHECK-LABEL: srlr_w:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrl.w $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.wu $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.w $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.w $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.w $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.w $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrlr.w $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = lshr <8 x i32> %a, %b
@@ -73,14 +53,7 @@ entry:
define <4 x i64> @srlr_d(<4 x i64> %a, <4 x i64> %b) nounwind {
; CHECK-LABEL: srlr_d:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrl.d $xr2, $xr0, $xr1
-; CHECK-NEXT: xvsubi.du $xr3, $xr1, 1
-; CHECK-NEXT: xvsrl.d $xr3, $xr0, $xr3
-; CHECK-NEXT: xvrepli.d $xr4, 1
-; CHECK-NEXT: xvand.v $xr3, $xr3, $xr4
-; CHECK-NEXT: xvadd.d $xr2, $xr3, $xr2
-; CHECK-NEXT: xvseqi.d $xr1, $xr1, 0
-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr0, $xr1
+; CHECK-NEXT: xvsrlr.d $xr0, $xr0, $xr1
; CHECK-NEXT: ret
entry:
%0 = lshr <4 x i64> %a, %b
@@ -96,9 +69,7 @@ entry:
define <32 x i8> @srlr_b_1(<32 x i8> %a) nounwind {
; CHECK-LABEL: srlr_b_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrli.b $xr1, $xr0, 1
-; CHECK-NEXT: xvandi.b $xr0, $xr0, 1
-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrlri.b $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = lshr <32 x i8> %a, splat (i8 1)
@@ -110,10 +81,7 @@ entry:
define <32 x i8> @srlr_b_7(<32 x i8> %a) nounwind {
; CHECK-LABEL: srlr_b_7:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrli.b $xr1, $xr0, 7
-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 6
-; CHECK-NEXT: xvandi.b $xr0, $xr0, 1
-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrlri.b $xr0, $xr0, 7
; CHECK-NEXT: ret
entry:
%0 = lshr <32 x i8> %a, splat (i8 7)
@@ -126,10 +94,7 @@ entry:
define <16 x i16> @srlr_h_1(<16 x i16> %a) nounwind {
; CHECK-LABEL: srlr_h_1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvsrli.h $xr1, $xr0, 1
-; CHECK-NEXT: xvrepli.h $xr2, 1
-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr2
-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvsrlri.h $xr0, $xr0, 1
; CHECK-NEXT: ret
entry:
%0 = lshr <16 x i16> %a, splat (i16 1)
@@ -141,11 +106,7 @@ entry:
define <16 x i16> @srlr_h_15(<16 x i16> %a) nounwind {
; CHECK-LABEL: srlr_h_15:
; CHECK: # %bb.0: # %entry
-; CHECK-NE...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192921
More information about the llvm-branch-commits
mailing list