[LLVM][Intrinsics] Add validation for vararg intrinsics (#193777)

Add validation for use of `llvm_vararg_ty` in intrinsic type signature.
This commit is contained in:
Rahul Joshi
2026-04-30 09:09:56 -07:00
committed by GitHub
parent ad72bee704
commit 94201c35f3
4 changed files with 51 additions and 6 deletions

View File

@@ -227,7 +227,7 @@ namespace Intrinsic {
}
// OneNthEltsVecArguments uses both a divisor N and a reference argument for
// the full-width vector to match
// the full-width vector to match.
unsigned getVectorDivisor() const {
assert(Kind == OneNthEltsVec);
return OverloadInfo >> 16;
@@ -285,7 +285,7 @@ namespace Intrinsic {
LLVM_ABI bool matchIntrinsicVarArg(bool isVarArg,
ArrayRef<IITDescriptor> &Infos);
/// Gets the type arguments of an intrinsic call by matching type contraints
/// Gets the overload types of an intrinsic call by matching type contraints
/// specified by the .td file. The overloaded types are pushed into the
/// OverloadTys vector.
///

View File

@@ -0,0 +1,35 @@
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST0 2>&1 | FileCheck %s --check-prefix=CHECK-TEST0
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST1 2>&1 | FileCheck %s --check-prefix=CHECK-TEST1
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST2 2>&1 | FileCheck %s --check-prefix=CHECK-TEST2
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST3 2>&1 | FileCheck %s --check-prefix=CHECK-TEST3
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST4 2>&1 | FileCheck %s --check-prefix=CHECK-TEST4
// This unit test tests whether invalid use of `llvm_vararg_ty` are flagged.
#define TEST_INTRINSICS_SUPPRESS_DEFS
include "llvm/IR/Intrinsics.td"
#ifdef TEST0
// CHECK-TEST0: error: cannot use llvm_vararg_ty as a return type
def int_test: Intrinsic<[llvm_vararg_ty], []>;
#endif // TEST0
#ifdef TEST1
// CHECK-TEST1: error: cannot use llvm_vararg_ty as a return type
def int_test: Intrinsic<[llvm_i32_ty, llvm_vararg_ty], []>;
#endif // TEST1
#ifdef TEST2
// CHECK-TEST2: error: llvm_vararg_ty can only be the last parameter type
def int_test: Intrinsic<[], [llvm_i32_ty, llvm_vararg_ty, llvm_i1_ty]>;
#endif // TEST2
#ifdef TEST3
// CHECK-TEST3: error: llvm_vararg_ty can only be the last parameter type
def int_test: Intrinsic<[], [llvm_i32_ty, llvm_vararg_ty, llvm_vararg_ty]>;
#endif // TEST3
#ifdef TEST4
// CHECK-TEST4: error: llvm_vararg_ty can only be the last parameter type
def int_test: Intrinsic<[], [llvm_vararg_ty, llvm_i32_ty, llvm_vararg_ty]>;
#endif // TEST4

View File

@@ -3,5 +3,6 @@
include "llvm/IR/Intrinsics.td"
// CHECK-LABEL: IIT_LongEncodingTable
// CHECK: /* 0 */ 0, 26, 0,
def int_foo : Intrinsic<[], [llvm_vararg_ty]>;

View File

@@ -322,11 +322,20 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
// Types field is a concatenation of Return types followed by Param types.
unsigned Idx = 0;
for (; Idx < NumRet; ++Idx)
IS.RetTys.push_back(TypeList->getElementAsRecord(Idx));
for (; Idx < NumRet; ++Idx) {
const Record *RetTy = TypeList->getElementAsRecord(Idx);
if (RetTy->getName() == "llvm_vararg_ty")
PrintFatalError(DefLoc, "cannot use llvm_vararg_ty as a return type");
IS.RetTys.push_back(RetTy);
}
for (unsigned E = TypeList->size(); Idx < E; ++Idx)
IS.ParamTys.push_back(TypeList->getElementAsRecord(Idx));
for (unsigned E = TypeList->size(); Idx < E; ++Idx) {
const Record *ParamTy = TypeList->getElementAsRecord(Idx);
if (Idx != E - 1 && ParamTy->getName() == "llvm_vararg_ty")
PrintFatalError(DefLoc,
"llvm_vararg_ty can only be the last parameter type");
IS.ParamTys.push_back(ParamTy);
}
// Parse the intrinsic properties.
const ListInit *PropList = R->getValueAsListInit("IntrProperties");