Index: llvm/trunk/include/llvm/IR/Intrinsics.h =================================================================== --- llvm/trunk/include/llvm/IR/Intrinsics.h +++ llvm/trunk/include/llvm/IR/Intrinsics.h @@ -134,6 +134,15 @@ /// of IITDescriptors. void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl &T); + /// Match the specified type (which comes from an intrinsic argument or return + /// value) with the type constraints specified by the .td file. If the given + /// type is an overloaded type it is pushed to the ArgTys vector. + /// + /// Returns false if the given type matches with the constraints, true + /// otherwise. + bool matchIntrinsicType(Type *Ty, ArrayRef &Infos, + SmallVectorImpl &ArgTys); + } // End Intrinsic namespace } // End llvm namespace Index: llvm/trunk/lib/IR/Function.cpp =================================================================== --- llvm/trunk/lib/IR/Function.cpp +++ llvm/trunk/lib/IR/Function.cpp @@ -922,6 +922,144 @@ #include "llvm/IR/Intrinsics.gen" #undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN +bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef &Infos, + SmallVectorImpl &ArgTys) { + using namespace Intrinsic; + + // If we ran out of descriptors, there are too many arguments. + if (Infos.empty()) return true; + IITDescriptor D = Infos.front(); + Infos = Infos.slice(1); + + switch (D.Kind) { + case IITDescriptor::Void: return !Ty->isVoidTy(); + case IITDescriptor::VarArg: return true; + case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); + case IITDescriptor::Token: return !Ty->isTokenTy(); + case IITDescriptor::Metadata: return !Ty->isMetadataTy(); + case IITDescriptor::Half: return !Ty->isHalfTy(); + case IITDescriptor::Float: return !Ty->isFloatTy(); + case IITDescriptor::Double: return !Ty->isDoubleTy(); + case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); + case IITDescriptor::Vector: { + VectorType *VT = dyn_cast(Ty); + return !VT || VT->getNumElements() != D.Vector_Width || + matchIntrinsicType(VT->getElementType(), Infos, ArgTys); + } + case IITDescriptor::Pointer: { + PointerType *PT = dyn_cast(Ty); + return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace || + matchIntrinsicType(PT->getElementType(), Infos, ArgTys); + } + + case IITDescriptor::Struct: { + StructType *ST = dyn_cast(Ty); + if (!ST || ST->getNumElements() != D.Struct_NumElements) + return true; + + for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) + if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys)) + return true; + return false; + } + + case IITDescriptor::Argument: + // Two cases here - If this is the second occurrence of an argument, verify + // that the later instance matches the previous instance. + if (D.getArgumentNumber() < ArgTys.size()) + return Ty != ArgTys[D.getArgumentNumber()]; + + // Otherwise, if this is the first instance of an argument, record it and + // verify the "Any" kind. + assert(D.getArgumentNumber() == ArgTys.size() && "Table consistency error"); + ArgTys.push_back(Ty); + + switch (D.getArgumentKind()) { + case IITDescriptor::AK_Any: return false; // Success + case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); + case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); + case IITDescriptor::AK_AnyVector: return !isa(Ty); + case IITDescriptor::AK_AnyPointer: return !isa(Ty); + } + llvm_unreachable("all argument kinds not covered"); + + case IITDescriptor::ExtendArgument: { + // This may only be used when referring to a previous vector argument. + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(NewTy)) + NewTy = VectorType::getExtendedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth()); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::TruncArgument: { + // This may only be used when referring to a previous vector argument. + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(NewTy)) + NewTy = VectorType::getTruncatedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::HalfVecArgument: + // This may only be used when referring to a previous vector argument. + return D.getArgumentNumber() >= ArgTys.size() || + !isa(ArgTys[D.getArgumentNumber()]) || + VectorType::getHalfElementsVectorType( + cast(ArgTys[D.getArgumentNumber()])) != Ty; + case IITDescriptor::SameVecWidthArgument: { + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + VectorType * ReferenceType = + dyn_cast(ArgTys[D.getArgumentNumber()]); + VectorType *ThisArgType = dyn_cast(Ty); + if (!ThisArgType || !ReferenceType || + (ReferenceType->getVectorNumElements() != + ThisArgType->getVectorNumElements())) + return true; + return matchIntrinsicType(ThisArgType->getVectorElementType(), + Infos, ArgTys); + } + case IITDescriptor::PtrToArgument: { + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + Type * ReferenceType = ArgTys[D.getArgumentNumber()]; + PointerType *ThisArgType = dyn_cast(Ty); + return (!ThisArgType || ThisArgType->getElementType() != ReferenceType); + } + case IITDescriptor::VecOfPtrsToElt: { + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + VectorType * ReferenceType = + dyn_cast (ArgTys[D.getArgumentNumber()]); + VectorType *ThisArgVecTy = dyn_cast(Ty); + if (!ThisArgVecTy || !ReferenceType || + (ReferenceType->getVectorNumElements() != + ThisArgVecTy->getVectorNumElements())) + return true; + PointerType *ThisArgEltTy = + dyn_cast(ThisArgVecTy->getVectorElementType()); + if (!ThisArgEltTy) + return true; + return ThisArgEltTy->getElementType() != + ReferenceType->getVectorElementType(); + } + } + llvm_unreachable("unhandled"); +} + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -441,8 +441,6 @@ void verifyMustTailCall(CallInst &CI); bool performTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT, unsigned ArgNo, std::string &Suffix); - bool verifyIntrinsicType(Type *Ty, ArrayRef &Infos, - SmallVectorImpl &ArgTys); bool verifyIntrinsicIsVarArg(bool isVarArg, ArrayRef &Infos); bool verifyAttributeCount(AttributeSet Attrs, unsigned Params); @@ -3727,150 +3725,6 @@ InstsInThisBlock.insert(&I); } -/// Verify that the specified type (which comes from an intrinsic argument or -/// return value) matches the type constraints specified by the .td file (e.g. -/// an "any integer" argument really is an integer). -/// -/// This returns true on error but does not print a message. -bool Verifier::verifyIntrinsicType(Type *Ty, - ArrayRef &Infos, - SmallVectorImpl &ArgTys) { - using namespace Intrinsic; - - // If we ran out of descriptors, there are too many arguments. - if (Infos.empty()) return true; - IITDescriptor D = Infos.front(); - Infos = Infos.slice(1); - - switch (D.Kind) { - case IITDescriptor::Void: return !Ty->isVoidTy(); - case IITDescriptor::VarArg: return true; - case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); - case IITDescriptor::Token: return !Ty->isTokenTy(); - case IITDescriptor::Metadata: return !Ty->isMetadataTy(); - case IITDescriptor::Half: return !Ty->isHalfTy(); - case IITDescriptor::Float: return !Ty->isFloatTy(); - case IITDescriptor::Double: return !Ty->isDoubleTy(); - case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); - case IITDescriptor::Vector: { - VectorType *VT = dyn_cast(Ty); - return !VT || VT->getNumElements() != D.Vector_Width || - verifyIntrinsicType(VT->getElementType(), Infos, ArgTys); - } - case IITDescriptor::Pointer: { - PointerType *PT = dyn_cast(Ty); - return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace || - verifyIntrinsicType(PT->getElementType(), Infos, ArgTys); - } - - case IITDescriptor::Struct: { - StructType *ST = dyn_cast(Ty); - if (!ST || ST->getNumElements() != D.Struct_NumElements) - return true; - - for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) - if (verifyIntrinsicType(ST->getElementType(i), Infos, ArgTys)) - return true; - return false; - } - - case IITDescriptor::Argument: - // Two cases here - If this is the second occurrence of an argument, verify - // that the later instance matches the previous instance. - if (D.getArgumentNumber() < ArgTys.size()) - return Ty != ArgTys[D.getArgumentNumber()]; - - // Otherwise, if this is the first instance of an argument, record it and - // verify the "Any" kind. - assert(D.getArgumentNumber() == ArgTys.size() && "Table consistency error"); - ArgTys.push_back(Ty); - - switch (D.getArgumentKind()) { - case IITDescriptor::AK_Any: return false; // Success - case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); - case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); - case IITDescriptor::AK_AnyVector: return !isa(Ty); - case IITDescriptor::AK_AnyPointer: return !isa(Ty); - } - llvm_unreachable("all argument kinds not covered"); - - case IITDescriptor::ExtendArgument: { - // This may only be used when referring to a previous vector argument. - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - - Type *NewTy = ArgTys[D.getArgumentNumber()]; - if (VectorType *VTy = dyn_cast(NewTy)) - NewTy = VectorType::getExtendedElementVectorType(VTy); - else if (IntegerType *ITy = dyn_cast(NewTy)) - NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth()); - else - return true; - - return Ty != NewTy; - } - case IITDescriptor::TruncArgument: { - // This may only be used when referring to a previous vector argument. - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - - Type *NewTy = ArgTys[D.getArgumentNumber()]; - if (VectorType *VTy = dyn_cast(NewTy)) - NewTy = VectorType::getTruncatedElementVectorType(VTy); - else if (IntegerType *ITy = dyn_cast(NewTy)) - NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2); - else - return true; - - return Ty != NewTy; - } - case IITDescriptor::HalfVecArgument: - // This may only be used when referring to a previous vector argument. - return D.getArgumentNumber() >= ArgTys.size() || - !isa(ArgTys[D.getArgumentNumber()]) || - VectorType::getHalfElementsVectorType( - cast(ArgTys[D.getArgumentNumber()])) != Ty; - case IITDescriptor::SameVecWidthArgument: { - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - VectorType * ReferenceType = - dyn_cast(ArgTys[D.getArgumentNumber()]); - VectorType *ThisArgType = dyn_cast(Ty); - if (!ThisArgType || !ReferenceType || - (ReferenceType->getVectorNumElements() != - ThisArgType->getVectorNumElements())) - return true; - return verifyIntrinsicType(ThisArgType->getVectorElementType(), - Infos, ArgTys); - } - case IITDescriptor::PtrToArgument: { - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - Type * ReferenceType = ArgTys[D.getArgumentNumber()]; - PointerType *ThisArgType = dyn_cast(Ty); - return (!ThisArgType || ThisArgType->getElementType() != ReferenceType); - } - case IITDescriptor::VecOfPtrsToElt: { - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - VectorType * ReferenceType = - dyn_cast (ArgTys[D.getArgumentNumber()]); - VectorType *ThisArgVecTy = dyn_cast(Ty); - if (!ThisArgVecTy || !ReferenceType || - (ReferenceType->getVectorNumElements() != - ThisArgVecTy->getVectorNumElements())) - return true; - PointerType *ThisArgEltTy = - dyn_cast(ThisArgVecTy->getVectorElementType()); - if (!ThisArgEltTy) - return true; - return ThisArgEltTy->getElementType() != - ReferenceType->getVectorElementType(); - } - } - llvm_unreachable("unhandled"); -} - /// Verify if the intrinsic has variable arguments. This method is intended to /// be called after all the fixed arguments have been verified first. /// @@ -3913,10 +3767,12 @@ ArrayRef TableRef = Table; SmallVector ArgTys; - Assert(!verifyIntrinsicType(IFTy->getReturnType(), TableRef, ArgTys), + Assert(!Intrinsic::matchIntrinsicType(IFTy->getReturnType(), + TableRef, ArgTys), "Intrinsic has incorrect return type!", IF); for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i) - Assert(!verifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys), + Assert(!Intrinsic::matchIntrinsicType(IFTy->getParamType(i), + TableRef, ArgTys), "Intrinsic has incorrect argument type!", IF); // Verify if the intrinsic call matches the vararg property.