diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp index b7dcd10bac809..1a05aea432bee 100644 --- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp +++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp @@ -113,6 +113,31 @@ void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI, O << Imm; } +unsigned SPIRVInstPrinter::printMemoryOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + O << ' '; + if (OpNo >= MI->getNumOperands()) + return OpNo; + const uint64_t Mask = MI->getOperand(OpNo).getImm(); + printSymbolicOperand(MI, OpNo, O); + unsigned NextOp = OpNo + 1; + static constexpr uint64_t ParameterizedMasks[] = { + SPIRV::MemoryOperand::Aligned, + SPIRV::MemoryOperand::MakePointerAvailableKHR, + SPIRV::MemoryOperand::MakePointerVisibleKHR, + SPIRV::MemoryOperand::AliasScopeINTELMask, + SPIRV::MemoryOperand::NoAliasINTELMask, + }; + for (uint64_t ParamMask : ParameterizedMasks) { + if (!(Mask & ParamMask)) + continue; + O << ' '; + printOperand(MI, NextOp, O); + ++NextOp; + } + return NextOp; +} + void SPIRVInstPrinter::recordIntType(const MCInst *MI) { MCRegister IntTypeReg = MI->getOperand(0).getReg(); unsigned Bitwidth = MI->getOperand(1).getImm(); @@ -192,10 +217,7 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address, switch (OpCode) { case SPIRV::OpLoad: case SPIRV::OpStore: - OS << ' '; - printSymbolicOperand( - MI, FirstVariableIndex, OS); - printRemainingVariableOps(MI, FirstVariableIndex + 1, OS); + printMemoryOperand(MI, FirstVariableIndex, OS); break; case SPIRV::OpSwitch: if (MI->getFlags() & SPIRV::INST_PRINTER_WIDTH64) { @@ -253,17 +275,8 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address, case SPIRV::OpCopyMemory: case SPIRV::OpCopyMemorySized: { const unsigned NumOps = MI->getNumOperands(); - for (unsigned i = NumFixedOps; i < NumOps; ++i) { - OS << ' '; - printSymbolicOperand(MI, i, - OS); - if (MI->getOperand(i).getImm() & MemoryOperand::Aligned) { - assert(i + 1 < NumOps && "Missing alignment operand"); - OS << ' '; - printOperand(MI, i + 1, OS); - i += 1; - } - } + for (unsigned i = NumFixedOps; i < NumOps;) + i = printMemoryOperand(MI, i, OS); break; } case SPIRV::OpConstantI: @@ -346,13 +359,8 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address, } case SPIRV::OpPredicatedLoadINTEL: case SPIRV::OpPredicatedStoreINTEL: { - const unsigned NumOps = MI->getNumOperands(); - if (NumOps > NumFixedOps) { - OS << ' '; - printSymbolicOperand( - MI, NumOps - 1, OS); - break; - } + if (MI->getNumOperands() > NumFixedOps) + printMemoryOperand(MI, NumFixedOps, OS); break; } default: diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h index b195c3de1801d..4d9450376a0a4 100644 --- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h +++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h @@ -43,6 +43,7 @@ class SPIRVInstPrinter : public MCInstPrinter { bool SkipImmediates = false); void printOpConstantVarOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O); + unsigned printMemoryOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printExtension(const MCInst *MI, unsigned OpNo, raw_ostream &O); template diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-copy-memory.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-copy-memory.ll new file mode 100644 index 0000000000000..89bdfbc2bd96d --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-copy-memory.ll @@ -0,0 +1,25 @@ +; Aliasing metadata on OpCopyMemory adds an alignment literal and an +; alias-list ID after the memory access mask. + +; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - -filetype=obj | spirv-val %} + +; CHECK: %[[#List:]] = OpAliasScopeListDeclINTEL + +; CHECK: %[[#]] = OpFunction +define void @copy_aliased() { +entry: +; CHECK: OpCopyMemory %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List]] + call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) align 4 @dst, ptr addrspace(1) align 4 @src, i64 20, i1 false), !alias.scope !1 + ret void +} + +%struct.T = type <{ float, float, float, float, float }> +@src = external dso_local addrspace(1) global %struct.T, align 4 +@dst = external dso_local addrspace(1) global %struct.T, align 4 + +declare void @llvm.memcpy.p1.p1.i64(ptr addrspace(1), ptr addrspace(1), i64, i1) + +!1 = !{!2} +!2 = distinct !{!2, !3, !"copy_aliased: %this"} +!3 = distinct !{!3, !"copy_aliased"}