[llvm] [LLVM][Intrinsics] Adds an API to automatically resolve overload types (PR #169007)

Rajat Bajpai via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 26 03:34:25 PST 2025


================
@@ -197,4 +197,169 @@ TEST(IntrinsicAttributes, TestGetFnAttributesBug) {
   AttributeSet AS = getFnAttributes(Context, experimental_guard);
   EXPECT_FALSE(AS.hasAttributes());
 }
+
+// Tests non-overloaded intrinsic declaration.
+TEST_F(IntrinsicsTest, NonOverloadedIntrinsic) {
+  Type *RetTy = Type::getVoidTy(Context);
+  SmallVector<Type *, 1> ArgTys;
+  ArgTys.push_back(Type::getInt1Ty(Context));
+
+  Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::assume,
+                                                  RetTy, ArgTys);
+
+  ASSERT_NE(F, nullptr);
+  EXPECT_EQ(F->getIntrinsicID(), Intrinsic::assume);
+  EXPECT_EQ(F->getReturnType(), RetTy);
+  EXPECT_EQ(F->arg_size(), 1u);
+  EXPECT_FALSE(F->isVarArg());
+  EXPECT_EQ(F->getName(), "llvm.assume");
+}
+
+// Tests overloaded intrinsic with automatic type resolution for scalar types.
+TEST_F(IntrinsicsTest, OverloadedIntrinsicScalar) {
+  Type *RetTy = Type::getInt32Ty(Context);
+  SmallVector<Type *, 2> ArgTys;
+  ArgTys.push_back(Type::getInt32Ty(Context));
+  ArgTys.push_back(Type::getInt32Ty(Context));
+
+  Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax,
+                                                  RetTy, ArgTys);
+
+  ASSERT_NE(F, nullptr);
+  EXPECT_EQ(F->getIntrinsicID(), Intrinsic::umax);
+  EXPECT_EQ(F->getReturnType(), RetTy);
+  EXPECT_EQ(F->arg_size(), 2u);
+  EXPECT_FALSE(F->isVarArg());
+  EXPECT_EQ(F->getName(), "llvm.umax.i32");
+}
+
+// Tests overloaded intrinsic with automatic type resolution for vector types.
+TEST_F(IntrinsicsTest, OverloadedIntrinsicVector) {
+  Type *RetTy = FixedVectorType::get(Type::getInt32Ty(Context), 4);
+  SmallVector<Type *, 2> ArgTys;
+  ArgTys.push_back(RetTy);
+  ArgTys.push_back(RetTy);
+
+  Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax,
+                                                  RetTy, ArgTys);
+
+  ASSERT_NE(F, nullptr);
+  EXPECT_EQ(F->getIntrinsicID(), Intrinsic::umax);
+  EXPECT_EQ(F->getReturnType(), RetTy);
+  EXPECT_EQ(F->arg_size(), 2u);
+  EXPECT_FALSE(F->isVarArg());
+  EXPECT_EQ(F->getName(), "llvm.umax.v4i32");
+}
+
+// Tests vararg intrinsic declaration.
+TEST_F(IntrinsicsTest, VarArgIntrinsicStatepoint) {
+  Type *RetTy = Type::getTokenTy(Context);
+  SmallVector<Type *, 5> ArgTys;
+  ArgTys.push_back(Type::getInt64Ty(Context));    // ID
+  ArgTys.push_back(Type::getInt32Ty(Context));    // NumPatchBytes
+  ArgTys.push_back(PointerType::get(Context, 0)); // Target
+  ArgTys.push_back(Type::getInt32Ty(Context));    // NumCallArgs
+  ArgTys.push_back(Type::getInt32Ty(Context));    // Flags
+
+  Function *F = Intrinsic::getOrInsertDeclaration(
+      M.get(), Intrinsic::experimental_gc_statepoint, RetTy, ArgTys);
+
+  ASSERT_NE(F, nullptr);
+  EXPECT_EQ(F->getIntrinsicID(), Intrinsic::experimental_gc_statepoint);
+  EXPECT_EQ(F->getReturnType(), RetTy);
+  EXPECT_EQ(F->arg_size(), 5u);
+  EXPECT_TRUE(F->isVarArg()) << "experimental_gc_statepoint must be vararg";
+  EXPECT_EQ(F->getName(), "llvm.experimental.gc.statepoint.p0");
+}
+
+// Tests that different overloads create different declarations.
+TEST_F(IntrinsicsTest, DifferentOverloads) {
+  // i32 version
+  Type *RetTy32 = Type::getInt32Ty(Context);
+  SmallVector<Type *, 2> ArgTys32;
+  ArgTys32.push_back(Type::getInt32Ty(Context));
+  ArgTys32.push_back(Type::getInt32Ty(Context));
+
+  Function *F32 = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax,
----------------
rajatbajpai wrote:

sure, makes sense.

https://github.com/llvm/llvm-project/pull/169007


More information about the llvm-commits mailing list