Skip to content

Commit 802663b

Browse files
committed
[RISCV] use vwadd.vx for extended splat.
1 parent 556bf03 commit 802663b

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13589,6 +13589,8 @@ struct NodeExtensionHelper {
1358913589
case RISCVISD::VZEXT_VL:
1359013590
case RISCVISD::FP_EXTEND_VL:
1359113591
return OrigOperand.getOperand(0);
13592+
case ISD::SPLAT_VECTOR:
13593+
return OrigOperand.getOperand(0).getOperand(0);
1359213594
default:
1359313595
return OrigOperand;
1359413596
}
@@ -13640,6 +13642,8 @@ struct NodeExtensionHelper {
1364013642
case RISCVISD::VZEXT_VL:
1364113643
case RISCVISD::FP_EXTEND_VL:
1364213644
return DAG.getNode(ExtOpc, DL, NarrowVT, Source, Mask, VL);
13645+
case ISD::SPLAT_VECTOR:
13646+
return DAG.getNode(ISD::SPLAT_VECTOR, DL, NarrowVT, Source, Mask, VL);
1364313647
case RISCVISD::VMV_V_X_VL:
1364413648
return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, NarrowVT,
1364513649
DAG.getUNDEF(NarrowVT), Source.getOperand(1), VL);
@@ -13817,6 +13821,35 @@ struct NodeExtensionHelper {
1381713821
Mask = OrigOperand.getOperand(1);
1381813822
VL = OrigOperand.getOperand(2);
1381913823
break;
13824+
case ISD::SPLAT_VECTOR: {
13825+
SDValue ScalarOp = OrigOperand.getOperand(0);
13826+
unsigned ScalarOpc = ScalarOp.getOpcode();
13827+
13828+
MVT ScalarVT = ScalarOp.getSimpleValueType();
13829+
unsigned ScalarSize = ScalarVT.getScalarSizeInBits();
13830+
unsigned NarrowSize = ScalarSize / 2;
13831+
13832+
// Ensuring the scalar element is legal.
13833+
if (NarrowSize < 8)
13834+
break;
13835+
13836+
SupportsSExt = ScalarOpc == ISD::SIGN_EXTEND_INREG;
13837+
13838+
if (ScalarOpc == ISD::AND) {
13839+
if (ConstantSDNode *MaskNode =
13840+
dyn_cast<ConstantSDNode>(ScalarOp.getOperand(1)))
13841+
SupportsZExt = MaskNode->getAPIntValue() ==
13842+
APInt::getBitsSet(ScalarSize, 0, NarrowSize);
13843+
}
13844+
13845+
EnforceOneUse = false;
13846+
CheckMask = false;
13847+
13848+
MVT VT = OrigOperand.getSimpleValueType();
13849+
SDLoc DL(Root);
13850+
std::tie(Mask, VL) = getDefaultScalableVLOps(VT, DL, DAG, Subtarget);
13851+
break;
13852+
}
1382013853
case RISCVISD::VMV_V_X_VL: {
1382113854
// Historically, we didn't care about splat values not disappearing during
1382213855
// combines.

llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,3 +1466,156 @@ define <vscale x 2 x i32> @vwadd_wv_disjoint_or(<vscale x 2 x i32> %x.i32, <vsca
14661466
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
14671467
ret <vscale x 2 x i32> %or
14681468
}
1469+
1470+
define <vscale x 8 x i64> @vwadd_vx_splat_zext(<vscale x 8 x i32> %va, i32 %b) {
1471+
; RV32-LABEL: vwadd_vx_splat_zext:
1472+
; RV32: # %bb.0:
1473+
; RV32-NEXT: addi sp, sp, -16
1474+
; RV32-NEXT: .cfi_def_cfa_offset 16
1475+
; RV32-NEXT: sw zero, 12(sp)
1476+
; RV32-NEXT: sw a0, 8(sp)
1477+
; RV32-NEXT: addi a0, sp, 8
1478+
; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1479+
; RV32-NEXT: vlse64.v v16, (a0), zero
1480+
; RV32-NEXT: vwaddu.wv v16, v16, v8
1481+
; RV32-NEXT: vmv8r.v v8, v16
1482+
; RV32-NEXT: addi sp, sp, 16
1483+
; RV32-NEXT: ret
1484+
;
1485+
; RV64-LABEL: vwadd_vx_splat_zext:
1486+
; RV64: # %bb.0:
1487+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1488+
; RV64-NEXT: vwaddu.vx v16, v8, a0
1489+
; RV64-NEXT: vmv8r.v v8, v16
1490+
; RV64-NEXT: ret
1491+
%sb = zext i32 %b to i64
1492+
%head = insertelement <vscale x 8 x i64> poison, i64 %sb, i32 0
1493+
%splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> poison, <vscale x 8 x i32> zeroinitializer
1494+
%vc = zext <vscale x 8 x i32> %va to <vscale x 8 x i64>
1495+
%ve = add <vscale x 8 x i64> %vc, %splat
1496+
ret <vscale x 8 x i64> %ve
1497+
}
1498+
1499+
define <vscale x 8 x i32> @vwadd_vx_splat_zext_i1(<vscale x 8 x i1> %va, i16 %b) {
1500+
; RV32-LABEL: vwadd_vx_splat_zext_i1:
1501+
; RV32: # %bb.0:
1502+
; RV32-NEXT: slli a0, a0, 16
1503+
; RV32-NEXT: srli a0, a0, 16
1504+
; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, mu
1505+
; RV32-NEXT: vmv.v.x v8, a0
1506+
; RV32-NEXT: vadd.vi v8, v8, 1, v0.t
1507+
; RV32-NEXT: ret
1508+
;
1509+
; RV64-LABEL: vwadd_vx_splat_zext_i1:
1510+
; RV64: # %bb.0:
1511+
; RV64-NEXT: slli a0, a0, 48
1512+
; RV64-NEXT: srli a0, a0, 48
1513+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1514+
; RV64-NEXT: vmv.v.i v8, 0
1515+
; RV64-NEXT: vmerge.vim v8, v8, 1, v0
1516+
; RV64-NEXT: vadd.vx v8, v8, a0
1517+
; RV64-NEXT: ret
1518+
%sb = zext i16 %b to i32
1519+
%head = insertelement <vscale x 8 x i32> poison, i32 %sb, i32 0
1520+
%splat = shufflevector <vscale x 8 x i32> %head, <vscale x 8 x i32> poison, <vscale x 8 x i32> zeroinitializer
1521+
%vc = zext <vscale x 8 x i1> %va to <vscale x 8 x i32>
1522+
%ve = add <vscale x 8 x i32> %vc, %splat
1523+
ret <vscale x 8 x i32> %ve
1524+
}
1525+
1526+
define <vscale x 8 x i64> @vwadd_wx_splat_zext(<vscale x 8 x i64> %va, i32 %b) {
1527+
; RV32-LABEL: vwadd_wx_splat_zext:
1528+
; RV32: # %bb.0:
1529+
; RV32-NEXT: addi sp, sp, -16
1530+
; RV32-NEXT: .cfi_def_cfa_offset 16
1531+
; RV32-NEXT: sw zero, 12(sp)
1532+
; RV32-NEXT: sw a0, 8(sp)
1533+
; RV32-NEXT: addi a0, sp, 8
1534+
; RV32-NEXT: vsetvli a1, zero, e64, m8, ta, ma
1535+
; RV32-NEXT: vlse64.v v16, (a0), zero
1536+
; RV32-NEXT: vadd.vv v8, v8, v16
1537+
; RV32-NEXT: addi sp, sp, 16
1538+
; RV32-NEXT: ret
1539+
;
1540+
; RV64-LABEL: vwadd_wx_splat_zext:
1541+
; RV64: # %bb.0:
1542+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1543+
; RV64-NEXT: vwaddu.wx v8, v8, a0
1544+
; RV64-NEXT: ret
1545+
%sb = zext i32 %b to i64
1546+
%head = insertelement <vscale x 8 x i64> poison, i64 %sb, i32 0
1547+
%splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> poison, <vscale x 8 x i32> zeroinitializer
1548+
%ve = add <vscale x 8 x i64> %va, %splat
1549+
ret <vscale x 8 x i64> %ve
1550+
}
1551+
1552+
define <vscale x 8 x i64> @vwadd_vx_splat_sext(<vscale x 8 x i32> %va, i32 %b) {
1553+
; RV32-LABEL: vwadd_vx_splat_sext:
1554+
; RV32: # %bb.0:
1555+
; RV32-NEXT: vsetvli a1, zero, e64, m8, ta, ma
1556+
; RV32-NEXT: vmv.v.x v16, a0
1557+
; RV32-NEXT: vsetvli zero, zero, e32, m4, ta, ma
1558+
; RV32-NEXT: vwadd.wv v16, v16, v8
1559+
; RV32-NEXT: vmv8r.v v8, v16
1560+
; RV32-NEXT: ret
1561+
;
1562+
; RV64-LABEL: vwadd_vx_splat_sext:
1563+
; RV64: # %bb.0:
1564+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1565+
; RV64-NEXT: vwadd.vx v16, v8, a0
1566+
; RV64-NEXT: vmv8r.v v8, v16
1567+
; RV64-NEXT: ret
1568+
%sb = sext i32 %b to i64
1569+
%head = insertelement <vscale x 8 x i64> poison, i64 %sb, i32 0
1570+
%splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> poison, <vscale x 8 x i32> zeroinitializer
1571+
%vc = sext <vscale x 8 x i32> %va to <vscale x 8 x i64>
1572+
%ve = add <vscale x 8 x i64> %vc, %splat
1573+
ret <vscale x 8 x i64> %ve
1574+
}
1575+
1576+
define <vscale x 8 x i32> @vwadd_vx_splat_sext_i1(<vscale x 8 x i1> %va, i16 %b) {
1577+
; RV32-LABEL: vwadd_vx_splat_sext_i1:
1578+
; RV32: # %bb.0:
1579+
; RV32-NEXT: slli a0, a0, 16
1580+
; RV32-NEXT: srai a0, a0, 16
1581+
; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, mu
1582+
; RV32-NEXT: vmv.v.x v8, a0
1583+
; RV32-NEXT: li a0, 1
1584+
; RV32-NEXT: vsub.vx v8, v8, a0, v0.t
1585+
; RV32-NEXT: ret
1586+
;
1587+
; RV64-LABEL: vwadd_vx_splat_sext_i1:
1588+
; RV64: # %bb.0:
1589+
; RV64-NEXT: slli a0, a0, 48
1590+
; RV64-NEXT: srai a0, a0, 48
1591+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1592+
; RV64-NEXT: vmv.v.i v8, 0
1593+
; RV64-NEXT: vmerge.vim v8, v8, 1, v0
1594+
; RV64-NEXT: vrsub.vx v8, v8, a0
1595+
; RV64-NEXT: ret
1596+
%sb = sext i16 %b to i32
1597+
%head = insertelement <vscale x 8 x i32> poison, i32 %sb, i32 0
1598+
%splat = shufflevector <vscale x 8 x i32> %head, <vscale x 8 x i32> poison, <vscale x 8 x i32> zeroinitializer
1599+
%vc = sext <vscale x 8 x i1> %va to <vscale x 8 x i32>
1600+
%ve = add <vscale x 8 x i32> %vc, %splat
1601+
ret <vscale x 8 x i32> %ve
1602+
}
1603+
1604+
define <vscale x 8 x i64> @vwadd_wx_splat_sext(<vscale x 8 x i64> %va, i32 %b) {
1605+
; RV32-LABEL: vwadd_wx_splat_sext:
1606+
; RV32: # %bb.0:
1607+
; RV32-NEXT: vsetvli a1, zero, e64, m8, ta, ma
1608+
; RV32-NEXT: vadd.vx v8, v8, a0
1609+
; RV32-NEXT: ret
1610+
;
1611+
; RV64-LABEL: vwadd_wx_splat_sext:
1612+
; RV64: # %bb.0:
1613+
; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
1614+
; RV64-NEXT: vwadd.wx v8, v8, a0
1615+
; RV64-NEXT: ret
1616+
%sb = sext i32 %b to i64
1617+
%head = insertelement <vscale x 8 x i64> poison, i64 %sb, i32 0
1618+
%splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> poison, <vscale x 8 x i32> zeroinitializer
1619+
%ve = add <vscale x 8 x i64> %va, %splat
1620+
ret <vscale x 8 x i64> %ve
1621+
}

0 commit comments

Comments
 (0)