[Clang][RISCV] Implement vlsseg.

Differential Revision: https://reviews.llvm.org/D103796
This commit is contained in:
Hsiangkai Wang 2021-06-07 17:54:00 +08:00
parent 9dcd75f86f
commit a9de8f7a53
3 changed files with 11007 additions and 0 deletions

View File

@ -931,6 +931,77 @@ multiclass RVVUnitStridedSegLoadFF<string op> {
}
}
multiclass RVVStridedSegLoad<string op> {
foreach type = TypeList in {
defvar eew = !cond(!eq(type, "c") : "8",
!eq(type, "s") : "16",
!eq(type, "i") : "32",
!eq(type, "l") : "64",
!eq(type, "x") : "16",
!eq(type, "f") : "32",
!eq(type, "d") : "64");
foreach nf = NFList in {
let Name = op # nf # "e" # eew # "_v",
IRName = op # nf,
IRNameMask = op # nf # "_mask",
NF = nf,
HasNoMaskedOverloaded = false,
ManualCodegen = [{
{
// builtin: (val0 address, val1 address, ..., ptr, stride, vl)
IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
Ops[NF + 2]->getType()};
// intrinsic: (ptr, stride, vl)
llvm::Value *Operands[] = {Ops[NF], Ops[NF + 1], Ops[NF + 2]};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
clang::CharUnits Align = CharUnits::fromQuantity(
IntrinsicTypes[0]->getScalarSizeInBits() / 8);
llvm::Value *V;
for (unsigned I = 0; I < NF; ++I) {
V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
Address(Ops[I], Align));
}
return V;
}
}],
ManualCodegenMask = [{
{
// builtin: (val0 address, ..., mask, maskedoff0, ..., ptr, stride, vl)
// intrinsic: (maskedoff0, ..., ptr, stride, mask, vl)
IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
Ops[2 * NF + 3]->getType()};
SmallVector<llvm::Value*, 12> Operands;
for (unsigned I = 0; I < NF; ++I)
Operands.push_back(Ops[NF + I + 1]);
Operands.push_back(Ops[2 * NF + 1]);
Operands.push_back(Ops[2 * NF + 2]);
Operands.push_back(Ops[NF]);
Operands.push_back(Ops[2 * NF + 3]);
assert(Operands.size() == NF + 4);
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
clang::CharUnits Align = CharUnits::fromQuantity(
IntrinsicTypes[0]->getScalarSizeInBits() / 8);
llvm::Value *V;
for (unsigned I = 0; I < NF; ++I) {
V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
Address(Ops[I], Align));
}
return V;
}
}] in {
defvar PV = PVString<nf, /*signed=*/true>.S;
defvar PUV = PVString<nf, /*signed=*/false>.S;
def : RVVBuiltin<"v", "0" # PV # "PCe" # "t", type>;
if !not(IsFloat<type>.val) then {
def : RVVBuiltin<"Uv", "0" # PUV # "PCUe" # "t", type>;
}
}
}
}
}
multiclass RVVAMOBuiltinSet<bit has_signed = false, bit has_unsigned = false,
bit has_fp = false> {
defvar type_list = !if(has_fp, ["i","l","f","d"], ["i","l"]);
@ -1250,6 +1321,7 @@ defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>;
let RequiredExtension = "Zvlsseg" in {
defm : RVVUnitStridedSegLoad<"vlseg">;
defm : RVVUnitStridedSegLoadFF<"vlseg">;
defm : RVVStridedSegLoad<"vlsseg">;
}
// 8. Vector AMO Operations

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff