[SPIR-V] Fix ExecutionMode generation (#143888)
PR #141787 added code to emit the Fragment execution model. This required emitting the OriginUpperLeft ExecutionMode. But this was done by using the same codepath used for OpEntrypoint. This has 2 issues: - the interface variables were added to both OpEntryPoint and OpExecutionMode. - the existing OpExecutionMode logic was not used. This commit fixes this, regrouping OpExecutionMode handling in one place, and fixing bad codegen issue when interface variiables are added.
This commit is contained in:
@@ -510,6 +510,22 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
|
||||
continue;
|
||||
MCRegister FReg = MAI->getFuncReg(&F);
|
||||
assert(FReg.isValid());
|
||||
|
||||
if (Attribute Attr = F.getFnAttribute("hlsl.shader"); Attr.isValid()) {
|
||||
// SPIR-V common validation: Fragment requires OriginUpperLeft or
|
||||
// OriginLowerLeft.
|
||||
// VUID-StandaloneSpirv-OriginLowerLeft-04653: Fragment must declare
|
||||
// OriginUpperLeft.
|
||||
if (Attr.getValueAsString() == "pixel") {
|
||||
MCInst Inst;
|
||||
Inst.setOpcode(SPIRV::OpExecutionMode);
|
||||
Inst.addOperand(MCOperand::createReg(FReg));
|
||||
unsigned EM =
|
||||
static_cast<unsigned>(SPIRV::ExecutionMode::OriginUpperLeft);
|
||||
Inst.addOperand(MCOperand::createImm(EM));
|
||||
outputMCInst(Inst);
|
||||
}
|
||||
}
|
||||
if (MDNode *Node = F.getMetadata("reqd_work_group_size"))
|
||||
outputExecutionModeFromMDNode(FReg, Node, SPIRV::ExecutionMode::LocalSize,
|
||||
3, 1);
|
||||
|
||||
@@ -475,21 +475,10 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
|
||||
// environment if we need to.
|
||||
const SPIRVSubtarget *ST =
|
||||
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
|
||||
SPIRV::ExecutionModel::ExecutionModel ExecutionModel =
|
||||
getExecutionModel(*ST, F);
|
||||
auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)
|
||||
.addImm(static_cast<uint32_t>(ExecutionModel))
|
||||
.addImm(static_cast<uint32_t>(getExecutionModel(*ST, F)))
|
||||
.addUse(FuncVReg);
|
||||
addStringImm(F.getName(), MIB);
|
||||
|
||||
if (ExecutionModel == SPIRV::ExecutionModel::Fragment) {
|
||||
// SPIR-V common validation: Fragment requires OriginUpperLeft or
|
||||
// OriginLowerLeft VUID-StandaloneSpirv-OriginLowerLeft-04653: Fragment
|
||||
// must declare OriginUpperLeft.
|
||||
MIRBuilder.buildInstr(SPIRV::OpExecutionMode)
|
||||
.addUse(FuncVReg)
|
||||
.addImm(static_cast<uint32_t>(SPIRV::ExecutionMode::OriginUpperLeft));
|
||||
}
|
||||
} else if (F.getLinkage() != GlobalValue::InternalLinkage &&
|
||||
F.getLinkage() != GlobalValue::PrivateLinkage) {
|
||||
SPIRV::LinkageType::LinkageType LnkTy =
|
||||
|
||||
@@ -595,8 +595,6 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
|
||||
collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
|
||||
} else if (OpCode == SPIRV::OpEntryPoint) {
|
||||
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
|
||||
} else if (OpCode == SPIRV::OpExecutionMode) {
|
||||
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
|
||||
} else if (TII->isAliasingInstr(MI)) {
|
||||
collectOtherInstr(MI, MAI, SPIRV::MB_AliasingInsts, IS);
|
||||
} else if (TII->isDecorationInstr(MI)) {
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
; RUN: llc -O0 -mtriple=spirv-unknown-vulkan1.3-pixel %s -o - | FileCheck %s
|
||||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan1.3-pixel %s -o - -filetype=obj | spirv-val --target-env vulkan1.3 %}
|
||||
|
||||
; CHECK-DAG: OpEntryPoint Fragment %[[#entry:]] "main"
|
||||
; CHECK-DAG: OpEntryPoint Fragment %[[#entry:]] "main" {{.*}}
|
||||
; CHECK-DAG: OpExecutionMode %[[#entry]] OriginUpperLeft
|
||||
|
||||
define void @main() #1 {
|
||||
|
||||
define void @main() #0 {
|
||||
entry:
|
||||
%0 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 1, i32 1, i32 0, i1 false)
|
||||
%1 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %0, i32 0)
|
||||
store i32 1, ptr addrspace(11) %1, align 4
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #1 = { "hlsl.shader"="pixel" }
|
||||
declare target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32, i32, i32, i32, i1) #1
|
||||
|
||||
attributes #0 = { "hlsl.shader"="pixel" }
|
||||
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
|
||||
|
||||
Reference in New Issue
Block a user