[llvm-branch-commits] [llvm] [mlir] [IR] Make @llvm.memset prototype byte width dependent (PR #106537)

Sergei Barannikov via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat May 2 06:50:28 PDT 2026


https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106537

>From 37f8c63991c438df8c543286064da2b87083c3e9 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Thu, 1 Aug 2024 23:47:25 +0300
Subject: [PATCH] [IR] Make @llvm.memset prototype byte width dependent

This patch changes the type of the value argument of @llvm.memset and
similar intrinsics from i8 to iN, where N is the byte width specified
in data layout string.
Note that the argument still has fixed type (not overloaded), but type
checker will complain if the type does not match the byte width.

Ideally, the type of the argument would be dependent on the address
space of the pointer argument. It is easy to do this (and I did it
downstream as a PoC), but since data layout string doesn't currently
allow different byte widths for different address spaces, I refrained
from doing it now.
---
 llvm/include/llvm-c/Core.h                    |  2 +-
 llvm/include/llvm/IR/Intrinsics.h             |  9 ++-
 llvm/include/llvm/IR/Intrinsics.td            | 13 ++--
 llvm/lib/AsmParser/LLParser.cpp               |  3 +-
 llvm/lib/IR/AutoUpgrade.cpp                   |  3 +-
 llvm/lib/IR/Core.cpp                          |  4 +-
 llvm/lib/IR/Function.cpp                      |  4 +-
 llvm/lib/IR/Intrinsics.cpp                    | 62 +++++++++++--------
 llvm/lib/IR/Verifier.cpp                      |  2 +-
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  3 +-
 .../NumericalStabilitySanitizer.cpp           |  2 +-
 .../LLVMIR/LLVMToLLVMIRTranslation.cpp        |  3 +-
 12 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 86f636c636783..8aa6738903082 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -3163,7 +3163,7 @@ LLVM_C_ABI LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
  *
  * @see llvm::Intrinsic::getType()
  */
-LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
+LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID,
                                             LLVMTypeRef *OverloadTypes,
                                             size_t OverloadCount);
 
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index a69f23e889318..027473f0a13df 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -23,6 +23,7 @@
 
 namespace llvm {
 
+class DataLayout;
 class Type;
 class FunctionType;
 class Function;
@@ -77,7 +78,7 @@ namespace Intrinsic {
                                              ArrayRef<Type *> OverloadTys);
 
   /// Return the function type for an intrinsic.
-  LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id,
+  LLVM_ABI FunctionType *getType(const Module *M, ID id,
                                  ArrayRef<Type *> OverloadTys = {});
 
   /// Returns true if the intrinsic can be overloaded.
@@ -161,6 +162,7 @@ namespace Intrinsic {
     enum IITDescriptorKind {
       // Concrete types. Additional qualifiers listed in comments.
       Void,
+      Byte,
       VarArg,
       MMX,
       Token,
@@ -269,7 +271,7 @@ namespace Intrinsic {
   /// Returns false if the given type matches with the constraints, true
   /// otherwise. If returning true, an error message to indicate the reason of
   /// mismatch is printed to \p OS.
-  LLVM_ABI bool matchIntrinsicSignature(FunctionType *FTy,
+  LLVM_ABI bool matchIntrinsicSignature(const DataLayout &DL, FunctionType *FTy,
                                         ArrayRef<IITDescriptor> &Infos,
                                         SmallVectorImpl<Type *> &OverloadTys,
                                         raw_ostream &OS);
@@ -281,7 +283,8 @@ namespace Intrinsic {
   /// Returns false if the given ID and function type combination is not a
   /// valid intrinsic call. Also prints the error message to indicate the reason
   /// of the mismatch to \p OS.
-  LLVM_ABI bool isSignatureValid(Intrinsic::ID ID, FunctionType *FT,
+  LLVM_ABI bool isSignatureValid(const DataLayout &DL, Intrinsic::ID ID,
+                                 FunctionType *FT,
                                  SmallVectorImpl<Type *> &OverloadTys,
                                  raw_ostream &OS = nulls());
 
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 2028d232084f9..7e85d368aacd7 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -361,6 +361,7 @@ def IIT_V6 : IIT_Vec<6, 50>;
 def IIT_V10 : IIT_Vec<10, 51>;
 def IIT_V2048 : IIT_Vec<2048, 52>;
 def IIT_V4096 : IIT_Vec<4096, 53>;
+def IIT_BYTE : IIT_Base<54>;
 }
 
 defvar IIT_all_FixedTypes = !filter(iit, IIT_all,
@@ -399,6 +400,10 @@ class LLVMType<ValueType vt> {
     !foreach(iit, IITs,     iit.Number));
 }
 
+class LLVMByteType : LLVMType<OtherVT> {
+  let Sig = [IIT_BYTE.Number];
+}
+
 class LLVMAnyType<ValueType vt> : LLVMType<vt> {
   int ArgCode = !cond(
     !eq(vt, Any)     : AnyKind.Any,
@@ -548,7 +553,7 @@ class LLVMVectorOfAnyPointersToElt<int oidx>
 
 
 def llvm_void_ty       : LLVMType<isVoid>;
-
+def llvm_byte_ty       : LLVMByteType;
 def llvm_any_ty        : LLVMAnyType<Any>;
 def llvm_anyint_ty     : LLVMAnyType<iAny>;
 def llvm_anyfloat_ty   : LLVMAnyType<fAny>;
@@ -1108,7 +1113,7 @@ def int_memmove : Intrinsic<[],
                              WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
                              ImmArg<ArgIndex<3>>]>;
 def int_memset  : Intrinsic<[],
-                            [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
+                            [llvm_anyptr_ty, llvm_byte_ty, llvm_anyint_ty,
                              llvm_i1_ty],
                             [IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
                              IntrNoFree, IntrNoCallback,
@@ -1121,7 +1126,7 @@ def int_memset  : Intrinsic<[],
 // The third argument (specifying the size) must be a constant.
 def int_memset_inline
     : Intrinsic<[],
-      [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i1_ty],
+      [llvm_anyptr_ty, llvm_byte_ty, llvm_anyint_ty, llvm_i1_ty],
       [IntrWriteMem, IntrArgMemOnly, IntrWillReturn, IntrNoFree, IntrNoCallback,
        NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>,
        ImmArg<ArgIndex<3>>]>;
@@ -2771,7 +2776,7 @@ def int_memmove_element_unordered_atomic
 
 // @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize)
 def int_memset_element_unordered_atomic
-    : Intrinsic<[], [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty],
+    : Intrinsic<[], [llvm_anyptr_ty, llvm_byte_ty, llvm_anyint_ty, llvm_i32_ty],
                 [IntrWriteMem, IntrArgMemOnly, IntrWillReturn, IntrNoSync,
                  NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>,
                  ImmArg<ArgIndex<3>>]>;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index dadbc510cdbd5..2af0f1622167c 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -346,7 +346,8 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
 
         SmallVector<Type *> OverloadTys;
         if (IID != Intrinsic::not_intrinsic &&
-            Intrinsic::isSignatureValid(IID, CB->getFunctionType(), OverloadTys,
+            Intrinsic::isSignatureValid(M->getDataLayout(), IID,
+                                        CB->getFunctionType(), OverloadTys,
                                         ErrorOS)) {
           U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
         } else {
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 433300ec63585..28a4e6efae09a 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1913,7 +1913,8 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
   if (Intrinsic::ID id = F->getIntrinsicID()) {
     // Only do this if the intrinsic signature is valid.
     SmallVector<Type *> OverloadTys;
-    if (Intrinsic::isSignatureValid(id, F->getFunctionType(), OverloadTys))
+    if (Intrinsic::isSignatureValid(F->getDataLayout(), id,
+                                    F->getFunctionType(), OverloadTys))
       F->setAttributes(
           Intrinsic::getAttributes(F->getContext(), id, F->getFunctionType()));
   }
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 5e6b03d01b6ba..8335a617ea9e3 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2568,12 +2568,12 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
   return Str.data();
 }
 
-LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
+LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID,
                                  LLVMTypeRef *OverloadTypes,
                                  size_t OverloadCount) {
   auto IID = llvm_map_to_intrinsic_id(ID);
   ArrayRef<Type *> OverloadTys(unwrap(OverloadTypes), OverloadCount);
-  return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, OverloadTys));
+  return wrap(llvm::Intrinsic::getType(unwrap(Mod), IID, OverloadTys));
 }
 
 char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *OverloadTypes,
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index de5d3f62efdc9..861e3e447ef84 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -508,7 +508,9 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
     // Don't set the attributes if the intrinsic signature is invalid. This
     // case will either be auto-upgraded or fail verification.
     SmallVector<Type *> OverloadTys;
-    if (!Intrinsic::isSignatureValid(IntID, Ty, OverloadTys))
+    assert(ParentModule);
+    if (!Intrinsic::isSignatureValid(ParentModule->getDataLayout(), IntID, Ty,
+                                     OverloadTys))
       return;
 
     setAttributes(Intrinsic::getAttributes(getContext(), IntID, Ty));
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index c5a0531a089b6..5c7e10fb2f3fc 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -173,9 +173,9 @@ static std::string getIntrinsicNameImpl(Intrinsic::ID Id,
   if (HasUnnamedType) {
     assert(M && "unnamed types need a module");
     if (!FT)
-      FT = Intrinsic::getType(M->getContext(), Id, OverloadTys);
+      FT = Intrinsic::getType(M, Id, OverloadTys);
     else
-      assert(FT == Intrinsic::getType(M->getContext(), Id, OverloadTys) &&
+      assert(FT == Intrinsic::getType(M, Id, OverloadTys) &&
              "Provided FunctionType must match arguments");
     return M->getUniqueIntrinsicName(Result, Id, FT);
   }
@@ -224,6 +224,9 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
   case IIT_Done:
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
     return;
+  case IIT_BYTE:
+    OutputTable.push_back(IITDescriptor::get(IITDescriptor::Byte, 0));
+    return;
   case IIT_VARARG:
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
     return;
@@ -494,8 +497,8 @@ void Intrinsic::getIntrinsicInfoTableEntries(
 }
 
 static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
-                             ArrayRef<Type *> OverloadTys,
-                             LLVMContext &Context) {
+                             ArrayRef<Type *> OverloadTys, LLVMContext &Context,
+                             const DataLayout &DL) {
   using namespace Intrinsic;
 
   IITDescriptor D = Infos.consume_front();
@@ -503,6 +506,8 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
   switch (D.Kind) {
   case IITDescriptor::Void:
     return Type::getVoidTy(Context);
+  case IITDescriptor::Byte:
+    return Type::getIntNTy(Context, DL.getByteWidth());
   case IITDescriptor::VarArg:
     return Type::getVoidTy(Context);
   case IITDescriptor::MMX:
@@ -531,14 +536,14 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
   case IITDescriptor::Integer:
     return IntegerType::get(Context, D.IntegerWidth);
   case IITDescriptor::Vector:
-    return VectorType::get(DecodeFixedType(Infos, OverloadTys, Context),
+    return VectorType::get(DecodeFixedType(Infos, OverloadTys, Context, DL),
                            D.VectorWidth);
   case IITDescriptor::Pointer:
     return PointerType::get(Context, D.PointerAddressSpace);
   case IITDescriptor::Struct: {
     SmallVector<Type *, 8> Elts;
     for (unsigned i = 0, e = D.StructNumElements; i != e; ++i)
-      Elts.push_back(DecodeFixedType(Infos, OverloadTys, Context));
+      Elts.push_back(DecodeFixedType(Infos, OverloadTys, Context, DL));
     return StructType::get(Context, Elts);
   }
   // For any overload kind or partially dependent type, substitute it with the
@@ -575,7 +580,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
         cast<VectorType>(OverloadTys[D.getOverloadIndex()]),
         D.getVectorDivisor());
   case IITDescriptor::SameVecWidth: {
-    Type *EltTy = DecodeFixedType(Infos, OverloadTys, Context);
+    Type *EltTy = DecodeFixedType(Infos, OverloadTys, Context, DL);
     Type *Ty = OverloadTys[D.getOverloadIndex()];
     if (auto *VTy = dyn_cast<VectorType>(Ty))
       return VectorType::get(EltTy, VTy->getElementCount());
@@ -597,17 +602,19 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
   llvm_unreachable("unhandled");
 }
 
-FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
+FunctionType *Intrinsic::getType(const Module *M, ID id,
                                  ArrayRef<Type *> OverloadTys) {
   SmallVector<IITDescriptor, 8> Table;
   getIntrinsicInfoTableEntries(id, Table);
 
   ArrayRef<IITDescriptor> TableRef = Table;
-  Type *ResultTy = DecodeFixedType(TableRef, OverloadTys, Context);
+  Type *ResultTy = DecodeFixedType(TableRef, OverloadTys, M->getContext(),
+                                   M->getDataLayout());
 
   SmallVector<Type *, 8> ArgTys;
   while (!TableRef.empty())
-    ArgTys.push_back(DecodeFixedType(TableRef, OverloadTys, Context));
+    ArgTys.push_back(DecodeFixedType(TableRef, OverloadTys, M->getContext(),
+                                     M->getDataLayout()));
 
   // VarArg intrinsics encode a void type as the last argument type. Detect that
   // and then drop the void argument.
@@ -775,7 +782,7 @@ Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
                                             ArrayRef<Type *> OverloadTys) {
   // There can never be multiple globals with the same name of different types,
   // because intrinsics must be a specific type.
-  FunctionType *FT = getType(M->getContext(), id, OverloadTys);
+  FunctionType *FT = getType(M, id, OverloadTys);
   return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FT);
 }
 
@@ -798,8 +805,8 @@ Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id, Type *RetTy,
 
   // Automatically determine the overloaded types.
   SmallVector<Type *, 4> OverloadTys;
-  [[maybe_unused]] bool MatchResult =
-      matchIntrinsicSignature(FTy, TableRef, OverloadTys, nulls());
+  [[maybe_unused]] bool MatchResult = matchIntrinsicSignature(
+      M->getDataLayout(), FTy, TableRef, OverloadTys, nulls());
   assert(MatchResult == false && "intrinsic signature mismatch");
   return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FTy);
 }
@@ -850,7 +857,8 @@ using DeferredIntrinsicMatchPair =
     std::pair<Type *, ArrayRef<Intrinsic::IITDescriptor>>;
 
 static bool
-matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
+matchIntrinsicType(const DataLayout &DL, Type *Ty,
+                   ArrayRef<Intrinsic::IITDescriptor> &Infos,
                    SmallVectorImpl<Type *> &OverloadTys,
                    SmallVectorImpl<DeferredIntrinsicMatchPair> &DeferredChecks,
                    bool IsDeferredCheck) {
@@ -872,6 +880,8 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
   switch (D.Kind) {
   case IITDescriptor::Void:
     return !Ty->isVoidTy();
+  case IITDescriptor::Byte:
+    return !Ty->isIntegerTy(DL.getByteWidth());
   case IITDescriptor::VarArg:
     return true;
   case IITDescriptor::MMX: {
@@ -905,7 +915,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
   case IITDescriptor::Vector: {
     VectorType *VT = dyn_cast<VectorType>(Ty);
     return !VT || VT->getElementCount() != D.VectorWidth ||
-           matchIntrinsicType(VT->getElementType(), Infos, OverloadTys,
+           matchIntrinsicType(DL, VT->getElementType(), Infos, OverloadTys,
                               DeferredChecks, IsDeferredCheck);
   }
   case IITDescriptor::Pointer: {
@@ -920,7 +930,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
       return true;
 
     for (unsigned i = 0, e = D.StructNumElements; i != e; ++i)
-      if (matchIntrinsicType(ST->getElementType(i), Infos, OverloadTys,
+      if (matchIntrinsicType(DL, ST->getElementType(i), Infos, OverloadTys,
                              DeferredChecks, IsDeferredCheck))
         return true;
     return false;
@@ -1016,7 +1026,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
         return true;
       EltTy = ThisArgType->getElementType();
     }
-    return matchIntrinsicType(EltTy, Infos, OverloadTys, DeferredChecks,
+    return matchIntrinsicType(DL, EltTy, Infos, OverloadTys, DeferredChecks,
                               IsDeferredCheck);
   }
   case IITDescriptor::VecOfAnyPtrsToElt: {
@@ -1095,12 +1105,13 @@ static bool isIntrinsicVarArg(ArrayRef<Intrinsic::IITDescriptor> &Infos,
 }
 
 bool Intrinsic::matchIntrinsicSignature(
-    FunctionType *FTy, ArrayRef<Intrinsic::IITDescriptor> &Infos,
+    const DataLayout &DL, FunctionType *FTy,
+    ArrayRef<Intrinsic::IITDescriptor> &Infos,
     SmallVectorImpl<Type *> &OverloadTys, raw_ostream &OS) {
   bool IsVarArg = isIntrinsicVarArg(Infos, /*Consume=*/true);
 
   SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks;
-  if (matchIntrinsicType(FTy->getReturnType(), Infos, OverloadTys,
+  if (matchIntrinsicType(DL, FTy->getReturnType(), Infos, OverloadTys,
                          DeferredChecks, false)) {
     OS << "intrinsic has incorrect return type!";
     return true;
@@ -1109,7 +1120,7 @@ bool Intrinsic::matchIntrinsicSignature(
   unsigned NumDeferredReturnChecks = DeferredChecks.size();
 
   for (Type *Ty : FTy->params()) {
-    if (matchIntrinsicType(Ty, Infos, OverloadTys, DeferredChecks, false)) {
+    if (matchIntrinsicType(DL, Ty, Infos, OverloadTys, DeferredChecks, false)) {
       OS << "intrinsic has incorrect argument type!";
       return true;
     }
@@ -1117,7 +1128,7 @@ bool Intrinsic::matchIntrinsicSignature(
 
   for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {
     DeferredIntrinsicMatchPair &Check = DeferredChecks[I];
-    if (!matchIntrinsicType(Check.first, Check.second, OverloadTys,
+    if (!matchIntrinsicType(DL, Check.first, Check.second, OverloadTys,
                             DeferredChecks, true))
       continue;
     if (I < NumDeferredReturnChecks)
@@ -1143,7 +1154,8 @@ bool Intrinsic::matchIntrinsicSignature(
   return false;
 }
 
-bool Intrinsic::isSignatureValid(Intrinsic::ID ID, FunctionType *FT,
+bool Intrinsic::isSignatureValid(const DataLayout &DL, Intrinsic::ID ID,
+                                 FunctionType *FT,
                                  SmallVectorImpl<Type *> &OverloadTys,
                                  raw_ostream &OS) {
   if (!ID)
@@ -1153,14 +1165,14 @@ bool Intrinsic::isSignatureValid(Intrinsic::ID ID, FunctionType *FT,
   getIntrinsicInfoTableEntries(ID, Table);
   ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
 
-  return !matchIntrinsicSignature(FT, TableRef, OverloadTys, OS);
+  return !matchIntrinsicSignature(DL, FT, TableRef, OverloadTys, OS);
 }
 
 bool Intrinsic::isSignatureValid(Function *F,
                                  SmallVectorImpl<Type *> &OverloadTys,
                                  raw_ostream &OS) {
-  return isSignatureValid(F->getIntrinsicID(), F->getFunctionType(),
-                          OverloadTys, OS);
+  return isSignatureValid(F->getDataLayout(), F->getIntrinsicID(),
+                          F->getFunctionType(), OverloadTys, OS);
 }
 
 std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 79d4834a7a30d..153b4aa808952 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5926,7 +5926,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
   std::string ErrMsg;
   raw_string_ostream ErrOS(ErrMsg);
   SmallVector<Type *, 4> OverloadTys;
-  bool IsValid = Intrinsic::isSignatureValid(ID, IFTy, OverloadTys, ErrOS);
+  bool IsValid = Intrinsic::isSignatureValid(DL, ID, IFTy, OverloadTys, ErrOS);
   Check(IsValid, ErrMsg, IF);
 
   // Now that we have the intrinsic ID and the actual argument types (and we
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 200b5aec77a85..f9fc1165bd658 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -19643,8 +19643,9 @@ Align SITargetLowering::computeKnownAlignForTargetInstr(
     // site specifies a lower alignment?
     Intrinsic::ID IID = GI->getIntrinsicID();
     LLVMContext &Ctx = VT.getMachineFunction().getFunction().getContext();
+    const Module *M = VT.getMachineFunction().getFunction().getParent();
     AttributeList Attrs =
-        Intrinsic::getAttributes(Ctx, IID, Intrinsic::getType(Ctx, IID));
+        Intrinsic::getAttributes(Ctx, IID, Intrinsic::getType(M, IID));
     if (MaybeAlign RetAlign = Attrs.getRetAlignment())
       return *RetAlign;
   }
diff --git a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
index f40816d07d566..e148d4586486f 100644
--- a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
@@ -1580,7 +1580,7 @@ Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase(
   // Check that the widened intrinsic is valid.
   SmallVector<Type *, 4> OverloadTys;
   [[maybe_unused]] bool IsValid =
-      Intrinsic::isSignatureValid(WidenedId, WidenedFnTy, OverloadTys);
+      Intrinsic::isSignatureValid(DL, WidenedId, WidenedFnTy, OverloadTys);
   assert(IsValid && "invalid widened intrinsic");
   // For known intrinsic functions, we create a second call to the same
   // intrinsic with a different type.
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 5474689c9b0b5..9a29e69cc2f89 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -94,7 +94,8 @@ getOverloadedDeclaration(CallIntrinsicOp op, llvm::Intrinsic::ID id,
   std::string errorMsg;
   llvm::raw_string_ostream errorOS(errorMsg);
   SmallVector<llvm::Type *, 8> overloadedTys;
-  if (!llvm::Intrinsic::isSignatureValid(id, ft, overloadedTys, errorOS)) {
+  if (!llvm::Intrinsic::isSignatureValid(module->getDataLayout(), id, ft,
+                                         overloadedTys, errorOS)) {
     return mlir::emitError(op.getLoc(), "call intrinsic signature ")
            << diagStr(ft) << " to overloaded intrinsic " << op.getIntrinAttr()
            << " does not match any of the overloads: " << errorMsg;



More information about the llvm-branch-commits mailing list