diff options
author | Alex Richardson <alexrichardson@google.com> | 2025-08-05 16:25:31 -0700 |
---|---|---|
committer | Alex Richardson <alexrichardson@google.com> | 2025-08-05 16:25:31 -0700 |
commit | a0dcd64920d736f158532ded1d3d6b324a4edfd8 (patch) | |
tree | 05860fd0750091287fd238495d507105628420c1 | |
parent | fc2850fc7657c2ac8bff48818e797929f46168fc (diff) | |
download | llvm-users/arichardson/spr/main.capturetracking-handle-ptrtoaddr.zip llvm-users/arichardson/spr/main.capturetracking-handle-ptrtoaddr.tar.gz llvm-users/arichardson/spr/main.capturetracking-handle-ptrtoaddr.tar.bz2 |
[𝘀𝗽𝗿] changes to main this commit is based onusers/arichardson/spr/main.capturetracking-handle-ptrtoaddr
Created using spr 1.3.6-beta.1
[skip ci]
49 files changed, 708 insertions, 92 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index bac13cc..5279e69 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -12521,6 +12521,59 @@ Example: %Y = ptrtoint ptr %P to i64 ; yields zero extension on 32-bit architecture %Z = ptrtoint <4 x ptr> %P to <4 x i64>; yields vector zero extension for a vector of addresses on 32-bit architecture +.. _i_ptrtoaddr: + +'``ptrtoaddr .. to``' Instruction +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + <result> = ptrtoaddr <ty> <value> to <ty2> ; yields ty2 + +Overview: +""""""""" + +The '``ptrtoaddr``' instruction converts the pointer or a vector of +pointers ``value`` to the underlying integer address (or vector of integers) of +type ``ty2``. This is different from :ref:`ptrtoint <i_ptrtoint>` in that it +only operates on the index bits of the pointer and ignores all other bits. +``ty2`` must be the integer type (or vector of integers) matching the pointer +index width of the address space of ``ty``. + +Arguments: +"""""""""" + +The '``ptrtoaddr``' instruction takes a ``value`` to cast, which must be +a value of type :ref:`pointer <t_pointer>` or a vector of pointers, and a +type to cast it to ``ty2``, which must be an :ref:`integer <t_integer>` or +a vector of integers type. + +Semantics: +"""""""""" + +The '``ptrtoaddr``' instruction converts ``value`` to integer type ``ty2`` by +interpreting the lowest index-width pointer representation bits as an integer. +If the address size and the pointer representation size are the same and +``value`` and ``ty2`` are the same size, then nothing is done (*no-op cast*) +other than a type change. + +The ``ptrtoaddr`` instruction always :ref:`captures the address but not the provenance <pointercapture>` +of the pointer argument. + +Example: +"""""""" +This example assumes pointers in address space 1 are 64 bits in size with an +address width of 32 bits (``p1:64:64:64:32`` :ref:`datalayout string<langref_datalayout>`) +.. code-block:: llvm + + %X = ptrtoaddr ptr addrspace(1) %P to i8 ; extracts low 32 bits and truncates + %Y = ptrtoaddr ptr addrspace(1) %P to i64 ; extracts low 32 bits and zero extends + %Z = ptrtoaddr <4 x ptr addrspace(1)> %P to <4 x i64>; yields vector zero extension of low 32 bits for each pointer + + .. _i_inttoptr: '``inttoptr .. to``' Instruction diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 021f321..c15d148 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -56,6 +56,10 @@ Makes programs 10x faster by doing Special New Thing. Changes to the LLVM IR ---------------------- +* The `ptrtoaddr` instruction was introduced. This instruction returns the + address component of a pointer type variable but unlike `ptrtoint` does not + capture provenance ([#125687](https://github.com/llvm/llvm-project/pull/125687)). + Changes to LLVM infrastructure ------------------------------ diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index d645646..9879d0d 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -111,6 +111,7 @@ typedef enum { LLVMFPTrunc = 37, LLVMFPExt = 38, LLVMPtrToInt = 39, + LLVMPtrToAddr = 69, LLVMIntToPtr = 40, LLVMBitCast = 41, LLVMAddrSpaceCast = 60, diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 2ea87b3..9e0f37a9 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -731,6 +731,12 @@ public: return 0; break; } + case Instruction::PtrToAddr: { + unsigned DstSize = Dst->getScalarSizeInBits(); + if (DL.isLegalInteger(DstSize) && DstSize >= DL.getAddressSizeInBits(Src)) + return 0; + break; + } case Instruction::PtrToInt: { unsigned DstSize = Dst->getScalarSizeInBits(); if (DL.isLegalInteger(DstSize) && @@ -1437,6 +1443,7 @@ public: Op2Info, Operands, I); } case Instruction::IntToPtr: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::SIToFP: case Instruction::UIToFP: diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index a2311d2..e6a0eae 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -319,6 +319,7 @@ enum Kind { kw_fptoui, kw_fptosi, kw_inttoptr, + kw_ptrtoaddr, kw_ptrtoint, kw_bitcast, kw_addrspacecast, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index dc78eb4..1c7d346 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -456,7 +456,8 @@ enum CastOpcodes { CAST_PTRTOINT = 9, CAST_INTTOPTR = 10, CAST_BITCAST = 11, - CAST_ADDRSPACECAST = 12 + CAST_ADDRSPACECAST = 12, + CAST_PTRTOADDR = 13, }; /// UnaryOpcodes - These are values used in the bitcode files to encode which diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 6fd05c8..3d7ccd5 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -486,6 +486,10 @@ private: bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) { return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder); } + bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) { + // FIXME: this is not correct for pointers with addr width != pointer width + return translatePtrToInt(U, MIRBuilder); + } bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) { return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder); } diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index 9c9fc88..e06e6ad 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1158,6 +1158,8 @@ public: LLVM_ABI static Constant *getXor(Constant *C1, Constant *C2); LLVM_ABI static Constant *getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced = false); + LLVM_ABI static Constant *getPtrToAddr(Constant *C, Type *Ty, + bool OnlyIfReduced = false); LLVM_ABI static Constant *getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced = false); LLVM_ABI static Constant *getIntToPtr(Constant *C, Type *Ty, diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 7c600e7..3d449e9 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2192,7 +2192,10 @@ public: return CreateCast(Instruction::FPExt, V, DestTy, Name, FPMathTag, FMFSource); } - + Value *CreatePtrToAddr(Value *V, const Twine &Name = "") { + return CreateCast(Instruction::PtrToInt, V, + BB->getDataLayout().getAddressType(V->getType()), Name); + } Value *CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::PtrToInt, V, DestTy, Name); diff --git a/llvm/include/llvm/IR/InstVisitor.h b/llvm/include/llvm/IR/InstVisitor.h index 6d5398b..8e4dc64 100644 --- a/llvm/include/llvm/IR/InstVisitor.h +++ b/llvm/include/llvm/IR/InstVisitor.h @@ -183,6 +183,7 @@ public: RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);} RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);} RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);} + RetTy visitPtrToAddrInst(PtrToAddrInst &I) { DELEGATE(CastInst);} RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);} RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);} RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);} diff --git a/llvm/include/llvm/IR/Instruction.def b/llvm/include/llvm/IR/Instruction.def index a5ad92f..face6a9 100644 --- a/llvm/include/llvm/IR/Instruction.def +++ b/llvm/include/llvm/IR/Instruction.def @@ -190,35 +190,36 @@ HANDLE_CAST_INST(43, UIToFP , UIToFPInst ) // UInt -> floating point HANDLE_CAST_INST(44, SIToFP , SIToFPInst ) // SInt -> floating point HANDLE_CAST_INST(45, FPTrunc , FPTruncInst ) // Truncate floating point HANDLE_CAST_INST(46, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(48, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(49, BitCast , BitCastInst ) // Type cast -HANDLE_CAST_INST(50, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast - LAST_CAST_INST(50) +HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer (bitcast) +HANDLE_CAST_INST(48, PtrToAddr, PtrToAddrInst) // Pointer -> Address +HANDLE_CAST_INST(49, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(50, BitCast , BitCastInst ) // Type cast +HANDLE_CAST_INST(51, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast + LAST_CAST_INST(51) - FIRST_FUNCLETPAD_INST(51) -HANDLE_FUNCLETPAD_INST(51, CleanupPad, CleanupPadInst) -HANDLE_FUNCLETPAD_INST(52, CatchPad , CatchPadInst) - LAST_FUNCLETPAD_INST(52) + FIRST_FUNCLETPAD_INST(52) +HANDLE_FUNCLETPAD_INST(52, CleanupPad, CleanupPadInst) +HANDLE_FUNCLETPAD_INST(53, CatchPad , CatchPadInst) + LAST_FUNCLETPAD_INST(53) // Other operators... - FIRST_OTHER_INST(53) -HANDLE_OTHER_INST(53, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(54, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(55, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(56, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(57, Select , SelectInst ) // select instruction -HANDLE_USER_INST (58, UserOp1, Instruction) // May be used internally in a pass -HANDLE_USER_INST (59, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(60, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(61, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(62, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(63, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(64, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(65, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(66, LandingPad, LandingPadInst) // Landing pad instruction. -HANDLE_OTHER_INST(67, Freeze, FreezeInst) // Freeze instruction. - LAST_OTHER_INST(67) + FIRST_OTHER_INST(54) +HANDLE_OTHER_INST(54, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(55, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(56, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(57, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(58, Select , SelectInst ) // select instruction +HANDLE_USER_INST (59, UserOp1, Instruction) // May be used internally in a pass +HANDLE_USER_INST (60, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(61, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(62, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(63, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(64, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(65, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(66, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(67, LandingPad, LandingPadInst) // Landing pad instruction. +HANDLE_OTHER_INST(68, Freeze, FreezeInst) // Freeze instruction. + LAST_OTHER_INST(68) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 6f69b68..95a0a7f 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -4949,6 +4949,46 @@ public: } }; +/// This class represents a cast from a pointer to an address (non-capturing +/// ptrtoint). +class PtrToAddrInst : public CastInst { +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + + /// Clone an identical PtrToAddrInst. + PtrToAddrInst *cloneImpl() const; + +public: + /// Constructor with insert-before-instruction semantics + PtrToAddrInst(Value *S, ///< The value to be converted + Type *Ty, ///< The type to convert to + const Twine &NameStr = "", ///< A name for the new instruction + InsertPosition InsertBefore = + nullptr ///< Where to insert the new instruction + ); + + /// Gets the pointer operand. + Value *getPointerOperand() { return getOperand(0); } + /// Gets the pointer operand. + const Value *getPointerOperand() const { return getOperand(0); } + /// Gets the operand index of the pointer operand. + static unsigned getPointerOperandIndex() { return 0U; } + + /// Returns the address space of the pointer operand. + unsigned getPointerAddressSpace() const { + return getPointerOperand()->getType()->getPointerAddressSpace(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return I->getOpcode() == PtrToAddr; + } + static bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + //===----------------------------------------------------------------------===// // BitCastInst Class //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h index 8344eae..10816c0 100644 --- a/llvm/include/llvm/IR/Operator.h +++ b/llvm/include/llvm/IR/Operator.h @@ -595,6 +595,37 @@ struct OperandTraits<PtrToIntOperator> DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PtrToIntOperator, Value) +class PtrToAddrOperator + : public ConcreteOperator<Operator, Instruction::PtrToAddr> { + friend class PtrToAddr; + friend class ConstantExpr; + +public: + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + Value *getPointerOperand() { return getOperand(0); } + const Value *getPointerOperand() const { return getOperand(0); } + + static unsigned getPointerOperandIndex() { + return 0U; // get index for modifying correct operand + } + + /// Method to return the pointer operand as a PointerType. + Type *getPointerOperandType() const { return getPointerOperand()->getType(); } + + /// Method to return the address space of the pointer operand. + unsigned getPointerAddressSpace() const { + return cast<PointerType>(getPointerOperandType())->getAddressSpace(); + } +}; + +template <> +struct OperandTraits<PtrToAddrOperator> + : public FixedNumOperandTraits<PtrToAddrOperator, 1> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PtrToAddrOperator, Value) + class BitCastOperator : public ConcreteOperator<Operator, Instruction::BitCast> { friend class BitCastInst; diff --git a/llvm/include/llvm/SandboxIR/Instruction.h b/llvm/include/llvm/SandboxIR/Instruction.h index 4e3ff19..e1c1ca0 100644 --- a/llvm/include/llvm/SandboxIR/Instruction.h +++ b/llvm/include/llvm/SandboxIR/Instruction.h @@ -2278,6 +2278,8 @@ class CastInst : public UnaryInstruction { return Opcode::FPToSI; case llvm::Instruction::FPExt: return Opcode::FPExt; + case llvm::Instruction::PtrToAddr: + return Opcode::PtrToAddr; case llvm::Instruction::PtrToInt: return Opcode::PtrToInt; case llvm::Instruction::IntToPtr: @@ -2364,6 +2366,8 @@ class FPToUIInst final : public CastInstImpl<Instruction::Opcode::FPToUI> {}; class FPToSIInst final : public CastInstImpl<Instruction::Opcode::FPToSI> {}; class IntToPtrInst final : public CastInstImpl<Instruction::Opcode::IntToPtr> { }; +class PtrToAddrInst final + : public CastInstImpl<Instruction::Opcode::PtrToAddr> {}; class PtrToIntInst final : public CastInstImpl<Instruction::Opcode::PtrToInt> { }; class BitCastInst final : public CastInstImpl<Instruction::Opcode::BitCast> {}; diff --git a/llvm/include/llvm/SandboxIR/Values.def b/llvm/include/llvm/SandboxIR/Values.def index a55abbd..72683e4 100644 --- a/llvm/include/llvm/SandboxIR/Values.def +++ b/llvm/include/llvm/SandboxIR/Values.def @@ -118,6 +118,7 @@ DEF_INSTR(Cast, OPCODES(\ OP(FPToUI) \ OP(FPToSI) \ OP(FPExt) \ + OP(PtrToAddr) \ OP(PtrToInt) \ OP(IntToPtr) \ OP(SIToFP) \ diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 759c553..338f9e8 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1482,6 +1482,20 @@ Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C, switch (Opcode) { default: llvm_unreachable("Missing case"); + case Instruction::PtrToAddr: + if (auto *GEP = dyn_cast<GEPOperator>(C)) { + // For now just handle the basic case of GEPs on NULL for ptrtoaddr. + // (ptrtoaddr (gep null, x)) -> x + // (ptrtoaddr (gep (gep null, x), y) -> x + y, etc. + unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); + APInt BaseOffset(BitWidth, 0); + auto *Base = cast<Constant>(GEP->stripAndAccumulateConstantOffsets( + DL, BaseOffset, /*AllowNonInbounds=*/true)); + if (Base->isNullValue()) { + return ConstantInt::get(C->getContext(), BaseOffset); + } + } + break; case Instruction::PtrToInt: if (auto *CE = dyn_cast<ConstantExpr>(C)) { Constant *FoldedValue = nullptr; diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 520c6a0..3d5bd61 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -928,6 +928,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(fptoui, FPToUI); INSTKEYWORD(fptosi, FPToSI); INSTKEYWORD(inttoptr, IntToPtr); + INSTKEYWORD(ptrtoaddr, PtrToAddr); INSTKEYWORD(ptrtoint, PtrToInt); INSTKEYWORD(bitcast, BitCast); INSTKEYWORD(addrspacecast, AddrSpaceCast); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 13bef1f..1bc2906 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4273,6 +4273,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { case lltok::kw_bitcast: case lltok::kw_addrspacecast: case lltok::kw_inttoptr: + case lltok::kw_ptrtoaddr: case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); Type *DestTy = nullptr; @@ -7310,6 +7311,7 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_fptoui: case lltok::kw_fptosi: case lltok::kw_inttoptr: + case lltok::kw_ptrtoaddr: case lltok::kw_ptrtoint: return parseCast(Inst, PFS, KeywordVal); case lltok::kw_fptrunc: diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 290d873..22a0d0f 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1283,6 +1283,7 @@ static int getDecodedCastOpcode(unsigned Val) { case bitc::CAST_SITOFP : return Instruction::SIToFP; case bitc::CAST_FPTRUNC : return Instruction::FPTrunc; case bitc::CAST_FPEXT : return Instruction::FPExt; + case bitc::CAST_PTRTOADDR: return Instruction::PtrToAddr; case bitc::CAST_PTRTOINT: return Instruction::PtrToInt; case bitc::CAST_INTTOPTR: return Instruction::IntToPtr; case bitc::CAST_BITCAST : return Instruction::BitCast; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 7e0d81f..f01aa69 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -647,6 +647,7 @@ static unsigned getEncodedCastOpcode(unsigned Opcode) { case Instruction::SIToFP : return bitc::CAST_SITOFP; case Instruction::FPTrunc : return bitc::CAST_FPTRUNC; case Instruction::FPExt : return bitc::CAST_FPEXT; + case Instruction::PtrToAddr: return bitc::CAST_PTRTOADDR; case Instruction::PtrToInt: return bitc::CAST_PTRTOINT; case Instruction::IntToPtr: return bitc::CAST_INTTOPTR; case Instruction::BitCast : return bitc::CAST_BITCAST; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 6166271..30c022d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3549,6 +3549,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV, break; // Error } + case Instruction::PtrToAddr: case Instruction::PtrToInt: { const DataLayout &DL = getDataLayout(); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 1636465..a0b9e90 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3974,6 +3974,11 @@ void SelectionDAGBuilder::visitSIToFP(const User &I) { setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurSDLoc(), DestVT, N)); } +void SelectionDAGBuilder::visitPtrToAddr(const User &I) { + // FIXME: this is not correct for pointers with addr width != pointer width + visitPtrToInt(I); +} + void SelectionDAGBuilder::visitPtrToInt(const User &I) { // What to do depends on the size of the integer and the size of the pointer. // We can either truncate, zero extend, or no-op, accordingly. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 1c27807..ccb87c6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -574,6 +574,7 @@ private: void visitFPToSI(const User &I); void visitUIToFP(const User &I); void visitSIToFP(const User &I); + void visitPtrToAddr(const User &I); void visitPtrToInt(const User &I); void visitIntToPtr(const User &I); void visitBitCast(const User &I); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 68b8a00..b751328 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1892,6 +1892,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const { case SIToFP: return ISD::SINT_TO_FP; case FPTrunc: return ISD::FP_ROUND; case FPExt: return ISD::FP_EXTEND; + case PtrToAddr: return ISD::BITCAST; case PtrToInt: return ISD::BITCAST; case IntToPtr: return ISD::BITCAST; case BitCast: return ISD::BITCAST; diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index d4ad21e..6b202ba 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -254,6 +254,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, return FoldBitCast(V, DestTy); case Instruction::AddrSpaceCast: case Instruction::IntToPtr: + case Instruction::PtrToAddr: case Instruction::PtrToInt: return nullptr; } diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index e09c139..2fcdbcc6 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -829,6 +829,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp, case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::IntToPtr: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::AddrSpaceCast: // Conservatively return getFull set. diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index a3c725b..c7e3113a 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1567,6 +1567,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty, case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: @@ -2223,6 +2224,8 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty, llvm_unreachable("Invalid cast opcode"); case Instruction::Trunc: return getTrunc(C, Ty, OnlyIfReduced); + case Instruction::PtrToAddr: + return getPtrToAddr(C, Ty, OnlyIfReduced); case Instruction::PtrToInt: return getPtrToInt(C, Ty, OnlyIfReduced); case Instruction::IntToPtr: @@ -2280,6 +2283,20 @@ Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) { return getFoldedCast(Instruction::Trunc, C, Ty, OnlyIfReduced); } +Constant *ConstantExpr::getPtrToAddr(Constant *C, Type *DstTy, + bool OnlyIfReduced) { + assert(C->getType()->isPtrOrPtrVectorTy() && + "PtrToAddr source must be pointer or pointer vector"); + assert(DstTy->isIntOrIntVectorTy() && + "PtrToAddr destination must be integer or integer vector"); + assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy)); + if (isa<VectorType>(C->getType())) + assert(cast<VectorType>(C->getType())->getElementCount() == + cast<VectorType>(DstTy)->getElementCount() && + "Invalid cast between a different number of vector elements"); + return getFoldedCast(Instruction::PtrToAddr, C, DstTy, OnlyIfReduced); +} + Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy, bool OnlyIfReduced) { assert(C->getType()->isPtrOrPtrVectorTy() && @@ -2435,6 +2452,7 @@ bool ConstantExpr::isDesirableCastOp(unsigned Opcode) { case Instruction::FPToSI: return false; case Instruction::Trunc: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: @@ -2457,6 +2475,7 @@ bool ConstantExpr::isSupportedCastOp(unsigned Opcode) { case Instruction::FPToSI: return false; case Instruction::Trunc: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: @@ -3401,6 +3420,7 @@ Instruction *ConstantExpr::getAsInstruction() const { switch (getOpcode()) { case Instruction::Trunc: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 7b799c7..11d33e2 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -404,6 +404,7 @@ findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases, return findBaseObject(CE->getOperand(0), Aliases, Op); } case Instruction::IntToPtr: + case Instruction::PtrToAddr: case Instruction::PtrToInt: case Instruction::BitCast: case Instruction::GetElementPtr: diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 763cc18..2ed9425 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -817,6 +817,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case UIToFP: return "uitofp"; case SIToFP: return "sitofp"; case IntToPtr: return "inttoptr"; + case PtrToAddr: return "ptrtoaddr"; case PtrToInt: return "ptrtoint"; case BitCast: return "bitcast"; case AddrSpaceCast: return "addrspacecast"; diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index b896382..a1751c0 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2798,6 +2798,7 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode, return false; case Instruction::BitCast: return true; // BitCast never modifies bits. + case Instruction::PtrToAddr: case Instruction::PtrToInt: return DL.getIntPtrType(SrcTy)->getScalarSizeInBits() == DestTy->getScalarSizeInBits(); @@ -2855,26 +2856,29 @@ unsigned CastInst::isEliminableCastPair( // same reason. const unsigned numCastOps = Instruction::CastOpsEnd - Instruction::CastOpsBegin; + // clang-format off static const uint8_t CastResults[numCastOps][numCastOps] = { - // T F F U S F F P I B A -+ - // R Z S P P I I T P 2 N T S | - // U E E 2 2 2 2 R E I T C C +- secondOp - // N X X U S F F N X N 2 V V | - // C T T I I P P C T T P T T -+ - { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ - { 8, 1, 9,99,99, 2,17,99,99,99, 2, 3, 0}, // ZExt | - { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // FPTrunc | - { 99,99,99, 2, 2,99,99, 8, 2,99,99, 4, 0}, // FPExt | - { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | - { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | - { 5, 5, 5, 0, 0, 5, 5, 0, 0,16, 5, 1,14}, // BitCast | - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ + // T F F U S F F P P I B A -+ + // R Z S P P I I T P 2 2 N T S | + // U E E 2 2 2 2 R E I A T C C +- secondOp + // N X X U S F F N X N D 2 V V | + // C T T I I P P C T T R P T T -+ + { 1, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // Trunc -+ + { 8, 1, 9,99,99, 2,17,99,99,99,99, 2, 3, 0}, // ZExt | + { 8, 0, 1,99,99, 0, 2,99,99,99,99, 0, 3, 0}, // SExt | + { 0, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // FPToUI | + { 0, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // FPToSI | + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // UIToFP +- firstOp + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // SIToFP | + { 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // FPTrunc | + { 99,99,99, 2, 2,99,99, 8, 2,99,99,99, 4, 0}, // FPExt | + { 1, 0, 0,99,99, 0, 0,99,99,99,99, 7, 3, 0}, // PtrToInt | + { 1, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // PtrToAddr | + { 99,99,99,99,99,99,99,99,99,11,99,99,15, 0}, // IntToPtr | + { 5, 5, 5, 0, 0, 5, 5, 0, 0,16,16, 5, 1,14}, // BitCast | + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ }; + // clang-format on // TODO: This logic could be encoded into the table above and handled in the // switch below. @@ -3046,6 +3050,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); + case PtrToAddr: return new PtrToAddrInst (S, Ty, Name, InsertBefore); case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); case BitCast: @@ -3347,6 +3352,7 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) { case Instruction::FPToSI: return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && SrcEC == DstEC; + case Instruction::PtrToAddr: case Instruction::PtrToInt: if (SrcEC != DstEC) return false; @@ -3460,6 +3466,12 @@ PtrToIntInst::PtrToIntInst(Value *S, Type *Ty, const Twine &Name, assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } +PtrToAddrInst::PtrToAddrInst(Value *S, Type *Ty, const Twine &Name, + InsertPosition InsertBefore) + : CastInst(Ty, PtrToAddr, S, Name, InsertBefore) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToAddr"); +} + IntToPtrInst::IntToPtrInst(Value *S, Type *Ty, const Twine &Name, InsertPosition InsertBefore) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { @@ -4427,6 +4439,10 @@ PtrToIntInst *PtrToIntInst::cloneImpl() const { return new PtrToIntInst(getOperand(0), getType()); } +PtrToAddrInst *PtrToAddrInst::cloneImpl() const { + return new PtrToAddrInst(getOperand(0), getType()); +} + IntToPtrInst *IntToPtrInst::cloneImpl() const { return new IntToPtrInst(getOperand(0), getType()); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 3ff9895..d96edb3 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -566,6 +566,7 @@ private: void visitUIToFPInst(UIToFPInst &I); void visitSIToFPInst(SIToFPInst &I); void visitIntToPtrInst(IntToPtrInst &I); + void visitPtrToAddrInst(PtrToAddrInst &I); void visitPtrToIntInst(PtrToIntInst &I); void visitBitCastInst(BitCastInst &I); void visitAddrSpaceCastInst(AddrSpaceCastInst &I); @@ -3532,6 +3533,28 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) { visitInstruction(I); } +void Verifier::visitPtrToAddrInst(PtrToAddrInst &I) { + // Get the source and destination types + Type *SrcTy = I.getOperand(0)->getType(); + Type *DestTy = I.getType(); + + Check(SrcTy->isPtrOrPtrVectorTy(), "PtrToAddr source must be pointer", &I); + Check(DestTy->isIntOrIntVectorTy(), "PtrToAddr result must be integral", &I); + Check(SrcTy->isVectorTy() == DestTy->isVectorTy(), "PtrToAddr type mismatch", + &I); + + if (SrcTy->isVectorTy()) { + auto *VSrc = cast<VectorType>(SrcTy); + auto *VDest = cast<VectorType>(DestTy); + Check(VSrc->getElementCount() == VDest->getElementCount(), + "PtrToAddr vector width mismatch", &I); + } + + Type *AddrTy = DL.getAddressType(SrcTy); + Check(AddrTy == DestTy, "PtrToAddr result must be address width", &I); + visitInstruction(I); +} + void Verifier::visitPtrToIntInst(PtrToIntInst &I) { // Get the source and destination types Type *SrcTy = I.getOperand(0)->getType(); diff --git a/llvm/lib/SandboxIR/Context.cpp b/llvm/lib/SandboxIR/Context.cpp index fe34037..70ac68a 100644 --- a/llvm/lib/SandboxIR/Context.cpp +++ b/llvm/lib/SandboxIR/Context.cpp @@ -256,6 +256,7 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) { case llvm::Instruction::FPToUI: case llvm::Instruction::FPToSI: case llvm::Instruction::FPExt: + case llvm::Instruction::PtrToAddr: case llvm::Instruction::PtrToInt: case llvm::Instruction::IntToPtr: case llvm::Instruction::SIToFP: diff --git a/llvm/lib/SandboxIR/Instruction.cpp b/llvm/lib/SandboxIR/Instruction.cpp index 956047c..1a81d18 100644 --- a/llvm/lib/SandboxIR/Instruction.cpp +++ b/llvm/lib/SandboxIR/Instruction.cpp @@ -1007,6 +1007,9 @@ static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) { return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI); case Instruction::Opcode::FPExt: return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt); + case Instruction::Opcode::PtrToAddr: + return static_cast<llvm::Instruction::CastOps>( + llvm::Instruction::PtrToAddr); case Instruction::Opcode::PtrToInt: return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt); case Instruction::Opcode::IntToPtr: diff --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp index b3bffeb..e12cf7c 100644 --- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp +++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp @@ -263,6 +263,7 @@ static bool isUniformShape(Value *V) { case llvm::Instruction::FPExt: return true; case llvm::Instruction::AddrSpaceCast: + case CastInst::PtrToAddr: case CastInst::PtrToInt: case CastInst::IntToPtr: return false; diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp index f32d57f..e414c12 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp @@ -81,6 +81,7 @@ LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes( case Instruction::Opcode::FPToUI: case Instruction::Opcode::FPToSI: case Instruction::Opcode::FPExt: + case Instruction::Opcode::PtrToAddr: case Instruction::Opcode::PtrToInt: case Instruction::Opcode::IntToPtr: case Instruction::Opcode::SIToFP: diff --git a/llvm/test/Analysis/IR2Vec/Inputs/dummy_2D_vocab.json b/llvm/test/Analysis/IR2Vec/Inputs/dummy_2D_vocab.json index 9b38f2e..07fde84 100644 --- a/llvm/test/Analysis/IR2Vec/Inputs/dummy_2D_vocab.json +++ b/llvm/test/Analysis/IR2Vec/Inputs/dummy_2D_vocab.json @@ -47,6 +47,7 @@ "FPTrunc": [89, 90], "FPExt": [91, 92], "PtrToInt": [93, 94], + "PtrToAddr": [135, 136], "IntToPtr": [95, 96], "BitCast": [97, 98], "AddrSpaceCast": [99, 100], diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt index 79fcf82..1b9b3c2 100644 --- a/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt +++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt @@ -45,6 +45,7 @@ Key: SIToFP: [ 87.00 88.00 ] Key: FPTrunc: [ 89.00 90.00 ] Key: FPExt: [ 91.00 92.00 ] Key: PtrToInt: [ 93.00 94.00 ] +Key: PtrToAddr: [ 135.00 136.00 ] Key: IntToPtr: [ 95.00 96.00 ] Key: BitCast: [ 97.00 98.00 ] Key: AddrSpaceCast: [ 99.00 100.00 ] diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt index 584bd31..9673e7f 100644 --- a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt +++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt @@ -45,6 +45,7 @@ Key: SIToFP: [ 43.50 44.00 ] Key: FPTrunc: [ 44.50 45.00 ] Key: FPExt: [ 45.50 46.00 ] Key: PtrToInt: [ 46.50 47.00 ] +Key: PtrToAddr: [ 67.50 68.00 ] Key: IntToPtr: [ 47.50 48.00 ] Key: BitCast: [ 48.50 49.00 ] Key: AddrSpaceCast: [ 49.50 50.00 ] diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt index 2727c85..1f575d2 100644 --- a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt +++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt @@ -45,6 +45,7 @@ Key: SIToFP: [ 8.70 8.80 ] Key: FPTrunc: [ 8.90 9.00 ] Key: FPExt: [ 9.10 9.20 ] Key: PtrToInt: [ 9.30 9.40 ] +Key: PtrToAddr: [ 13.50 13.60 ] Key: IntToPtr: [ 9.50 9.60 ] Key: BitCast: [ 9.70 9.80 ] Key: AddrSpaceCast: [ 9.90 10.00 ] diff --git a/llvm/test/Assembler/ptrtoaddr-invalid.ll b/llvm/test/Assembler/ptrtoaddr-invalid.ll new file mode 100644 index 0000000..dff787b --- /dev/null +++ b/llvm/test/Assembler/ptrtoaddr-invalid.ll @@ -0,0 +1,84 @@ +;; Check all requirements on the ptrtoaddr instruction operands +;; Most of these invalid cases are detected at parse time but some are only +;; detected at verification time (see Verifier::visitPtrToAddrInst()) +; RUN: rm -rf %t && split-file --leading-lines %s %t + +;--- src_vec_dst_no_vec.ll +; RUN: not llvm-as %t/src_vec_dst_no_vec.ll -o /dev/null 2>&1 | FileCheck -check-prefix=SRC_VEC_DST_NO_VEC %s --implicit-check-not="error:" +define i64 @bad(<2 x ptr> %p) { + %addr = ptrtoaddr <2 x ptr> %p to i64 + ; SRC_VEC_DST_NO_VEC: [[#@LINE-1]]:21: error: invalid cast opcode for cast from '<2 x ptr>' to 'i64' + ret i64 %addr +} + +;--- src_no_vec_dst_vec.ll +; RUN: not llvm-as %t/src_no_vec_dst_vec.ll -o /dev/null 2>&1 | FileCheck -check-prefix=SRC_NO_VEC_DST_VEC %s --implicit-check-not="error:" +define <2 x i64> @bad(ptr %p) { + %addr = ptrtoaddr ptr %p to <2 x i64> + ; SRC_NO_VEC_DST_VEC: [[#@LINE-1]]:21: error: invalid cast opcode for cast from 'ptr' to '<2 x i64>' + ret <2 x i64> %addr +} + +;--- dst_not_int.ll +; RUN: not llvm-as %t/dst_not_int.ll -o /dev/null 2>&1 | FileCheck -check-prefix=DST_NOT_INT %s --implicit-check-not="error:" +define float @bad(ptr %p) { + %addr = ptrtoaddr ptr %p to float + ; DST_NOT_INT: [[#@LINE-1]]:21: error: invalid cast opcode for cast from 'ptr' to 'float' + ret float %addr +} + +;--- dst_not_int_vec.ll +; RUN: not llvm-as %t/dst_not_int_vec.ll -o /dev/null 2>&1 | FileCheck -check-prefix=DST_NOT_INT_VEC %s --implicit-check-not="error:" +define <2 x float> @bad(<2 x ptr> %p) { + %addr = ptrtoaddr <2 x ptr> %p to <2 x float> + ; DST_NOT_INT_VEC: [[#@LINE-1]]:21: error: invalid cast opcode for cast from '<2 x ptr>' to '<2 x float>' + ret <2 x float> %addr +} + +;--- src_not_ptr.ll +; RUN: not llvm-as %t/src_not_ptr.ll -o /dev/null 2>&1 | FileCheck -check-prefix=SRC_NOT_PTR %s --implicit-check-not="error:" +define i64 @bad(i32 %p) { + %addr = ptrtoaddr i32 %p to i64 + ; SRC_NOT_PTR: [[#@LINE-1]]:21: error: invalid cast opcode for cast from 'i32' to 'i64' + ret i64 %addr +} + +;--- src_not_ptr_vec.ll +; RUN: not llvm-as %t/src_not_ptr_vec.ll -o /dev/null 2>&1 | FileCheck -check-prefix=SRC_NOT_PTR_VEC %s --implicit-check-not="error:" +define <2 x i64> @bad(<2 x i32> %p) { + %addr = ptrtoaddr <2 x i32> %p to <2 x i64> + ; SRC_NOT_PTR_VEC: [[#@LINE-1]]:21: error: invalid cast opcode for cast from '<2 x i32>' to '<2 x i64>' + ret <2 x i64> %addr +} + +;--- vec_src_fewer_elems.ll +; RUN: not llvm-as %t/vec_src_fewer_elems.ll -o /dev/null 2>&1 | FileCheck -check-prefix=VEC_SRC_FEWER_ELEMS %s --implicit-check-not="error:" +define <4 x i64> @bad(<2 x ptr> %p) { + %addr = ptrtoaddr <2 x ptr> %p to <4 x i64> + ; VEC_SRC_FEWER_ELEMS: [[#@LINE-1]]:21: error: invalid cast opcode for cast from '<2 x ptr>' to '<4 x i64>' + ret <4 x i64> %addr +} + +;--- vec_dst_fewer_elems.ll +; RUN: not llvm-as %t/vec_dst_fewer_elems.ll -o /dev/null 2>&1 | FileCheck -check-prefix=VEC_DST_FEWER_ELEMS %s --implicit-check-not="error:" +define <2 x i64> @bad(<4 x ptr> %p) { + %addr = ptrtoaddr <4 x ptr> %p to <2 x i64> + ; VEC_DST_FEWER_ELEMS: [[#@LINE-1]]:21: error: invalid cast opcode for cast from '<4 x ptr>' to '<2 x i64>' + ret <2 x i64> %addr +} + +;--- dst_not_addr_size.ll +; The following invalid IR is caught by the verifier, not the parser: +; RUN: llvm-as %t/dst_not_addr_size.ll --disable-output --disable-verify +; RUN: not llvm-as %t/dst_not_addr_size.ll -o /dev/null 2>&1 | FileCheck -check-prefix=DST_NOT_ADDR_SIZE %s --implicit-check-not="error:" +; DST_NOT_ADDR_SIZE: assembly parsed, but does not verify as correct! +define i32 @bad(ptr %p) { + %addr = ptrtoaddr ptr %p to i32 + ; DST_NOT_ADDR_SIZE: PtrToAddr result must be address width + ret i32 %addr +} +define <4 x i32> @bad_vec(<4 x ptr> %p) { + %addr = ptrtoaddr <4 x ptr> %p to <4 x i32> + ; DST_NOT_ADDR_SIZE: PtrToAddr result must be address width + ret <4 x i32> %addr +} diff --git a/llvm/test/Assembler/ptrtoaddr.ll b/llvm/test/Assembler/ptrtoaddr.ll new file mode 100644 index 0000000..f21410b --- /dev/null +++ b/llvm/test/Assembler/ptrtoaddr.ll @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +target datalayout = "p1:64:64:64:32" + +@i_as0 = global i32 0 +@global_cast_as0 = global i64 ptrtoaddr (ptr @i_as0 to i64) +; CHECK: @global_cast_as0 = global i64 ptrtoaddr (ptr @i_as0 to i64) +@i_as1 = addrspace(1) global i32 0 +@global_cast_as1 = global i32 ptrtoaddr (ptr addrspace(1) @i_as1 to i32) +; CHECK: @global_cast_as1 = global i32 ptrtoaddr (ptr addrspace(1) @i_as1 to i32) + +define i64 @test_as0(ptr %p) { + %addr = ptrtoaddr ptr %p to i64 + ; CHECK: %addr = ptrtoaddr ptr %p to i64 + ret i64 %addr +} + +define i32 @test_as1(ptr addrspace(1) %p) { + %addr = ptrtoaddr ptr addrspace(1) %p to i32 + ; CHECK: %addr = ptrtoaddr ptr addrspace(1) %p to i32 + ret i32 %addr +} + +define <2 x i32> @test_vec_as1(<2 x ptr addrspace(1)> %p) { + %addr = ptrtoaddr <2 x ptr addrspace(1)> %p to <2 x i32> + ; CHECK: %addr = ptrtoaddr <2 x ptr addrspace(1)> %p to <2 x i32> + ret <2 x i32> %addr +} diff --git a/llvm/test/Bitcode/ptrtoaddr.ll b/llvm/test/Bitcode/ptrtoaddr.ll new file mode 100644 index 0000000..6c5fed2 --- /dev/null +++ b/llvm/test/Bitcode/ptrtoaddr.ll @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +target datalayout = "p1:64:64:64:32" + +@i_as0 = global i32 0 +@global_cast_as0 = global i64 ptrtoaddr (ptr @i_as0 to i64) +; CHECK: @global_cast_as0 = global i64 ptrtoaddr (ptr @i_as0 to i64) +@i_as1 = addrspace(1) global i32 0 +@global_cast_as1 = global i32 ptrtoaddr (ptr addrspace(1) @i_as1 to i32) +; CHECK: @global_cast_as1 = global i32 ptrtoaddr (ptr addrspace(1) @i_as1 to i32) + +define i64 @test_as0(ptr %p) { + %addr = ptrtoaddr ptr %p to i64 + ; CHECK: %addr = ptrtoaddr ptr %p to i64 + ret i64 %addr +} + +define i32 @test_as1(ptr addrspace(1) %p) { + %addr = ptrtoaddr ptr addrspace(1) %p to i32 + ; CHECK: %addr = ptrtoaddr ptr addrspace(1) %p to i32 + ret i32 %addr +} + +define <2 x i32> @test_vec_as1(<2 x ptr addrspace(1)> %p) { + %addr = ptrtoaddr <2 x ptr addrspace(1)> %p to <2 x i32> + ; CHECK: %addr = ptrtoaddr <2 x ptr addrspace(1)> %p to <2 x i32> + ret <2 x i32> %addr +} diff --git a/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll b/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll new file mode 100644 index 0000000..f65d99d --- /dev/null +++ b/llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll @@ -0,0 +1,109 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=CHECK + +define i1 @ptrtoaddr_1(ptr %p) { +; CHECK-LABEL: ptrtoaddr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorb $1, %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i1 + %ret = xor i1 %trunc, 1 + ret i1 %ret +} + +define i8 @ptrtoaddr_8(ptr %p) { +; CHECK-LABEL: ptrtoaddr_8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notb %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i8 + %ret = xor i8 %trunc, -1 + ret i8 %ret +} + +define i16 @ptrtoaddr_16(ptr %p) { +; CHECK-LABEL: ptrtoaddr_16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notw %ax +; CHECK-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i16 + %ret = xor i16 %trunc, -1 + ret i16 %ret +} + +define i32 @ptrtoaddr_32(ptr %p) { +; CHECK-LABEL: ptrtoaddr_32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i32 + %ret = xor i32 %trunc, -1 + ret i32 %ret +} + +define i64 @ptrtoaddr_64(ptr %p) { +; CHECK-LABEL: ptrtoaddr_64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ret = xor i64 %addr, -1 + ret i64 %ret +} + +define i128 @ptrtoaddr_128(ptr %p) { +; CHECK-LABEL: ptrtoaddr_128: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: notq %rax +; CHECK-NEXT: notq %rdx +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ext = zext i64 %addr to i128 + %ret = xor i128 %ext, -1 + ret i128 %ret +} + +; TODO: Vector version cannot be handled by GlobalIsel yet (same error as ptrtoint: https://github.com/llvm/llvm-project/issues/150875). +; define <2 x i64> @ptrtoaddr_vec(<2 x ptr> %p) { +; entry: +; %addr = ptrtoaddr <2 x ptr> %p to <2 x i64> +; %ret = xor <2 x i64> %addr, <i64 -1, i64 -1> +; ret <2 x i64> %ret +;} + +; UTC_ARGS: --disable + +@foo = global [16 x i8] zeroinitializer +@addr = global i64 ptrtoaddr (ptr @foo to i64) +; CHECK: addr: +; CHECK-NEXT: .quad foo +; CHECK-NEXT: .size addr, 8 +@addr_plus_one = global i64 ptrtoaddr (ptr getelementptr (i8, ptr @foo, i64 1) to i64) +; CHECK: addr_plus_one: +; CHECK-NEXT: .quad foo+1 +; CHECK-NEXT: .size addr_plus_one, 8 +@const_addr = global i64 ptrtoaddr (ptr getelementptr (i8, ptr null, i64 1) to i64) +; CHECK: const_addr: +; CHECK-NEXT: .quad 0+1 +; CHECK-NEXT: .size const_addr, 8 diff --git a/llvm/test/CodeGen/X86/ptrtoaddr.ll b/llvm/test/CodeGen/X86/ptrtoaddr.ll new file mode 100644 index 0000000..24bf9db --- /dev/null +++ b/llvm/test/CodeGen/X86/ptrtoaddr.ll @@ -0,0 +1,113 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-linux-gnu < %s -o - | FileCheck %s --check-prefix=CHECK + +define i1 @ptrtoaddr_1(ptr %p) { +; CHECK-LABEL: ptrtoaddr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: xorb $1, %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i1 + %ret = xor i1 %trunc, 1 + ret i1 %ret +} + +define i8 @ptrtoaddr_8(ptr %p) { +; CHECK-LABEL: ptrtoaddr_8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notb %al +; CHECK-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i8 + %ret = xor i8 %trunc, -1 + ret i8 %ret +} + +define i16 @ptrtoaddr_16(ptr %p) { +; CHECK-LABEL: ptrtoaddr_16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i16 + %ret = xor i16 %trunc, -1 + ret i16 %ret +} + +define i32 @ptrtoaddr_32(ptr %p) { +; CHECK-LABEL: ptrtoaddr_32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %trunc = trunc i64 %addr to i32 + %ret = xor i32 %trunc, -1 + ret i32 %ret +} + +define i64 @ptrtoaddr_64(ptr %p) { +; CHECK-LABEL: ptrtoaddr_64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ret = xor i64 %addr, -1 + ret i64 %ret +} + +define i128 @ptrtoaddr_128(ptr %p) { +; CHECK-LABEL: ptrtoaddr_128: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: notq %rax +; CHECK-NEXT: movq $-1, %rdx +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr ptr %p to i64 + %ext = zext i64 %addr to i128 + %ret = xor i128 %ext, -1 + ret i128 %ret +} + + +define <2 x i64> @ptrtoaddr_vec(<2 x ptr> %p) { +; CHECK-LABEL: ptrtoaddr_vec: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pxor %xmm1, %xmm0 +; CHECK-NEXT: retq +entry: + %addr = ptrtoaddr <2 x ptr> %p to <2 x i64> + %ret = xor <2 x i64> %addr, <i64 -1, i64 -1> + ret <2 x i64> %ret +} + +; UTC_ARGS: --disable + +@foo = global [16 x i8] zeroinitializer +@addr = global i64 ptrtoaddr (ptr @foo to i64) +; CHECK: addr: +; CHECK-NEXT: .quad foo +; CHECK-NEXT: .size addr, 8 +@addr_plus_one = global i64 ptrtoaddr (ptr getelementptr (i8, ptr @foo, i64 1) to i64) +; CHECK: addr_plus_one: +; CHECK-NEXT: .quad foo+1 +; CHECK-NEXT: .size addr_plus_one, 8 +@const_addr = global i64 ptrtoaddr (ptr getelementptr (i8, ptr null, i64 1) to i64) +; CHECK: const_addr: +; CHECK-NEXT: .quad 0+1 +; CHECK-NEXT: .size const_addr, 8 diff --git a/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll b/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll index 88eff97..0c2db4a 100644 --- a/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll +++ b/llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll @@ -7,9 +7,9 @@ define i32 @nested(i32 %src) #0 { ; CHECK-SAME: i32 [[A0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[BB15160:.*:]] ; CHECK-NEXT: [[T1:%.*]] = call token @llvm.experimental.convergence.entry() -; CHECK-NEXT: %"vl77672llvm.experimental.convergence.anchor()" = call token @llvm.experimental.convergence.anchor() -; CHECK-NEXT: %"op68297(vl77672)" = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[A0]]) [ "convergencectrl"(token %"vl77672llvm.experimental.convergence.anchor()") ] -; CHECK-NEXT: ret i32 %"op68297(vl77672)" +; CHECK-NEXT: %"vl14659llvm.experimental.convergence.anchor()" = call token @llvm.experimental.convergence.anchor() +; CHECK-NEXT: %"op15516(vl14659)" = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[A0]]) [ "convergencectrl"(token %"vl14659llvm.experimental.convergence.anchor()") ] +; CHECK-NEXT: ret i32 %"op15516(vl14659)" ; %t1 = call token @llvm.experimental.convergence.entry() %t2 = call token @llvm.experimental.convergence.anchor() diff --git a/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll b/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll index 35ac0fd..b9be105 100644 --- a/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll +++ b/llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll @@ -8,18 +8,18 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"vl72693([[A1]], 1)" = add i32 [[A1]], 1 ; CHECK-NEXT: br label %[[BB16110:.*]] ; CHECK: [[BB16110]]: -; CHECK-NEXT: %"op10912(op18080, vl72693)" = phi i32 [ %"op18080(op10412, op17645)", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] -; CHECK-NEXT: %"op10912(op17645, vl72693)" = phi i32 [ %"op17645(op10912)70", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] -; CHECK-NEXT: %"op15084(op10912)" = mul i32 %"op10912(op18080, vl72693)", undef -; CHECK-NEXT: %"op16562(op15084)" = xor i32 -1, %"op15084(op10912)" -; CHECK-NEXT: %"op44627(op10912, op16562)" = add i32 %"op10912(op18080, vl72693)", %"op16562(op15084)" -; CHECK-NEXT: %"op17645(op10912)" = add i32 -1, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17645, op44627)" = add i32 %"op17645(op10912)", %"op44627(op10912, op16562)" -; CHECK-NEXT: %"op17720(op15084, op18080)" = mul i32 %"op15084(op10912)", %"op18080(op17645, op44627)" -; CHECK-NEXT: %"op16562(op17720)" = xor i32 -1, %"op17720(op15084, op18080)" -; CHECK-NEXT: %"op17430(op16562, op18080)" = add i32 %"op16562(op17720)", %"op18080(op17645, op44627)" +; CHECK-NEXT: %"op81283(op18080, vl72693)" = phi i32 [ %"op18080(op10412, op18131)", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] +; CHECK-NEXT: %"op81283(op18131, vl72693)" = phi i32 [ %"op18131(op81283)70", %[[BB16110]] ], [ %"vl72693([[A1]], 1)", %[[BB76951]] ] +; CHECK-NEXT: %"op13219(op81283)" = mul i32 %"op81283(op18080, vl72693)", undef +; CHECK-NEXT: %"op16562(op13219)" = xor i32 -1, %"op13219(op81283)" +; CHECK-NEXT: %"op12556(op16562, op81283)" = add i32 %"op16562(op13219)", %"op81283(op18080, vl72693)" +; CHECK-NEXT: %"op18131(op81283)" = add i32 -1, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op12556, op18131)" = add i32 %"op12556(op16562, op81283)", %"op18131(op81283)" +; CHECK-NEXT: %"op17720(op13219, op18080)" = mul i32 %"op13219(op81283)", %"op18080(op12556, op18131)" +; CHECK-NEXT: %"op16562(op17720)" = xor i32 -1, %"op17720(op13219, op18080)" +; CHECK-NEXT: %"op17430(op16562, op18080)" = add i32 %"op16562(op17720)", %"op18080(op12556, op18131)" ; CHECK-NEXT: %"op10412(op17430)" = add i32 %"op17430(op16562, op18080)", undef -; CHECK-NEXT: %"op17720(op10412, op17720)" = mul i32 %"op10412(op17430)", %"op17720(op15084, op18080)" +; CHECK-NEXT: %"op17720(op10412, op17720)" = mul i32 %"op10412(op17430)", %"op17720(op13219, op18080)" ; CHECK-NEXT: %"op16562(op17720)1" = xor i32 -1, %"op17720(op10412, op17720)" ; CHECK-NEXT: %"op17430(op10412, op16562)" = add i32 %"op10412(op17430)", %"op16562(op17720)1" ; CHECK-NEXT: %"op10412(op17430)2" = add i32 %"op17430(op10412, op16562)", undef @@ -45,11 +45,11 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17720(op10412, op17720)21" = mul i32 %"op10412(op17430)20", %"op17720(op10412, op17720)17" ; CHECK-NEXT: %"op16562(op17720)22" = xor i32 -1, %"op17720(op10412, op17720)21" ; CHECK-NEXT: %"op17430(op10412, op16562)23" = add i32 %"op10412(op17430)20", %"op16562(op17720)22" -; CHECK-NEXT: %"op17645(op10912)24" = add i32 -9, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17430, op17645)" = add i32 %"op17430(op10412, op16562)23", %"op17645(op10912)24" -; CHECK-NEXT: %"op17720(op17720, op18080)" = mul i32 %"op17720(op10412, op17720)21", %"op18080(op17430, op17645)" +; CHECK-NEXT: %"op18131(op81283)24" = add i32 -9, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op17430, op18131)" = add i32 %"op17430(op10412, op16562)23", %"op18131(op81283)24" +; CHECK-NEXT: %"op17720(op17720, op18080)" = mul i32 %"op17720(op10412, op17720)21", %"op18080(op17430, op18131)" ; CHECK-NEXT: %"op16562(op17720)25" = xor i32 -1, %"op17720(op17720, op18080)" -; CHECK-NEXT: %"op17430(op16562, op18080)26" = add i32 %"op16562(op17720)25", %"op18080(op17430, op17645)" +; CHECK-NEXT: %"op17430(op16562, op18080)26" = add i32 %"op16562(op17720)25", %"op18080(op17430, op18131)" ; CHECK-NEXT: %"op10412(op17430)27" = add i32 %"op17430(op16562, op18080)26", undef ; CHECK-NEXT: %"op17720(op10412, op17720)28" = mul i32 %"op10412(op17430)27", %"op17720(op17720, op18080)" ; CHECK-NEXT: %"op16562(op17720)29" = xor i32 -1, %"op17720(op10412, op17720)28" @@ -66,11 +66,11 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17720(op10412, op17720)40" = mul i32 %"op10412(op17430)39", %"op17720(op10412, op17720)36" ; CHECK-NEXT: %"op16562(op17720)41" = xor i32 -1, %"op17720(op10412, op17720)40" ; CHECK-NEXT: %"op17430(op10412, op16562)42" = add i32 %"op10412(op17430)39", %"op16562(op17720)41" -; CHECK-NEXT: %"op17645(op10912)43" = add i32 -14, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op17430, op17645)44" = add i32 %"op17430(op10412, op16562)42", %"op17645(op10912)43" -; CHECK-NEXT: %"op17720(op17720, op18080)45" = mul i32 %"op17720(op10412, op17720)40", %"op18080(op17430, op17645)44" +; CHECK-NEXT: %"op18131(op81283)43" = add i32 -14, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op17430, op18131)44" = add i32 %"op17430(op10412, op16562)42", %"op18131(op81283)43" +; CHECK-NEXT: %"op17720(op17720, op18080)45" = mul i32 %"op17720(op10412, op17720)40", %"op18080(op17430, op18131)44" ; CHECK-NEXT: %"op16562(op17720)46" = xor i32 -1, %"op17720(op17720, op18080)45" -; CHECK-NEXT: %"op17430(op16562, op18080)47" = add i32 %"op16562(op17720)46", %"op18080(op17430, op17645)44" +; CHECK-NEXT: %"op17430(op16562, op18080)47" = add i32 %"op16562(op17720)46", %"op18080(op17430, op18131)44" ; CHECK-NEXT: %"op10412(op17430)48" = add i32 %"op17430(op16562, op18080)47", undef ; CHECK-NEXT: %"op17720(op10412, op17720)49" = mul i32 %"op10412(op17430)48", %"op17720(op17720, op18080)45" ; CHECK-NEXT: %"op16562(op17720)50" = xor i32 -1, %"op17720(op10412, op17720)49" @@ -93,9 +93,9 @@ define void @test(ptr, i32) { ; CHECK-NEXT: %"op17430(op10412, op16562)67" = add i32 %"op10412(op17430)64", %"op16562(op17720)66" ; CHECK-NEXT: %"op10412(op17430)68" = add i32 %"op17430(op10412, op16562)67", undef ; CHECK-NEXT: %"op10412(op10412)69" = add i32 %"op10412(op17430)68", undef -; CHECK-NEXT: %"op17645(op10912)70" = add i32 -21, %"op10912(op17645, vl72693)" -; CHECK-NEXT: %"op18080(op10412, op17645)" = add i32 %"op10412(op10412)69", %"op17645(op10912)70" -; CHECK-NEXT: store i32 %"op18080(op10412, op17645)", ptr [[A0]], align 4 +; CHECK-NEXT: %"op18131(op81283)70" = add i32 -21, %"op81283(op18131, vl72693)" +; CHECK-NEXT: %"op18080(op10412, op18131)" = add i32 %"op10412(op10412)69", %"op18131(op81283)70" +; CHECK-NEXT: store i32 %"op18080(op10412, op18131)", ptr [[A0]], align 4 ; CHECK-NEXT: br label %[[BB16110]] ; bb: diff --git a/llvm/test/Transforms/IRNormalizer/reordering-basic.ll b/llvm/test/Transforms/IRNormalizer/reordering-basic.ll index fd09ce0..06e67e0 100644 --- a/llvm/test/Transforms/IRNormalizer/reordering-basic.ll +++ b/llvm/test/Transforms/IRNormalizer/reordering-basic.ll @@ -28,16 +28,16 @@ define double @baz(double %x) { ; CHECK-SAME: double [[A0:%.*]]) { ; CHECK-NEXT: [[BB76951:.*:]] ; CHECK-NEXT: [[IFCOND:%.*]] = fcmp one double [[A0]], 0.000000e+00 -; CHECK-NEXT: br i1 [[IFCOND]], label %[[BB91455:.*]], label %[[BB914551:.*]] -; CHECK: [[BB91455]]: -; CHECK-NEXT: %"vl15001bir()" = call double @bir() +; CHECK-NEXT: br i1 [[IFCOND]], label %[[BB47054:.*]], label %[[BB470541:.*]] +; CHECK: [[BB47054]]: +; CHECK-NEXT: %"vl16994bir()" = call double @bir() ; CHECK-NEXT: br label %[[BB17254:.*]] -; CHECK: [[BB914551]]: -; CHECK-NEXT: %"vl69719bar()" = call double @bar() +; CHECK: [[BB470541]]: +; CHECK-NEXT: %"vl88592bar()" = call double @bar() ; CHECK-NEXT: br label %[[BB17254]] ; CHECK: [[BB17254]]: -; CHECK-NEXT: %"op19734(vl15001, vl69719)" = phi double [ %"vl15001bir()", %[[BB91455]] ], [ %"vl69719bar()", %[[BB914551]] ] -; CHECK-NEXT: ret double %"op19734(vl15001, vl69719)" +; CHECK-NEXT: %"op16411(vl16994, vl88592)" = phi double [ %"vl16994bir()", %[[BB47054]] ], [ %"vl88592bar()", %[[BB470541]] ] +; CHECK-NEXT: ret double %"op16411(vl16994, vl88592)" ; entry: %ifcond = fcmp one double %x, 0.000000e+00 diff --git a/llvm/test/Transforms/IRNormalizer/reordering.ll b/llvm/test/Transforms/IRNormalizer/reordering.ll index 64abe8e..a3dbcb5 100644 --- a/llvm/test/Transforms/IRNormalizer/reordering.ll +++ b/llvm/test/Transforms/IRNormalizer/reordering.ll @@ -23,7 +23,7 @@ declare void @effecting() ; Place dead instruction(s) before the terminator define void @call_effecting() { ; CHECK-LABEL: define void @call_effecting() { -; CHECK-NEXT: bb15160: +; CHECK-NEXT: bb14885: ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: [[TMP0:%.*]] = add i32 0, 1 ; CHECK-NEXT: ret void @@ -51,7 +51,7 @@ exit: define void @dont_move_above_alloca() { ; CHECK-LABEL: define void @dont_move_above_alloca() { -; CHECK-NEXT: bb15160: +; CHECK-NEXT: bb14885: ; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: ret void @@ -65,7 +65,7 @@ declare void @effecting1() define void @dont_reorder_effecting() { ; CHECK-LABEL: define void @dont_reorder_effecting() { -; CHECK-NEXT: bb10075: +; CHECK-NEXT: bb45003: ; CHECK-NEXT: call void @effecting() ; CHECK-NEXT: call void @effecting1() ; CHECK-NEXT: ret void @@ -79,7 +79,7 @@ declare void @effecting2(i32) define void @dont_reorder_effecting1() { ; CHECK-LABEL: define void @dont_reorder_effecting1() { -; CHECK-NEXT: bb10075: +; CHECK-NEXT: bb45003: ; CHECK-NEXT: [[ONE:%.*]] = add i32 1, 1 ; CHECK-NEXT: call void @effecting2(i32 [[ONE]]) ; CHECK-NEXT: [[TWO:%.*]] = add i32 2, 2 diff --git a/llvm/unittests/Analysis/IR2VecTest.cpp b/llvm/unittests/Analysis/IR2VecTest.cpp index e288585..f7838cc4 100644 --- a/llvm/unittests/Analysis/IR2VecTest.cpp +++ b/llvm/unittests/Analysis/IR2VecTest.cpp @@ -320,11 +320,13 @@ TEST_F(IR2VecTestFixture, GetInstVecMap) { EXPECT_TRUE(InstMap.count(AddInst)); EXPECT_TRUE(InstMap.count(RetInst)); - EXPECT_EQ(InstMap.at(AddInst).size(), 2u); - EXPECT_EQ(InstMap.at(RetInst).size(), 2u); + const auto &AddEmb = InstMap.at(AddInst); + const auto &RetEmb = InstMap.at(RetInst); + EXPECT_EQ(AddEmb.size(), 2u); + EXPECT_EQ(RetEmb.size(), 2u); - EXPECT_TRUE(InstMap.at(AddInst).approximatelyEquals(Embedding(2, 27.6))); - EXPECT_TRUE(InstMap.at(RetInst).approximatelyEquals(Embedding(2, 16.8))); + EXPECT_TRUE(AddEmb.approximatelyEquals(Embedding(2, 27.9))); + EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(2, 17.0))); } TEST_F(IR2VecTestFixture, GetBBVecMap) { @@ -337,9 +339,9 @@ TEST_F(IR2VecTestFixture, GetBBVecMap) { EXPECT_TRUE(BBMap.count(BB)); EXPECT_EQ(BBMap.at(BB).size(), 2u); - // BB vector should be sum of add and ret: {27.6, 27.6} + {16.8, 16.8} = - // {44.4, 44.4} - EXPECT_TRUE(BBMap.at(BB).approximatelyEquals(Embedding(2, 44.4))); + // BB vector should be sum of add and ret: {27.9, 27.9} + {17.0, 17.0} = + // {44.9, 44.9} + EXPECT_TRUE(BBMap.at(BB).approximatelyEquals(Embedding(2, 44.9))); } TEST_F(IR2VecTestFixture, GetBBVector) { @@ -349,7 +351,7 @@ TEST_F(IR2VecTestFixture, GetBBVector) { const auto &BBVec = Emb->getBBVector(*BB); EXPECT_EQ(BBVec.size(), 2u); - EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 44.4))); + EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 44.9))); } TEST_F(IR2VecTestFixture, GetFunctionVector) { @@ -360,8 +362,8 @@ TEST_F(IR2VecTestFixture, GetFunctionVector) { EXPECT_EQ(FuncVec.size(), 2u); - // Function vector should match BB vector (only one BB): {44.4, 44.4} - EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 44.4))); + // Function vector should match BB vector (only one BB): {44.9, 44.9} + EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 44.9))); } static constexpr unsigned MaxOpcodes = Vocabulary::MaxOpcodes; |