[llvm] e41df5c - [SPIR-V] Fix OpDecorate emission after vreg def. (#114426)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 04:11:00 PST 2024


Author: Nathan Gauër
Date: 2024-11-04T13:10:57+01:00
New Revision: e41df5cb8e34f471da351d6e78c0e47e3639fd12

URL: https://github.com/llvm/llvm-project/commit/e41df5cb8e34f471da351d6e78c0e47e3639fd12
DIFF: https://github.com/llvm/llvm-project/commit/e41df5cb8e34f471da351d6e78c0e47e3639fd12.diff

LOG: [SPIR-V] Fix OpDecorate emission after vreg def. (#114426)

In SPIR-V, OpDecorate instructions are allowed to forward-declare a
virtual register. But while we are at the MIR level, we must comply with
stricter rules, meaning OpDecorate should be emited after, not before
the reg definition.
(In some cases, we defined those just before, switching to just after).

Related to #110652

---------

Signed-off-by: Nathan Gauër <brioche at google.com>

Added: 
    llvm/test/CodeGen/SPIRV/decoration-order.ll

Modified: 
    llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
    llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 526305d7ed28ab..892912a5680113 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -990,13 +990,13 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
     Register VarReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
     GR.add(GV, GR.CurMF, VarReg);
 
-    buildOpDecorate(VarReg, I, TII, SPIRV::Decoration::Constant, {});
     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpVariable))
         .addDef(VarReg)
         .addUse(GR.getSPIRVTypeID(VarTy))
         .addImm(SPIRV::StorageClass::UniformConstant)
         .addUse(Const)
         .constrainAllUses(TII, TRI, RBI);
+    buildOpDecorate(VarReg, I, TII, SPIRV::Decoration::Constant, {});
     SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
         ValTy, I, TII, SPIRV::StorageClass::UniformConstant);
     SrcReg = MRI->createGenericVirtualRegister(LLT::scalar(64));

diff  --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index cc34cf877dea97..790d86f191fd86 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -829,7 +829,7 @@ static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB) {
     for (MachineInstr &MI : MBB) {
       if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_decoration))
         continue;
-      MIB.setInsertPt(*MI.getParent(), MI);
+      MIB.setInsertPt(*MI.getParent(), MI.getNextNode());
       buildOpSpirvDecorations(MI.getOperand(1).getReg(), MIB,
                               MI.getOperand(2).getMetadata());
       ToErase.push_back(&MI);

diff  --git a/llvm/test/CodeGen/SPIRV/decoration-order.ll b/llvm/test/CodeGen/SPIRV/decoration-order.ll
new file mode 100644
index 00000000000000..e8299e9735a063
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/decoration-order.ll
@@ -0,0 +1,15 @@
+; RUN: %if spirv-tools %{ llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; This test checks the OpDecorate MIR is generated after the associated
+; vreg definition in the case of an array size declared through this lowering.
+
+define spir_func i32 @foo() {
+entry:
+  %var = alloca i64
+  br label %block
+
+block:
+  call void @llvm.memset.p0.i64(ptr align 8 %var, i8 0, i64 24, i1 false)
+  ret i32 0
+}
+
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)


        


More information about the llvm-commits mailing list