aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Richardson <alexrichardson@google.com>2025-08-05 16:25:31 -0700
committerAlex Richardson <alexrichardson@google.com>2025-08-05 16:25:31 -0700
commita0dcd64920d736f158532ded1d3d6b324a4edfd8 (patch)
tree05860fd0750091287fd238495d507105628420c1
parentfc2850fc7657c2ac8bff48818e797929f46168fc (diff)
downloadllvm-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]
-rw-r--r--llvm/docs/LangRef.rst53
-rw-r--r--llvm/docs/ReleaseNotes.md4
-rw-r--r--llvm/include/llvm-c/Core.h1
-rw-r--r--llvm/include/llvm/Analysis/TargetTransformInfoImpl.h7
-rw-r--r--llvm/include/llvm/AsmParser/LLToken.h1
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h4
-rw-r--r--llvm/include/llvm/IR/Constants.h2
-rw-r--r--llvm/include/llvm/IR/IRBuilder.h5
-rw-r--r--llvm/include/llvm/IR/InstVisitor.h1
-rw-r--r--llvm/include/llvm/IR/Instruction.def53
-rw-r--r--llvm/include/llvm/IR/Instructions.h40
-rw-r--r--llvm/include/llvm/IR/Operator.h31
-rw-r--r--llvm/include/llvm/SandboxIR/Instruction.h4
-rw-r--r--llvm/include/llvm/SandboxIR/Values.def1
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp14
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp2
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp1
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp5
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h1
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp1
-rw-r--r--llvm/lib/IR/ConstantFold.cpp1
-rw-r--r--llvm/lib/IR/ConstantRange.cpp1
-rw-r--r--llvm/lib/IR/Constants.cpp20
-rw-r--r--llvm/lib/IR/Globals.cpp1
-rw-r--r--llvm/lib/IR/Instruction.cpp1
-rw-r--r--llvm/lib/IR/Instructions.cpp52
-rw-r--r--llvm/lib/IR/Verifier.cpp23
-rw-r--r--llvm/lib/SandboxIR/Context.cpp1
-rw-r--r--llvm/lib/SandboxIR/Instruction.cpp3
-rw-r--r--llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp1
-rw-r--r--llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp1
-rw-r--r--llvm/test/Analysis/IR2Vec/Inputs/dummy_2D_vocab.json1
-rw-r--r--llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt1
-rw-r--r--llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt1
-rw-r--r--llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt1
-rw-r--r--llvm/test/Assembler/ptrtoaddr-invalid.ll84
-rw-r--r--llvm/test/Assembler/ptrtoaddr.ll27
-rw-r--r--llvm/test/Bitcode/ptrtoaddr.ll27
-rw-r--r--llvm/test/CodeGen/X86/GlobalISel/ptrtoaddr.ll109
-rw-r--r--llvm/test/CodeGen/X86/ptrtoaddr.ll113
-rw-r--r--llvm/test/Transforms/IRNormalizer/regression-convergence-tokens.ll6
-rw-r--r--llvm/test/Transforms/IRNormalizer/regression-infinite-loop.ll44
-rw-r--r--llvm/test/Transforms/IRNormalizer/reordering-basic.ll14
-rw-r--r--llvm/test/Transforms/IRNormalizer/reordering.ll8
-rw-r--r--llvm/unittests/Analysis/IR2VecTest.cpp22
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;