[llvm] [SPIR-V] Inline assembly support (PR #93164)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 23 03:34:53 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-spir-v
Author: Vyacheslav Levytskyy (VyacheslavLevytskyy)
<details>
<summary>Changes</summary>
This PR introduces support for inline assembly calls for SPIR-V Backend in general, and support for SPV_INTEL_inline_assembly [1] extension in particular.
As a part of the PR there appears an opportunity to bring coherent inline assembly information up to latest passes of the transformation process (emitting final SPIR-V instructions), so that PR makes it easy to add any another required flavor of inline assembly, other then supported by the vendor specific SPV_INTEL_inline_assembly extension, if/when needed.
At the moment, however, SPV_INTEL_inline_assembly is the only implemented way to bring LLVM IR inline assembly calls up to valid SPIR-V instructions and also the default one. This means that inline assembly calls will generate an error message of such extension is not used to prevent LLVM-generated error messages at the final stages of translation. When the SPV_INTEL_inline_assembly extension is mentioned among supported, translation of inline assembly is intercepted by this extension implementation on a pre-legalizer step, and this is a place where support for a new inline assembly extension may be added if needed.
This PR also extends support for register classes, improves type inference during pre-legalizer pass, and fixes a minor bug with asm-printing of string literals.
[1] https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_inline_assembly.asciidoc
---
Patch is 38.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/93164.diff
22 Files Affected:
- (modified) llvm/docs/SPIRVUsage.rst (+6)
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1)
- (modified) llvm/lib/Target/SPIRV/CMakeLists.txt (+1)
- (modified) llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp (+44-4)
- (modified) llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp (+2)
- (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+23)
- (modified) llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp (+22)
- (modified) llvm/lib/Target/SPIRV/SPIRVISelLowering.h (+9)
- (added) llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.cpp (+46)
- (added) llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.h (+33)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp (+12-1)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstrInfo.h (+1)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstrInfo.td (+10)
- (modified) llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp (+10-1)
- (modified) llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp (+2-1)
- (modified) llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp (+144-6)
- (modified) llvm/lib/Target/SPIRV/SPIRVRegisterBanks.td (+1-1)
- (modified) llvm/lib/Target/SPIRV/SPIRVRegisterInfo.td (+6-2)
- (modified) llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp (+1)
- (modified) llvm/lib/Target/SPIRV/SPIRVSubtarget.h (+6)
- (modified) llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td (+4)
- (added) llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_inline_assembly/inline_asm.ll (+99)
``````````diff
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index d27177a4541a4..1f6157e53664a 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -143,6 +143,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
- Adds instructions to convert between single-precision 32-bit floating-point values and 16-bit bfloat16 values.
* - ``SPV_INTEL_function_pointers``
- Allows translation of function pointers.
+ * - ``SPV_INTEL_inline_assembly``
+ - Allows to use inline assembly.
* - ``SPV_INTEL_optnone``
- Adds OptNoneINTEL value for Function Control mask that indicates a request to not optimize the function.
* - ``SPV_INTEL_subgroups``
@@ -333,6 +335,10 @@ SPIR-V backend, along with their descriptions and argument details.
- 32-bit Integer
- `[]`
- Generates an undefined value. Useful for optimizations and indicating uninitialized variables.
+ * - `int_spv_inline_asm`
+ - None
+ - `[Metadata, Metadata, Vararg]`
+ - Associates inline assembly features to inline assembly call instances by creating metadatas and preserving original arguments. Not emitted directly but used to support SPIR-V representation in LLVM IR.
* - `int_spv_assume`
- None
- `[1-bit Integer]`
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index cc84decc43407..90f12674d0470 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -36,6 +36,7 @@ let TargetPrefix = "spv" in {
def int_spv_alloca : Intrinsic<[llvm_any_ty], []>;
def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty]>;
def int_spv_undef : Intrinsic<[llvm_i32_ty], []>;
+ def int_spv_inline_asm : Intrinsic<[], [llvm_metadata_ty, llvm_metadata_ty, llvm_vararg_ty]>;
// Expect, Assume Intrinsics
def int_spv_assume : Intrinsic<[], [llvm_i1_ty]>;
diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt
index 7001ac382f41c..fe09d5903045c 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -17,6 +17,7 @@ add_llvm_target(SPIRVCodeGen
SPIRVAsmPrinter.cpp
SPIRVBuiltins.cpp
SPIRVCallLowering.cpp
+ SPIRVInlineAsmLowering.cpp
SPIRVCommandLine.cpp
SPIRVDuplicatesTracker.cpp
SPIRVEmitIntrinsics.cpp
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
index b468b71cc0efb..a32adfca5ccbe 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
@@ -313,6 +313,41 @@ void SPIRVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
}
+/*
+void SPIRVInstPrinter::printStringImm(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNo).isReg() || OpNo >= MI->getNumOperands())
+ return;
+
+ unsigned StrStartIndex = OpNo;
+ std::string Str = getSPIRVStringOperand(*MI, StrStartIndex);
+ O << '"';
+ for (char c : Str) {
+ // Escape ", \n characters (might break for complex UTF-8).
+ if (c == '\n') {
+ O.write("\\n", 2);
+ } else {
+ if (c == '"')
+ O.write('\\');
+ O.write(c);
+ }
+ }
+ O << '"';
+
+ unsigned numOpsInString = (Str.size() / 4) + 1;
+ StrStartIndex += numOpsInString;
+
+ // Check for final Op of "OpDecorate %x %stringImm %linkageAttribute".
+ if (MI->getOpcode() == SPIRV::OpDecorate &&
+ MI->getOperand(1).getImm() ==
+ static_cast<unsigned>(Decoration::LinkageAttributes)) {
+ O << ' ';
+ printSymbolicOperand<OperandCategory::LinkageTypeOperand>(
+ MI, StrStartIndex, O);
+ }
+}
+*/
+
void SPIRVInstPrinter::printStringImm(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const unsigned NumOps = MI->getNumOperands();
@@ -321,14 +356,19 @@ void SPIRVInstPrinter::printStringImm(const MCInst *MI, unsigned OpNo,
if (MI->getOperand(StrStartIndex).isReg())
break;
- std::string Str = getSPIRVStringOperand(*MI, OpNo);
+ std::string Str = getSPIRVStringOperand(*MI, StrStartIndex);
if (StrStartIndex != OpNo)
O << ' '; // Add a space if we're starting a new string/argument.
O << '"';
for (char c : Str) {
- if (c == '"')
- O.write('\\'); // Escape " characters (might break for complex UTF-8).
- O.write(c);
+ // Escape ", \n characters (might break for complex UTF-8).
+ if (c == '\n') {
+ O.write("\\n", 2);
+ } else {
+ if (c == '"')
+ O.write('\\');
+ O.write(c);
+ }
}
O << '"';
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 752d71eddd99a..7f531542544ab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -47,6 +47,8 @@ static const std::map<std::string, SPIRV::Extension::Extension>
SPIRV::Extension::Extension::SPV_KHR_bit_instructions},
{"SPV_KHR_linkonce_odr",
SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
+ {"SPV_INTEL_inline_assembly",
+ SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
{"SPV_INTEL_bfloat16_conversion",
SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
{"SPV_KHR_subgroup_rotate",
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index a1a08c5c699b6..ea53fe55e7ab5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -140,6 +140,7 @@ class SPIRVEmitIntrinsics
Instruction *visitAllocaInst(AllocaInst &I);
Instruction *visitAtomicCmpXchgInst(AtomicCmpXchgInst &I);
Instruction *visitUnreachableInst(UnreachableInst &I);
+ Instruction *visitCallInst(CallInst &I);
StringRef getPassName() const override { return "SPIRV emit intrinsics"; }
@@ -629,6 +630,28 @@ void SPIRVEmitIntrinsics::preprocessCompositeConstants(IRBuilder<> &B) {
}
}
+Instruction *SPIRVEmitIntrinsics::visitCallInst(CallInst &Call) {
+ if (!Call.isInlineAsm())
+ return &Call;
+
+ const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
+ LLVMContext &Ctx = F->getContext();
+
+ Constant *TyC = UndefValue::get(IA->getFunctionType());
+ MDString *ConstraintString = MDString::get(Ctx, IA->getConstraintString());
+ SmallVector<Value *> Args = {
+ MetadataAsValue::get(Ctx,
+ MDNode::get(Ctx, ValueAsMetadata::getConstant(TyC))),
+ MetadataAsValue::get(Ctx, MDNode::get(Ctx, ConstraintString))};
+ for (unsigned OpIdx = 0; OpIdx < Call.arg_size(); OpIdx++)
+ Args.push_back(Call.getArgOperand(OpIdx));
+
+ IRBuilder<> B(Call.getParent());
+ B.SetInsertPoint(&Call);
+ B.CreateIntrinsic(Intrinsic::spv_inline_asm, {}, {Args});
+ return &Call;
+}
+
Instruction *SPIRVEmitIntrinsics::visitSwitchInst(SwitchInst &I) {
BasicBlock *ParentBB = I.getParent();
IRBuilder<> B(ParentBB);
diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
index 96b4a570a26b1..2bd22bbd63169 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
@@ -82,6 +82,28 @@ bool SPIRVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
return false;
}
+std::pair<unsigned, const TargetRegisterClass *>
+SPIRVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ StringRef Constraint,
+ MVT VT) const {
+ const TargetRegisterClass *RC = nullptr;
+ if (Constraint.starts_with("{"))
+ return std::make_pair(0u, RC);
+
+ if (VT.isFloatingPoint())
+ RC = VT.isVector() ? &SPIRV::vfIDRegClass
+ : (VT.getScalarSizeInBits() > 32 ? &SPIRV::fID64RegClass
+ : &SPIRV::fIDRegClass);
+ else if (VT.isInteger())
+ RC = VT.isVector() ? &SPIRV::vIDRegClass
+ : (VT.getScalarSizeInBits() > 32 ? &SPIRV::ID64RegClass
+ : &SPIRV::IDRegClass);
+ else
+ RC = &SPIRV::IDRegClass;
+
+ return std::make_pair(0u, RC);
+}
+
// Insert a bitcast before the instruction to keep SPIR-V code valid
// when there is a type mismatch between results and operand types.
static void validatePtrTypes(const SPIRVSubtarget &STI,
diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
index 8c1de7d97d1a3..6fc200abf4627 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h
@@ -55,6 +55,15 @@ class SPIRVTargetLowering : public TargetLowering {
MachineFunction &MF,
unsigned Intrinsic) const override;
+ std::pair<unsigned, const TargetRegisterClass *>
+ getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ StringRef Constraint, MVT VT) const override;
+ unsigned
+ getNumRegisters(LLVMContext &Context, EVT VT,
+ std::optional<MVT> RegisterVT = std::nullopt) const override {
+ return 1;
+ }
+
// Call the default implementation and finalize target lowering by inserting
// extra instructions required to preserve validity of SPIR-V code imposed by
// the standard.
diff --git a/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.cpp
new file mode 100644
index 0000000000000..8bd4fb6bf8b11
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.cpp
@@ -0,0 +1,46 @@
+//===--- SPIRVInlineAsmLowering.cpp - Inline Asm lowering -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the lowering of LLVM inline asm calls to machine code
+// calls for GlobalISel.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVInlineAsmLowering.h"
+#include "SPIRVSubtarget.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+
+using namespace llvm;
+
+SPIRVInlineAsmLowering::SPIRVInlineAsmLowering(const SPIRVTargetLowering &TLI)
+ : InlineAsmLowering(&TLI) {}
+
+bool SPIRVInlineAsmLowering::lowerAsmOperandForConstraint(
+ Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
+ MachineIRBuilder &MIRBuilder) const {
+ Value *ValOp = nullptr;
+ if (isa<ConstantInt>(Val)) {
+ ValOp = Val;
+ } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(Val)) {
+ Ops.push_back(MachineOperand::CreateFPImm(CFP));
+ return true;
+ } else if (auto *II = dyn_cast<IntrinsicInst>(Val)) {
+ if (II->getIntrinsicID() == Intrinsic::spv_track_constant) {
+ if (isa<ConstantInt>(II->getOperand(0))) {
+ ValOp = II->getOperand(0);
+ } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(II->getOperand(0))) {
+ Ops.push_back(MachineOperand::CreateFPImm(CFP));
+ return true;
+ }
+ }
+ }
+ return ValOp ? InlineAsmLowering::lowerAsmOperandForConstraint(
+ ValOp, Constraint, Ops, MIRBuilder)
+ : false;
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.h b/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.h
new file mode 100644
index 0000000000000..72291855a18c4
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVInlineAsmLowering.h
@@ -0,0 +1,33 @@
+//===--- SPIRVInlineAsmLowering.h - Inline Asm lowering ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes how to lower LLVM inline asm calls to machine
+// code calls for GlobalISel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVINLINEASMLOWERING_H
+#define LLVM_LIB_TARGET_SPIRV_SPIRVINLINEASMLOWERING_H
+
+#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
+
+namespace llvm {
+
+class SPIRVTargetLowering;
+
+class SPIRVInlineAsmLowering : public InlineAsmLowering {
+public:
+ SPIRVInlineAsmLowering(const SPIRVTargetLowering &TLI);
+ bool
+ lowerAsmOperandForConstraint(Value *Val, StringRef Constraint,
+ std::vector<MachineOperand> &Ops,
+ MachineIRBuilder &MIRBuilder) const override;
+};
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_SPIRV_SPIRVINLINEASMLOWERING_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index af98f2f880459..12cf7613a45cf 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -47,6 +47,16 @@ bool SPIRVInstrInfo::isConstantInstr(const MachineInstr &MI) const {
}
}
+bool SPIRVInstrInfo::isInlineAsmDefInstr(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ case SPIRV::OpAsmTargetINTEL:
+ case SPIRV::OpAsmINTEL:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool SPIRVInstrInfo::isTypeDeclInstr(const MachineInstr &MI) const {
auto &MRI = MI.getMF()->getRegInfo();
if (MI.getNumDefs() >= 1 && MI.getOperand(0).isReg()) {
@@ -246,7 +256,8 @@ void SPIRVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
}
bool SPIRVInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
- if (MI.getOpcode() == SPIRV::GET_ID || MI.getOpcode() == SPIRV::GET_fID ||
+ if (MI.getOpcode() == SPIRV::GET_ID || MI.getOpcode() == SPIRV::GET_ID64 ||
+ MI.getOpcode() == SPIRV::GET_fID || MI.getOpcode() == SPIRV::GET_fID64 ||
MI.getOpcode() == SPIRV::GET_pID32 ||
MI.getOpcode() == SPIRV::GET_pID64 || MI.getOpcode() == SPIRV::GET_vfID ||
MI.getOpcode() == SPIRV::GET_vID || MI.getOpcode() == SPIRV::GET_vpID32 ||
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
index 4f2781c9404b8..95f3874913572 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
@@ -30,6 +30,7 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
const SPIRVRegisterInfo &getRegisterInfo() const { return RI; }
bool isHeaderInstr(const MachineInstr &MI) const;
bool isConstantInstr(const MachineInstr &MI) const;
+ bool isInlineAsmDefInstr(const MachineInstr &MI) const;
bool isTypeDeclInstr(const MachineInstr &MI) const;
bool isDecorationInstr(const MachineInstr &MI) const;
bool canUseFastMathFlags(const MachineInstr &MI) const;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index a6bedab6d4ee5..7c9b84a48a2a7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -18,7 +18,9 @@ let isCodeGenOnly=1 in {
def ASSIGN_TYPE: Pseudo<(outs ANYID:$dst_id), (ins ANYID:$src_id, TYPE:$src_ty)>;
def DECL_TYPE: Pseudo<(outs ANYID:$dst_id), (ins ANYID:$src_id, TYPE:$src_ty)>;
def GET_ID: Pseudo<(outs ID:$dst_id), (ins ANYID:$src)>;
+ def GET_ID64: Pseudo<(outs ID64:$dst_id), (ins ANYID:$src)>;
def GET_fID: Pseudo<(outs fID:$dst_id), (ins ANYID:$src)>;
+ def GET_fID64: Pseudo<(outs fID64:$dst_id), (ins ANYID:$src)>;
def GET_pID32: Pseudo<(outs pID32:$dst_id), (ins ANYID:$src)>;
def GET_pID64: Pseudo<(outs pID64:$dst_id), (ins ANYID:$src)>;
def GET_vID: Pseudo<(outs vID:$dst_id), (ins ANYID:$src)>;
@@ -854,3 +856,11 @@ def OpGroupLogicalOrKHR: Op<6407, (outs ID:$res), (ins TYPE:$type, ID:$scope, i3
"$res = OpGroupLogicalOrKHR $type $scope $groupOp $value">;
def OpGroupLogicalXorKHR: Op<6408, (outs ID:$res), (ins TYPE:$type, ID:$scope, i32imm:$groupOp, ID:$value),
"$res = OpGroupLogicalXorKHR $type $scope $groupOp $value">;
+
+// Inline Assembly Instructions
+def OpAsmTargetINTEL: Op<5609, (outs ID:$res), (ins StringImm:$str), "$res = OpAsmTargetINTEL $str">;
+def OpAsmINTEL: Op<5610, (outs ID:$res), (ins TYPE:$type, TYPE:$asm_type, ID:$target,
+ StringImm:$asm, StringImm:$constraints),
+ "$res = OpAsmINTEL $type $asm_type $target $asm">;
+def OpAsmCallINTEL: Op<5611, (outs ID:$res), (ins TYPE:$type, ID:$asm, variable_ops),
+ "$res = OpAsmCallINTEL $type $asm">;
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index cbe7c5ca30570..f6b1fe7f0fbdc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -440,7 +440,8 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS);
} else if (OpCode == SPIRV::OpFunction) {
collectFuncNames(MI, &*F);
- } else if (OpCode == SPIRV::OpTypeForwardPointer) {
+ } else if (OpCode == SPIRV::OpTypeForwardPointer/* ||
+ TII->isInlineAsmDefInstr(MI)*/) {
collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS, false);
}
}
@@ -1151,6 +1152,14 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
}
break;
+ case SPIRV::OpAsmTargetINTEL:
+ case SPIRV::OpAsmINTEL:
+ case SPIRV::OpAsmCallINTEL:
+ if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
+ Reqs.addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
+ Reqs.addCapability(SPIRV::Capability::AsmINTEL);
+ }
+ break;
default:
break;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index d652b5de60808..c3842f0266706 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -54,7 +54,8 @@ extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
} // namespace llvm
static bool isMetaInstrGET(unsigned Opcode) {
- return Opcode == SPIRV::GET_ID || Opcode == SPIRV::GET_fID ||
+ return Opcode == SPIRV::GET_ID || Opcode == SPIRV::GET_ID64 ||
+ Opcode == SPIRV::GET_fID || Opcode == SPIRV::GET_fID64 ||
Opcode == SPIRV::GET_pID32 || Opcode == SPIRV::GET_pID64 ||
Opcode == SPIRV::GET_vID || Opcode == SPIRV::GET_vfID ||
Opcode == SPIRV::GET_vpID32 || Opcode == SPIRV::GET_vpID64;
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 9bff23dd96668..85299a49a6b94 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -215,6 +215,8 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR,
SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
break;
}
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_SEXT:
case TargetOpcode::G_ZEXT: {
if (MI->getOperand(1).isReg()) {
if (MachineInstr *DefInstr =
@@ -457,12 +459,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
Ty = VectorType::get(ElemTy, NumElts, false);
}
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
- } else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
- MI.getOpcode() == TargetOpcode::G_ZEXT ||
- MI.getOpcode() == TargetOpcode::G_PTRTOINT ||
- MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
- MI.getOpcode() == TargetOpcode::COPY ||
- MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
+ } else if (MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
propagateSPIRVType(&MI, GR, MRI, MIB);
}
@@ -474,6 +471,24 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
for (MachineInstr *MI : ToEra...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/93164
More information about the llvm-commits
mailing list