[PATCH] D130776: [IRBuilder] CreateIntrinsic with implicit mangling

Jay Foad via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 29 06:51:11 PDT 2022


foad created this revision.
foad added reviewers: nhaehnle, matejam.
Herald added subscribers: nlopes, hiraditya.
Herald added a project: All.
foad requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Add a new IRBuilderBase::CreateIntrinsic which takes the return type and
argument values for the intrinsic call but does not take an explicit
list of types to mangle. Instead the builder works this out from the
intrinsic declaration and the types of the supplied arguments.

This means that the mangling is hidden from the client, which in turn
means that intrinsic definitions can change which arguments are mangled
without requiring any changes to the client code.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130776

Files:
  llvm/include/llvm/IR/IRBuilder.h
  llvm/lib/IR/IRBuilder.cpp
  llvm/unittests/IR/IRBuilderTest.cpp


Index: llvm/unittests/IR/IRBuilderTest.cpp
===================================================================
--- llvm/unittests/IR/IRBuilderTest.cpp
+++ llvm/unittests/IR/IRBuilderTest.cpp
@@ -137,6 +137,29 @@
   EXPECT_EQ(II->getIntrinsicID(), Intrinsic::set_rounding);
 }
 
+TEST_F(IRBuilderTest, IntrinsicMangling) {
+  IRBuilder<> Builder(BB);
+  Type *VoidTy = Builder.getVoidTy();
+  Type *Int64Ty = Builder.getInt64Ty();
+  Value *Int64Val = Builder.getInt64(0);
+  Value *DoubleVal = UndefValue::get(Builder.getDoubleTy());
+  CallInst *Call;
+
+  // Mangled return type, no arguments.
+  Call = Builder.CreateIntrinsic(Int64Ty, Intrinsic::coro_size, {});
+  EXPECT_EQ(Call->getCalledFunction()->getName(), "llvm.coro.size.i64");
+
+  // Void return type, mangled argument type.
+  Call =
+      Builder.CreateIntrinsic(VoidTy, Intrinsic::set_loop_iterations, Int64Val);
+  EXPECT_EQ(Call->getCalledFunction()->getName(),
+            "llvm.set.loop.iterations.i64");
+
+  // Mangled return type and argument type.
+  Call = Builder.CreateIntrinsic(Int64Ty, Intrinsic::lround, DoubleVal);
+  EXPECT_EQ(Call->getCalledFunction()->getName(), "llvm.lround.i64.f64");
+}
+
 TEST_F(IRBuilderTest, IntrinsicsWithScalableVectors) {
   IRBuilder<> Builder(BB);
   CallInst *Call;
Index: llvm/lib/IR/IRBuilder.cpp
===================================================================
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -891,6 +891,33 @@
   return createCallHelper(Fn, Args, Name, FMFSource);
 }
 
+CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
+                                         ArrayRef<Value *> Args,
+                                         Instruction *FMFSource,
+                                         const Twine &Name) {
+  Module *M = BB->getModule();
+
+  SmallVector<Intrinsic::IITDescriptor> Table;
+  Intrinsic::getIntrinsicInfoTableEntries(ID, Table);
+  ArrayRef<Intrinsic::IITDescriptor> TableRef(Table);
+
+  SmallVector<Type *> ArgTys;
+  ArgTys.reserve(Args.size());
+  for (auto &I : Args)
+    ArgTys.push_back(I->getType());
+  FunctionType *FTy = FunctionType::get(RetTy, ArgTys, false);
+  SmallVector<Type *> OverloadTys;
+  Intrinsic::MatchIntrinsicTypesResult Res =
+      matchIntrinsicSignature(FTy, TableRef, OverloadTys);
+  (void)Res;
+  assert(Res == Intrinsic::MatchIntrinsicTypes_Match && TableRef.empty() &&
+         "Wrong types for intrinsic!");
+  // TODO: Handle varargs intrinsics.
+
+  Function *Fn = Intrinsic::getDeclaration(M, ID, OverloadTys);
+  return createCallHelper(Fn, Args, Name, FMFSource);
+}
+
 CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
     Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
     const Twine &Name, MDNode *FPMathTag,
Index: llvm/include/llvm/IR/IRBuilder.h
===================================================================
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -883,7 +883,7 @@
                                   Instruction *FMFSource = nullptr,
                                   const Twine &Name = "");
 
-  /// Create a call to intrinsic \p ID with \p args, mangled using \p Types. If
+  /// Create a call to intrinsic \p ID with \p Args, mangled using \p Types. If
   /// \p FMFSource is provided, copy fast-math-flags from that instruction to
   /// the intrinsic.
   CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef<Type *> Types,
@@ -891,6 +891,14 @@
                             Instruction *FMFSource = nullptr,
                             const Twine &Name = "");
 
+  /// Create a call to intrinsic \p ID with \p RetTy and \p Args. If
+  /// \p FMFSource is provided, copy fast-math-flags from that instruction to
+  /// the intrinsic.
+  CallInst *CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
+                            ArrayRef<Value *> Args,
+                            Instruction *FMFSource = nullptr,
+                            const Twine &Name = "");
+
   /// Create call to the minnum intrinsic.
   CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") {
     return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, nullptr, Name);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D130776.448620.patch
Type: text/x-patch
Size: 4185 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220729/da0047cd/attachment.bin>


More information about the llvm-commits mailing list