[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