diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/IR/Core.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/IR/Mangler.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 10 |
5 files changed, 54 insertions, 31 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 6b202ba..3842b1a 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -55,15 +55,8 @@ foldConstantCastPair( Type *MidTy = Op->getType(); Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode()); Instruction::CastOps secondOp = Instruction::CastOps(opc); - - // Assume that pointers are never more than 64 bits wide, and only use this - // for the middle type. Otherwise we could end up folding away illegal - // bitcasts between address spaces with different sizes. - IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext()); - - // Let CastInst::isEliminableCastPair do the heavy lifting. return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, - nullptr, FakeIntPtrTy, nullptr); + /*DL=*/nullptr); } static Constant *FoldBitCast(Constant *V, Type *DestTy) { diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index df0c85b..3f1cc1e 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -2403,6 +2403,14 @@ LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, GlobalValue::ExternalLinkage, Name, unwrap(M))); } +LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, const char *Name, + size_t NameLen, LLVMTypeRef FunctionTy) { + return wrap(unwrap(M) + ->getOrInsertFunction(StringRef(Name, NameLen), + unwrap<FunctionType>(FunctionTy)) + .getCallee()); +} + LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name) { return wrap(unwrap(M)->getFunction(Name)); } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 941e41f..88e7c44 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2824,10 +2824,10 @@ bool CastInst::isNoopCast(const DataLayout &DL) const { /// The function returns a resultOpcode so these two casts can be replaced with: /// * %Replacement = resultOpcode %SrcTy %x to DstTy /// If no such cast is permitted, the function returns 0. -unsigned CastInst::isEliminableCastPair( - Instruction::CastOps firstOp, Instruction::CastOps secondOp, - Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, - Type *DstIntPtrTy) { +unsigned CastInst::isEliminableCastPair(Instruction::CastOps firstOp, + Instruction::CastOps secondOp, + Type *SrcTy, Type *MidTy, Type *DstTy, + const DataLayout *DL) { // Define the 144 possibilities for these two cast instructions. The values // in this matrix determine what to do in a given situation and select the // case in the switch below. The rows correspond to firstOp, the columns @@ -2936,24 +2936,16 @@ unsigned CastInst::isEliminableCastPair( return 0; // Cannot simplify if address spaces are different! - if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) + if (SrcTy != DstTy) return 0; - unsigned MidSize = MidTy->getScalarSizeInBits(); - // We can still fold this without knowing the actual sizes as long we - // know that the intermediate pointer is the largest possible + // Cannot simplify if the intermediate integer size is smaller than the // pointer size. - // FIXME: Is this always true? - if (MidSize == 64) - return Instruction::BitCast; - - // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size. - if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy) + unsigned MidSize = MidTy->getScalarSizeInBits(); + if (!DL || MidSize < DL->getPointerTypeSizeInBits(SrcTy)) return 0; - unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits(); - if (MidSize >= PtrSize) - return Instruction::BitCast; - return 0; + + return Instruction::BitCast; } case 8: { // ext, trunc -> bitcast, if the SrcTy and DstTy are the same @@ -2973,14 +2965,17 @@ unsigned CastInst::isEliminableCastPair( // zext, sext -> zext, because sext can't sign extend after zext return Instruction::ZExt; case 11: { - // inttoptr, ptrtoint/ptrtoaddr -> bitcast if SrcSize<=PtrSize and - // SrcSize==DstSize - if (!MidIntPtrTy) + // inttoptr, ptrtoint/ptrtoaddr -> bitcast if SrcSize<=PtrSize/AddrSize + // and SrcSize==DstSize + if (!DL) return 0; - unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits(); + unsigned MidSize = secondOp == Instruction::PtrToAddr + ? DL->getAddressSizeInBits(MidTy) + : DL->getPointerTypeSizeInBits(MidTy); unsigned SrcSize = SrcTy->getScalarSizeInBits(); unsigned DstSize = DstTy->getScalarSizeInBits(); - if (SrcSize <= PtrSize && SrcSize == DstSize) + // TODO: Could also produce zext or trunc here. + if (SrcSize <= MidSize && SrcSize == DstSize) return Instruction::BitCast; return 0; } diff --git a/llvm/lib/IR/Mangler.cpp b/llvm/lib/IR/Mangler.cpp index ca6a480..55c825d 100644 --- a/llvm/lib/IR/Mangler.cpp +++ b/llvm/lib/IR/Mangler.cpp @@ -307,6 +307,19 @@ std::optional<std::string> llvm::getArm64ECMangledFunctionName(StringRef Name) { if (Name.contains("$$h")) return std::nullopt; + // Handle MD5 mangled names, which use a slightly different rule from + // other C++ manglings. + // + // A non-Arm64EC function: + // + // ??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@ + // + // An Arm64EC function: + // + // ??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@$$h@ + if (Name.starts_with("??@") && Name.ends_with("@")) + return (Name + "$$h@").str(); + // Ask the demangler where we should insert "$$h". auto InsertIdx = getArm64ECInsertionPointInMangledName(Name); if (!InsertIdx) @@ -324,6 +337,10 @@ llvm::getArm64ECDemangledFunctionName(StringRef Name) { if (Name[0] != '?') return std::nullopt; + // MD5 mangled name; see comment in getArm64ECMangledFunctionName. + if (Name.starts_with("??@") && Name.ends_with("@$$h@")) + return Name.drop_back(4).str(); + // Drop the ARM64EC "$$h" tag. std::pair<StringRef, StringRef> Pair = Name.split("$$h"); if (Pair.second.empty()) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 6b3cd27..71a8a38 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -543,6 +543,7 @@ private: void visitAliasScopeListMetadata(const MDNode *MD); void visitAccessGroupMetadata(const MDNode *MD); void visitCapturesMetadata(Instruction &I, const MDNode *Captures); + void visitAllocTokenMetadata(Instruction &I, MDNode *MD); template <class Ty> bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -5395,6 +5396,12 @@ void Verifier::visitCapturesMetadata(Instruction &I, const MDNode *Captures) { } } +void Verifier::visitAllocTokenMetadata(Instruction &I, MDNode *MD) { + Check(isa<CallBase>(I), "!alloc_token should only exist on calls", &I); + Check(MD->getNumOperands() == 1, "!alloc_token must have 1 operand", MD); + Check(isa<MDString>(MD->getOperand(0)), "expected string", MD); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -5625,6 +5632,9 @@ void Verifier::visitInstruction(Instruction &I) { if (MDNode *Captures = I.getMetadata(LLVMContext::MD_captures)) visitCapturesMetadata(I, Captures); + if (MDNode *MD = I.getMetadata(LLVMContext::MD_alloc_token)) + visitAllocTokenMetadata(I, MD); + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { CheckDI(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N, AreDebugLocsAllowed::Yes); |