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] Fix OpDecorate emission after vreg def. #114426

Merged
merged 2 commits into from
Nov 4, 2024
Merged

Conversation

Keenuts
Copy link
Contributor

@Keenuts Keenuts commented Oct 31, 2024

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

@llvmbot
Copy link
Member

llvmbot commented Oct 31, 2024

@llvm/pr-subscribers-backend-spir-v

Author: Nathan Gauër (Keenuts)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/114426.diff

3 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+1-1)
  • (modified) llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp (+1-1)
  • (added) llvm/test/CodeGen/SPIRV/decoration-order.ll (+15)
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..b6ffb6e5bd39cc
--- /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(ptr addrspace(4) %Buf, ptr addrspace(4) %Item) {
+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)

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 llvm#110652

Signed-off-by: Nathan Gauër <brioche@google.com>
Signed-off-by: Nathan Gauër <brioche@google.com>
@Keenuts
Copy link
Contributor Author

Keenuts commented Nov 4, 2024

Thanks for the review! Rebased on main. Merging once green.

@Keenuts
Copy link
Contributor Author

Keenuts commented Nov 4, 2024

There are 2 broken tests, also broken on main:

  • CodeGen/SPIRV/transcoding/RelationalOperators.ll
  • CodeGen/SPIRV/uitofp-with-bool.ll
    Those are unrelated to this PR.

@Keenuts Keenuts merged commit e41df5c into llvm:main Nov 4, 2024
6 of 9 checks passed
@Keenuts Keenuts deleted the decoration branch November 4, 2024 12:11
@VyacheslavLevytskyy
Copy link
Contributor

There are 2 broken tests, also broken on main:

  • CodeGen/SPIRV/transcoding/RelationalOperators.ll
  • CodeGen/SPIRV/uitofp-with-bool.ll
    Those are unrelated to this PR.

@Keenuts I'm checking this now.

@Keenuts
Copy link
Contributor Author

Keenuts commented Nov 4, 2024

There are 2 broken tests, also broken on main:

  • CodeGen/SPIRV/transcoding/RelationalOperators.ll
  • CodeGen/SPIRV/uitofp-with-bool.ll
    Those are unrelated to this PR.

@Keenuts I'm checking this now.

Looks like this was fixed by #114630 (comment)

@VyacheslavLevytskyy
Copy link
Contributor

Thank you @Keenuts

PhilippRados pushed a commit to PhilippRados/llvm-project that referenced this pull request Nov 6, 2024
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 llvm#110652

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants