Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2963,7 +2963,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 *ParamTypes,
size_t ParamCount);

Expand Down
13 changes: 8 additions & 5 deletions llvm/include/llvm/IR/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

namespace llvm {

class DataLayout;
class Type;
class FunctionType;
class Function;
Expand Down Expand Up @@ -75,7 +76,7 @@ namespace Intrinsic {
LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);

/// 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 *> Tys = {});

/// Returns true if the intrinsic can be overloaded.
Expand Down Expand Up @@ -135,6 +136,7 @@ namespace Intrinsic {
struct IITDescriptor {
enum IITDescriptorKind {
Void,
Byte,
VarArg,
MMX,
Token,
Expand Down Expand Up @@ -247,9 +249,9 @@ namespace Intrinsic {
///
/// Returns false if the given type matches with the constraints, true
/// otherwise.
LLVM_ABI MatchIntrinsicTypesResult
matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
SmallVectorImpl<Type *> &ArgTys);
LLVM_ABI MatchIntrinsicTypesResult matchIntrinsicSignature(
const DataLayout &DL, FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
SmallVectorImpl<Type *> &ArgTys);

/// Verify if the intrinsic has variable arguments. This method is intended to
/// be called after all the fixed arguments have been matched first.
Expand All @@ -264,7 +266,8 @@ namespace Intrinsic {
///
/// Returns false if the given ID and function type combination is not a
/// valid intrinsic call.
LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT,
LLVM_ABI bool getIntrinsicSignature(const DataLayout &DL, Intrinsic::ID,
FunctionType *FT,
SmallVectorImpl<Type *> &ArgTys);

/// Same as previous, but accepts a Function instead of ID and FunctionType.
Expand Down
13 changes: 9 additions & 4 deletions llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,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,
Expand Down Expand Up @@ -376,6 +377,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> {
let ArgCode = !cond(
!eq(vt, Any) : ArgKind.Any,
Expand Down Expand Up @@ -481,7 +486,7 @@ class LLVMVectorOfBitcastsToInt<int num>
: LLVMMatchType<num, IIT_VEC_OF_BITCASTS_TO_INT>;

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>;
Expand Down Expand Up @@ -1011,7 +1016,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,
Expand All @@ -1024,7 +1029,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>>]>;
Expand Down Expand Up @@ -2621,7 +2626,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>>]>;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {

SmallVector<Type *> OverloadTys;
if (IID != Intrinsic::not_intrinsic &&
Intrinsic::getIntrinsicSignature(IID, CB->getFunctionType(),
OverloadTys)) {
Intrinsic::getIntrinsicSignature(
M->getDataLayout(), IID, CB->getFunctionType(), OverloadTys)) {
U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
} else {
// Try to upgrade the intrinsic.
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/IR/AutoUpgrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1749,7 +1749,9 @@ 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::getIntrinsicSignature(id, F->getFunctionType(), OverloadTys))
assert(F->getParent());
if (Intrinsic::getIntrinsicSignature(F->getDataLayout(), id,
F->getFunctionType(), OverloadTys))
F->setAttributes(
Intrinsic::getAttributes(F->getContext(), id, F->getFunctionType()));
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2496,11 +2496,11 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
return Str.data();
}

LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID,
LLVMTypeRef *ParamTypes, size_t ParamCount) {
auto IID = llvm_map_to_intrinsic_id(ID);
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
return wrap(llvm::Intrinsic::getType(unwrap(Mod), IID, Tys));
}

char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes,
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,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::getIntrinsicSignature(IntID, Ty, OverloadTys))
assert(ParentModule);
if (!Intrinsic::getIntrinsicSignature(ParentModule->getDataLayout(), IntID,
Ty, OverloadTys))
return;

setAttributes(Intrinsic::getAttributes(getContext(), IntID, Ty));
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
FunctionType *FTy = FunctionType::get(RetTy, ArgTys, false);
SmallVector<Type *> OverloadTys;
Intrinsic::MatchIntrinsicTypesResult Res =
matchIntrinsicSignature(FTy, TableRef, OverloadTys);
matchIntrinsicSignature(M->getDataLayout(), FTy, TableRef, OverloadTys);
(void)Res;
assert(Res == Intrinsic::MatchIntrinsicTypes_Match && TableRef.empty() &&
"Wrong types for intrinsic!");
Expand Down
61 changes: 36 additions & 25 deletions llvm/lib/IR/Intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
if (HasUnnamedType) {
assert(M && "unnamed types need a module");
if (!FT)
FT = Intrinsic::getType(M->getContext(), Id, Tys);
FT = Intrinsic::getType(M, Id, Tys);
else
assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
assert((FT == Intrinsic::getType(M, Id, Tys)) &&
"Provided FunctionType must match arguments");
return M->getUniqueIntrinsicName(Result, Id, FT);
}
Expand Down Expand Up @@ -212,6 +212,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;
Expand Down Expand Up @@ -471,7 +474,8 @@ void Intrinsic::getIntrinsicInfoTableEntries(
}

static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
ArrayRef<Type *> Tys, LLVMContext &Context) {
ArrayRef<Type *> Tys, LLVMContext &Context,
const DataLayout &DL) {
using namespace Intrinsic;

IITDescriptor D = Infos.front();
Expand All @@ -480,6 +484,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:
Expand Down Expand Up @@ -508,14 +514,14 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Integer:
return IntegerType::get(Context, D.Integer_Width);
case IITDescriptor::Vector:
return VectorType::get(DecodeFixedType(Infos, Tys, Context),
return VectorType::get(DecodeFixedType(Infos, Tys, Context, DL),
D.Vector_Width);
case IITDescriptor::Pointer:
return PointerType::get(Context, D.Pointer_AddressSpace);
case IITDescriptor::Struct: {
SmallVector<Type *, 8> Elts;
for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
Elts.push_back(DecodeFixedType(Infos, Tys, Context));
Elts.push_back(DecodeFixedType(Infos, Tys, Context, DL));
return StructType::get(Context, Elts);
}
case IITDescriptor::Argument:
Expand Down Expand Up @@ -548,7 +554,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
return VectorType::getOneNthElementsVectorType(
cast<VectorType>(Tys[D.getRefArgNumber()]), D.getVectorDivisor());
case IITDescriptor::SameVecWidthArgument: {
Type *EltTy = DecodeFixedType(Infos, Tys, Context);
Type *EltTy = DecodeFixedType(Infos, Tys, Context, DL);
Type *Ty = Tys[D.getArgumentNumber()];
if (auto *VTy = dyn_cast<VectorType>(Ty))
return VectorType::get(EltTy, VTy->getElementCount());
Expand All @@ -573,17 +579,18 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
llvm_unreachable("unhandled");
}

FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
ArrayRef<Type *> Tys) {
FunctionType *Intrinsic::getType(const Module *M, ID id, ArrayRef<Type *> Tys) {
SmallVector<IITDescriptor, 8> Table;
getIntrinsicInfoTableEntries(id, Table);

ArrayRef<IITDescriptor> TableRef = Table;
Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
Type *ResultTy =
DecodeFixedType(TableRef, Tys, M->getContext(), M->getDataLayout());

SmallVector<Type *, 8> ArgTys;
while (!TableRef.empty())
ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
ArgTys.push_back(
DecodeFixedType(TableRef, Tys, M->getContext(), M->getDataLayout()));

// DecodeFixedType returns Void for IITDescriptor::Void and
// IITDescriptor::VarArg If we see void type as the type of the last argument,
Expand Down Expand Up @@ -724,7 +731,7 @@ Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
ArrayRef<Type *> Tys) {
// There can never be multiple globals with the same name of different types,
// because intrinsics must be a specific type.
auto *FT = getType(M->getContext(), id, Tys);
auto *FT = getType(M, id, Tys);
Function *F = cast<Function>(
M->getOrInsertFunction(
Tys.empty() ? getName(id) : getName(id, Tys, M, FT), FT)
Expand Down Expand Up @@ -792,7 +799,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 *> &ArgTys,
SmallVectorImpl<DeferredIntrinsicMatchPair> &DeferredChecks,
bool IsDeferredCheck) {
Expand All @@ -815,6 +823,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: {
Expand Down Expand Up @@ -848,7 +858,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Vector: {
VectorType *VT = dyn_cast<VectorType>(Ty);
return !VT || VT->getElementCount() != D.Vector_Width ||
matchIntrinsicType(VT->getElementType(), Infos, ArgTys,
matchIntrinsicType(DL, VT->getElementType(), Infos, ArgTys,
DeferredChecks, IsDeferredCheck);
}
case IITDescriptor::Pointer: {
Expand All @@ -863,7 +873,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return true;

for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys,
if (matchIntrinsicType(DL, ST->getElementType(i), Infos, ArgTys,
DeferredChecks, IsDeferredCheck))
return true;
return false;
Expand Down Expand Up @@ -954,7 +964,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return true;
EltTy = ThisArgType->getElementType();
}
return matchIntrinsicType(EltTy, Infos, ArgTys, DeferredChecks,
return matchIntrinsicType(DL, EltTy, Infos, ArgTys, DeferredChecks,
IsDeferredCheck);
}
case IITDescriptor::VecOfAnyPtrsToElt: {
Expand Down Expand Up @@ -1018,24 +1028,24 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
}

Intrinsic::MatchIntrinsicTypesResult
Intrinsic::matchIntrinsicSignature(FunctionType *FTy,
Intrinsic::matchIntrinsicSignature(const DataLayout &DL, FunctionType *FTy,
ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type *> &ArgTys) {
SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks;
if (matchIntrinsicType(FTy->getReturnType(), Infos, ArgTys, DeferredChecks,
false))
if (matchIntrinsicType(DL, FTy->getReturnType(), Infos, ArgTys,
DeferredChecks, false))
return MatchIntrinsicTypes_NoMatchRet;

unsigned NumDeferredReturnChecks = DeferredChecks.size();

for (auto *Ty : FTy->params())
if (matchIntrinsicType(Ty, Infos, ArgTys, DeferredChecks, false))
if (matchIntrinsicType(DL, Ty, Infos, ArgTys, DeferredChecks, false))
return MatchIntrinsicTypes_NoMatchArg;

for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {
DeferredIntrinsicMatchPair &Check = DeferredChecks[I];
if (matchIntrinsicType(Check.first, Check.second, ArgTys, DeferredChecks,
true))
if (matchIntrinsicType(DL, Check.first, Check.second, ArgTys,
DeferredChecks, true))
return I < NumDeferredReturnChecks ? MatchIntrinsicTypes_NoMatchRet
: MatchIntrinsicTypes_NoMatchArg;
}
Expand All @@ -1062,7 +1072,8 @@ bool Intrinsic::matchIntrinsicVarArg(
return true;
}

bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
bool Intrinsic::getIntrinsicSignature(const DataLayout &DL, Intrinsic::ID ID,
FunctionType *FT,
SmallVectorImpl<Type *> &ArgTys) {
if (!ID)
return false;
Expand All @@ -1071,7 +1082,7 @@ bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
getIntrinsicInfoTableEntries(ID, Table);
ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;

if (Intrinsic::matchIntrinsicSignature(FT, TableRef, ArgTys) !=
if (Intrinsic::matchIntrinsicSignature(DL, FT, TableRef, ArgTys) !=
Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
return false;
}
Expand All @@ -1082,8 +1093,8 @@ bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,

bool Intrinsic::getIntrinsicSignature(Function *F,
SmallVectorImpl<Type *> &ArgTys) {
return getIntrinsicSignature(F->getIntrinsicID(), F->getFunctionType(),
ArgTys);
return getIntrinsicSignature(F->getDataLayout(), F->getIntrinsicID(),
F->getFunctionType(), ArgTys);
}

std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5682,7 +5682,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
// Walk the descriptors to extract overloaded types.
SmallVector<Type *, 4> ArgTys;
Intrinsic::MatchIntrinsicTypesResult Res =
Intrinsic::matchIntrinsicSignature(IFTy, TableRef, ArgTys);
Intrinsic::matchIntrinsicSignature(DL, IFTy, TableRef, ArgTys);
Check(Res != Intrinsic::MatchIntrinsicTypes_NoMatchRet,
"Intrinsic has incorrect return type!", IF);
Check(Res != Intrinsic::MatchIntrinsicTypes_NoMatchArg,
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18118,8 +18118,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;
}
Expand Down
Loading
Loading