Skip to content

[IR] Introduce the ptrtoaddr instruction #139357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: users/arichardson/spr/main.ir-introduce-the-ptrtoaddr-instruction
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12432,6 +12432,61 @@ 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.

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 and either truncating or zero extending that value to the size of the
integer type.
If the address of ``value`` is smaller than ``ty2`` then a zero extension is
done. If the address of ``value`` is larger than ``ty2`` then a truncation is
done. 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`` always :ref:`captures the address (but not 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
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ typedef enum {
LLVMFPTrunc = 37,
LLVMFPExt = 38,
LLVMPtrToInt = 39,
LLVMPtrToAddr = 69,
LLVMIntToPtr = 40,
LLVMBitCast = 41,
LLVMAddrSpaceCast = 60,
Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,13 @@ class TargetTransformInfoImplBase {
return 0;
break;
}
case Instruction::PtrToAddr: {
unsigned DstSize = Dst->getScalarSizeInBits();
if (DL.isLegalInteger(DstSize) &&
DstSize >= DL.getPointerAddressSizeInBits(Src))
return 0;
break;
}
case Instruction::PtrToInt: {
unsigned DstSize = Dst->getScalarSizeInBits();
if (DL.isLegalInteger(DstSize) &&
Expand Down Expand Up @@ -1441,6 +1448,7 @@ class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
Op2Info, Operands, I);
}
case Instruction::IntToPtr:
case Instruction::PtrToAddr:
case Instruction::PtrToInt:
case Instruction::SIToFP:
case Instruction::UIToFP:
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ enum Kind {
kw_fptoui,
kw_fptosi,
kw_inttoptr,
kw_ptrtoaddr,
kw_ptrtoint,
kw_bitcast,
kw_addrspacecast,
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ class IRTranslator : public MachineFunctionPass {
bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
}
bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) {
return translatePtrToInt(U, MIRBuilder);
}
bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
}
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/InstVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class InstVisitor {
RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);}
RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);}
RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
RetTy visitPtrToAddrInst(PtrToAddrInst &I) { DELEGATE(PtrToIntInst);}
RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
Expand Down
53 changes: 27 additions & 26 deletions llvm/include/llvm/IR/Instruction.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 34 additions & 1 deletion llvm/include/llvm/IR/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -4881,6 +4881,9 @@ class PtrToIntInst : public CastInst {
/// Clone an identical PtrToIntInst.
PtrToIntInst *cloneImpl() const;

PtrToIntInst(unsigned Op, Value *S, Type *Ty, const Twine &NameStr,
InsertPosition InsertBefore);

public:
/// Constructor with insert-before-instruction semantics
PtrToIntInst(Value *S, ///< The value to be converted
Expand All @@ -4904,13 +4907,43 @@ class PtrToIntInst : public CastInst {

// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
return I->getOpcode() == PtrToInt;
return I->getOpcode() == PtrToInt || I->getOpcode() == PtrToAddr;
}
static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};

/// This class represents a cast from a pointer to an address (non-capturing
/// ptrtoint). Inherits from PtrToIntInst since it is a less restrictive version
/// of ptrtoint, so treating it as ptrtoint is conservatively correct.
class PtrToAddrInst : public PtrToIntInst {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not sure if it makes sense to inherit here since most of the time we use switch statements instead of isa<>, but I figured this would help with initial implementation.

protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;

/// Clone an identical PtrToIntInst.
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
);

// 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
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/SandboxIR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -2264,6 +2264,7 @@ class CastInst : public UnaryInstruction {
return Opcode::FPToSI;
case llvm::Instruction::FPExt:
return Opcode::FPExt;
case llvm::Instruction::PtrToAddr:
case llvm::Instruction::PtrToInt:
return Opcode::PtrToInt;
case llvm::Instruction::IntToPtr:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,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);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4275,6 +4275,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
case lltok::kw_bitcast:
case lltok::kw_addrspacecast:
case lltok::kw_inttoptr:
// ptrtoaddr not supported in constant exprs (yet?).
case lltok::kw_ptrtoint: {
unsigned Opc = Lex.getUIntVal();
Type *DestTy = nullptr;
Expand Down Expand Up @@ -7237,6 +7238,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:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,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;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,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;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3877,6 +3877,10 @@ void SelectionDAGBuilder::visitSIToFP(const User &I) {
setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurSDLoc(), DestVT, N));
}

void SelectionDAGBuilder::visitPtrToAddr(const User &I) {
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.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class SelectionDAGBuilder {
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);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,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;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,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";
Expand Down
Loading
Loading