Skip to content

Commit d7fb9c5

Browse files
author
git apple-llvm automerger
committed
Merge commit 'a6805a0e02c9' from llvm.org/master into apple/main
2 parents a1a8abb + a6805a0 commit d7fb9c5

File tree

14 files changed

+10724
-92
lines changed

14 files changed

+10724
-92
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,43 @@ let TargetPrefix = "riscv" in {
6666
defm int_riscv_masked_cmpxchg : MaskedAtomicRMWFiveArgIntrinsics;
6767

6868
} // TargetPrefix = "riscv"
69+
70+
//===----------------------------------------------------------------------===//
71+
// Vectors
72+
73+
class RISCVVIntrinsic {
74+
// These intrinsics may accept illegal integer values in their llvm_any_ty
75+
// operand, so they have to be extended. If set to zero then the intrinsic
76+
// does not have any operand that must be extended.
77+
Intrinsic IntrinsicID = !cast<Intrinsic>(NAME);
78+
bits<4> ExtendOperand = 0;
79+
}
80+
81+
let TargetPrefix = "riscv" in {
82+
// For destination vector type is the same as first source vector.
83+
// Input: (vector_in, vector_in/scalar_in, vl)
84+
class RISCVBinaryAAXNoMask
85+
: Intrinsic<[llvm_anyvector_ty],
86+
[LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
87+
[IntrNoMem]>, RISCVVIntrinsic {
88+
let ExtendOperand = 2;
89+
}
90+
// For destination vector type is the same as first source vector (with mask).
91+
// Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
92+
class RISCVBinaryAAXMask
93+
: Intrinsic<[llvm_anyvector_ty],
94+
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
95+
llvm_anyvector_ty, llvm_anyint_ty],
96+
[IntrNoMem]>, RISCVVIntrinsic {
97+
let ExtendOperand = 3;
98+
}
99+
100+
multiclass RISCVBinaryAAX {
101+
def "int_riscv_" # NAME : RISCVBinaryAAXNoMask;
102+
def "int_riscv_" # NAME # "_mask" : RISCVBinaryAAXMask;
103+
}
104+
105+
defm vadd : RISCVBinaryAAX;
106+
defm vsub : RISCVBinaryAAX;
107+
defm vrsub : RISCVBinaryAAX;
108+
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 118 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
331331

332332
setBooleanContents(ZeroOrOneBooleanContent);
333333

334-
if (Subtarget.hasStdExtV())
334+
if (Subtarget.hasStdExtV()) {
335335
setBooleanVectorContents(ZeroOrOneBooleanContent);
336+
// RVV intrinsics may have illegal operands.
337+
for (auto VT : {MVT::i8, MVT::i16, MVT::i32})
338+
setOperationAction(ISD::INTRINSIC_WO_CHAIN, VT, Custom);
339+
}
336340

337341
// Function alignments.
338342
const Align FunctionAlignment(Subtarget.hasStdExtC() ? 2 : 4);
@@ -1002,6 +1006,28 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
10021006
SelectionDAG &DAG) const {
10031007
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
10041008
SDLoc DL(Op);
1009+
1010+
if (Subtarget.hasStdExtV()) {
1011+
// Some RVV intrinsics may claim that they want an integer operand to be
1012+
// extended.
1013+
if (const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II =
1014+
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo)) {
1015+
if (II->ExtendedOperand) {
1016+
assert(II->ExtendedOperand < Op.getNumOperands());
1017+
SmallVector<SDValue, 8> Operands(Op->op_begin(), Op->op_end());
1018+
SDValue &ScalarOp = Operands[II->ExtendedOperand];
1019+
if (ScalarOp.getValueType() == MVT::i8 ||
1020+
ScalarOp.getValueType() == MVT::i16 ||
1021+
ScalarOp.getValueType() == MVT::i32) {
1022+
ScalarOp =
1023+
DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), ScalarOp);
1024+
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
1025+
Operands);
1026+
}
1027+
}
1028+
}
1029+
}
1030+
10051031
switch (IntNo) {
10061032
default:
10071033
return SDValue(); // Don't custom lower most intrinsics.
@@ -2038,6 +2064,16 @@ static const MCPhysReg ArgFPR64s[] = {
20382064
RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, RISCV::F13_D,
20392065
RISCV::F14_D, RISCV::F15_D, RISCV::F16_D, RISCV::F17_D
20402066
};
2067+
// This is an interim calling convention and it may be changed in the future.
2068+
static const MCPhysReg ArgVRs[] = {
2069+
RISCV::V16, RISCV::V17, RISCV::V18, RISCV::V19, RISCV::V20,
2070+
RISCV::V21, RISCV::V22, RISCV::V23
2071+
};
2072+
static const MCPhysReg ArgVRM2s[] = {
2073+
RISCV::V16M2, RISCV::V18M2, RISCV::V20M2, RISCV::V22M2
2074+
};
2075+
static const MCPhysReg ArgVRM4s[] = {RISCV::V16M4, RISCV::V20M4};
2076+
static const MCPhysReg ArgVRM8s[] = {RISCV::V16M8};
20412077

20422078
// Pass a 2*XLEN argument that has been split into two XLEN values through
20432079
// registers or the stack as necessary.
@@ -2082,7 +2118,8 @@ static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1,
20822118
static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
20832119
MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo,
20842120
ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed,
2085-
bool IsRet, Type *OrigTy) {
2121+
bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI,
2122+
Optional<unsigned> FirstMaskArgument) {
20862123
unsigned XLen = DL.getLargestLegalIntTypeSizeInBits();
20872124
assert(XLen == 32 || XLen == 64);
20882125
MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64;
@@ -2215,7 +2252,34 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
22152252
Reg = State.AllocateReg(ArgFPR32s);
22162253
else if (ValVT == MVT::f64 && !UseGPRForF64)
22172254
Reg = State.AllocateReg(ArgFPR64s);
2218-
else
2255+
else if (ValVT.isScalableVector()) {
2256+
const TargetRegisterClass *RC = TLI.getRegClassFor(ValVT);
2257+
if (RC == &RISCV::VRRegClass) {
2258+
// Assign the first mask argument to V0.
2259+
// This is an interim calling convention and it may be changed in the
2260+
// future.
2261+
if (FirstMaskArgument.hasValue() &&
2262+
ValNo == FirstMaskArgument.getValue()) {
2263+
Reg = State.AllocateReg(RISCV::V0);
2264+
} else {
2265+
Reg = State.AllocateReg(ArgVRs);
2266+
}
2267+
} else if (RC == &RISCV::VRM2RegClass) {
2268+
Reg = State.AllocateReg(ArgVRM2s);
2269+
} else if (RC == &RISCV::VRM4RegClass) {
2270+
Reg = State.AllocateReg(ArgVRM4s);
2271+
} else if (RC == &RISCV::VRM8RegClass) {
2272+
Reg = State.AllocateReg(ArgVRM8s);
2273+
} else {
2274+
llvm_unreachable("Unhandled class register for ValueType");
2275+
}
2276+
if (!Reg) {
2277+
LocInfo = CCValAssign::Indirect;
2278+
// Try using a GPR to pass the address
2279+
Reg = State.AllocateReg(ArgGPRs);
2280+
LocVT = XLenVT;
2281+
}
2282+
} else
22192283
Reg = State.AllocateReg(ArgGPRs);
22202284
unsigned StackOffset =
22212285
Reg ? 0 : State.AllocateStack(XLen / 8, Align(XLen / 8));
@@ -2238,8 +2302,9 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
22382302
return false;
22392303
}
22402304

2241-
assert((!UseGPRForF16_F32 || !UseGPRForF64 || LocVT == XLenVT) &&
2242-
"Expected an XLenVT at this stage");
2305+
assert((!UseGPRForF16_F32 || !UseGPRForF64 || LocVT == XLenVT ||
2306+
(TLI.getSubtarget().hasStdExtV() && ValVT.isScalableVector())) &&
2307+
"Expected an XLenVT or scalable vector types at this stage");
22432308

22442309
if (Reg) {
22452310
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
@@ -2256,12 +2321,32 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
22562321
return false;
22572322
}
22582323

2324+
template <typename ArgTy>
2325+
static void preAssignMask(const ArgTy &Args,
2326+
Optional<unsigned> &FirstMaskArgument,
2327+
CCState &CCInfo) {
2328+
unsigned NumArgs = Args.size();
2329+
for (unsigned I = 0; I != NumArgs; ++I) {
2330+
MVT ArgVT = Args[I].VT;
2331+
if (!ArgVT.isScalableVector() ||
2332+
ArgVT.getVectorElementType().SimpleTy != MVT::i1)
2333+
continue;
2334+
2335+
FirstMaskArgument = I;
2336+
break;
2337+
}
2338+
}
2339+
22592340
void RISCVTargetLowering::analyzeInputArgs(
22602341
MachineFunction &MF, CCState &CCInfo,
22612342
const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet) const {
22622343
unsigned NumArgs = Ins.size();
22632344
FunctionType *FType = MF.getFunction().getFunctionType();
22642345

2346+
Optional<unsigned> FirstMaskArgument;
2347+
if (Subtarget.hasStdExtV())
2348+
preAssignMask(Ins, FirstMaskArgument, CCInfo);
2349+
22652350
for (unsigned i = 0; i != NumArgs; ++i) {
22662351
MVT ArgVT = Ins[i].VT;
22672352
ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
@@ -2274,7 +2359,8 @@ void RISCVTargetLowering::analyzeInputArgs(
22742359

22752360
RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
22762361
if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
2277-
ArgFlags, CCInfo, /*IsFixed=*/true, IsRet, ArgTy)) {
2362+
ArgFlags, CCInfo, /*IsFixed=*/true, IsRet, ArgTy, *this,
2363+
FirstMaskArgument)) {
22782364
LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type "
22792365
<< EVT(ArgVT).getEVTString() << '\n');
22802366
llvm_unreachable(nullptr);
@@ -2288,14 +2374,19 @@ void RISCVTargetLowering::analyzeOutputArgs(
22882374
CallLoweringInfo *CLI) const {
22892375
unsigned NumArgs = Outs.size();
22902376

2377+
Optional<unsigned> FirstMaskArgument;
2378+
if (Subtarget.hasStdExtV())
2379+
preAssignMask(Outs, FirstMaskArgument, CCInfo);
2380+
22912381
for (unsigned i = 0; i != NumArgs; i++) {
22922382
MVT ArgVT = Outs[i].VT;
22932383
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
22942384
Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr;
22952385

22962386
RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
22972387
if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
2298-
ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
2388+
ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy, *this,
2389+
FirstMaskArgument)) {
22992390
LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type "
23002391
<< EVT(ArgVT).getEVTString() << "\n");
23012392
llvm_unreachable(nullptr);
@@ -2327,31 +2418,13 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
23272418
// The caller is responsible for loading the full value if the argument is
23282419
// passed with CCValAssign::Indirect.
23292420
static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
2330-
const CCValAssign &VA, const SDLoc &DL) {
2421+
const CCValAssign &VA, const SDLoc &DL,
2422+
const RISCVTargetLowering &TLI) {
23312423
MachineFunction &MF = DAG.getMachineFunction();
23322424
MachineRegisterInfo &RegInfo = MF.getRegInfo();
23332425
EVT LocVT = VA.getLocVT();
23342426
SDValue Val;
2335-
const TargetRegisterClass *RC;
2336-
2337-
switch (LocVT.getSimpleVT().SimpleTy) {
2338-
default:
2339-
llvm_unreachable("Unexpected register type");
2340-
case MVT::i32:
2341-
case MVT::i64:
2342-
RC = &RISCV::GPRRegClass;
2343-
break;
2344-
case MVT::f16:
2345-
RC = &RISCV::FPR16RegClass;
2346-
break;
2347-
case MVT::f32:
2348-
RC = &RISCV::FPR32RegClass;
2349-
break;
2350-
case MVT::f64:
2351-
RC = &RISCV::FPR64RegClass;
2352-
break;
2353-
}
2354-
2427+
const TargetRegisterClass *RC = TLI.getRegClassFor(LocVT.getSimpleVT());
23552428
Register VReg = RegInfo.createVirtualRegister(RC);
23562429
RegInfo.addLiveIn(VA.getLocReg(), VReg);
23572430
Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
@@ -2623,7 +2696,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
26232696
if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64)
26242697
ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, DL);
26252698
else if (VA.isRegLoc())
2626-
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL);
2699+
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this);
26272700
else
26282701
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
26292702

@@ -3071,12 +3144,18 @@ bool RISCVTargetLowering::CanLowerReturn(
30713144
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
30723145
SmallVector<CCValAssign, 16> RVLocs;
30733146
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3147+
3148+
Optional<unsigned> FirstMaskArgument;
3149+
if (Subtarget.hasStdExtV())
3150+
preAssignMask(Outs, FirstMaskArgument, CCInfo);
3151+
30743152
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
30753153
MVT VT = Outs[i].VT;
30763154
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
30773155
RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
30783156
if (CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full,
3079-
ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr))
3157+
ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr,
3158+
*this, FirstMaskArgument))
30803159
return false;
30813160
}
30823161
return true;
@@ -3673,3 +3752,12 @@ RISCVTargetLowering::getRegisterByName(const char *RegName, LLT VT,
36733752
StringRef(RegName) + "\"."));
36743753
return Reg;
36753754
}
3755+
3756+
namespace llvm {
3757+
namespace RISCVVIntrinsicsTable {
3758+
3759+
#define GET_RISCVVIntrinsicsTable_IMPL
3760+
#include "RISCVGenSearchableTables.inc"
3761+
3762+
} // namespace RISCVVIntrinsicsTable
3763+
} // namespace llvm

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class RISCVTargetLowering : public TargetLowering {
8787
explicit RISCVTargetLowering(const TargetMachine &TM,
8888
const RISCVSubtarget &STI);
8989

90+
const RISCVSubtarget &getSubtarget() const { return Subtarget; }
91+
9092
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
9193
MachineFunction &MF,
9294
unsigned Intrinsic) const override;
@@ -269,6 +271,20 @@ class RISCVTargetLowering : public TargetLowering {
269271
const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
270272
MachineFunction &MF) const;
271273
};
274+
275+
namespace RISCVVIntrinsicsTable {
276+
277+
struct RISCVVIntrinsicInfo {
278+
unsigned int IntrinsicID;
279+
unsigned int ExtendedOperand;
280+
};
281+
282+
using namespace RISCV;
283+
284+
#define GET_RISCVVIntrinsicsTable_DECL
285+
#include "RISCVGenSearchableTables.inc"
286+
287+
} // end namespace RISCVVIntrinsicsTable
272288
}
273289

274290
#endif

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,37 @@ void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
9898
return;
9999
}
100100

101-
// FPR->FPR copies
101+
// FPR->FPR copies and VR->VR copies.
102102
unsigned Opc;
103+
bool IsScalableVector = false;
103104
if (RISCV::FPR16RegClass.contains(DstReg, SrcReg))
104105
Opc = RISCV::FSGNJ_H;
105106
else if (RISCV::FPR32RegClass.contains(DstReg, SrcReg))
106107
Opc = RISCV::FSGNJ_S;
107108
else if (RISCV::FPR64RegClass.contains(DstReg, SrcReg))
108109
Opc = RISCV::FSGNJ_D;
109-
else
110+
else if (RISCV::VRRegClass.contains(DstReg, SrcReg)) {
111+
Opc = RISCV::PseudoVMV1R_V;
112+
IsScalableVector = true;
113+
} else if (RISCV::VRM2RegClass.contains(DstReg, SrcReg)) {
114+
Opc = RISCV::PseudoVMV2R_V;
115+
IsScalableVector = true;
116+
} else if (RISCV::VRM4RegClass.contains(DstReg, SrcReg)) {
117+
Opc = RISCV::PseudoVMV4R_V;
118+
IsScalableVector = true;
119+
} else if (RISCV::VRM8RegClass.contains(DstReg, SrcReg)) {
120+
Opc = RISCV::PseudoVMV8R_V;
121+
IsScalableVector = true;
122+
} else
110123
llvm_unreachable("Impossible reg-to-reg copy");
111124

112-
BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
113-
.addReg(SrcReg, getKillRegState(KillSrc))
114-
.addReg(SrcReg, getKillRegState(KillSrc));
125+
if (IsScalableVector)
126+
BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
127+
.addReg(SrcReg, getKillRegState(KillSrc));
128+
else
129+
BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
130+
.addReg(SrcReg, getKillRegState(KillSrc))
131+
.addReg(SrcReg, getKillRegState(KillSrc));
115132
}
116133

117134
void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,

0 commit comments

Comments
 (0)