Skip to content

[SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. #129689

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

Merged
merged 25 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bbf7b42
Dissociate Logical/Physical from OpenCL/Vulkan env.
Apr 16, 2025
f6bf74b
Extra change to complete dissociation.
maarquitos14 Apr 16, 2025
4c7bbc2
Use entry points to help determine the env.
maarquitos14 Apr 23, 2025
ecb4f79
Explicitly add vulkan to triple of failing tests.
maarquitos14 Apr 24, 2025
1a4e754
Fix clang-format issue.
maarquitos14 May 1, 2025
54adad6
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 1, 2025
314f4e0
Fix failing test.
maarquitos14 May 1, 2025
6d0cf9e
Fix debug build.
maarquitos14 May 1, 2025
0f95726
Fix failing tests.
maarquitos14 May 1, 2025
a42ecac
Fix test failure.
maarquitos14 May 1, 2025
3221f7e
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 14, 2025
0cb18d0
Address code review feedback.
maarquitos14 May 14, 2025
4d84546
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 14, 2025
7a0be57
Fix build issues.
maarquitos14 May 14, 2025
70835b9
Fix typo.
maarquitos14 May 14, 2025
afa72c1
Fix test failure.
maarquitos14 May 14, 2025
b7879b5
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 15, 2025
85d600f
Fix test failure.
maarquitos14 May 15, 2025
5513335
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 27, 2025
61f2abd
Address code review feedback.
maarquitos14 May 27, 2025
a36faa4
Address more code review feedback.
maarquitos14 May 28, 2025
fcc219a
Turn assertion into fatal error.
maarquitos14 May 28, 2025
42df23d
Replace is[Kernel|Shader]Env with is[Kernel|Shader].
maarquitos14 May 30, 2025
dd530b9
Merge remote-tracking branch 'origin/main' into maronas/use-spirv-fri…
maarquitos14 May 30, 2025
248c5e6
Fix test failure.
maarquitos14 May 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,11 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
Inst.addOperand(MCOperand::createImm(TypeCode));
outputMCInst(Inst);
}
if (ST->isOpenCLEnv() && !M.getNamedMetadata("spirv.ExecutionMode") &&
// FIXME: At the moment, `isOpenCLEnv()` is not precise enough. This is
// because the Triple is not always precise enough. For now, we'll rely
// instead on `isLogicalSPIRV()`, but this should be changed when
// `isOpenCLEnv()` is precise enough.
if (!ST->isLogicalSPIRV() && !M.getNamedMetadata("spirv.ExecutionMode") &&
!M.getNamedMetadata("opencl.enable.FP_CONTRACT")) {
MCInst Inst;
Inst.setOpcode(SPIRV::OpExecutionMode);
Expand Down
37 changes: 35 additions & 2 deletions llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,42 @@ static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx,

static SPIRV::ExecutionModel::ExecutionModel
getExecutionModel(const SPIRVSubtarget &STI, const Function &F) {
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV()`, but this
// should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be true
// at the same time.
if (STI.isOpenCLEnv())
return SPIRV::ExecutionModel::Kernel;

if (STI.isVulkanEnv()) {
auto attribute = F.getFnAttribute("hlsl.shader");
if (!attribute.isValid()) {
report_fatal_error(
"This entry point lacks mandatory hlsl.shader attribute.");
}

const auto value = attribute.getValueAsString();
if (value == "compute")
return SPIRV::ExecutionModel::GLCompute;

report_fatal_error(
"This HLSL entry point is not supported by this backend.");
}

assert(STI.getEnv() == SPIRVSubtarget::Unknown);
// Can we rely on "hlsl.shader" attribute? Is it mandatory for Vulkan env? If
// so, we can set Env to Vulkan whenever we find it, and to OpenCL otherwise.

// We will now change the Env based on the attribute, so we need to strip
// `const` out of the ref to STI.
SPIRVSubtarget *NonConstSTI = const_cast<SPIRVSubtarget *>(&STI);
auto attribute = F.getFnAttribute("hlsl.shader");
if (!attribute.isValid()) {
report_fatal_error(
"This entry point lacks mandatory hlsl.shader attribute.");
NonConstSTI->setEnv(SPIRVSubtarget::OpenCL);
return SPIRV::ExecutionModel::Kernel;
}
NonConstSTI->setEnv(SPIRVSubtarget::Vulkan);

const auto value = attribute.getValueAsString();
if (value == "compute")
Expand Down Expand Up @@ -439,6 +467,11 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,

// Handle entry points and function linkage.
if (isEntryPoint(F)) {
// EntryPoints can help us to determine the environment we're working on.
// Therefore, we need a non-const pointer to SPIRVSubtarget to update the
// environment if we need to.
const SPIRVSubtarget *ST =
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)
.addImm(static_cast<uint32_t>(getExecutionModel(*ST, F)))
.addUse(FuncVReg);
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,10 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
// TODO: maybe move to GenerateDecorations pass.
const SPIRVSubtarget &ST =
cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
if (IsConst && ST.isOpenCLEnv())
// FIXME: Constant requires Kernel Capabilities, so we only emit it if we are
// in OpenCL env. However, that is not good enough at the moment, so we use
// `!isLogicalSPIRV()` instead.
if (IsConst && !ST.isLogicalSPIRV())
buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Constant, {});

if (GVar && GVar->getAlign().valueOrOne().value() != 1) {
Expand Down
49 changes: 28 additions & 21 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
.addUse(GV);
return MIB.constrainAllUses(TII, TRI, RBI) &&
BuildMI(BB, I, I.getDebugLoc(),
TII.get(STI.isVulkanEnv()
TII.get(STI.isLogicalSPIRV()
? SPIRV::OpInBoundsAccessChain
: SPIRV::OpInBoundsPtrAccessChain))
.addDef(ResVReg)
Expand Down Expand Up @@ -1036,7 +1036,7 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I,
unsigned Opcode) const {
if (STI.isOpenCLEnv() && I.getOperand(1).isReg()) {
if (!STI.isLogicalSPIRV() && I.getOperand(1).isReg()) {
Register SrcReg = I.getOperand(1).getReg();
bool IsGV = false;
for (MachineRegisterInfo::def_instr_iterator DefIt =
Expand Down Expand Up @@ -2058,7 +2058,7 @@ bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
auto ExtractOp =
Signed ? SPIRV::OpBitFieldSExtract : SPIRV::OpBitFieldUExtract;

bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
// Extract the i8 element, multiply and add it to the accumulator
for (unsigned i = 0; i < 4; i++) {
// A[i]
Expand Down Expand Up @@ -2194,11 +2194,12 @@ bool SPIRVInstructionSelector::selectWaveOpInst(Register ResVReg,
MachineBasicBlock &BB = *I.getParent();
SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);

auto BMI = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I,
IntTy, TII, STI.isOpenCLEnv()));
auto BMI =
BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
!STI.isLogicalSPIRV()));

for (unsigned J = 2; J < I.getNumOperands(); J++) {
BMI.addUse(I.getOperand(J).getReg());
Expand All @@ -2222,7 +2223,7 @@ bool SPIRVInstructionSelector::selectWaveActiveCountBits(
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy,
TII, STI.isOpenCLEnv()))
TII, !STI.isLogicalSPIRV()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(BallotReg)
.constrainAllUses(TII, TRI, RBI);
Expand Down Expand Up @@ -2253,7 +2254,7 @@ bool SPIRVInstructionSelector::selectWaveReduceMax(Register ResVReg,
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
STI.isOpenCLEnv()))
!STI.isLogicalSPIRV()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg())
.constrainAllUses(TII, TRI, RBI);
Expand All @@ -2280,7 +2281,7 @@ bool SPIRVInstructionSelector::selectWaveReduceSum(Register ResVReg,
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
STI.isOpenCLEnv()))
!STI.isLogicalSPIRV()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg());
}
Expand Down Expand Up @@ -2502,7 +2503,7 @@ bool SPIRVInstructionSelector::selectFCmp(Register ResVReg,
Register SPIRVInstructionSelector::buildZerosVal(const SPIRVType *ResType,
MachineInstr &I) const {
// OpenCL uses nulls for Zero. In HLSL we don't use null constants.
bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
if (ResType->getOpcode() == SPIRV::OpTypeVector)
return GR.getOrCreateConstVector(0UL, I, ResType, TII, ZeroAsNull);
return GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull);
Expand All @@ -2511,7 +2512,7 @@ Register SPIRVInstructionSelector::buildZerosVal(const SPIRVType *ResType,
Register SPIRVInstructionSelector::buildZerosValF(const SPIRVType *ResType,
MachineInstr &I) const {
// OpenCL uses nulls for Zero. In HLSL we don't use null constants.
bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
APFloat VZero = getZeroFP(GR.getTypeForSPIRVType(ResType));
if (ResType->getOpcode() == SPIRV::OpTypeVector)
return GR.getOrCreateConstVector(VZero, I, ResType, TII, ZeroAsNull);
Expand All @@ -2521,7 +2522,7 @@ Register SPIRVInstructionSelector::buildZerosValF(const SPIRVType *ResType,
Register SPIRVInstructionSelector::buildOnesValF(const SPIRVType *ResType,
MachineInstr &I) const {
// OpenCL uses nulls for Zero. In HLSL we don't use null constants.
bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
APFloat VOne = getOneFP(GR.getTypeForSPIRVType(ResType));
if (ResType->getOpcode() == SPIRV::OpTypeVector)
return GR.getOrCreateConstVector(VOne, I, ResType, TII, ZeroAsNull);
Expand Down Expand Up @@ -2709,10 +2710,10 @@ bool SPIRVInstructionSelector::selectConst(Register ResVReg,
Reg = GR.getOrCreateConstNullPtr(MIRBuilder, ResType);
} else if (Opcode == TargetOpcode::G_FCONSTANT) {
Reg = GR.getOrCreateConstFP(I.getOperand(1).getFPImm()->getValue(), I,
ResType, TII, STI.isOpenCLEnv());
ResType, TII, !STI.isLogicalSPIRV());
} else {
Reg = GR.getOrCreateConstInt(I.getOperand(1).getCImm()->getZExtValue(), I,
ResType, TII, STI.isOpenCLEnv());
ResType, TII, !STI.isLogicalSPIRV());
}
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
}
Expand Down Expand Up @@ -2792,7 +2793,7 @@ bool SPIRVInstructionSelector::selectGEP(Register ResVReg,
// OpAccessChain could be used for OpenCL, but the SPIRV-LLVM Translator only
// relies on PtrAccessChain, so we'll try not to deviate. For Vulkan however,
// we have to use Op[InBounds]AccessChain.
const unsigned Opcode = STI.isVulkanEnv()
const unsigned Opcode = STI.isLogicalSPIRV()
? (IsGEPInBounds ? SPIRV::OpInBoundsAccessChain
: SPIRV::OpAccessChain)
: (IsGEPInBounds ? SPIRV::OpInBoundsPtrAccessChain
Expand Down Expand Up @@ -3489,7 +3490,7 @@ bool SPIRVInstructionSelector::selectFirstBitSet64Overflow(

// On odd component counts we need to handle one more component
if (CurrentComponent != ComponentCount) {
bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
Register FinalElemReg = MRI->createVirtualRegister(GR.getRegClass(I64Type));
Register ConstIntLastIdx = GR.getOrCreateConstInt(
ComponentCount - 1, I, BaseType, TII, ZeroAsNull);
Expand Down Expand Up @@ -3519,7 +3520,7 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
Register SrcReg, unsigned BitSetOpcode, bool SwapPrimarySide) const {
unsigned ComponentCount = GR.getScalarOrVectorComponentCount(ResType);
SPIRVType *BaseType = GR.retrieveScalarOrVectorIntType(ResType);
bool ZeroAsNull = STI.isOpenCLEnv();
bool ZeroAsNull = !STI.isLogicalSPIRV();
Register ConstIntZero =
GR.getOrCreateConstInt(0, I, BaseType, TII, ZeroAsNull);
Register ConstIntOne =
Expand Down Expand Up @@ -3721,7 +3722,10 @@ bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(I.getOperand(2).getReg())
.constrainAllUses(TII, TRI, RBI);
if (!STI.isVulkanEnv()) {
// FIXME: Alignment requires Kernel Capabilities, so we only emit it if we are
// in OpenCL env. However, that is not good enough at the moment, so we use
// `!isLogicalSPIRV()` instead.
if (!STI.isLogicalSPIRV()) {
unsigned Alignment = I.getOperand(3).getImm();
buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::Alignment, {Alignment});
}
Expand All @@ -3740,7 +3744,10 @@ bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
.addUse(GR.getSPIRVTypeID(ResType))
.addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
.constrainAllUses(TII, TRI, RBI);
if (!STI.isVulkanEnv()) {
// FIXME: Alignment requires Kernel Capabilities, so we only emit it if we are
// in OpenCL env. However, that is not good enough at the moment, so we use
// `!isLogicalSPIRV()` instead.
if (!STI.isLogicalSPIRV()) {
unsigned Alignment = I.getOperand(2).getImm();
buildOpDecorate(ResVReg, *It, TII, SPIRV::Decoration::Alignment,
{Alignment});
Expand Down
71 changes: 59 additions & 12 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
SPIRV::RequirementHandler &Reqs) {
// A set of capabilities to avoid if there is another option.
AvoidCapabilitiesSet AvoidCaps;
if (ST.isOpenCLEnv())
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV()`, but this
// should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be true
// at the same time.
if (!ST.isLogicalSPIRV())
AvoidCaps.S.insert(SPIRV::Capability::Shader);

VersionTuple ReqMinVer = getSymbolicOperandMinVersion(Category, i);
Expand Down Expand Up @@ -144,8 +149,13 @@ void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
static_cast<SPIRV::MemoryModel::MemoryModel>(getMetadataUInt(MemMD, 1));
} else {
// TODO: Add support for VulkanMemoryModel.
MAI.Mem = ST->isOpenCLEnv() ? SPIRV::MemoryModel::OpenCL
: SPIRV::MemoryModel::GLSL450;
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV()`, but
// this should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be
// true at the same time.
MAI.Mem = !ST->isLogicalSPIRV() ? SPIRV::MemoryModel::OpenCL
: SPIRV::MemoryModel::GLSL450;
if (MAI.Mem == SPIRV::MemoryModel::OpenCL) {
unsigned PtrSize = ST->getPointerSize();
MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
Expand Down Expand Up @@ -175,7 +185,11 @@ void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
// OpenCL 1.0 by default for the OpenCL environment to avoid puzzling
// run-times with Unknown/0.0 version output. For a reference, LLVM-SPIRV
// Translator avoids potential issues with run-times in a similar manner.
if (ST->isOpenCLEnv()) {
// FIXME: At the moment, `isOpenCLEnv()` is not precise enough. This is
// because the Triple is not always precise enough. For now, we'll rely
// instead on `isLogicalSPIRV()`, but this should be changed when
// `isOpenCLEnv()` is precise enough.
if (!ST->isLogicalSPIRV()) {
MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
MAI.SrcLangVersion = 100000;
} else {
Expand Down Expand Up @@ -203,7 +217,12 @@ void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
MAI.Addr, *ST);

if (ST->isOpenCLEnv()) {
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV()`, but this
// should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be true
// at the same time.
if (!ST->isLogicalSPIRV()) {
// TODO: check if it's required by default.
MAI.ExtInstSetMap[static_cast<unsigned>(
SPIRV::InstructionSet::OpenCL_std)] = MAI.getNextIDRegister();
Expand Down Expand Up @@ -804,12 +823,17 @@ void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
addAvailableCaps(EnabledCapabilities);
}

if (ST.isOpenCLEnv()) {
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV`, but this
// should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be true
// at the same time.
if (!ST.isLogicalSPIRV()) {
initAvailableCapabilitiesForOpenCL(ST);
return;
}

if (ST.isVulkanEnv()) {
if (ST.isLogicalSPIRV()) {
initAvailableCapabilitiesForVulkan(ST);
return;
}
Expand Down Expand Up @@ -969,7 +993,12 @@ static void addOpTypeImageReqs(const MachineInstr &MI,
}

// Has optional access qualifier.
if (ST.isOpenCLEnv()) {
// FIXME: ImageBasic/ImageReadWrite capabilities require Kernel capability.
// However, for now, both `isVulkanEnv()` and `isOpenCLEnv()` can return
// true under some circumstances. Instead, we're using `isLogicalSPIRV()`,
// but we should change this when `isVulkanEnv()` and `isOpenCLEnv()` are
// precise enough.
if (!ST.isLogicalSPIRV()) {
if (MI.getNumOperands() > 8 &&
MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
Reqs.addRequirements(SPIRV::Capability::ImageReadWrite);
Expand Down Expand Up @@ -1267,7 +1296,12 @@ void addInstrRequirements(const MachineInstr &MI,
ST);
// If it's a type of pointer to float16 targeting OpenCL, add Float16Buffer
// capability.
if (!ST.isOpenCLEnv())
// FIXME: Float16Buffer capability requires Kernel capability. However,
// for now, both `isVulkanEnv()` and `isOpenCLEnv()` can return true under
// some circumstances. Instead, we're using `isLogicalSPIRV()`, but we
// should change this when `isVulkanEnv()` and `isOpenCLEnv()` are precise
// enough.
if (ST.isLogicalSPIRV())
break;
assert(MI.getOperand(2).isReg());
const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
Expand Down Expand Up @@ -1342,7 +1376,12 @@ void addInstrRequirements(const MachineInstr &MI,
addOpTypeImageReqs(MI, Reqs, ST);
break;
case SPIRV::OpTypeSampler:
if (!ST.isVulkanEnv()) {
// FIXME: ImageBasic capability requires Kernel capability. However, for
// now, both `isVulkanEnv()` and `isOpenCLEnv()` can return true under
// some circumstances. Instead, we're using `isLogicalSPIRV()`, but
// we should change this when `isVulkanEnv()` and `isOpenCLEnv()` are
// precise enough.
if (!ST.isLogicalSPIRV()) {
Reqs.addCapability(SPIRV::Capability::ImageBasic);
}
break;
Expand Down Expand Up @@ -1769,7 +1808,11 @@ void addInstrRequirements(const MachineInstr &MI,
// not allowed to produce
// StorageImageReadWithoutFormat/StorageImageWriteWithoutFormat, see
// https://github.com/KhronosGroup/SPIRV-Headers/issues/487
if (isImageTypeWithUnknownFormat(TypeDef) && !ST.isOpenCLEnv())

// FIXME: For now, `isOpenCLEnv()` is not precise enough. Instead, we're
// using `isLogicalSPIRV()`, but we should change this when `isOpenCLEnv()`
// is precise enough.
if (isImageTypeWithUnknownFormat(TypeDef) && ST.isLogicalSPIRV())
Reqs.addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
break;
}
Expand All @@ -1782,7 +1825,11 @@ void addInstrRequirements(const MachineInstr &MI,
// not allowed to produce
// StorageImageReadWithoutFormat/StorageImageWriteWithoutFormat, see
// https://github.com/KhronosGroup/SPIRV-Headers/issues/487
if (isImageTypeWithUnknownFormat(TypeDef) && !ST.isOpenCLEnv())

// FIXME: For now, `isOpenCLEnv()` is not precise enough. Instead, we're
// using `isLogicalSPIRV()`, but we should change this when `isOpenCLEnv()`
// is precise enough.
if (isImageTypeWithUnknownFormat(TypeDef) && ST.isLogicalSPIRV())
Reqs.addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
break;
}
Expand Down
Loading