Skip to content

Commit

Permalink
[RISCV] Add the passthru operand for RVV nomask load intrinsics.
Browse files Browse the repository at this point in the history
The goal is support tail and mask policy in RVV builtins.
We focus on IR part first.
If the passthru operand is undef, we use tail agnostic, otherwise
use tail undisturbed.

Co-Authored-by: Hsiangkai Wang <Hsiangkai@gmail.com>

Reviewers: craig.topper, frasercrmck

Differential Revision: https://reviews.llvm.org/D117647
  • Loading branch information
zakk0610 committed Jan 26, 2022
1 parent 69da422 commit 9273378
Show file tree
Hide file tree
Showing 31 changed files with 2,709 additions and 1,063 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/riscv_vector.td
Expand Up @@ -595,6 +595,7 @@ let HasNoMaskedOverloaded = false,
ManualCodegen = [{
IntrinsicTypes = {ResultType, Ops[1]->getType()};
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
}],
ManualCodegenMask= [{
// Move mask to right before vl.
Expand Down Expand Up @@ -628,6 +629,7 @@ multiclass RVVVLEFFBuiltin<list<string> types> {
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
Value *NewVL = Ops[1];
Ops.erase(Ops.begin() + 1);
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
Expand Down Expand Up @@ -677,6 +679,7 @@ multiclass RVVVLSEBuiltin<list<string> types> {
ManualCodegen = [{
IntrinsicTypes = {ResultType, Ops[2]->getType()};
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
}],
ManualCodegenMask= [{
// Move mask to right before vl.
Expand All @@ -698,6 +701,7 @@ multiclass RVVIndexedLoad<string op> {
let ManualCodegen = [{
IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
}],
ManualCodegenMask = [{
// Move mask to right before vl.
Expand Down
382 changes: 191 additions & 191 deletions clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vloxei.c

Large diffs are not rendered by default.

382 changes: 191 additions & 191 deletions clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vluxei.c

Large diffs are not rendered by default.

118 changes: 59 additions & 59 deletions clang/test/CodeGen/RISCV/rvv-intrinsics/vle.c

Large diffs are not rendered by default.

118 changes: 59 additions & 59 deletions clang/test/CodeGen/RISCV/rvv-intrinsics/vleff.c

Large diffs are not rendered by default.

424 changes: 212 additions & 212 deletions clang/test/CodeGen/RISCV/rvv-intrinsics/vloxei.c

Large diffs are not rendered by default.

118 changes: 59 additions & 59 deletions clang/test/CodeGen/RISCV/rvv-intrinsics/vlse.c

Large diffs are not rendered by default.

424 changes: 212 additions & 212 deletions clang/test/CodeGen/RISCV/rvv-intrinsics/vluxei.c

Large diffs are not rendered by default.

47 changes: 30 additions & 17 deletions llvm/include/llvm/IR/IntrinsicsRISCV.td
Expand Up @@ -175,26 +175,37 @@ let TargetPrefix = "riscv" in {
ImmArg<ArgIndex<0>>,
ImmArg<ArgIndex<1>>]>;

// For unit stride load
// For unit stride mask load
// Input: (pointer, vl)
class RISCVUSLoad
class RISCVUSMLoad
: Intrinsic<[llvm_anyvector_ty],
[LLVMPointerType<LLVMMatchType<0>>,
llvm_anyint_ty],
[NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 1;
}
// For unit stride load
// Input: (passthru, pointer, vl)
class RISCVUSLoad
: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMPointerType<LLVMMatchType<0>>,
llvm_anyint_ty],
[NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 2;
}
// For unit stride fault-only-first load
// Input: (pointer, vl)
// Input: (passthru, pointer, vl)
// Output: (data, vl)
// NOTE: We model this with default memory properties since we model writing
// VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
class RISCVUSLoadFF
: Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
[LLVMPointerType<LLVMMatchType<0>>, LLVMMatchType<1>],
[NoCapture<ArgIndex<0>>]>,
[LLVMMatchType<0>,
LLVMPointerType<LLVMMatchType<0>>, LLVMMatchType<1>],
[NoCapture<ArgIndex<1>>]>,
RISCVVIntrinsic {
let VLOperand = 1;
let VLOperand = 2;
}
// For unit stride load with mask
// Input: (maskedoff, pointer, mask, vl, ta)
Expand Down Expand Up @@ -222,14 +233,15 @@ let TargetPrefix = "riscv" in {
[NoCapture<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>, RISCVVIntrinsic {
let VLOperand = 3;
}
// For strided load
// Input: (pointer, stride, vl)
// For strided load with passthru operand
// Input: (passthru, pointer, stride, vl)
class RISCVSLoad
: Intrinsic<[llvm_anyvector_ty],
[LLVMPointerType<LLVMMatchType<0>>,
[LLVMMatchType<0>,
LLVMPointerType<LLVMMatchType<0>>,
llvm_anyint_ty, LLVMMatchType<1>],
[NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 2;
[NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 3;
}
// For strided load with mask
// Input: (maskedoff, pointer, stride, mask, vl, ta)
Expand All @@ -243,14 +255,15 @@ let TargetPrefix = "riscv" in {
RISCVVIntrinsic {
let VLOperand = 4;
}
// For indexed load
// Input: (pointer, index, vl)
// For indexed load with passthru operand
// Input: (passthru, pointer, index, vl)
class RISCVILoad
: Intrinsic<[llvm_anyvector_ty],
[LLVMPointerType<LLVMMatchType<0>>,
[LLVMMatchType<0>,
LLVMPointerType<LLVMMatchType<0>>,
llvm_anyvector_ty, llvm_anyint_ty],
[NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 2;
[NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic {
let VLOperand = 3;
}
// For indexed load with mask
// Input: (maskedoff, pointer, index, mask, vl, ta)
Expand Down Expand Up @@ -1124,7 +1137,7 @@ let TargetPrefix = "riscv" in {
defm vsoxei : RISCVIStore;
defm vsuxei : RISCVIStore;

def int_riscv_vlm : RISCVUSLoad;
def int_riscv_vlm : RISCVUSMLoad;
def int_riscv_vsm : RISCVUSStore;

defm vadd : RISCVBinaryAAX;
Expand Down
49 changes: 36 additions & 13 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Expand Up @@ -86,8 +86,12 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
SDVTList VTs = CurDAG->getVTList({VT, MVT::Other});
SDValue IntID =
CurDAG->getTargetConstant(Intrinsic::riscv_vlse, DL, MVT::i64);
SDValue Ops[] = {Chain, IntID, StackSlot,
CurDAG->getRegister(RISCV::X0, MVT::i64), VL};
SDValue Ops[] = {Chain,
IntID,
CurDAG->getUNDEF(VT),
StackSlot,
CurDAG->getRegister(RISCV::X0, MVT::i64),
VL};

SDValue Result = CurDAG->getMemIntrinsicNode(
ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops, MVT::i64, MPI, Align(8),
Expand Down Expand Up @@ -1210,9 +1214,14 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());

unsigned CurOp = 2;
// Masked intrinsic only have TU version pseduo instructions.
bool IsTU = IsMasked || (!IsMasked && !Node->getOperand(CurOp).isUndef());
SmallVector<SDValue, 8> Operands;
if (IsMasked)
if (IsTU)
Operands.push_back(Node->getOperand(CurOp++));
else
// Skip the undef passthru operand for nomask TA version pseudo
CurOp++;

MVT IndexVT;
addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
Expand All @@ -1230,7 +1239,7 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
"values when XLEN=32");
}
const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
IsMasked, IsTU, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
static_cast<unsigned>(IndexLMUL));
MachineSDNode *Load =
CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
Expand All @@ -1255,16 +1264,25 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());

unsigned CurOp = 2;
// The riscv_vlm intrinsic are always tail agnostic and no passthru operand.
bool HasPassthruOperand = IntNo != Intrinsic::riscv_vlm;
// Masked intrinsic only have TU version pseduo instructions.
bool IsTU =
HasPassthruOperand &&
((!IsMasked && !Node->getOperand(CurOp).isUndef()) || IsMasked);
SmallVector<SDValue, 8> Operands;
if (IsMasked)
if (IsTU)
Operands.push_back(Node->getOperand(CurOp++));
else if (HasPassthruOperand)
// Skip the undef passthru operand for nomask TA version pseudo
CurOp++;

addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
Operands, /*IsLoad=*/true);

RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
const RISCV::VLEPseudo *P =
RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
RISCV::getVLEPseudo(IsMasked, IsTU, IsStrided, /*FF*/ false, Log2SEW,
static_cast<unsigned>(LMUL));
MachineSDNode *Load =
CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
Expand All @@ -1283,18 +1301,23 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());

unsigned CurOp = 2;
// Masked intrinsic only have TU version pseduo instructions.
bool IsTU = IsMasked || (!IsMasked && !Node->getOperand(CurOp).isUndef());
SmallVector<SDValue, 7> Operands;
if (IsMasked)
if (IsTU)
Operands.push_back(Node->getOperand(CurOp++));
else
// Skip the undef passthru operand for nomask TA version pseudo
CurOp++;

addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
/*IsStridedOrIndexed*/ false, Operands,
/*IsLoad=*/true);

RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
const RISCV::VLEPseudo *P =
RISCV::getVLEPseudo(IsMasked, /*Strided*/ false, /*FF*/ true, Log2SEW,
static_cast<unsigned>(LMUL));
RISCV::getVLEPseudo(IsMasked, IsTU, /*Strided*/ false, /*FF*/ true,
Log2SEW, static_cast<unsigned>(LMUL));
MachineSDNode *Load =
CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0),
MVT::Other, MVT::Glue, Operands);
Expand Down Expand Up @@ -1424,8 +1447,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
"values when XLEN=32");
}
const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
static_cast<unsigned>(IndexLMUL));
IsMasked, /*TU*/ false, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL), static_cast<unsigned>(IndexLMUL));
MachineSDNode *Store =
CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);

Expand Down Expand Up @@ -1622,8 +1645,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {

RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
const RISCV::VLEPseudo *P = RISCV::getVLEPseudo(
/*IsMasked*/ false, /*IsStrided*/ true, /*FF*/ false, Log2SEW,
static_cast<unsigned>(LMUL));
/*IsMasked*/ false, /*IsTU*/ false, /*IsStrided*/ true, /*FF*/ false,
Log2SEW, static_cast<unsigned>(LMUL));
MachineSDNode *Load =
CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
Expand Up @@ -161,6 +161,7 @@ struct VSXSEGPseudo {

struct VLEPseudo {
uint16_t Masked : 1;
uint16_t IsTU : 1;
uint16_t Strided : 1;
uint16_t FF : 1;
uint16_t Log2SEW : 3;
Expand All @@ -178,6 +179,7 @@ struct VSEPseudo {

struct VLX_VSXPseudo {
uint16_t Masked : 1;
uint16_t IsTU : 1;
uint16_t Ordered : 1;
uint16_t Log2SEW : 3;
uint16_t LMUL : 3;
Expand Down
20 changes: 15 additions & 5 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -2452,8 +2452,12 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
SDVTList VTs = DAG.getVTList({ContainerVT, MVT::Other});
SDValue IntID =
DAG.getTargetConstant(Intrinsic::riscv_vlse, DL, XLenVT);
SDValue Ops[] = {Ld->getChain(), IntID, NewAddr,
DAG.getRegister(RISCV::X0, XLenVT), VL};
SDValue Ops[] = {Ld->getChain(),
IntID,
DAG.getUNDEF(ContainerVT),
NewAddr,
DAG.getRegister(RISCV::X0, XLenVT),
VL};
SDValue NewLoad = DAG.getMemIntrinsicNode(
ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops, SVT,
DAG.getMachineFunction().getMachineMemOperand(
Expand Down Expand Up @@ -4574,7 +4578,9 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,

auto *Load = cast<MemIntrinsicSDNode>(Op);
SmallVector<SDValue, 8> Ops{Load->getChain(), IntID};
if (!IsUnmasked)
if (IsUnmasked)
Ops.push_back(DAG.getUNDEF(ContainerVT));
else
Ops.push_back(PassThru);
Ops.push_back(Op.getOperand(3)); // Ptr
Ops.push_back(Op.getOperand(4)); // Stride
Expand Down Expand Up @@ -5432,7 +5438,9 @@ SDValue RISCVTargetLowering::lowerMaskedLoad(SDValue Op,
unsigned IntID =
IsUnmasked ? Intrinsic::riscv_vle : Intrinsic::riscv_vle_mask;
SmallVector<SDValue, 8> Ops{Chain, DAG.getTargetConstant(IntID, DL, XLenVT)};
if (!IsUnmasked)
if (IsUnmasked)
Ops.push_back(DAG.getUNDEF(ContainerVT));
else
Ops.push_back(PassThru);
Ops.push_back(BasePtr);
if (!IsUnmasked)
Expand Down Expand Up @@ -5813,7 +5821,9 @@ SDValue RISCVTargetLowering::lowerMaskedGather(SDValue Op,
unsigned IntID =
IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
SmallVector<SDValue, 8> Ops{Chain, DAG.getTargetConstant(IntID, DL, XLenVT)};
if (!IsUnmasked)
if (IsUnmasked)
Ops.push_back(DAG.getUNDEF(ContainerVT));
else
Ops.push_back(PassThru);
Ops.push_back(BasePtr);
Ops.push_back(Index);
Expand Down

0 comments on commit 9273378

Please sign in to comment.