[llvm] bb8ce25 - Intrinsic::getName: require a Module argument

Jeroen Dobbelaere via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 14 05:57:35 PDT 2021


Author: Jeroen Dobbelaere
Date: 2021-06-14T14:52:29+02:00
New Revision: bb8ce25e88218be60d2a4ea9c9b0b721809eff27

URL: https://github.com/llvm/llvm-project/commit/bb8ce25e88218be60d2a4ea9c9b0b721809eff27
DIFF: https://github.com/llvm/llvm-project/commit/bb8ce25e88218be60d2a4ea9c9b0b721809eff27.diff

LOG: Intrinsic::getName: require a Module argument

Ensure that we provide a `Module` when checking if a rename of an intrinsic is necessary.

This fixes the issue that was detected by https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32288
(as mentioned by @fhahn), after committing D91250.

Note that the `LLVMIntrinsicCopyOverloadedName` is being deprecated in favor of `LLVMIntrinsicCopyOverloadedName2`.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D99173

Added: 
    

Modified: 
    llvm/docs/ReleaseNotes.rst
    llvm/include/llvm-c/Core.h
    llvm/include/llvm/IR/Intrinsics.h
    llvm/lib/CodeGen/MachineOperand.cpp
    llvm/lib/CodeGen/ReplaceWithVeclib.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/lib/IR/AutoUpgrade.cpp
    llvm/lib/IR/Core.cpp
    llvm/lib/IR/Function.cpp
    llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
    llvm/test/Assembler/auto_upgrade_intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 98117a24fcee9..bb88699fc76de 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -121,6 +121,10 @@ Changes to the OCaml bindings
 Changes to the C API
 --------------------
 
+* The C API function ``LLVMIntrinsicCopyOverloadedName`` has been deprecated.
+  Please migrate to ``LLVMIntrinsicCopyOverloadedName2`` which takes an extra
+  module argument and which also handles unnamed types.
+  ('D99173' <https://reviews.llvm.org/D99173>'_)
 
 Changes to the Go bindings
 --------------------------

diff  --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 7a17b6943177b..1a5e763cfc600 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2514,6 +2514,12 @@ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
  */
 const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
 
+/** Deprecated: Use LLVMIntrinsicCopyOverloadedName2 instead. */
+const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
+                                            LLVMTypeRef *ParamTypes,
+                                            size_t ParamCount,
+                                            size_t *NameLength);
+
 /**
  * Copies the name of an overloaded intrinsic identified by a given list of
  * parameter types.
@@ -2521,12 +2527,14 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
  * Unlike LLVMIntrinsicGetName, the caller is responsible for freeing the
  * returned string.
  *
+ * This version also supports unnamed types.
+ *
  * @see llvm::Intrinsic::getName()
  */
-const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
-                                            LLVMTypeRef *ParamTypes,
-                                            size_t ParamCount,
-                                            size_t *NameLength);
+const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
+                                             LLVMTypeRef *ParamTypes,
+                                             size_t ParamCount,
+                                             size_t *NameLength);
 
 /**
  * Obtain if the intrinsic identified by the given ID is overloaded.

diff  --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index ae84ee8f354a0..15275001ab4c6 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -55,21 +55,23 @@ namespace Intrinsic {
   /// version of getName if overloads are required.
   StringRef getName(ID id);
 
-  /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
-  /// Note, this version of getName supports overloads, but not unnamed types.
-  /// It is less efficient than the StringRef version of this function. If no
-  /// overloads are required, it is safe to use this version, but better to use
-  /// the StringRef version.
-  std::string getName(ID Id, ArrayRef<Type *> Tys);
+  /// Return the LLVM name for an intrinsic, without encoded types for
+  /// overloading, such as "llvm.ssa.copy".
+  StringRef getBaseName(ID id);
 
-  /// Return the LLVM name for an intrinsic, such as "llvm.ssa.copy.p0s_s.1".
-  /// Note, this version of getName supports overloads and unnamed types, but is
-  /// less efficient than the StringRef version of this function.  If no
+  /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
+  /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
+  /// This is less efficient than the StringRef version of this function.  If no
   /// overloads are required, it is safe to use this version, but better to use
-  /// the StringRef version. A function type FT can be provided to avoid
-  /// computing it. It is used (or computed) if one of the types is based on an
-  /// unnamed type.
-  std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M, FunctionType *FT);
+  /// the StringRef version. If one of the types is based on an unnamed type, a
+  /// function type will be computed. Providing FT will avoid this computation.
+  std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+                      FunctionType *FT = nullptr);
+
+  /// Return the LLVM name for an intrinsic. This is a special version only to
+  /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
+  /// based on named types.
+  std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
 
   /// Return the function type for an intrinsic.
   FunctionType *getType(LLVMContext &Context, ID id,

diff  --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index c0ae0d27f4291..145423a2ad8d2 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -935,7 +935,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
   case MachineOperand::MO_IntrinsicID: {
     Intrinsic::ID ID = getIntrinsicID();
     if (ID < Intrinsic::num_intrinsics)
-      OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')';
+      OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
     else if (IntrinsicInfo)
       OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
     else

diff  --git a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
index 139860bcbf1e8..1619381967c42 100644
--- a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
+++ b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
@@ -142,7 +142,7 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
   // converted to scalar above.
   std::string ScalarName;
   if (Intrinsic::isOverloaded(IntrinsicID)) {
-    ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes);
+    ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes, CI.getModule());
   } else {
     ScalarName = Intrinsic::getName(IntrinsicID).str();
   }

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 7bba8d30eb3fa..73c207e589fba 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -145,7 +145,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
     unsigned OpNo = getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1;
     unsigned IID = cast<ConstantSDNode>(getOperand(OpNo))->getZExtValue();
     if (IID < Intrinsic::num_intrinsics)
-      return Intrinsic::getName((Intrinsic::ID)IID, None);
+      return Intrinsic::getBaseName((Intrinsic::ID)IID).str();
     else if (!G)
       return "Unknown intrinsic";
     else if (const TargetIntrinsicInfo *TII = G->getTarget().getIntrinsicInfo())

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3d035e875925f..e049be94fcf17 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3777,7 +3777,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) {
     unsigned iid =
       cast<ConstantSDNode>(N->getOperand(HasInputChain))->getZExtValue();
     if (iid < Intrinsic::num_intrinsics)
-      Msg << "intrinsic %" << Intrinsic::getName((Intrinsic::ID)iid, None);
+      Msg << "intrinsic %" << Intrinsic::getBaseName((Intrinsic::ID)iid);
     else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo())
       Msg << "target intrinsic %" << TII->getName(iid);
     else

diff  --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 7e14a075fc382..851e8e45f47d3 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -778,7 +778,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
         Intrinsic::lifetime_start : Intrinsic::invariant_start;
       auto Args = F->getFunctionType()->params();
       Type* ObjectPtr[1] = {Args[1]};
-      if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
+      if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
         return true;
@@ -792,7 +792,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
 
       auto Args = F->getFunctionType()->params();
       Type* ObjectPtr[1] = {Args[IsLifetimeEnd ? 1 : 2]};
-      if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
+      if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
         return true;
@@ -814,7 +814,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
   case 'm': {
     if (Name.startswith("masked.load.")) {
       Type *Tys[] = { F->getReturnType(), F->arg_begin()->getType() };
-      if (F->getName() != Intrinsic::getName(Intrinsic::masked_load, Tys)) {
+      if (F->getName() !=
+          Intrinsic::getName(Intrinsic::masked_load, Tys, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(),
                                           Intrinsic::masked_load,
@@ -825,7 +826,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
     if (Name.startswith("masked.store.")) {
       auto Args = F->getFunctionType()->params();
       Type *Tys[] = { Args[0], Args[1] };
-      if (F->getName() != Intrinsic::getName(Intrinsic::masked_store, Tys)) {
+      if (F->getName() !=
+          Intrinsic::getName(Intrinsic::masked_store, Tys, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(),
                                           Intrinsic::masked_store,
@@ -837,7 +839,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
     // to the new overload which includes an address space
     if (Name.startswith("masked.gather.")) {
       Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()};
-      if (F->getName() != Intrinsic::getName(Intrinsic::masked_gather, Tys)) {
+      if (F->getName() !=
+          Intrinsic::getName(Intrinsic::masked_gather, Tys, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(),
                                           Intrinsic::masked_gather, Tys);
@@ -847,7 +850,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
     if (Name.startswith("masked.scatter.")) {
       auto Args = F->getFunctionType()->params();
       Type *Tys[] = {Args[0], Args[1]};
-      if (F->getName() != Intrinsic::getName(Intrinsic::masked_scatter, Tys)) {
+      if (F->getName() !=
+          Intrinsic::getName(Intrinsic::masked_scatter, Tys, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(),
                                           Intrinsic::masked_scatter, Tys);
@@ -928,7 +932,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
     if (Name.startswith("objectsize.")) {
       Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
       if (F->arg_size() == 2 || F->arg_size() == 3 ||
-          F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) {
+          F->getName() !=
+              Intrinsic::getName(Intrinsic::objectsize, Tys, F->getParent())) {
         rename(F);
         NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
                                           Tys);
@@ -941,7 +946,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
     if (Name == "prefetch") {
       // Handle address space overloading.
       Type *Tys[] = {F->arg_begin()->getType()};
-      if (F->getName() != Intrinsic::getName(Intrinsic::prefetch, Tys)) {
+      if (F->getName() !=
+          Intrinsic::getName(Intrinsic::prefetch, Tys, F->getParent())) {
         rename(F);
         NewFn =
             Intrinsic::getDeclaration(F->getParent(), Intrinsic::prefetch, Tys);

diff  --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 084cb8c71d161..8a7060c148c95 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2411,7 +2411,18 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
                                             size_t *NameLength) {
   auto IID = llvm_map_to_intrinsic_id(ID);
   ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
-  auto Str = llvm::Intrinsic::getName(IID, Tys);
+  auto Str = llvm::Intrinsic::getNameNoUnnamedTypes(IID, Tys);
+  *NameLength = Str.length();
+  return strdup(Str.c_str());
+}
+
+const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
+                                             LLVMTypeRef *ParamTypes,
+                                             size_t ParamCount,
+                                             size_t *NameLength) {
+  auto IID = llvm_map_to_intrinsic_id(ID);
+  ArrayRef<Type *> Tys(unwrap(ParamTypes), ParamCount);
+  auto Str = llvm::Intrinsic::getName(IID, Tys, unwrap(Mod));
   *NameLength = Str.length();
   return strdup(Str.c_str());
 }

diff  --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 25c59d03c7b93..8f1148d461ebc 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -831,37 +831,53 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
   return Result;
 }
 
+StringRef Intrinsic::getBaseName(ID id) {
+  assert(id < num_intrinsics && "Invalid intrinsic ID!");
+  return IntrinsicNameTable[id];
+}
+
 StringRef Intrinsic::getName(ID id) {
   assert(id < num_intrinsics && "Invalid intrinsic ID!");
   assert(!Intrinsic::isOverloaded(id) &&
          "This version of getName does not support overloading");
-  return IntrinsicNameTable[id];
+  return getBaseName(id);
 }
 
-std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
-                               FunctionType *FT) {
-  assert(Id < num_intrinsics && "Invalid intrinsic ID!");
+static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
+                                        Module *M, FunctionType *FT,
+                                        bool EarlyModuleCheck) {
+
+  assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
   assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
          "This version of getName is for overloaded intrinsics only");
+  (void)EarlyModuleCheck;
+  assert((!EarlyModuleCheck || M ||
+          !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&
+         "Intrinsic overloading on pointer types need to provide a Module");
   bool HasUnnamedType = false;
-  std::string Result(IntrinsicNameTable[Id]);
-  for (Type *Ty : Tys) {
+  std::string Result(Intrinsic::getBaseName(Id));
+  for (Type *Ty : Tys)
     Result += "." + getMangledTypeStr(Ty, HasUnnamedType);
-  }
-  assert((M || !HasUnnamedType) && "unnamed types need a module");
-  if (M && HasUnnamedType) {
+  if (HasUnnamedType) {
+    assert(M && "unnamed types need a module");
     if (!FT)
-      FT = getType(M->getContext(), Id, Tys);
+      FT = Intrinsic::getType(M->getContext(), Id, Tys);
     else
-      assert((FT == getType(M->getContext(), Id, Tys)) &&
+      assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
              "Provided FunctionType must match arguments");
     return M->getUniqueIntrinsicName(Result, Id, FT);
   }
   return Result;
 }
 
-std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys) {
-  return getName(Id, Tys, nullptr, nullptr);
+std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+                               FunctionType *FT) {
+  assert(M && "We need to have a Module");
+  return getIntrinsicNameImpl(Id, Tys, M, FT, true);
+}
+
+std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) {
+  return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false);
 }
 
 /// IIT_Info - These are enumerators that describe the entries returned by the

diff  --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
index 088cbf4210e07..ab27e5b9c3e35 100644
--- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
@@ -1841,7 +1841,7 @@ class LowerMatrixIntrinsics {
           return;
         }
         IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
-        write(StringRef(Intrinsic::getName(II->getIntrinsicID(), {}))
+        write(Intrinsic::getBaseName(II->getIntrinsicID())
                   .drop_front(StringRef("llvm.matrix.").size()));
         write(".");
         std::string Tmp;

diff  --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
index a847787a32ecf..4758c7e134806 100644
--- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll
+++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
@@ -2,15 +2,14 @@
 ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
 ; RUN: verify-uselistorder %s
 
+%0 = type opaque;
+
 declare i8 @llvm.ctlz.i8(i8)
 declare i16 @llvm.ctlz.i16(i16)
 declare i32 @llvm.ctlz.i32(i32)
 declare i42 @llvm.ctlz.i42(i42)  ; Not a power-of-2
 
 
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
-
-
 define void @test.ctlz(i8 %a, i16 %b, i32 %c, i42 %d) {
 ; CHECK: @test.ctlz
 
@@ -51,6 +50,7 @@ entry:
 
 @a = private global [60 x i8] zeroinitializer, align 1
 
+declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
 define i32 @test.objectsize() {
 ; CHECK-LABEL: @test.objectsize(
 ; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
@@ -66,6 +66,24 @@ define i64 @test.objectsize.2() {
   ret i64 %s
 }
 
+ at u = private global [60 x %0*] zeroinitializer, align 1
+
+declare i32 @llvm.objectsize.i32.unnamed(%0**, i1) nounwind readonly
+define i32 @test.objectsize.unnamed() {
+; CHECK-LABEL: @test.objectsize.unnamed(
+; CHECK: @llvm.objectsize.i32.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false)
+  %s = call i32 @llvm.objectsize.i32.unnamed(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false)
+  ret i32 %s
+}
+
+declare i64 @llvm.objectsize.i64.p0p0s_s.0(%0**, i1) nounwind readonly
+define i64 @test.objectsize.unnamed.2() {
+; CHECK-LABEL: @test.objectsize.unnamed.2(
+; CHECK: @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false)
+  %s = call i64 @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false)
+  ret i64 %s
+}
+
 declare <2 x double> @llvm.masked.load.v2f64(<2 x double>* %ptrs, i32, <2 x i1> %mask, <2 x double> %src0)
 
 define <2 x double> @tests.masked.load(<2 x double>* %ptr, <2 x i1> %mask, <2 x double> %passthru)  {
@@ -116,6 +134,20 @@ define void @tests.invariant.start.end() {
   ret void
 }
 
+declare {}* @llvm.invariant.start.unnamed(i64, %0** nocapture) nounwind readonly
+declare void @llvm.invariant.end.unnamed({}*, i64, %0** nocapture) nounwind
+
+define void @tests.invariant.start.end.unnamed() {
+  ; CHECK-LABEL: @tests.invariant.start.end.unnamed(
+  %a = alloca %0*
+  %i = call {}* @llvm.invariant.start.unnamed(i64 1, %0** %a)
+  ; CHECK: call {}* @llvm.invariant.start.p0p0s_s.0
+  store %0* null, %0** %a
+  call void @llvm.invariant.end.unnamed({}* %i, i64 1, %0** %a)
+  ; CHECK: call void @llvm.invariant.end.p0p0s_s.0
+  ret void
+}
+
 @__stack_chk_guard = external global i8*
 declare void @llvm.stackprotectorcheck(i8**)
 
@@ -140,6 +172,20 @@ define void @tests.lifetime.start.end() {
   ret void
 }
 
+declare void  @llvm.lifetime.start.unnamed(i64, %0** nocapture) nounwind readonly
+declare void @llvm.lifetime.end.unnamed(i64, %0** nocapture) nounwind
+
+define void @tests.lifetime.start.end.unnamed() {
+  ; CHECK-LABEL: @tests.lifetime.start.end.unnamed(
+  %a = alloca %0*
+  call void @llvm.lifetime.start.unnamed(i64 1, %0** %a)
+  ; CHECK: call void @llvm.lifetime.start.p0p0s_s.0(i64 1, %0** %a)
+  store %0* null, %0** %a
+  call void @llvm.lifetime.end.unnamed(i64 1, %0** %a)
+  ; CHECK: call void @llvm.lifetime.end.p0p0s_s.0(i64 1, %0** %a)
+  ret void
+}
+
 declare void @llvm.prefetch(i8*, i32, i32, i32)
 define void @test.prefetch(i8* %ptr) {
 ; CHECK-LABEL: @test.prefetch(
@@ -156,10 +202,20 @@ define void @test.prefetch.2(i8* %ptr) {
   ret void
 }
 
+declare void @llvm.prefetch.unnamed(%0**, i32, i32, i32)
+define void @test.prefetch.unnamed(%0** %ptr) {
+; CHECK-LABEL: @test.prefetch.unnamed(
+; CHECK: @llvm.prefetch.p0p0s_s.0(%0** %ptr, i32 0, i32 3, i32 2)
+  call void @llvm.prefetch.unnamed(%0** %ptr, i32 0, i32 3, i32 2)
+  ret void
+}
+
 ; This is part of @test.objectsize(), since llvm.objectsize declaration gets
 ; emitted at the end.
 ; CHECK: declare i32 @llvm.objectsize.i32.p0i8
-
+; CHECK: declare i32 @llvm.objectsize.i32.p0p0s_s.0
 
 ; CHECK: declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
 ; CHECK: declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
+; CHECK: declare void @llvm.lifetime.start.p0p0s_s.0(i64 immarg, %0** nocapture)
+; CHECK: declare void @llvm.lifetime.end.p0p0s_s.0(i64 immarg, %0** nocapture)


        


More information about the llvm-commits mailing list