Skip to content

Commit ee2cb90

Browse files
monkchiangHsiangkai
authored andcommitted
[RISCV] Define vsadd/vsaddu/vssub/vssubu intrinsics.
We work with @rogfer01 from BSC to come out this patch. Authored-by: Roger Ferrer Ibanez <[email protected]> Co-Authored-by: ShihPo Hung <[email protected]> Co-Authored-by: Monk Chiang <[email protected]> Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D93366
1 parent 385e9a2 commit ee2cb90

14 files changed

+15136
-1
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,26 @@ let TargetPrefix = "riscv" in {
209209
let ExtendOperand = 2;
210210
}
211211

212+
// For Saturating binary operations.
213+
// The destination vector type is the same as first source vector.
214+
// Input: (vector_in, vector_in/scalar_in, vl)
215+
class RISCVSaturatingBinaryAAXNoMask
216+
: Intrinsic<[llvm_anyvector_ty],
217+
[LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
218+
[IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
219+
let ExtendOperand = 2;
220+
}
221+
// For Saturating binary operations with mask.
222+
// The destination vector type is the same as first source vector.
223+
// Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
224+
class RISCVSaturatingBinaryAAXMask
225+
: Intrinsic<[llvm_anyvector_ty],
226+
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
227+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
228+
[IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
229+
let ExtendOperand = 3;
230+
}
231+
212232
multiclass RISCVUSLoad {
213233
def "int_riscv_" # NAME : RISCVUSLoad;
214234
def "int_riscv_" # NAME # "_mask" : RISCVUSLoadMask;
@@ -243,6 +263,10 @@ let TargetPrefix = "riscv" in {
243263
multiclass RISCVBinaryMaskOut {
244264
def "int_riscv_" # NAME : RISCVBinaryMOut;
245265
}
266+
multiclass RISCVSaturatingBinaryAAX {
267+
def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXNoMask;
268+
def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMask;
269+
}
246270

247271
defm vle : RISCVUSLoad;
248272
defm vse : RISCVUSStore;
@@ -299,4 +323,9 @@ let TargetPrefix = "riscv" in {
299323
defm vfadd : RISCVBinaryAAX;
300324
defm vfsub : RISCVBinaryAAX;
301325
defm vfrsub : RISCVBinaryAAX;
326+
327+
defm vsaddu : RISCVSaturatingBinaryAAX;
328+
defm vsadd : RISCVSaturatingBinaryAAX;
329+
defm vssubu : RISCVSaturatingBinaryAAX;
330+
defm vssub : RISCVSaturatingBinaryAAX;
302331
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,13 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
350350
// RVV intrinsics may have illegal operands.
351351
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i8, Custom);
352352
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i16, Custom);
353-
if (Subtarget.is64Bit())
353+
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i8, Custom);
354+
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i16, Custom);
355+
356+
if (Subtarget.is64Bit()) {
354357
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i32, Custom);
358+
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i32, Custom);
359+
}
355360
}
356361

357362
// Function alignments.
@@ -599,6 +604,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
599604
}
600605
case ISD::INTRINSIC_WO_CHAIN:
601606
return LowerINTRINSIC_WO_CHAIN(Op, DAG);
607+
case ISD::INTRINSIC_W_CHAIN:
608+
return LowerINTRINSIC_W_CHAIN(Op, DAG);
602609
case ISD::BSWAP:
603610
case ISD::BITREVERSE: {
604611
// Convert BSWAP/BITREVERSE to GREVI to enable GREVI combinining.
@@ -1054,6 +1061,36 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
10541061
}
10551062
}
10561063

1064+
SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
1065+
SelectionDAG &DAG) const {
1066+
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1067+
SDLoc DL(Op);
1068+
1069+
if (Subtarget.hasStdExtV()) {
1070+
// Some RVV intrinsics may claim that they want an integer operand to be
1071+
// extended.
1072+
if (const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II =
1073+
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo)) {
1074+
if (II->ExtendedOperand) {
1075+
// The operands start from the second argument in INTRINSIC_W_CHAIN.
1076+
unsigned ExtendOp = II->ExtendedOperand + 1;
1077+
assert(ExtendOp < Op.getNumOperands());
1078+
SmallVector<SDValue, 8> Operands(Op->op_begin(), Op->op_end());
1079+
SDValue &ScalarOp = Operands[ExtendOp];
1080+
if (ScalarOp.getValueType() == MVT::i32 ||
1081+
ScalarOp.getValueType() == MVT::i16 ||
1082+
ScalarOp.getValueType() == MVT::i8) {
1083+
ScalarOp =
1084+
DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), ScalarOp);
1085+
return DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, Op->getVTList(), Operands);
1086+
}
1087+
}
1088+
}
1089+
}
1090+
1091+
return SDValue();
1092+
}
1093+
10571094
// Returns the opcode of the target-specific SDNode that implements the 32-bit
10581095
// form of the given Opcode.
10591096
static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ class RISCVTargetLowering : public TargetLowering {
260260
SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
261261
SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
262262
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
263+
SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
263264

264265
bool isEligibleForTailCallOptimization(
265266
CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,

llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,16 @@ defm PseudoVWMUL : VPseudoBinaryW_VV_VX;
12951295
defm PseudoVWMULU : VPseudoBinaryW_VV_VX;
12961296
defm PseudoVWMULSU : VPseudoBinaryW_VV_VX;
12971297

1298+
//===----------------------------------------------------------------------===//
1299+
// 13.1. Vector Single-Width Saturating Add and Subtract
1300+
//===----------------------------------------------------------------------===//
1301+
let Defs = [VXSAT], hasSideEffects = 1 in {
1302+
defm PseudoVSADDU : VPseudoBinaryV_VV_VX_VI;
1303+
defm PseudoVSADD : VPseudoBinaryV_VV_VX_VI;
1304+
defm PseudoVSSUBU : VPseudoBinaryV_VV_VX;
1305+
defm PseudoVSSUB : VPseudoBinaryV_VV_VX;
1306+
}
1307+
12981308
} // Predicates = [HasStdExtV]
12991309

13001310
let Predicates = [HasStdExtV, HasStdExtF] in {
@@ -1434,6 +1444,14 @@ defm "" : VPatBinaryW_VV_VX<"int_riscv_vwmul", "PseudoVWMUL">;
14341444
defm "" : VPatBinaryW_VV_VX<"int_riscv_vwmulu", "PseudoVWMULU">;
14351445
defm "" : VPatBinaryW_VV_VX<"int_riscv_vwmulsu", "PseudoVWMULSU">;
14361446

1447+
//===----------------------------------------------------------------------===//
1448+
// 13.1. Vector Single-Width Saturating Add and Subtract
1449+
//===----------------------------------------------------------------------===//
1450+
defm "" : VPatBinaryV_VV_VX_VI<"int_riscv_vsaddu", "PseudoVSADDU", AllIntegerVectors>;
1451+
defm "" : VPatBinaryV_VV_VX_VI<"int_riscv_vsadd", "PseudoVSADD", AllIntegerVectors>;
1452+
defm "" : VPatBinaryV_VV_VX<"int_riscv_vssubu", "PseudoVSSUBU", AllIntegerVectors>;
1453+
defm "" : VPatBinaryV_VV_VX<"int_riscv_vssub", "PseudoVSSUB", AllIntegerVectors>;
1454+
14371455
} // Predicates = [HasStdExtV]
14381456

14391457
let Predicates = [HasStdExtV, HasStdExtF] in {

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
9898
// V registers for code generation. We handle them manually.
9999
markSuperRegs(Reserved, RISCV::VL);
100100
markSuperRegs(Reserved, RISCV::VTYPE);
101+
markSuperRegs(Reserved, RISCV::VXSAT);
101102

102103
assert(checkAllSuperRegsMarked(Reserved));
103104
return Reserved;

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ let RegAltNameIndices = [ABIRegAltName] in {
379379

380380
def VTYPE : RISCVReg<0, "vtype", ["vtype"]>;
381381
def VL : RISCVReg<0, "vl", ["vl"]>;
382+
def VXSAT : RISCVReg<0, "vxsat", ["vxsat"]>;
382383
}
383384

384385
class RegisterTypes<list<ValueType> reg_types> {

0 commit comments

Comments
 (0)