[llvm] [SPIR-V] Add SPV_INTEL_memory_access_aliasing extension (PR #129800)
Dmitry Sidorov via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 5 14:11:59 PST 2025
https://github.com/MrSidims updated https://github.com/llvm/llvm-project/pull/129800
>From fce902c7c586dbef39178d1fe311646a13ccdf41 Mon Sep 17 00:00:00 2001
From: "Sidorov, Dmitry" <dmitry.sidorov at intel.com>
Date: Tue, 4 Mar 2025 06:20:26 -0800
Subject: [PATCH 1/4] [SPIR-V] Add SPV_INTEL_memory_access_aliasing extension
Spec can be found here https://github.com/intel/llvm/pull/15225
TODO for future patches:
- During spec review need to decide whether only FunctionCall or Atomic
instructions can be decorated and if not - move the code around adding
handling for other instructions;
- Handle optional string metadata;
- Handle LLVM atomic instructions;
- Handle SPIR-V friendly atomic calls returning via sret argument.
Signed-off-by: Sidorov, Dmitry <dmitry.sidorov at intel.com>
---
llvm/docs/SPIRVUsage.rst | 6 ++
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 3 +
llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 3 +
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 14 ++++
llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp | 2 +
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 54 ++++++++++++
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 14 +++-
llvm/lib/Target/SPIRV/SPIRVInstrInfo.h | 1 +
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 8 ++
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 38 +++++++--
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 9 ++
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h | 1 +
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 14 +++-
.../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 6 ++
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 71 ++++++++++++++++
llvm/lib/Target/SPIRV/SPIRVUtils.h | 8 ++
.../alias-barrier.ll | 18 ++++
.../alias-empty-md.ll | 26 ++++++
.../alias-load-store-atomic.ll | 34 ++++++++
.../alias-load-store-struct.ll | 25 ++++++
.../alias-load-store.ll | 65 +++++++++++++++
.../alias-masked-load-store.ll | 83 +++++++++++++++++++
22 files changed, 494 insertions(+), 9 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 93c53a04bc447..bed448ab7a383 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -173,6 +173,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
- Adds decorations that can be applied to global (module scope) variables to help code generation for FPGA devices.
* - ``SPV_INTEL_media_block_io``
- Adds additional subgroup block read and write functionality that allow applications to flexibly specify the width and height of the block to read from or write to a 2D image.
+ * - ``SPV_INTEL_memory_access_aliasing``
+ - Adds instructions and decorations to specify memory access aliasing, similar to alias.scope and noalias LLVM metadata.
* - ``SPV_INTEL_optnone``
- Adds OptNoneINTEL value for Function Control mask that indicates a request to not optimize the function.
* - ``SPV_INTEL_split_barrier``
@@ -301,6 +303,10 @@ SPIR-V backend, along with their descriptions and argument details.
- None
- `[Type, Metadata]`
- Assigns decoration to values by associating them with metadatas. Not emitted directly but used to support SPIR-V representation in LLVM IR.
+ * - `int_spv_assign_aliasing_decoration`
+ - None
+ - `[Type, 32-bit Integer, Metadata]`
+ - Assigns one of two memory aliasing decorations (specified by the second argument) to instructions using original alasing list metadata node. Not emitted directly but used to support SPIR-V representation in LLVM IR.
* - `int_spv_track_constant`
- Type
- `[Type, Metadata]`
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 38910ee263ee3..0c91d22fea1fa 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -137,4 +137,7 @@ let TargetPrefix = "spv" in {
def int_spv_resource_store_typedbuffer
: DefaultAttrsIntrinsic<[], [llvm_any_ty, llvm_i32_ty, llvm_anyvector_ty]>;
+ // Memory aliasing intrinsics
+ def int_spv_assign_aliasing_decoration : Intrinsic<[], [llvm_any_ty, llvm_i32_ty, llvm_metadata_ty], [ImmArg<ArgIndex<1>>]>;
+
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 8b06a7197a11e..086145ee69fc0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -611,6 +611,9 @@ void SPIRVAsmPrinter::outputModuleSections() {
outputModuleSection(SPIRV::MB_DebugNames);
// 7c. Debug: all OpModuleProcessed instructions.
outputModuleSection(SPIRV::MB_DebugModuleProcessed);
+ // xxx. SPV_INTEL_memory_access_aliasing instructions go before 8.
+ // "All annotation instructions"
+ outputModuleSection(SPIRV::MB_AliasingInsts);
// 8. All annotation instructions (all decorations).
outputAnnotations(*M);
// 9. All type declarations (OpTypeXXX instructions), all constant
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index 78f6b188c45c1..d5d084da91901 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -683,6 +683,20 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
return false;
MIB.addUse(Arg.Regs[0]);
}
+
+ if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing)) {
+ // Process aliasing metadata.
+ const CallBase *CI = Info.CB;
+ if (CI && CI->hasMetadata()) {
+ if (MDNode *MD = CI->getMetadata(LLVMContext::MD_alias_scope))
+ buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
+ SPIRV::Decoration::AliasScopeINTEL, MD);
+ if (MDNode *MD = CI->getMetadata(LLVMContext::MD_noalias))
+ buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
+ SPIRV::Decoration::NoAliasINTEL, MD);
+ }
+ }
+
return MIB.constrainAllUses(MIRBuilder.getTII(), *ST->getRegisterInfo(),
*ST->getRegBankInfo());
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 333e0131ac228..8d1714932c3c6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -53,6 +53,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_INTEL_subgroups},
{"SPV_INTEL_media_block_io",
SPIRV::Extension::Extension::SPV_INTEL_media_block_io},
+ {"SPV_INTEL_memory_access_aliasing",
+ SPIRV::Extension::Extension::SPV_INTEL_memory_access_aliasing},
{"SPV_INTEL_joint_matrix",
SPIRV::Extension::Extension::SPV_INTEL_joint_matrix},
{"SPV_KHR_uniform_group_instructions",
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 5dfba8427258f..854797c687124 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -172,6 +172,7 @@ class SPIRVEmitIntrinsics
unsigned OperandToReplace,
IRBuilder<> &B);
void insertPtrCastOrAssignTypeInstr(Instruction *I, IRBuilder<> &B);
+ bool shouldTryToAddMemAliasingDecoration(Instruction *Inst);
void insertSpirvDecorations(Instruction *I, IRBuilder<> &B);
void processGlobalValue(GlobalVariable &GV, IRBuilder<> &B);
void processParamTypes(Function *F, IRBuilder<> &B);
@@ -1249,6 +1250,7 @@ void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
llvm_unreachable("illegal aggregate intrinsic user");
}
}
+ New->copyMetadata(*Old);
Old->eraseFromParent();
}
@@ -1832,6 +1834,7 @@ Instruction *SPIRVEmitIntrinsics::visitStoreInst(StoreInst &I) {
Intrinsic::spv_store, {I.getValueOperand()->getType(), PtrOp->getType()},
{I.getValueOperand(), PtrOp, B.getInt16(Flags),
B.getInt8(I.getAlign().value())});
+ NewI->copyMetadata(I);
I.eraseFromParent();
return NewI;
}
@@ -2034,6 +2037,37 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
}
}
+bool SPIRVEmitIntrinsics::shouldTryToAddMemAliasingDecoration(
+ Instruction *Inst) {
+ const SPIRVSubtarget *STI = TM->getSubtargetImpl(*Inst->getFunction());
+ if (!STI->canUseExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing))
+ return false;
+ // Add aliasing decorations to internal load and store intrinsics
+ // and atomic instructions, skipping atomic store as it won't have ID to
+ // attach the decoration.
+ CallInst *CI = dyn_cast<CallInst>(Inst);
+ if (!CI)
+ return false;
+ if (Function *Fun = CI->getCalledFunction()) {
+ if (Fun->isIntrinsic()) {
+ switch (Fun->getIntrinsicID()) {
+ case Intrinsic::spv_load:
+ case Intrinsic::spv_store:
+ return true;
+ default:
+ return false;
+ }
+ }
+ std::string Name = getOclOrSpirvBuiltinDemangledName(Fun->getName());
+ const std::string Prefix = "__spirv_Atomic";
+ const bool IsAtomic = Name.find(Prefix) == 0;
+
+ if (!Fun->getReturnType()->isVoidTy() && IsAtomic)
+ return true;
+ }
+ return false;
+}
+
void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
IRBuilder<> &B) {
if (MDNode *MD = I->getMetadata("spirv.Decorations")) {
@@ -2041,6 +2075,26 @@ void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
B.CreateIntrinsic(Intrinsic::spv_assign_decoration, {I->getType()},
{I, MetadataAsValue::get(I->getContext(), MD)});
}
+ // Lower alias.scope/noalias metadata
+ {
+ auto processMemAliasingDecoration = [&](unsigned Kind) {
+ if (MDNode *AliasListMD = I->getMetadata(Kind)) {
+ if (shouldTryToAddMemAliasingDecoration(I)) {
+ uint32_t Dec = Kind == LLVMContext::MD_alias_scope
+ ? SPIRV::Decoration::AliasScopeINTEL
+ : SPIRV::Decoration::NoAliasINTEL;
+ SmallVector<Value *, 3> Args = {
+ I, ConstantInt::get(B.getInt32Ty(), Dec),
+ MetadataAsValue::get(I->getContext(), AliasListMD)};
+ setInsertPointAfterDef(B, I);
+ B.CreateIntrinsic(Intrinsic::spv_assign_aliasing_decoration,
+ {I->getType()}, {Args});
+ }
+ }
+ };
+ processMemAliasingDecoration(LLVMContext::MD_alias_scope);
+ processMemAliasingDecoration(LLVMContext::MD_noalias);
+ }
}
void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index 49b6b3bbb6cef..a22390b89f05f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -96,6 +96,17 @@ bool SPIRVInstrInfo::isDecorationInstr(const MachineInstr &MI) const {
}
}
+bool SPIRVInstrInfo::isAliasingInstr(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ case SPIRV::OpAliasDomainDeclINTEL:
+ case SPIRV::OpAliasScopeDeclINTEL:
+ case SPIRV::OpAliasScopeListDeclINTEL:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool SPIRVInstrInfo::isHeaderInstr(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case SPIRV::OpCapability:
@@ -114,7 +125,8 @@ bool SPIRVInstrInfo::isHeaderInstr(const MachineInstr &MI) const {
case SPIRV::OpModuleProcessed:
return true;
default:
- return isTypeDeclInstr(MI) || isConstantInstr(MI) || isDecorationInstr(MI);
+ return isTypeDeclInstr(MI) || isConstantInstr(MI) ||
+ isDecorationInstr(MI) || isAliasingInstr(MI);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
index 4e5059b4b8891..8fea120fcaf71 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
@@ -34,6 +34,7 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
bool isInlineAsmDefInstr(const MachineInstr &MI) const;
bool isTypeDeclInstr(const MachineInstr &MI) const;
bool isDecorationInstr(const MachineInstr &MI) const;
+ bool isAliasingInstr(const MachineInstr &MI) const;
bool canUseFastMathFlags(const MachineInstr &MI) const;
bool canUseNSW(const MachineInstr &MI) const;
bool canUseNUW(const MachineInstr &MI) const;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index 5e9a9bd145bca..a8f862271dbab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -948,3 +948,11 @@ def OpConvertHandleToSamplerINTEL: Op<6530, (outs ID:$res), (ins TYPE:$type, ID:
"$res = OpConvertHandleToSamplerINTEL $type $operand">;
def OpConvertHandleToSampledImageINTEL: Op<6531, (outs ID:$res), (ins TYPE:$type, ID:$operand),
"$res = OpConvertHandleToSampledImageINTEL $type $operand">;
+
+// SPV_INTEL_memory_access_aliasing
+def OpAliasDomainDeclINTEL: Op<5911, (outs ID:$res), (ins variable_ops),
+ "$res = OpAliasDomainDeclINTEL">;
+def OpAliasScopeDeclINTEL: Op<5912, (outs ID:$res), (ins ID:$AliasDomain, variable_ops),
+ "$res = OpAliasScopeDeclINTEL $AliasDomain">;
+def OpAliasScopeListDeclINTEL: Op<5913, (outs ID:$res), (ins variable_ops),
+ "$res = OpAliasScopeListDeclINTEL">;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index e7d8fe5bd8015..31a1aeca23f8a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1020,7 +1020,8 @@ bool SPIRVInstructionSelector::selectBitcast(Register ResVReg,
}
static void addMemoryOperands(MachineMemOperand *MemOp,
- MachineInstrBuilder &MIB) {
+ MachineInstrBuilder &MIB,
+ MachineIRBuilder &MIRBuilder) {
uint32_t SpvMemOp = static_cast<uint32_t>(SPIRV::MemoryOperand::None);
if (MemOp->isVolatile())
SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
@@ -1029,10 +1030,33 @@ static void addMemoryOperands(MachineMemOperand *MemOp,
if (MemOp->getAlign().value())
SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned);
+ [[maybe_unused]] MachineInstr *AliasList = nullptr;
+ [[maybe_unused]] MachineInstr *NoAliasList = nullptr;
+ const SPIRVSubtarget *ST =
+ static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
+ if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing)) {
+ if (auto *MD = MemOp->getAAInfo().Scope) {
+ AliasList = getOrAddMemAliasingINTELInst(MIRBuilder, MD);
+ if (AliasList)
+ SpvMemOp |=
+ static_cast<uint32_t>(SPIRV::MemoryOperand::AliasScopeINTELMask);
+ }
+ if (auto *MD = MemOp->getAAInfo().NoAlias) {
+ NoAliasList = getOrAddMemAliasingINTELInst(MIRBuilder, MD);
+ if (NoAliasList)
+ SpvMemOp |=
+ static_cast<uint32_t>(SPIRV::MemoryOperand::NoAliasINTELMask);
+ }
+ }
+
if (SpvMemOp != static_cast<uint32_t>(SPIRV::MemoryOperand::None)) {
MIB.addImm(SpvMemOp);
if (SpvMemOp & static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned))
MIB.addImm(MemOp->getAlign().value());
+ if (AliasList)
+ MIB.addUse(AliasList->getOperand(0).getReg());
+ if (NoAliasList)
+ MIB.addUse(NoAliasList->getOperand(0).getReg());
}
}
@@ -1081,7 +1105,8 @@ bool SPIRVInstructionSelector::selectLoad(Register ResVReg,
TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
} else {
- addMemoryOperands(*I.memoperands_begin(), MIB);
+ MachineIRBuilder MIRBuilder(I);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
}
return MIB.constrainAllUses(TII, TRI, RBI);
}
@@ -1123,7 +1148,8 @@ bool SPIRVInstructionSelector::selectStore(MachineInstr &I) const {
TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
} else {
- addMemoryOperands(*I.memoperands_begin(), MIB);
+ MachineIRBuilder MIRBuilder(I);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
}
return MIB.constrainAllUses(TII, TRI, RBI);
}
@@ -1200,8 +1226,10 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
.addUse(I.getOperand(0).getReg())
.addUse(SrcReg)
.addUse(I.getOperand(2).getReg());
- if (I.getNumMemOperands())
- addMemoryOperands(*I.memoperands_begin(), MIB);
+ if (I.getNumMemOperands()) {
+ MachineIRBuilder MIRBuilder(I);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
+ }
Result &= MIB.constrainAllUses(TII, TRI, RBI);
if (ResVReg.isValid() && ResVReg != MIB->getOperand(0).getReg())
Result &= BuildCOPY(ResVReg, MIB->getOperand(0).getReg(), I);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index fea3965dd8f2a..ea393a64351f7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -567,6 +567,8 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
} else if (OpCode == SPIRV::OpEntryPoint) {
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
+ } else if (TII->isAliasingInstr(MI)) {
+ collectOtherInstr(MI, MAI, SPIRV::MB_AliasingInsts, IS);
} else if (TII->isDecorationInstr(MI)) {
collectOtherInstr(MI, MAI, SPIRV::MB_Annotations, IS);
collectFuncNames(MI, &*F);
@@ -1251,6 +1253,13 @@ void addInstrRequirements(const MachineInstr &MI,
}
break;
}
+ case SPIRV::OpAliasDomainDeclINTEL:
+ case SPIRV::OpAliasScopeDeclINTEL:
+ case SPIRV::OpAliasScopeListDeclINTEL: {
+ Reqs.addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
+ Reqs.addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
+ break;
+ }
case SPIRV::OpBitReverse:
case SPIRV::OpBitFieldInsert:
case SPIRV::OpBitFieldSExtract:
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index 2b3599259a739..0beb4af1c99f6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -35,6 +35,7 @@ enum ModuleSectionType {
MB_DebugNames, // All OpName and OpMemberName intrs.
MB_DebugStrings, // All OpString intrs.
MB_DebugModuleProcessed, // All OpModuleProcessed instructions.
+ MB_AliasingInsts, // SPV_INTEL_memory_access_aliasing instructions.
MB_Annotations, // OpDecorate, OpMemberDecorate etc.
MB_TypeConstVars, // OpTypeXXX, OpConstantXXX, and global OpVariables.
MB_NonSemanticGlobalDI, // OpExtInst with e.g. DebugSource, DebugTypeBasic.
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 32f6af3d1440f..3da8e679cdeb1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -813,11 +813,19 @@ static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB) {
SmallVector<MachineInstr *, 10> ToErase;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
- if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_decoration))
+ if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_decoration) &&
+ !isSpvIntrinsic(MI, Intrinsic::spv_assign_aliasing_decoration))
continue;
MIB.setInsertPt(*MI.getParent(), MI.getNextNode());
- buildOpSpirvDecorations(MI.getOperand(1).getReg(), MIB,
- MI.getOperand(2).getMetadata());
+ if (isSpvIntrinsic(MI, Intrinsic::spv_assign_decoration)) {
+ buildOpSpirvDecorations(MI.getOperand(1).getReg(), MIB,
+ MI.getOperand(2).getMetadata());
+ } else {
+ buildMemAliasingOpDecorate(MI.getOperand(1).getReg(), MIB,
+ MI.getOperand(2).getImm(),
+ MI.getOperand(3).getMetadata());
+ }
+
ToErase.push_back(&MI);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index c7cb0a50752fe..a871518e2094c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -311,6 +311,7 @@ defm SPV_INTEL_joint_matrix : ExtensionOperand<114>;
defm SPV_INTEL_float_controls2 : ExtensionOperand<115>;
defm SPV_INTEL_bindless_images : ExtensionOperand<116>;
defm SPV_INTEL_long_composites : ExtensionOperand<117>;
+defm SPV_INTEL_memory_access_aliasing : ExtensionOperand<118>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -509,6 +510,7 @@ defm FloatingPointModeINTEL : CapabilityOperand<5583, 0, 0, [SPV_INTEL_float_con
defm FunctionFloatControlINTEL : CapabilityOperand<5821, 0, 0, [SPV_INTEL_float_controls2], []>;
defm LongCompositesINTEL : CapabilityOperand<6089, 0, 0, [SPV_INTEL_long_composites], []>;
defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
+defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory_access_aliasing], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
@@ -1257,6 +1259,8 @@ defm ImplementInRegisterMapINTEL : DecorationOperand<6191, 0, 0, [], [GlobalVari
defm FunctionRoundingModeINTEL : DecorationOperand<5822, 0, 0, [], [FunctionFloatControlINTEL]>;
defm FunctionDenormModeINTEL : DecorationOperand<5823, 0, 0, [], [FunctionFloatControlINTEL]>;
defm FunctionFloatingPointModeINTEL : DecorationOperand<6080, 0, 0, [], [FunctionFloatControlINTEL]>;
+defm AliasScopeINTEL : DecorationOperand<5914, 0, 0, [], [MemoryAccessAliasingINTEL]>;
+defm NoAliasINTEL : DecorationOperand<5915, 0, 0, [], [MemoryAccessAliasingINTEL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define BuiltIn enum values and at the same time
@@ -1529,6 +1533,8 @@ defm Nontemporal : MemoryOperandOperand<0x4, 0, 0, [], []>;
defm MakePointerAvailableKHR : MemoryOperandOperand<0x8, 0, 0, [], [VulkanMemoryModelKHR]>;
defm MakePointerVisibleKHR : MemoryOperandOperand<0x10, 0, 0, [], [VulkanMemoryModelKHR]>;
defm NonPrivatePointerKHR : MemoryOperandOperand<0x20, 0, 0, [], [VulkanMemoryModelKHR]>;
+defm AliasScopeINTELMask : MemoryOperandOperand<0x10000, 0, 0, [], [MemoryAccessAliasingINTEL]>;
+defm NoAliasINTELMask : MemoryOperandOperand<0x20000, 0, 0, [], [MemoryAccessAliasingINTEL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Scope enum values and at the same time
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index ddc66f98829a9..7ec7c14dbeb84 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -28,6 +28,8 @@
#include <vector>
namespace llvm {
+// map of aliasing decorations to aliasing metadata
+std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
// The following functions are used to add these string literals as a series of
// 32-bit integer operands with the correct format, and unpack them if necessary
@@ -174,6 +176,75 @@ void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
}
}
+// Aliasing list MD contains several scope MD nodes whithin it. Each scope MD
+// has a selfreference and an extra MD node for aliasing domain and also it
+// can contain an optional string operand. Domain MD contains a self-reference
+// with an optional string operand. Here we unfold the list, creating SPIR-V
+// aliasing instructions.
+// TODO: add support for an optional string operand.
+MachineInstr *getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder,
+ const MDNode *AliasingListMD) {
+ if (AliasingListMD->getNumOperands() == 0)
+ return nullptr;
+ if (auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
+ return L->second;
+
+ SmallVector<MachineInstr *> ScopeList;
+ MachineRegisterInfo *MRI = MIRBuilder.getMRI();
+ for (const MDOperand &MDListOp : AliasingListMD->operands()) {
+ if (MDNode *ScopeMD = dyn_cast<MDNode>(MDListOp)) {
+ if (ScopeMD->getNumOperands() < 2)
+ return nullptr;
+ MDNode *DomainMD = dyn_cast<MDNode>(ScopeMD->getOperand(1));
+ if (!DomainMD)
+ return nullptr;
+ auto *Domain = [&] {
+ auto D = AliasInstMDMap.find(DomainMD);
+ if (D != AliasInstMDMap.end())
+ return D->second;
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpAliasDomainDeclINTEL).addDef(Ret);
+ return MIB.getInstr();
+ }();
+ AliasInstMDMap.insert(std::make_pair(DomainMD, Domain));
+ auto *Scope = [&] {
+ auto S = AliasInstMDMap.find(ScopeMD);
+ if (S != AliasInstMDMap.end())
+ return S->second;
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpAliasScopeDeclINTEL)
+ .addDef(Ret)
+ .addUse(Domain->getOperand(0).getReg());
+ return MIB.getInstr();
+ }();
+ AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
+ ScopeList.push_back(Scope);
+ }
+ }
+
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpAliasScopeListDeclINTEL).addDef(Ret);
+ for (auto *Scope : ScopeList)
+ MIB.addUse(Scope->getOperand(0).getReg());
+ auto List = MIB.getInstr();
+ AliasInstMDMap.insert(std::make_pair(AliasingListMD, List));
+ return List;
+}
+
+void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
+ uint32_t Dec, const MDNode *AliasingListMD) {
+ MachineInstr *AliasList =
+ getOrAddMemAliasingINTELInst(MIRBuilder, AliasingListMD);
+ if (!AliasList)
+ return;
+ MIRBuilder.buildInstr(SPIRV::OpDecorate)
+ .addUse(Reg)
+ .addImm(Dec)
+ .addUse(AliasList->getOperand(0).getReg());
+}
+
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
MachineFunction *MF = I.getParent()->getParent();
MachineBasicBlock *MBB = &MF->front();
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 552adf2df7d17..301517fafa5a1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -148,6 +148,14 @@ void buildOpDecorate(Register Reg, MachineInstr &I, const SPIRVInstrInfo &TII,
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
const MDNode *GVarMD);
+// Add OpAliasDomainDeclINTEL, OpAliasScopeINTEL and OpAliasScopeListDeclINTEL
+// instructions.
+MachineInstr *getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder,
+ const MDNode *AliasingListMD);
+
+void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
+ uint32_t Dec, const MDNode *GVarMD);
+
// Return a valid position for the OpVariable instruction inside a function,
// i.e., at the beginning of the first block of the function.
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I);
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
new file mode 100644
index 0000000000000..55171685bee64
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
@@ -0,0 +1,18 @@
+; The test checks if the backend won't crash
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+
+; CHECK: OpControlBarrier
+; CHECK-NOT: MemoryAccessAliasingINTEL
+
+define spir_kernel void @barrier_simple()
+{
+ tail call spir_func void @_Z22__spirv_ControlBarrierjjj(i32 2, i32 2, i32 272), !noalias !1
+ ret void
+}
+
+declare dso_local spir_func void @_Z22__spirv_ControlBarrierjjj(i32, i32, i32)
+
+!1 = !{!2}
+!2 = distinct !{!2, !3}
+!3 = distinct !{!3}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
new file mode 100644
index 0000000000000..5c546898de9be
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
@@ -0,0 +1,26 @@
+; Check that the backend doesn't fail on a translation of empty aliasing
+; metadata
+
+; Check aliasing information translation on load and store
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+
+; CHECK-NOT: MemoryAccessAliasingINTEL
+; CHECK-NOT: SPV_INTEL_memory_access_aliasing
+; CHECK-NOT: OpAliasDomainDeclINTEL
+; CHECK-NOT: OpAliasScopeDeclINTEL
+; CHECK-NOT: OpAliasScopeListDeclINTEL
+
+define dso_local spir_kernel void @foo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1, ptr addrspace(1) noalias %_arg_3) local_unnamed_addr {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = addrspacecast ptr addrspace(1) %_arg_3 to ptr addrspace(4)
+ %3 = load i32, ptr addrspace(4) %0, align 4, !alias.scope !1
+ %4 = load i32, ptr addrspace(4) %1, align 4, !alias.scope !1
+ %add.i = add nsw i32 %4, %3
+ store i32 %add.i, ptr addrspace(4) %2, align 4, !noalias !1
+ ret void
+}
+
+!1 = !{}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
new file mode 100644
index 0000000000000..82aded442773d
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
@@ -0,0 +1,34 @@
+; Check aliasing information translation on atomic load and store
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+
+; CHECK: OpCapability MemoryAccessAliasingINTEL
+; CHECK: OpExtension "SPV_INTEL_memory_access_aliasing"
+; CHECK: %[[#Domain1:]] = OpAliasDomainDeclINTEL
+; CHECK: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
+; CHECK: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
+; CHECK: OpDecorate %[[#Load:]] NoAliasINTEL %[[#List1]]
+; CHECK: %[[#Load:]] = OpAtomicLoad
+
+define spir_func i32 @test_load(ptr addrspace(4) %object) #0 {
+entry:
+ %0 = call spir_func i32 @_Z18__spirv_AtomicLoadPU3AS4iii(ptr addrspace(4) %object, i32 1, i32 16), !noalias !1
+ ret i32 %0
+}
+
+declare spir_func i32 @_Z18__spirv_AtomicLoadPU3AS4iii(ptr addrspace(4), i32, i32)
+
+define spir_func void @test_store(ptr addrspace(4) %object, ptr addrspace(4) %expected, i32 %desired) {
+entry:
+ call spir_func void @_Z19__spirv_AtomicStorePU3AS4iiii(ptr addrspace(4) %object, i32 1, i32 16, i32 %desired), !noalias !4
+ ret void
+}
+
+declare spir_func void @_Z19__spirv_AtomicStorePU3AS4iiii(ptr addrspace(4), i32, i32, i32)
+
+!1 = !{!2}
+!2 = distinct !{!2, !3}
+!3 = distinct !{!3}
+!4 = !{!5}
+!5 = distinct !{!5, !6}
+!6 = distinct !{!6}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
new file mode 100644
index 0000000000000..f2dd82616b05b
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
@@ -0,0 +1,25 @@
+; Test if alias scope metadata translates well for a load/store with structure object
+; type (special case as such lowering uses spv_load/store intrinsics)
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+
+; CHECK: OpCapability MemoryAccessAliasingINTEL
+; CHECK: OpExtension "SPV_INTEL_memory_access_aliasing"
+; CHECK: %[[#Domain:]] = OpAliasDomainDeclINTEL
+; CHECK: %[[#Scope:]] = OpAliasScopeDeclINTEL %[[#Domain]]
+; CHECK: %[[#List:]] = OpAliasScopeListDeclINTEL %[[#Scope]]
+; CHECK: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List]]
+; CHECK: OpStore %[[#]] %[[#]] Aligned|NoAliasINTELMask 4 %[[#List]]
+
+define dso_local spir_kernel void @foo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1) {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = load {i32, i32}, ptr addrspace(4) %0, align 4, !alias.scope !1
+ store {i32, i32} %2, ptr addrspace(4) %1, align 4, !noalias !1
+ ret void
+}
+
+!1 = !{!2}
+!2 = distinct !{!2, !3, !"foo: %this"}
+!3 = distinct !{!3, !"foo"}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
new file mode 100644
index 0000000000000..464b7065a0beb
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
@@ -0,0 +1,65 @@
+; Check aliasing information translation on load and store
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
+
+; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
+; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
+; CHECK-EXT: %[[#Domain1:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
+; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
+; CHECK-EXT: %[[#Domain2:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain2]]
+; CHECK-EXT: %[[#List2:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
+; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+
+; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List2]]
+; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask|NoAliasINTELMask 4 %[[#List2]] %[[#List1]]
+; CHECK-EXT: OpStore %[[#]] %[[#]] Aligned|NoAliasINTELMask 4 %[[#List2]]
+
+; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List3]]
+; CHECK-EXT: %[[#]] = OpLoad %[[#]] %[[#]] Aligned|AliasScopeINTELMask 4 %[[#List3]]
+; CHECK-EXT: OpStore %[[#]] %[[#]] Aligned|NoAliasINTELMask 4 %[[#List3]]
+
+; CHECK-NO-EXT-NOT: MemoryAccessAliasingINTEL
+; CHECK-NO-EXT-NOT: SPV_INTEL_memory_access_aliasing
+; CHECK-NO-EXT-NOT: OpAliasDomainDeclINTEL
+; CHECK-NO-EXT-NOT: OpAliasScopeDeclINTEL
+; CHECK-NO-EXT-NOT: OpAliasScopeListDeclINTEL
+
+define dso_local spir_kernel void @foo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1, ptr addrspace(1) noalias %_arg_3) {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = addrspacecast ptr addrspace(1) %_arg_3 to ptr addrspace(4)
+ %3 = load i32, ptr addrspace(4) %0, align 4, !alias.scope !1
+ %4 = load i32, ptr addrspace(4) %1, align 4, !alias.scope !1, !noalias !7
+ %add.i = add nsw i32 %4, %3
+ store i32 %add.i, ptr addrspace(4) %2, align 4, !noalias !1
+ ret void
+}
+
+define dso_local spir_kernel void @boo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1, ptr addrspace(1) noalias %_arg_3, i32 %_arg_5) {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = addrspacecast ptr addrspace(1) %_arg_3 to ptr addrspace(4)
+ %3 = load i32, ptr addrspace(4) %0, align 4, !alias.scope !4
+ %4 = load i32, ptr addrspace(4) %1, align 4, !alias.scope !4
+ %add.i = add i32 %3, %_arg_5
+ %add3.i = add i32 %add.i, %4
+ store i32 %add3.i, ptr addrspace(4) %2, align 4, !noalias !4
+ ret void
+}
+
+!1 = !{!2}
+!2 = distinct !{!2, !3, !"foo: %this"}
+!3 = distinct !{!3, !"foo"}
+!4 = !{!5}
+!5 = distinct !{!5, !6, !"boo: %this"}
+!6 = distinct !{!6, !"boo"}
+!7 = !{!8}
+!8 = distinct !{!8, !9, !"foo: %this"}
+!9 = distinct !{!9, !"foo"}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
new file mode 100644
index 0000000000000..4586ed21069ff
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
@@ -0,0 +1,83 @@
+; Check aliasing information translation on function calls
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
+
+; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
+; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
+; CHECK-EXT: %[[#Domain1:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope1:]] = OpAliasScopeDeclINTEL %[[#Domain1]]
+; CHECK-EXT: %[[#List1:]] = OpAliasScopeListDeclINTEL %[[#Scope1]]
+; CHECK-EXT: %[[#Domain2:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain2]]
+; CHECK-EXT: %[[#List2:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+; CHECK-EXT: %[[#Domain3:]] = OpAliasDomainDeclINTEL
+; CHECK-EXT: %[[#Scope2:]] = OpAliasScopeDeclINTEL %[[#Domain3]]
+; CHECK-EXT: %[[#List3:]] = OpAliasScopeListDeclINTEL %[[#Scope2]]
+; CHECK-EXT: OpDecorate %[[#Fun1:]] AliasScopeINTEL %[[#List1]]
+; CHECK-EXT: OpDecorate %[[#Fun2:]] AliasScopeINTEL %[[#List1]]
+; CHECK-EXT: OpDecorate %[[#Fun2]] NoAliasINTEL %[[#List2]]
+; CHECK-EXT: OpDecorate %[[#Fun3:]] NoAliasINTEL %[[#List1]]
+; CHECK-EXT: OpDecorate %[[#Fun4:]] AliasScopeINTEL %[[#List3]]
+; CHECK-EXT: OpDecorate %[[#Fun5:]] AliasScopeINTEL %[[#List3]]
+; CHECK-EXT: OpDecorate %[[#Fun6:]] NoAliasINTEL %[[#List3]]
+; CHECK-EXT: %[[#Fun1]] = OpFunctionCall
+; CHECK-EXT: %[[#Fun2]] = OpFunctionCall
+; CHECK-EXT: %[[#Fun3]] = OpFunctionCall
+; CHECK-EXT: %[[#Fun4]] = OpFunctionCall
+; CHECK-EXT: %[[#Fun5]] = OpFunctionCall
+; CHECK-EXT: %[[#Fun6]] = OpFunctionCall
+
+; CHECK-NO-EXT-NOT: MemoryAccessAliasingINTEL
+; CHECK-NO-EXT-NOT: SPV_INTEL_memory_access_aliasing
+; CHECK-NO-EXT-NOT: OpAliasDomainDeclINTEL
+; CHECK-NO-EXT-NOT: OpAliasScopeDeclINTEL
+; CHECK-NO-EXT-NOT: OpAliasScopeListDeclINTEL
+
+define dso_local spir_kernel void @foo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1, ptr addrspace(1) noalias %_arg_3) {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = addrspacecast ptr addrspace(1) %_arg_3 to ptr addrspace(4)
+ %3 = call i32 @wrappedload(ptr addrspace(4) %0), !alias.scope !1
+ %4 = call i32 @wrappedload(ptr addrspace(4) %1), !alias.scope !1, !noalias !7
+ %add.i = add nsw i32 %4, %3
+ call void @wrappedstore(i32 %add.i, ptr addrspace(4) %2), !noalias !1
+ ret void
+}
+
+define dso_local spir_kernel void @boo(ptr addrspace(1) noalias %_arg_, ptr addrspace(1) noalias %_arg_1, ptr addrspace(1) noalias %_arg_3, i32 %_arg_5) {
+entry:
+ %0 = addrspacecast ptr addrspace(1) %_arg_ to ptr addrspace(4)
+ %1 = addrspacecast ptr addrspace(1) %_arg_1 to ptr addrspace(4)
+ %2 = addrspacecast ptr addrspace(1) %_arg_3 to ptr addrspace(4)
+ %3 = call i32 @wrappedload(ptr addrspace(4) %0), !alias.scope !4
+ %4 = call i32 @wrappedload(ptr addrspace(4) %1), !alias.scope !4
+ %add.i = add i32 %3, %_arg_5
+ %add3.i = add i32 %add.i, %4
+ call void @wrappedstore(i32 %add3.i, ptr addrspace(4) %2), !noalias !4
+ ret void
+}
+
+define dso_local spir_func i32 @wrappedload(ptr addrspace(4) %0) {
+entry:
+ %1 = load i32, ptr addrspace(4) %0, align 4
+ ret i32 %1
+}
+
+; Function Attrs: norecurse nounwind readnone
+define dso_local spir_func void @wrappedstore(i32 %0, ptr addrspace(4) %1) {
+entry:
+ store i32 %0, ptr addrspace(4) %1, align 4
+ ret void
+}
+
+!1 = !{!2}
+!2 = distinct !{!2, !3, !"foo: %this"}
+!3 = distinct !{!3, !"foo"}
+!4 = !{!5}
+!5 = distinct !{!5, !6, !"boo: %this"}
+!6 = distinct !{!6, !"boo"}
+!7 = !{!8}
+!8 = distinct !{!8, !9, !"foo: %this"}
+!9 = distinct !{!9, !"foo"}
>From 94cecfe58785a30ab3216bf9a4829c4012957c39 Mon Sep 17 00:00:00 2001
From: "Sidorov, Dmitry" <dmitry.sidorov at intel.com>
Date: Tue, 4 Mar 2025 15:58:52 -0800
Subject: [PATCH 2/4] fix typo
Signed-off-by: Sidorov, Dmitry <dmitry.sidorov at intel.com>
---
llvm/docs/SPIRVUsage.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index bed448ab7a383..6a27e0efaec7f 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -306,7 +306,7 @@ SPIR-V backend, along with their descriptions and argument details.
* - `int_spv_assign_aliasing_decoration`
- None
- `[Type, 32-bit Integer, Metadata]`
- - Assigns one of two memory aliasing decorations (specified by the second argument) to instructions using original alasing list metadata node. Not emitted directly but used to support SPIR-V representation in LLVM IR.
+ - Assigns one of two memory aliasing decorations (specified by the second argument) to instructions using original aliasing metadata node. Not emitted directly but used to support SPIR-V representation in LLVM IR.
* - `int_spv_track_constant`
- Type
- `[Type, Metadata]`
>From b7591cfadac07ff1ff63508b823ee500596d7980 Mon Sep 17 00:00:00 2001
From: "Sidorov, Dmitry" <dmitry.sidorov at intel.com>
Date: Wed, 5 Mar 2025 13:59:11 -0800
Subject: [PATCH 3/4] apply suggestions
Signed-off-by: Sidorov, Dmitry <dmitry.sidorov at intel.com>
---
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 4 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 70 ++++++++++++++++++
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 8 +++
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 13 ++--
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 7 +-
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 71 -------------------
llvm/lib/Target/SPIRV/SPIRVUtils.h | 9 +--
.../alias-barrier.ll | 2 +-
.../alias-empty-md.ll | 2 +-
.../alias-load-store-atomic.ll | 2 +-
.../alias-load-store-struct.ll | 2 +-
.../alias-load-store.ll | 4 +-
.../alias-masked-load-store.ll | 4 +-
13 files changed, 101 insertions(+), 97 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index d5d084da91901..8a4ae87f41fdf 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -689,10 +689,10 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
const CallBase *CI = Info.CB;
if (CI && CI->hasMetadata()) {
if (MDNode *MD = CI->getMetadata(LLVMContext::MD_alias_scope))
- buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
+ GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
SPIRV::Decoration::AliasScopeINTEL, MD);
if (MDNode *MD = CI->getMetadata(LLVMContext::MD_noalias))
- buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
+ GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
SPIRV::Decoration::NoAliasINTEL, MD);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index abc49b05c247a..2a4baa3d4c017 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -1731,3 +1731,73 @@ LLT SPIRVGlobalRegistry::getRegType(SPIRVType *SpvType) const {
}
return LLT::scalar(64);
}
+
+// Aliasing list MD contains several scope MD nodes whithin it. Each scope MD
+// has a selfreference and an extra MD node for aliasing domain and also it
+// can contain an optional string operand. Domain MD contains a self-reference
+// with an optional string operand. Here we unfold the list, creating SPIR-V
+// aliasing instructions.
+// TODO: add support for an optional string operand.
+MachineInstr *SPIRVGlobalRegistry::getOrAddMemAliasingINTELInst(
+ MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD) {
+ if (AliasingListMD->getNumOperands() == 0)
+ return nullptr;
+ if (auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
+ return L->second;
+
+ SmallVector<MachineInstr *> ScopeList;
+ MachineRegisterInfo *MRI = MIRBuilder.getMRI();
+ for (const MDOperand &MDListOp : AliasingListMD->operands()) {
+ if (MDNode *ScopeMD = dyn_cast<MDNode>(MDListOp)) {
+ if (ScopeMD->getNumOperands() < 2)
+ return nullptr;
+ MDNode *DomainMD = dyn_cast<MDNode>(ScopeMD->getOperand(1));
+ if (!DomainMD)
+ return nullptr;
+ auto *Domain = [&] {
+ auto D = AliasInstMDMap.find(DomainMD);
+ if (D != AliasInstMDMap.end())
+ return D->second;
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpAliasDomainDeclINTEL).addDef(Ret);
+ return MIB.getInstr();
+ }();
+ AliasInstMDMap.insert(std::make_pair(DomainMD, Domain));
+ auto *Scope = [&] {
+ auto S = AliasInstMDMap.find(ScopeMD);
+ if (S != AliasInstMDMap.end())
+ return S->second;
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpAliasScopeDeclINTEL)
+ .addDef(Ret)
+ .addUse(Domain->getOperand(0).getReg());
+ return MIB.getInstr();
+ }();
+ AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
+ ScopeList.push_back(Scope);
+ }
+ }
+
+ const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpAliasScopeListDeclINTEL).addDef(Ret);
+ for (auto *Scope : ScopeList)
+ MIB.addUse(Scope->getOperand(0).getReg());
+ auto List = MIB.getInstr();
+ AliasInstMDMap.insert(std::make_pair(AliasingListMD, List));
+ return List;
+}
+
+void SPIRVGlobalRegistry::buildMemAliasingOpDecorate(
+ Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec,
+ const MDNode *AliasingListMD) {
+ MachineInstr *AliasList =
+ getOrAddMemAliasingINTELInst(MIRBuilder, AliasingListMD);
+ if (!AliasList)
+ return;
+ MIRBuilder.buildInstr(SPIRV::OpDecorate)
+ .addUse(Reg)
+ .addImm(Dec)
+ .addUse(AliasList->getOperand(0).getReg());
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 0c94ec4df97f5..9f6530805f86b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -92,6 +92,9 @@ class SPIRVGlobalRegistry {
// Maps OpVariable and OpFunction-related v-regs to its LLVM IR definition.
DenseMap<std::pair<const MachineFunction *, Register>, const Value *> Reg2GO;
+ // map of aliasing decorations to aliasing metadata
+std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
+
// Add a new OpTypeXXX instruction without checking for duplicates.
SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AQ =
@@ -620,6 +623,11 @@ class SPIRVGlobalRegistry {
const TargetRegisterClass *getRegClass(SPIRVType *SpvType) const;
LLT getRegType(SPIRVType *SpvType) const;
+
+ MachineInstr *getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder,
+ const MDNode *AliasingListMD);
+ void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
+ uint32_t Dec, const MDNode *GVarMD);
};
} // end namespace llvm
#endif // LLLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 31a1aeca23f8a..f4a73242660e5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1021,7 +1021,8 @@ bool SPIRVInstructionSelector::selectBitcast(Register ResVReg,
static void addMemoryOperands(MachineMemOperand *MemOp,
MachineInstrBuilder &MIB,
- MachineIRBuilder &MIRBuilder) {
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry &GR) {
uint32_t SpvMemOp = static_cast<uint32_t>(SPIRV::MemoryOperand::None);
if (MemOp->isVolatile())
SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
@@ -1036,13 +1037,13 @@ static void addMemoryOperands(MachineMemOperand *MemOp,
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing)) {
if (auto *MD = MemOp->getAAInfo().Scope) {
- AliasList = getOrAddMemAliasingINTELInst(MIRBuilder, MD);
+ AliasList = GR.getOrAddMemAliasingINTELInst(MIRBuilder, MD);
if (AliasList)
SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::AliasScopeINTELMask);
}
if (auto *MD = MemOp->getAAInfo().NoAlias) {
- NoAliasList = getOrAddMemAliasingINTELInst(MIRBuilder, MD);
+ NoAliasList = GR.getOrAddMemAliasingINTELInst(MIRBuilder, MD);
if (NoAliasList)
SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::NoAliasINTELMask);
@@ -1106,7 +1107,7 @@ bool SPIRVInstructionSelector::selectLoad(Register ResVReg,
addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
} else {
MachineIRBuilder MIRBuilder(I);
- addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder, GR);
}
return MIB.constrainAllUses(TII, TRI, RBI);
}
@@ -1149,7 +1150,7 @@ bool SPIRVInstructionSelector::selectStore(MachineInstr &I) const {
addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
} else {
MachineIRBuilder MIRBuilder(I);
- addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder, GR);
}
return MIB.constrainAllUses(TII, TRI, RBI);
}
@@ -1228,7 +1229,7 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
.addUse(I.getOperand(2).getReg());
if (I.getNumMemOperands()) {
MachineIRBuilder MIRBuilder(I);
- addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder);
+ addMemoryOperands(*I.memoperands_begin(), MIB, MIRBuilder, GR);
}
Result &= MIB.constrainAllUses(TII, TRI, RBI);
if (ResVReg.isValid() && ResVReg != MIB->getOperand(0).getReg())
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 3da8e679cdeb1..51d8d4a26b8fc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -809,7 +809,8 @@ static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR,
insertInlineAsmProcess(MF, GR, ST, MIRBuilder, ToProcess);
}
-static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB) {
+static void insertSpirvDecorations(MachineFunction &MF, SPIRVGlobalRegistry *GR,
+ MachineIRBuilder MIB) {
SmallVector<MachineInstr *, 10> ToErase;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
@@ -821,7 +822,7 @@ static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB) {
buildOpSpirvDecorations(MI.getOperand(1).getReg(), MIB,
MI.getOperand(2).getMetadata());
} else {
- buildMemAliasingOpDecorate(MI.getOperand(1).getReg(), MIB,
+ GR->buildMemAliasingOpDecorate(MI.getOperand(1).getReg(), MIB,
MI.getOperand(2).getImm(),
MI.getOperand(3).getMetadata());
}
@@ -1041,7 +1042,7 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
processInstrsWithTypeFolding(MF, GR, MIB);
removeImplicitFallthroughs(MF, MIB);
- insertSpirvDecorations(MF, MIB);
+ insertSpirvDecorations(MF, GR, MIB);
insertInlineAsm(MF, GR, ST, MIB);
selectOpBitcasts(MF, GR, MIB);
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 7ec7c14dbeb84..ddc66f98829a9 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -28,8 +28,6 @@
#include <vector>
namespace llvm {
-// map of aliasing decorations to aliasing metadata
-std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
// The following functions are used to add these string literals as a series of
// 32-bit integer operands with the correct format, and unpack them if necessary
@@ -176,75 +174,6 @@ void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
}
}
-// Aliasing list MD contains several scope MD nodes whithin it. Each scope MD
-// has a selfreference and an extra MD node for aliasing domain and also it
-// can contain an optional string operand. Domain MD contains a self-reference
-// with an optional string operand. Here we unfold the list, creating SPIR-V
-// aliasing instructions.
-// TODO: add support for an optional string operand.
-MachineInstr *getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder,
- const MDNode *AliasingListMD) {
- if (AliasingListMD->getNumOperands() == 0)
- return nullptr;
- if (auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
- return L->second;
-
- SmallVector<MachineInstr *> ScopeList;
- MachineRegisterInfo *MRI = MIRBuilder.getMRI();
- for (const MDOperand &MDListOp : AliasingListMD->operands()) {
- if (MDNode *ScopeMD = dyn_cast<MDNode>(MDListOp)) {
- if (ScopeMD->getNumOperands() < 2)
- return nullptr;
- MDNode *DomainMD = dyn_cast<MDNode>(ScopeMD->getOperand(1));
- if (!DomainMD)
- return nullptr;
- auto *Domain = [&] {
- auto D = AliasInstMDMap.find(DomainMD);
- if (D != AliasInstMDMap.end())
- return D->second;
- const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- auto MIB =
- MIRBuilder.buildInstr(SPIRV::OpAliasDomainDeclINTEL).addDef(Ret);
- return MIB.getInstr();
- }();
- AliasInstMDMap.insert(std::make_pair(DomainMD, Domain));
- auto *Scope = [&] {
- auto S = AliasInstMDMap.find(ScopeMD);
- if (S != AliasInstMDMap.end())
- return S->second;
- const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpAliasScopeDeclINTEL)
- .addDef(Ret)
- .addUse(Domain->getOperand(0).getReg());
- return MIB.getInstr();
- }();
- AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
- ScopeList.push_back(Scope);
- }
- }
-
- const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- auto MIB =
- MIRBuilder.buildInstr(SPIRV::OpAliasScopeListDeclINTEL).addDef(Ret);
- for (auto *Scope : ScopeList)
- MIB.addUse(Scope->getOperand(0).getReg());
- auto List = MIB.getInstr();
- AliasInstMDMap.insert(std::make_pair(AliasingListMD, List));
- return List;
-}
-
-void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
- uint32_t Dec, const MDNode *AliasingListMD) {
- MachineInstr *AliasList =
- getOrAddMemAliasingINTELInst(MIRBuilder, AliasingListMD);
- if (!AliasList)
- return;
- MIRBuilder.buildInstr(SPIRV::OpDecorate)
- .addUse(Reg)
- .addImm(Dec)
- .addUse(AliasList->getOperand(0).getReg());
-}
-
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
MachineFunction *MF = I.getParent()->getParent();
MachineBasicBlock *MBB = &MF->front();
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 301517fafa5a1..40bcca2486cff 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -148,13 +148,8 @@ void buildOpDecorate(Register Reg, MachineInstr &I, const SPIRVInstrInfo &TII,
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
const MDNode *GVarMD);
-// Add OpAliasDomainDeclINTEL, OpAliasScopeINTEL and OpAliasScopeListDeclINTEL
-// instructions.
-MachineInstr *getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder,
- const MDNode *AliasingListMD);
-
-void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
- uint32_t Dec, const MDNode *GVarMD);
+//void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
+// uint32_t Dec, const MDNode *GVarMD);
// Return a valid position for the OpVariable instruction inside a function,
// i.e., at the beginning of the first block of the function.
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
index 55171685bee64..51649288b7c62 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-barrier.ll
@@ -1,6 +1,6 @@
; The test checks if the backend won't crash
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
; CHECK: OpControlBarrier
; CHECK-NOT: MemoryAccessAliasingINTEL
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
index 5c546898de9be..d275d6c0ea77b 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-empty-md.ll
@@ -3,7 +3,7 @@
; Check aliasing information translation on load and store
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
; CHECK-NOT: MemoryAccessAliasingINTEL
; CHECK-NOT: SPV_INTEL_memory_access_aliasing
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
index 82aded442773d..e8f55dce97a07 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-atomic.ll
@@ -1,6 +1,6 @@
; Check aliasing information translation on atomic load and store
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
; CHECK: OpCapability MemoryAccessAliasingINTEL
; CHECK: OpExtension "SPV_INTEL_memory_access_aliasing"
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
index f2dd82616b05b..e37793bafb821 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store-struct.ll
@@ -1,7 +1,7 @@
; Test if alias scope metadata translates well for a load/store with structure object
; type (special case as such lowering uses spv_load/store intrinsics)
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s
; CHECK: OpCapability MemoryAccessAliasingINTEL
; CHECK: OpExtension "SPV_INTEL_memory_access_aliasing"
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
index 464b7065a0beb..7487deb7f69f1 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-load-store.ll
@@ -1,7 +1,7 @@
; Check aliasing information translation on load and store
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
index 4586ed21069ff..dd0987fdfe75d 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_memory_access_aliasing/alias-masked-load-store.ll
@@ -1,7 +1,7 @@
; Check aliasing information translation on function calls
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs --spirv-ext=+SPV_INTEL_memory_access_aliasing %s -o - | FileCheck %s --check-prefix=CHECK-EXT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXT
; CHECK-EXT: OpCapability MemoryAccessAliasingINTEL
; CHECK-EXT: OpExtension "SPV_INTEL_memory_access_aliasing"
>From c99f87abafa5452e385098662557d8bbeb2337c0 Mon Sep 17 00:00:00 2001
From: "Sidorov, Dmitry" <dmitry.sidorov at intel.com>
Date: Wed, 5 Mar 2025 14:11:44 -0800
Subject: [PATCH 4/4] format
Signed-off-by: Sidorov, Dmitry <dmitry.sidorov at intel.com>
---
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 4 ++--
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 2 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 2 +-
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 4 ++--
llvm/lib/Target/SPIRV/SPIRVUtils.h | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index b0b7e5e455c32..3039f975a4df2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -702,10 +702,10 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
if (CI && CI->hasMetadata()) {
if (MDNode *MD = CI->getMetadata(LLVMContext::MD_alias_scope))
GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
- SPIRV::Decoration::AliasScopeINTEL, MD);
+ SPIRV::Decoration::AliasScopeINTEL, MD);
if (MDNode *MD = CI->getMetadata(LLVMContext::MD_noalias))
GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,
- SPIRV::Decoration::NoAliasINTEL, MD);
+ SPIRV::Decoration::NoAliasINTEL, MD);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index a0340dba3d574..24f9912e40be5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -1828,7 +1828,7 @@ void SPIRVGlobalRegistry::buildMemAliasingOpDecorate(
.addImm(Dec)
.addUse(AliasList->getOperand(0).getReg());
}
- void SPIRVGlobalRegistry::replaceAllUsesWith(Value *Old, Value *New,
+void SPIRVGlobalRegistry::replaceAllUsesWith(Value *Old, Value *New,
bool DeleteOld) {
Old->replaceAllUsesWith(New);
updateIfExistDeducedElementType(Old, New, DeleteOld);
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index d2b2fe59f5e88..89599f17ef737 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -93,7 +93,7 @@ class SPIRVGlobalRegistry {
DenseMap<std::pair<const MachineFunction *, Register>, const Value *> Reg2GO;
// map of aliasing decorations to aliasing metadata
-std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
+ std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
// Add a new OpTypeXXX instruction without checking for duplicates.
SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 995231e25eea7..baacd58b28028 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -833,8 +833,8 @@ static void insertSpirvDecorations(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MI.getOperand(2).getMetadata());
} else {
GR->buildMemAliasingOpDecorate(MI.getOperand(1).getReg(), MIB,
- MI.getOperand(2).getImm(),
- MI.getOperand(3).getMetadata());
+ MI.getOperand(2).getImm(),
+ MI.getOperand(3).getMetadata());
}
ToErase.push_back(&MI);
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 13a28c1036e55..238636dbead1d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -148,8 +148,8 @@ void buildOpDecorate(Register Reg, MachineInstr &I, const SPIRVInstrInfo &TII,
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
const MDNode *GVarMD);
-//void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
-// uint32_t Dec, const MDNode *GVarMD);
+// void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
+// uint32_t Dec, const MDNode *GVarMD);
// Return a valid position for the OpVariable instruction inside a function,
// i.e., at the beginning of the first block of the function.
More information about the llvm-commits
mailing list