Skip to content

Commit 83e83ec

Browse files
Keenutstomtor
authored andcommitted
[SPIR-V] Fix ExecutionMode generation (llvm#143888)
PR llvm#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.
1 parent c3de2f3 commit 83e83ec

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,22 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
510510
continue;
511511
MCRegister FReg = MAI->getFuncReg(&F);
512512
assert(FReg.isValid());
513+
514+
if (Attribute Attr = F.getFnAttribute("hlsl.shader"); Attr.isValid()) {
515+
// SPIR-V common validation: Fragment requires OriginUpperLeft or
516+
// OriginLowerLeft.
517+
// VUID-StandaloneSpirv-OriginLowerLeft-04653: Fragment must declare
518+
// OriginUpperLeft.
519+
if (Attr.getValueAsString() == "pixel") {
520+
MCInst Inst;
521+
Inst.setOpcode(SPIRV::OpExecutionMode);
522+
Inst.addOperand(MCOperand::createReg(FReg));
523+
unsigned EM =
524+
static_cast<unsigned>(SPIRV::ExecutionMode::OriginUpperLeft);
525+
Inst.addOperand(MCOperand::createImm(EM));
526+
outputMCInst(Inst);
527+
}
528+
}
513529
if (MDNode *Node = F.getMetadata("reqd_work_group_size"))
514530
outputExecutionModeFromMDNode(FReg, Node, SPIRV::ExecutionMode::LocalSize,
515531
3, 1);

llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -475,21 +475,10 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
475475
// environment if we need to.
476476
const SPIRVSubtarget *ST =
477477
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
478-
SPIRV::ExecutionModel::ExecutionModel ExecutionModel =
479-
getExecutionModel(*ST, F);
480478
auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)
481-
.addImm(static_cast<uint32_t>(ExecutionModel))
479+
.addImm(static_cast<uint32_t>(getExecutionModel(*ST, F)))
482480
.addUse(FuncVReg);
483481
addStringImm(F.getName(), MIB);
484-
485-
if (ExecutionModel == SPIRV::ExecutionModel::Fragment) {
486-
// SPIR-V common validation: Fragment requires OriginUpperLeft or
487-
// OriginLowerLeft VUID-StandaloneSpirv-OriginLowerLeft-04653: Fragment
488-
// must declare OriginUpperLeft.
489-
MIRBuilder.buildInstr(SPIRV::OpExecutionMode)
490-
.addUse(FuncVReg)
491-
.addImm(static_cast<uint32_t>(SPIRV::ExecutionMode::OriginUpperLeft));
492-
}
493482
} else if (F.getLinkage() != GlobalValue::InternalLinkage &&
494483
F.getLinkage() != GlobalValue::PrivateLinkage) {
495484
SPIRV::LinkageType::LinkageType LnkTy =

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,6 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
595595
collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
596596
} else if (OpCode == SPIRV::OpEntryPoint) {
597597
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
598-
} else if (OpCode == SPIRV::OpExecutionMode) {
599-
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
600598
} else if (TII->isAliasingInstr(MI)) {
601599
collectOtherInstr(MI, MAI, SPIRV::MB_AliasingInsts, IS);
602600
} else if (TII->isDecorationInstr(MI)) {
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
; RUN: llc -O0 -mtriple=spirv-unknown-vulkan1.3-pixel %s -o - | FileCheck %s
22
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan1.3-pixel %s -o - -filetype=obj | spirv-val --target-env vulkan1.3 %}
33

4-
; CHECK-DAG: OpEntryPoint Fragment %[[#entry:]] "main"
4+
; CHECK-DAG: OpEntryPoint Fragment %[[#entry:]] "main" {{.*}}
55
; CHECK-DAG: OpExecutionMode %[[#entry]] OriginUpperLeft
66

7-
define void @main() #1 {
7+
8+
define void @main() #0 {
89
entry:
10+
%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)
11+
%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)
12+
store i32 1, ptr addrspace(11) %1, align 4
13+
914
ret void
1015
}
1116

12-
attributes #1 = { "hlsl.shader"="pixel" }
17+
declare target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32, i32, i32, i32, i1) #1
18+
19+
attributes #0 = { "hlsl.shader"="pixel" }
20+
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }

0 commit comments

Comments
 (0)