Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] correct code for upstreaming #217

Merged
merged 4 commits into from
Aug 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class SPIRVAsmBackend : public MCAsmBackend {
return createSPIRVObjectTargetWriter();
}

// No instruction requires relaxation
// No instruction requires relaxation.
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const override {
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ FunctionPass *createSPIRVBasicBlockDominancePass();
ModulePass *createSPIRVLowerConstExprLegacyPass();
FunctionPass *createSPIRVPreLegalizerPass();
FunctionPass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);

InstructionSelector *
createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
const SPIRVSubtarget &Subtarget,
Expand Down
236 changes: 118 additions & 118 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Large diffs are not rendered by default.

26 changes: 15 additions & 11 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,30 @@
#define LLVM_LIB_TARGET_SPIRV_SPIRVBUILTINS_H

#include "SPIRVGlobalRegistry.h"
#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"

namespace llvm {
namespace SPIRV {
/// Lowers a builtin funtion call using the provided \p DemangledCall skeleton
/// and external instruction \p Set.
///
/// \return A pair of boolean values, the first true means the call recognized
/// as a builtin, the second one indicates the successful lowering.
/// \return A boolean value indicating the successful lowering, if the callee
/// is recognized as a builtin function.
///
/// \p DemangledCall is the skeleton of the lowered builtin function call.
/// \p Set is the external instruction set containing the given builtin.
/// \p OrigRet is the single original virtual return register if defined,
/// Register(0) otherwise.
/// \p OrigRetTy is the type of the \p OrigRet.
/// Register(0) otherwise.
/// \p OrigRetTy is the type of the \p OrigRet.
/// \p Args are the arguments of the lowered builtin call.
std::pair<bool, bool> lowerBuiltin(
const StringRef DemangledCall, SPIRV::InstructionSet::InstructionSet Set,
MachineIRBuilder &MIRBuilder, const Register OrigRet, const Type *OrigRetTy,
const SmallVectorImpl<Register> &Args, SPIRVGlobalRegistry *GR);

Optional<bool> lowerBuiltin(const StringRef DemangledCall,
InstructionSet::InstructionSet Set,
MachineIRBuilder &MIRBuilder,
const Register OrigRet, const Type *OrigRetTy,
const SmallVectorImpl<Register> &Args,
SPIRVGlobalRegistry *GR);
/// Handles the translation of the provided special opaque/builtin type \p Type
/// to SPIR-V type. Generates the corresponding machine instructions for the
/// target type or gets the already existing OpType<...> register from the
Expand All @@ -44,8 +47,9 @@ std::pair<bool, bool> lowerBuiltin(
///
/// \p Type is the special opaque/builtin type to be lowered.
SPIRVType *lowerBuiltinType(const StructType *Type,
AQ::AccessQualifier AccessQual,
AccessQualifier::AccessQualifier AccessQual,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR);
} // end namespace llvm
} // namespace SPIRV
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVBUILTINS_H
31 changes: 15 additions & 16 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
// TableGen records defining implementation details of demangled builtin
// TableGen records defining implementation details of demangled builtin
// functions and types.
//
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -577,22 +577,22 @@ class GroupBuiltin<string name, Op operation> {
!not(!eq(!find(name, "group_clustered_reduce_logical"), -1)) : ClusteredReduce.Value,
true : 0);
bit IsElect = !eq(operation, OpGroupNonUniformElect);
bit IsAllOrAny = !or(!eq(operation, OpGroupAll),
!eq(operation, OpGroupAny),
!eq(operation, OpGroupNonUniformAll),
bit IsAllOrAny = !or(!eq(operation, OpGroupAll),
!eq(operation, OpGroupAny),
!eq(operation, OpGroupNonUniformAll),
!eq(operation, OpGroupNonUniformAny));
bit IsAllEqual = !eq(operation, OpGroupNonUniformAllEqual);
bit IsBallot = !eq(operation, OpGroupNonUniformBallot);
bit IsInverseBallot = !eq(operation, OpGroupNonUniformInverseBallot);
bit IsBallotBitExtract = !eq(operation, OpGroupNonUniformBallotBitExtract);
bit IsBallotFindBit = !or(!eq(operation, OpGroupNonUniformBallotFindLSB),
bit IsBallotFindBit = !or(!eq(operation, OpGroupNonUniformBallotFindLSB),
!eq(operation, OpGroupNonUniformBallotFindMSB));
bit IsLogical = !or(!eq(operation, OpGroupNonUniformLogicalAnd),
!eq(operation, OpGroupNonUniformLogicalOr),
bit IsLogical = !or(!eq(operation, OpGroupNonUniformLogicalAnd),
!eq(operation, OpGroupNonUniformLogicalOr),
!eq(operation, OpGroupNonUniformLogicalXor));
bit NoGroupOperation = !or(IsElect, IsAllOrAny, IsAllEqual,
IsBallot, IsInverseBallot,
IsBallotBitExtract, IsBallotFindBit,
bit NoGroupOperation = !or(IsElect, IsAllOrAny, IsAllEqual,
IsBallot, IsInverseBallot,
IsBallotBitExtract, IsBallotFindBit,
!eq(operation, OpGroupNonUniformShuffle),
!eq(operation, OpGroupNonUniformShuffleXor),
!eq(operation, OpGroupNonUniformShuffleUp),
Expand Down Expand Up @@ -864,7 +864,7 @@ defm : DemangledGroupBuiltin<"group_clustered_reduce_logical_xor", WorkOrSub, Op
//
// name is the demangled name of the given builtin.
// set specifies which external instruction set the builtin belongs to.
// value specifies the value of the BuiltIn enum.
// value specifies the value of the BuiltIn enum.
//===----------------------------------------------------------------------===//
class GetBuiltin<string name, InstructionSet set, BuiltIn value> {
string Name = name;
Expand Down Expand Up @@ -912,7 +912,7 @@ defm : DemangledGetBuiltin<"get_enqueued_local_size", OpenCL_std, GetQuery, Enqu
defm : DemangledGetBuiltin<"get_num_groups", OpenCL_std, GetQuery, NumWorkgroups>;

//===----------------------------------------------------------------------===//
// Class defining an image query builtin record used for lowering the OpenCL
// Class defining an image query builtin record used for lowering the OpenCL
// "get_image_*" calls into OpImageQuerySize/OpImageQuerySizeLod instructions.
//
// name is the demangled name of the given builtin.
Expand Down Expand Up @@ -998,7 +998,7 @@ multiclass DemangledConvertBuiltin<string name, InstructionSet set> {
def : DemangledBuiltin<!strconcat(name, i, j), set, Convert, 1, 1>;
def : ConvertBuiltin<!strconcat(name, i, j), set>;

// Create records with the "_sat" modifier for all conversions except
// Create records with the "_sat" modifier for all conversions except
// those targeting floating-point types.
if !eq(!find(name, "float"), -1) then {
def : DemangledBuiltin<!strconcat(name, i, "_sat", j), set, Convert, 1, 1>;
Expand Down Expand Up @@ -1080,8 +1080,8 @@ foreach i = ["", "2", "3", "4", "8", "16"] in {
defm : DemangledVectorLoadStoreBuiltin<!strconcat("vstore_half", j), 3, 3, 176>;
} else {
defm : DemangledVectorLoadStoreBuiltin<!strconcat("vstore_half", i, j), 3, 3, 178>;
}
defm : DemangledVectorLoadStoreBuiltin<!strconcat("vstorea_half", i, j), 3, 3, 181>;
}
defm : DemangledVectorLoadStoreBuiltin<!strconcat("vstorea_half", i, j), 3, 3, 181>;
}
}

Expand Down Expand Up @@ -1130,7 +1130,6 @@ def : DemangledType<"spirv.Image", OpTypeImage>;
def : DemangledType<"spirv.SampledImage", OpTypeSampledImage>;
def : DemangledType<"spirv.Pipe", OpTypePipe>;


// Class definining lowering details for various variants of image type indentifiers.
class ImageType<string name> {
string Name = name;
Expand Down
44 changes: 20 additions & 24 deletions llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,29 +380,26 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
Register ResVReg =
Info.OrigRet.Regs.empty() ? Register(0) : Info.OrigRet.Regs[0];
std::string FuncName = Info.Callee.getGlobal()->getGlobalIdentifier();
std::string DemangledName = isOclOrSpirvBuiltin(FuncName);
if (!DemangledName.empty() && CF && CF->isDeclaration()) {
// TODO: check that it's OCL builtin, then apply OpenCL_std.
const auto *ST = static_cast<const SPIRVSubtarget *>(&MF.getSubtarget());
if (ST->canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
// Mangled names are for OpenCL builtins, so pass off to OpenCLBIFs.cpp.
const Type *OrigRetTy = Info.OrigRet.Ty;
if (FTy)
OrigRetTy = FTy->getReturnType();
SmallVector<Register, 8> ArgVRegs;
for (auto Arg : Info.OrigArgs) {
assert(Arg.Regs.size() == 1 && "Call arg has multiple VRegs");
ArgVRegs.push_back(Arg.Regs[0]);
SPIRVType *SPIRVTy = GR->getOrCreateSPIRVType(Arg.Ty, MIRBuilder);
GR->assignSPIRVTypeToVReg(SPIRVTy, Arg.Regs[0], MIRBuilder.getMF());
}
auto Res = lowerBuiltin(DemangledName, SPIRV::InstructionSet::OpenCL_std,
MIRBuilder, ResVReg, OrigRetTy, ArgVRegs, GR);
if (Res.first)
return Res.second;
std::string DemangledName = getOclOrSpirvBuiltinDemangledName(FuncName);
const auto *ST = static_cast<const SPIRVSubtarget *>(&MF.getSubtarget());
// TODO: check that it's OCL builtin, then apply OpenCL_std.
if (!DemangledName.empty() && CF && CF->isDeclaration() &&
ST->canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
const Type *OrigRetTy = Info.OrigRet.Ty;
if (FTy)
OrigRetTy = FTy->getReturnType();
SmallVector<Register, 8> ArgVRegs;
for (auto Arg : Info.OrigArgs) {
assert(Arg.Regs.size() == 1 && "Call arg has multiple VRegs");
ArgVRegs.push_back(Arg.Regs[0]);
SPIRVType *SPIRVTy = GR->getOrCreateSPIRVType(Arg.Ty, MIRBuilder);
GR->assignSPIRVTypeToVReg(SPIRVTy, Arg.Regs[0], MIRBuilder.getMF());
}
if (Optional<bool> Res = SPIRV::lowerBuiltin(
DemangledName, SPIRV::InstructionSet::OpenCL_std, MIRBuilder,
ResVReg, OrigRetTy, ArgVRegs, GR))
return *Res;
}

if (CF && CF->isDeclaration() &&
!GR->find(CF, &MIRBuilder.getMF()).isValid()) {
// Emit the type info and forward function declaration to the first MBB
Expand Down Expand Up @@ -441,7 +438,6 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
assert(arg.Regs.size() == 1 && "Call arg has multiple VRegs");
MIB.addUse(arg.Regs[0]);
}
const auto &STI = MF.getSubtarget();
return MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
*STI.getRegBankInfo());
return MIB.constrainAllUses(MIRBuilder.getTII(), *ST->getRegisterInfo(),
*ST->getRegBankInfo());
}
64 changes: 25 additions & 39 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,22 +340,17 @@ Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
if (EmitIR) {
MIRBuilder.buildSplatVector(SpvVecConst, SpvScalConst);
} else {
MachineInstrBuilder MIB;
if (Val) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
.addDef(SpvVecConst)
.addUse(getSPIRVTypeID(SpvType));
auto MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
.addDef(SpvVecConst)
.addUse(getSPIRVTypeID(SpvType));
for (unsigned i = 0; i < ElemCnt; ++i)
MIB.addUse(SpvScalConst);
} else {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(SpvVecConst)
.addUse(getSPIRVTypeID(SpvType));
MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(SpvVecConst)
.addUse(getSPIRVTypeID(SpvType));
}
const auto &Subtarget = CurMF->getSubtarget();
constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
*Subtarget.getRegisterInfo(),
*Subtarget.getRegBankInfo());
}
return SpvVecConst;
}
Expand Down Expand Up @@ -561,7 +556,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
}
auto SType = cast<StructType>(Ty);
assert(isSpecialOpaqueType(SType) && "Not a special opaque builtin type");
return lowerBuiltinType(SType, AccQual, MIRBuilder, this);
return SPIRV::lowerBuiltinType(SType, AccQual, MIRBuilder, this);
}

SPIRVType *SPIRVGlobalRegistry::getOpTypePointer(
Expand Down Expand Up @@ -819,18 +814,17 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeImage)
.addDef(ResVReg)
.addUse(getSPIRVTypeID(SampledType))
.addImm(Dim)
.addImm(Depth) // Depth (whether or not it is a Depth image)
.addImm(Arrayed) // Arrayed
.addImm(Multisampled) // Multisampled (0 = only single-sample)
.addImm(Sampled) // Sampled (0 = usage known at runtime)
.addImm(ImageFormat)
.addImm(AccessQual);
DT.add(TD, &MIRBuilder.getMF(), ResVReg);
return MIB;
return MIRBuilder.buildInstr(SPIRV::OpTypeImage)
.addDef(ResVReg)
.addUse(getSPIRVTypeID(SampledType))
.addImm(Dim)
.addImm(Depth) // Depth (whether or not it is a Depth image).
.addImm(Arrayed) // Arrayed.
.addImm(Multisampled) // Multisampled (0 = only single-sample).
.addImm(Sampled) // Sampled (0 = usage known at runtime).
.addImm(ImageFormat)
.addImm(AccessQual);
}

SPIRVType *
Expand All @@ -839,10 +833,8 @@ SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
constrainRegOperands(MIB);
DT.add(TD, &MIRBuilder.getMF(), ResVReg);
return MIB;
return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
}

SPIRVType *
Expand All @@ -852,12 +844,10 @@ SPIRVGlobalRegistry::getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder,
if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypePipe)
.addDef(ResVReg)
.addImm(AccessQual);
constrainRegOperands(MIB);
DT.add(TD, &MIRBuilder.getMF(), ResVReg);
return MIB;
return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
.addDef(ResVReg)
.addImm(AccessQual);
}

SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
Expand All @@ -869,12 +859,10 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
.addDef(ResVReg)
.addUse(getSPIRVTypeID(ImageType));
DT.add(TD, &MIRBuilder.getMF(), ResVReg);

return MIB;
return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
.addDef(ResVReg)
.addUse(getSPIRVTypeID(ImageType));
}

SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
Expand All @@ -883,10 +871,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
if (ResVReg.isValid())
return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(ResVReg);
ResVReg = createTypeVReg(MIRBuilder);
auto MIB = MIRBuilder.buildInstr(Opcode).addDef(ResVReg);
constrainRegOperands(MIB);
DT.add(Ty, &MIRBuilder.getMF(), ResVReg);
return MIB;
return MIRBuilder.buildInstr(Opcode).addDef(ResVReg);
}

const MachineInstr *
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class SPIRVGlobalRegistry {
AQ::AccessQualifier AccessQual, bool EmitIR);

public:
SPIRVGlobalRegistry(unsigned PointerSize);

MachineFunction *CurMF;

void add(const Constant *C, MachineFunction *MF, Register R) {
DT.add(C, MF, R);
}
Expand Down Expand Up @@ -104,10 +108,6 @@ class SPIRVGlobalRegistry {
// return SpecialTypesAndConstsMap;
// }

SPIRVGlobalRegistry(unsigned PointerSize);

MachineFunction *CurMF;

// Get or create a SPIR-V type corresponding the given LLVM IR type,
// and map it to the given VReg by creating an ASSIGN_TYPE instruction.
SPIRVType *assignTypeToVReg(const Type *Type, Register VReg,
Expand Down Expand Up @@ -290,7 +290,7 @@ class SPIRVGlobalRegistry {
SPIRV::StorageClass::StorageClass SClass = SPIRV::StorageClass::Function);
SPIRVType *getOrCreateSPIRVPointerType(
SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &TII,
SPIRV::StorageClass::StorageClass SC = SPIRV::StorageClass::Function);
SPIRV::StorageClass::StorageClass SClass = SPIRV::StorageClass::Function);

SPIRVType *getOrCreateOpTypeImage(MachineIRBuilder &MIRBuilder,
SPIRVType *SampledType, SPIRV::Dim::Dim Dim,
Expand All @@ -310,7 +310,6 @@ class SPIRVGlobalRegistry {
const Type *Ty, SPIRVType *RetType,
const SmallVectorImpl<SPIRVType *> &ArgTypes,
MachineIRBuilder &MIRBuilder);

SPIRVType *getOrCreateOpTypeByOpcode(const Type *Ty,
MachineIRBuilder &MIRBuilder,
unsigned Opcode);
Expand Down