Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 30 additions & 22 deletions llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<OperandCategory::MemoryOperandOperand>(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;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterating in one place and incrementing iterator in another is looking very fragile.

Lets imagine in the future in SPIR-V spec will be added another memory operand mask which makes an instruction accepting yet another literal operand. This memory operand was implemented with a bug and somehow we made it this far. In such case the loop block on L289 will be executed once more time re-processing all of the already processed masks, duplicating printed operands and making the iterator be out of bound.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left only one place with the increment, unified handling for all cases


void SPIRVInstPrinter::recordIntType(const MCInst *MI) {
MCRegister IntTypeReg = MI->getOperand(0).getReg();
unsigned Bitwidth = MI->getOperand(1).getImm();
Expand Down Expand Up @@ -192,10 +217,7 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
switch (OpCode) {
case SPIRV::OpLoad:
case SPIRV::OpStore:
OS << ' ';
printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
MI, FirstVariableIndex, OS);
printRemainingVariableOps(MI, FirstVariableIndex + 1, OS);
printMemoryOperand(MI, FirstVariableIndex, OS);
break;
case SPIRV::OpSwitch:
if (MI->getFlags() & SPIRV::INST_PRINTER_WIDTH64) {
Expand Down Expand Up @@ -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<OperandCategory::MemoryOperandOperand>(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:
Expand Down Expand Up @@ -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<OperandCategory::MemoryOperandOperand>(
MI, NumOps - 1, OS);
break;
}
if (MI->getNumOperands() > NumFixedOps)
printMemoryOperand(MI, NumFixedOps, OS);
break;
}
default:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <SPIRV::OperandCategory::OperandCategory category>
Expand Down
Original file line number Diff line number Diff line change
@@ -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"}
Loading