[llvm] [MachineVerifier] Query TargetInstrInfo for PHI nodes. (PR #110507)
Nathan Gauër via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 30 08:33:14 PDT 2024
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/110507
>From 8d4cde5e9605c6ee5b80537b1947e0c92286ea66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Mon, 30 Sep 2024 13:55:28 +0200
Subject: [PATCH 1/2] [MachineVerifier] Query TargetInstrInfo for PHI nodes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
MachineVerifier can run post-ISel, and the SPIR-V can emit phi nodes.
This means G_PHI/PHI are not the only 2 opcodes representing phi nodes.
In addition, the SPIR-V instruction operands are ordered slightly
differently (1 additional operand before the pairs).
There are multiple ways to solve this, but here I decided to go with the
less invasive, but less generic method. However the refactoring
mentioned in the rest of this commit can still be done later, as it
also relies on TII exposing an `isPhiInstr`.
Alternative designs
===================
1st alternative:
----------------
Add a bit in MCInstDesc for phi instructions (See #110019).
This was refused as the MCInstDesc bits are "pricy", and a that only
impacts 3 instructions is not a wise expense.
2nd alternative:
----------------
Refactorize MachineInstr::isPHI() to use TargetInstrInfo.
This was almost possible, as MachineInstr often has a parent MBB, and
thus a parent MF which links to the TargetInstrInfo.
In MachineInstr: this->getMF().getTargetInstrInfo().isPhiInstr(*this)
This however breaks as soon as the MachineInstr is removed from it's
parent block.
Solving this requires passing TII as a parameter to isPHI. Passing TII
requires each code using `isPHI` to also pass TII. This is a very
invasive change, which impacts almost every backends, and several
passes.
Fixes #108844
Signed-off-by: Nathan Gauër <brioche at google.com>
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 26 ++++++++++++++++
llvm/lib/CodeGen/MachineVerifier.cpp | 33 ++++++++++++---------
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 24 +++++++++++++++
llvm/lib/Target/SPIRV/SPIRVInstrInfo.h | 5 ++++
4 files changed, 74 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 07b59b241d9f9a..b4bf8ca984c9f4 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -2278,6 +2278,32 @@ class TargetInstrInfo : public MCInstrInfo {
llvm_unreachable("unknown number of operands necessary");
}
+ // This this instruction a PHI node.
+ // This function should be favored over MI.isPHI() as it allows backends to
+ // define additional PHI instructions.
+ virtual bool isPhiInstr(const MachineInstr &MI) const {
+ return MI.getOpcode() == TargetOpcode::G_PHI ||
+ MI.getOpcode() == TargetOpcode::PHI;
+ }
+
+ // Returns the number of [Value, Src] pairs this phi instruction has.
+ // Only valid to call on a phi node.
+ virtual unsigned getNumPhiIncomingPair(const MachineInstr &MI) const {
+ assert(isPhiInstr(MI));
+ // G_PHI/PHI only have a single operand before the pairs. 2 Operands per
+ // pair.
+ return (MI.getNumOperands() - 1) / 2;
+ }
+
+ // Returns the |index|'th [Value, Src] pair of this phi instruction.
+ virtual std::pair<MachineOperand, MachineBasicBlock *>
+ getPhiIncomingPair(const MachineInstr &MI, unsigned index) const {
+ // Behavior for G_PHI/PHI instructions.
+ MachineOperand Operand = MI.getOperand(index * 2 + 1);
+ MachineBasicBlock *MBB = MI.getOperand(index * 2 + 2).getMBB();
+ return {Operand, MBB};
+ }
+
private:
mutable std::unique_ptr<MIRFormatter> Formatter;
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 24a0f41775cc1d..eb9d67fe9d14cf 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2202,7 +2202,7 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
if (MI->getFlag(MachineInstr::NoConvergent) && !MCID.isConvergent())
report("NoConvergent flag expected only on convergent instructions.", MI);
- if (MI->isPHI()) {
+ if (TII->isPhiInstr(*MI)) {
if (MF->getProperties().hasProperty(
MachineFunctionProperties::Property::NoPHIs))
report("Found PHI instruction with NoPHIs property set", MI);
@@ -2705,7 +2705,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
break;
case MachineOperand::MO_MachineBasicBlock:
- if (MI->isPHI() && !MO->getMBB()->isSuccessor(MI->getParent()))
+ if (TII->isPhiInstr(*MI) && !MO->getMBB()->isSuccessor(MI->getParent()))
report("PHI operand is not in the CFG", MO, MONum);
break;
@@ -2776,7 +2776,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
}
LiveQueryResult LRQ = LR.Query(UseIdx);
- bool HasValue = LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut());
+ bool HasValue = LRQ.valueIn() || (TII->isPhiInstr(*MI) && LRQ.valueOut());
// Check if we have a segment at the use, note however that we only need one
// live subregister range, the others may be dead.
if (!HasValue && LaneMask.none()) {
@@ -2895,7 +2895,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
// Check LiveInts liveness and kill.
if (LiveInts && !LiveInts->isNotInMIMap(*MI)) {
SlotIndex UseIdx;
- if (MI->isPHI()) {
+ if (TII->isPhiInstr(*MI)) {
// PHI use occurs on the edge, so check for live out here instead.
UseIdx = LiveInts->getMBBEndIdx(
MI->getOperand(MONum + 1).getMBB()).getPrevSlot();
@@ -2926,7 +2926,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
continue;
checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask);
LiveQueryResult LRQ = SR.Query(UseIdx);
- if (LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut()))
+ if (LRQ.valueIn() || (TII->isPhiInstr(*MI) && LRQ.valueOut()))
LiveInMask |= SR.LaneMask;
}
// At least parts of the register has to be live at the use.
@@ -2936,7 +2936,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
report_context(UseIdx);
}
// For PHIs all lanes should be live
- if (MI->isPHI() && LiveInMask != MOMask) {
+ if (TII->isPhiInstr(*MI) && LiveInMask != MOMask) {
report("Not all lanes of PHI source live at use", MO, MONum);
report_context(*LI);
report_context(UseIdx);
@@ -2987,7 +2987,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
// must be live in. PHI instructions are handled separately.
if (MInfo.regsKilled.count(Reg))
report("Using a killed virtual register", MO, MONum);
- else if (!MI->isPHI())
+ else if (!TII->isPhiInstr(*MI))
MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI));
}
}
@@ -3211,17 +3211,22 @@ void MachineVerifier::calcRegsRequired() {
todo.insert(Pred);
}
- // Handle the PHI node.
- for (const MachineInstr &MI : MBB.phis()) {
- for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
+ // Handle the PHI nodes.
+ // Note: MBB.phis() only returns range containing PHI/G_PHI instructions.
+ // MachineVerifier checks MIR post-ISel, and some backends do have their own
+ // phi nodes.
+ for (const MachineInstr &MI : MBB) {
+ // PHI nodes must be the first instructions of the MBB.
+ if (!TII->isPhiInstr(MI))
+ break;
+ for (unsigned i = 0; i < TII->getNumPhiIncomingPair(MI); ++i) {
+ auto [Op, Pred] = TII->getPhiIncomingPair(MI, i);
// Skip those Operands which are undef regs or not regs.
- if (!MI.getOperand(i).isReg() || !MI.getOperand(i).readsReg())
+ if (!Op.isReg() || !Op.readsReg())
continue;
// Get register and predecessor for one PHI edge.
- Register Reg = MI.getOperand(i).getReg();
- const MachineBasicBlock *Pred = MI.getOperand(i + 1).getMBB();
-
+ Register Reg = Op.getReg();
BBInfo &PInfo = MBBInfoMap[Pred];
if (PInfo.addRequired(Reg))
todo.insert(Pred);
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index e8a6b4fdbae977..0029bcb830e381 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -267,3 +267,27 @@ bool SPIRVInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
}
return false;
}
+
+// The SPIR-V backends can emit the OpPhi instruction.
+bool SPIRVInstrInfo::isPhiInstr(const MachineInstr &MI) const {
+ return TargetInstrInfo::isPhiInstr(MI) || MI.getOpcode() == SPIRV::OpPhi;
+}
+
+unsigned SPIRVInstrInfo::getNumPhiIncomingPair(const MachineInstr &MI) const {
+ // OpPhi has 2 operands before the [Value, Src] pairs.
+ if (MI.getOpcode() == SPIRV::OpPhi)
+ return (MI.getNumOperands() - 2) / 2;
+ return TargetInstrInfo::getNumPhiIncomingPair(MI);
+}
+
+std::pair<MachineOperand, MachineBasicBlock *>
+SPIRVInstrInfo::getPhiIncomingPair(const MachineInstr &MI,
+ unsigned index) const {
+ if (MI.getOpcode() != SPIRV::OpPhi)
+ return TargetInstrInfo::getPhiIncomingPair(MI, index);
+
+ // Skip the first 2 operands (dst, type), and access each [Value, Src] pairs.
+ MachineOperand Operand = MI.getOperand(index * 2 + 2);
+ MachineBasicBlock *MBB = MI.getOperand(index * 2 + 3).getMBB();
+ return {Operand, MBB};
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
index 67d2d979cb5a15..bae008adaa85c9 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
@@ -54,6 +54,11 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
bool KillSrc, bool RenamableDest = false,
bool RenamableSrc = false) const override;
bool expandPostRAPseudo(MachineInstr &MI) const override;
+
+ bool isPhiInstr(const MachineInstr &MI) const override;
+ unsigned getNumPhiIncomingPair(const MachineInstr &MI) const override;
+ std::pair<MachineOperand, MachineBasicBlock *>
+ getPhiIncomingPair(const MachineInstr &MI, unsigned index) const override;
};
namespace SPIRV {
>From 8605d4d0dabe9219609fa24c1ebf4fcf45edb2a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Mon, 30 Sep 2024 17:32:33 +0200
Subject: [PATCH 2/2] add -machine-verifier flags
---
llvm/test/CodeGen/SPIRV/branching/if-merging.ll | 2 +-
llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll | 2 +-
.../CodeGen/SPIRV/optimizations/add-check-overflow.ll | 4 ++--
.../CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll | 10 +++++-----
llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll | 2 +-
.../SPIRV/structurizer/cf.for.short-circuited-cond.ll | 2 +-
.../structurizer/cf.while.short-circuited-cond.ll | 2 +-
.../CodeGen/SPIRV/structurizer/condition-linear.ll | 2 +-
llvm/test/CodeGen/SPIRV/transcoding/OpImageReadMS.ll | 2 +-
9 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/branching/if-merging.ll b/llvm/test/CodeGen/SPIRV/branching/if-merging.ll
index 52eeb216234e5d..3fb7e000c1025c 100644
--- a/llvm/test/CodeGen/SPIRV/branching/if-merging.ll
+++ b/llvm/test/CodeGen/SPIRV/branching/if-merging.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -verify-machineinstrs | FileCheck %s
;; NOTE: This does not check for structured control-flow operations.
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
index e7a986980f250e..40b046a9dd6221 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -verify-machineinstrs | FileCheck %s
; CHECK-DAG: OpDecorate %[[#Memset_p0i32:]] LinkageAttributes "spirv.llvm_memset_p0_i32" Export
; CHECK-DAG: OpDecorate %[[#Memset_p3i32:]] LinkageAttributes "spirv.llvm_memset_p3_i32" Export
diff --git a/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll b/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
index 1a630f77a44c5d..dfda2d0920e910 100644
--- a/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
@@ -2,10 +2,10 @@
; in the special case when those intrinsics are being generated by the CodeGenPrepare;
; pass during translations with optimization (note -O3 in llc arguments).
-; RUN: llc -O3 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O3 -mtriple=spirv32-unknown-unknown %s -o - -verify-machineinstrs | FileCheck %s
; RUN: %if spirv-tools %{ llc -O3 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; RUN: llc -O3 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O3 -mtriple=spirv64-unknown-unknown %s -o - -verify-machineinstrs | FileCheck %s
; RUN: %if spirv-tools %{ llc -O3 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; CHECK-DAG: OpName %[[Val:.*]] "math"
diff --git a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
index cd4d9325c76599..9030b003880321 100644
--- a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
@@ -1,11 +1,11 @@
; This test shows how value attributes are being passed during different translation steps.
; See also test/CodeGen/SPIRV/optimizations/add-check-overflow.ll.
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=prepare-functions 2>&1 | FileCheck %s --check-prefix=CHECK-PREPARE
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=prepare-functions 2>&1 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-PREPARE
; Intrinsics with aggregate return type are not substituted/removed.
; CHECK-PREPARE: @llvm.uadd.with.overflow.i32
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=emit-intrinsics 2>&1 | FileCheck %s --check-prefix=CHECK-IR
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=emit-intrinsics 2>&1 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-IR
; Aggregate data are wrapped into @llvm.fake.use(),
; and their attributes are packed into a metadata for @llvm.spv.value.md().
; CHECK-IR: %[[R1:.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32
@@ -18,20 +18,20 @@
; Origin data type of the value.
; CHECK-IR: !1 = !{{[{]}}{{[{]}} i32, i1 {{[}]}} poison{{[}]}}
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=irtranslator 2>&1 | FileCheck %s --check-prefix=CHECK-GMIR
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=irtranslator 2>&1 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-GMIR
; Required info succeeded to get through IRTranslator.
; CHECK-GMIR: %[[phires:.*]]:_(s32) = G_PHI
; CHECK-GMIR: %[[math:.*]]:id(s32), %[[ov:.*]]:_(s1) = G_UADDO %[[phires]]:_, %[[#]]:_
; CHECK-GMIR: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.spv.value.md), !0
; CHECK-GMIR: FAKE_USE %[[math]]:id(s32), %[[ov]]:_(s1)
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=spirv-prelegalizer 2>&1 | FileCheck %s --check-prefix=CHECK-PRE
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=spirv-prelegalizer 2>&1 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-PRE
; Internal service instructions are consumed.
; CHECK-PRE: G_UADDO
; CHECK-PRE-NO: llvm.spv.value.md
; CHECK-PRE-NO: FAKE_USE
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=instruction-select 2>&1 | FileCheck %s --check-prefix=CHECK-ISEL
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=instruction-select 2>&1 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-ISEL
; Names and types are restored and correctly encoded. Correct instruction selection is completed.
; CHECK-ISEL-DAG: %[[int32:.*]]:type = OpTypeInt 32, 0
; CHECK-ISEL-DAG: %[[struct:.*]]:type = OpTypeStruct %[[int32]]:type, %[[int32]]:type
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll b/llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll
index 4934b17c8c002e..8a0585d0bf202f 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s
+; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - -verify-machineinstrs | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/cf.for.short-circuited-cond.ll b/llvm/test/CodeGen/SPIRV/structurizer/cf.for.short-circuited-cond.ll
index 1b5e868317fba5..453509a3a6fd4f 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/cf.for.short-circuited-cond.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/cf.for.short-circuited-cond.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s
+; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - -verify-machineinstrs | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=9
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/cf.while.short-circuited-cond.ll b/llvm/test/CodeGen/SPIRV/structurizer/cf.while.short-circuited-cond.ll
index 79ce0c15e5c43b..f65176a4249a8c 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/cf.while.short-circuited-cond.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/cf.while.short-circuited-cond.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s
+; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - -verify-machineinstrs | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
;
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/condition-linear.ll b/llvm/test/CodeGen/SPIRV/structurizer/condition-linear.ll
index faab2553ae6f51..19fe131702c382 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/condition-linear.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/condition-linear.ll
@@ -1,5 +1,5 @@
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
-; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s --match-full-lines
+; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - -verify-machineinstrs | FileCheck %s --match-full-lines
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan-compute"
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpImageReadMS.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpImageReadMS.ll
index f4e34c325e6013..ed57720c51616d 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpImageReadMS.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpImageReadMS.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-SPIRV
; CHECK-SPIRV: %[[#]] = OpImageRead %[[#]] %[[#]] %[[#]] Sample %[[#]]
More information about the llvm-commits
mailing list