Skip to content

Commit

Permalink
Add addrspacecast instruction.
Browse files Browse the repository at this point in the history
Patch by Michele Scandale!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194760 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
arsenm committed Nov 15, 2013
1 parent 2b7fef0 commit 59d3ae6
Show file tree
Hide file tree
Showing 51 changed files with 588 additions and 229 deletions.
55 changes: 52 additions & 3 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,10 @@ The following is the syntax for constant expressions:
Convert a constant, CST, to another TYPE. The constraints of the
operands are the same as those for the :ref:`bitcast
instruction <i_bitcast>`.
``addrspacecast (CST to TYPE)``
Convert a constant pointer or constant vector of pointer, CST, to another
TYPE in a different address space. The constraints of the operands are the
same as those for the :ref:`addrspacecast instruction <i_addrspacecast>`.
``getelementptr (CSTPTR, IDX0, IDX1, ...)``, ``getelementptr inbounds (CSTPTR, IDX0, IDX1, ...)``
Perform the :ref:`getelementptr operation <i_getelementptr>` on
constants. As with the :ref:`getelementptr <i_getelementptr>`
Expand Down Expand Up @@ -5726,9 +5730,9 @@ is always a *no-op cast* because no bits change with this
conversion. The conversion is done as if the ``value`` had been stored
to memory and read back as type ``ty2``. Pointer (or vector of
pointers) types may only be converted to other pointer (or vector of
pointers) types with this instruction if the pointer sizes are
equal. To convert pointers to other types, use the :ref:`inttoptr
<i_inttoptr>` or :ref:`ptrtoint <i_ptrtoint>` instructions first.
pointers) types with the same address space through this instruction.
To convert pointers to other types, use the :ref:`inttoptr <i_inttoptr>`
or :ref:`ptrtoint <i_ptrtoint>` instructions first.

Example:
""""""""
Expand All @@ -5740,6 +5744,51 @@ Example:
%Z = bitcast <2 x int> %V to i64; ; yields i64: %V
%Z = bitcast <2 x i32*> %V to <2 x i64*> ; yields <2 x i64*>
.. _i_addrspacecast:

'``addrspacecast .. to``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

::

<result> = addrspacecast <pty> <ptrval> to <pty2> ; yields pty2

Overview:
"""""""""

The '``addrspacecast``' instruction converts ``ptrval`` from ``pty`` in
address space ``n`` to type ``pty2`` in address space ``m``.

Arguments:
""""""""""

The '``addrspacecast``' instruction takes a pointer or vector of pointer value
to cast and a pointer type to cast it to, which must have a different
address space.

Semantics:
""""""""""

The '``addrspacecast``' instruction converts the pointer value
``ptrval`` to type ``pty2``. It can be a *no-op cast* or a complex
value modification, depending on the target and the address spaces
pair. Pointers conversion within the same address space must be
performed with ``bitcast`` instruction. Note that if the address space
conversion is legal then both result and operand refer to the same memory
location.

Example:
""""""""

.. code-block:: llvm
%X = addrspacecast i32* %x to addrspace(1) i32* ; yields addrspace(1) i32*:%x
%Y = addrspacecast addrspace(1) <2 x i32>* %y to addrspace(2) i64* ; yields addrspace(2) i32*:%y
%Z = addrspacecast <4 x i32*> %z to <4 x float addrspace(3)*> ; yelds <4 x float addrspace(3)*>:%z
.. _otherops:

Other Operations
Expand Down
5 changes: 5 additions & 0 deletions include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ typedef enum {
LLVMPtrToInt = 39,
LLVMIntToPtr = 40,
LLVMBitCast = 41,
LLVMAddrSpaceCast = 60,

/* Other Operators */
LLVMICmp = 42,
Expand Down Expand Up @@ -1159,6 +1160,7 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
macro(AddrSpaceCastInst) \
macro(BitCastInst) \
macro(FPExtInst) \
macro(FPToSIInst) \
Expand Down Expand Up @@ -1630,6 +1632,7 @@ LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType);
LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal,
Expand Down Expand Up @@ -2605,6 +2608,8 @@ LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
Expand Down
13 changes: 13 additions & 0 deletions include/llvm/AutoUpgrade.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
#define LLVM_AUTOUPGRADE_H

namespace llvm {
class Constant;
class Module;
class GlobalVariable;
class Function;
class CallInst;
class Instruction;
class Value;
class Type;

/// This is a more granular function that simply checks an intrinsic function
/// for upgrading, and returns true if it requires upgrading. It may return
Expand All @@ -44,6 +47,16 @@ namespace llvm {
/// If the TBAA tag for the given instruction uses the scalar TBAA format,
/// we upgrade it to the struct-path aware TBAA format.
void UpgradeInstWithTBAATag(Instruction *I);

/// This is an auto-upgrade for bitcast between pointers with different
/// address spaces: the instruction is replaced by a pair ptrtoint+inttoptr.
Instruction *UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
Instruction *&Temp);

/// This is an auto-upgrade for bitcast constant expression between pointers
/// with different address spaces: the instruction is replaced by a pair
/// ptrtoint+inttoptr.
Value *UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy);
} // End llvm namespace

#endif
3 changes: 2 additions & 1 deletion include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ namespace bitc {
CAST_FPEXT = 8,
CAST_PTRTOINT = 9,
CAST_INTTOPTR = 10,
CAST_BITCAST = 11
CAST_BITCAST = 11,
CAST_ADDRSPACECAST = 12
};

/// BinaryOpcodes - These are values used in the bitcode files to encode which
Expand Down
4 changes: 4 additions & 0 deletions include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ namespace ISD {
/// getNode().
BITCAST,

/// ADDRSPACECAST - This operator converts between pointers of different
/// address spaces.
ADDRSPACECAST,

/// CONVERT_RNDSAT - This operator is used to support various conversions
/// between various types (float, signed, unsigned and vectors of those
/// types) with rounding and saturation. NOTE: Avoid using this operator as
Expand Down
4 changes: 4 additions & 0 deletions include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,10 @@ class SelectionDAG {
/// getMDNode - Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);

/// getAddrSpaceCast - Return an AddrSpaceCastSDNode.
SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
unsigned SrcAS, unsigned DestAS);

/// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type.
SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
Expand Down
17 changes: 17 additions & 0 deletions include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,23 @@ class HandleSDNode : public SDNode {
const SDValue &getValue() const { return Op; }
};

class AddrSpaceCastSDNode : public UnarySDNode {
private:
unsigned SrcAddrSpace;
unsigned DestAddrSpace;

public:
AddrSpaceCastSDNode(unsigned Order, DebugLoc dl, EVT VT, SDValue X,
unsigned SrcAS, unsigned DestAS);

unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
unsigned getDestAddressSpace() const { return DestAddrSpace; }

static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ADDRSPACECAST;
}
};

/// Abstact virtual class for operations for memory operations
class MemSDNode : public SDNode {
private:
Expand Down
1 change: 1 addition & 0 deletions include/llvm/IR/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ class ConstantExpr : public Constant {
static Constant *getPtrToInt(Constant *C, Type *Ty);
static Constant *getIntToPtr(Constant *C, Type *Ty);
static Constant *getBitCast (Constant *C, Type *Ty);
static Constant *getAddrSpaceCast (Constant *C, Type *Ty);

static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
Expand Down
4 changes: 4 additions & 0 deletions include/llvm/IR/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,10 @@ class IRBuilder : public IRBuilderBase, public Inserter {
const Twine &Name = "") {
return CreateCast(Instruction::BitCast, V, DestTy, Name);
}
Value *CreateAddrSpaceCast(Value *V, Type *DestTy,
const Twine &Name = "") {
return CreateCast(Instruction::AddrSpaceCast, V, DestTy, Name);
}
Value *CreateZExtOrBitCast(Value *V, Type *DestTy,
const Twine &Name = "") {
if (V->getType() == DestTy)
Expand Down
35 changes: 18 additions & 17 deletions include/llvm/IR/Instruction.def
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,26 @@ HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(44)
HANDLE_CAST_INST(45, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
LAST_CAST_INST(45)

// Other operators...
FIRST_OTHER_INST(45)
HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(58, LandingPad, LandingPadInst) // Landing pad instruction.
LAST_OTHER_INST(58)
FIRST_OTHER_INST(46)
HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction.
LAST_OTHER_INST(59)

#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
Expand Down
37 changes: 37 additions & 0 deletions include/llvm/IR/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -3615,6 +3615,43 @@ class BitCastInst : public CastInst {
}
};

//===----------------------------------------------------------------------===//
// AddrSpaceCastInst Class
//===----------------------------------------------------------------------===//

/// \brief This class represents a conversion between pointers from
/// one address space to another.
class AddrSpaceCastInst : public CastInst {
protected:
/// \brief Clone an identical AddrSpaceCastInst
virtual AddrSpaceCastInst *clone_impl() const;

public:
/// \brief Constructor with insert-before-instruction semantics
AddrSpaceCastInst(
Value *S, ///< The value to be casted
Type *Ty, ///< The type to casted to
const Twine &NameStr = "", ///< A name for the new instruction
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);

/// \brief Constructor with insert-at-end-of-block semantics
AddrSpaceCastInst(
Value *S, ///< The value to be casted
Type *Ty, ///< The type to casted to
const Twine &NameStr, ///< A name for the new instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);

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

} // End llvm namespace

#endif
1 change: 1 addition & 0 deletions include/llvm/InstVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ class InstVisitor {
RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
Expand Down
5 changes: 5 additions & 0 deletions include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,11 @@ class TargetLoweringBase {
return 0;
}

/// Returns true if a cast between SrcAS and DestAS is a noop.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
return false;
}

//===--------------------------------------------------------------------===//
/// \name Helpers for TargetTransformInfo implementations
/// @{
Expand Down
12 changes: 7 additions & 5 deletions lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ static Constant* StripPtrCastKeepAS(Constant* Ptr) {
if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) {
NewPtrTy = NewPtrTy->getElementType()->getPointerTo(
OldPtrTy->getAddressSpace());
Ptr = ConstantExpr::getBitCast(Ptr, NewPtrTy);
Ptr = ConstantExpr::getPointerCast(Ptr, NewPtrTy);
}
return Ptr;
}
Expand Down Expand Up @@ -995,17 +995,18 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
case Instruction::IntToPtr:
// If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
// the int size is >= the ptr size. This requires knowing the width of a
// pointer, so it can't be done in ConstantExpr::getCast.
// the int size is >= the ptr size and the address spaces are the same.
// This requires knowing the width of a pointer, so it can't be done in
// ConstantExpr::getCast.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
if (TD && CE->getOpcode() == Instruction::PtrToInt) {
Constant *SrcPtr = CE->getOperand(0);
unsigned SrcPtrSize = TD->getPointerTypeSizeInBits(SrcPtr->getType());
unsigned MidIntSize = CE->getType()->getScalarSizeInBits();

if (MidIntSize >= SrcPtrSize) {
unsigned DestPtrSize = TD->getPointerTypeSizeInBits(DestTy);
if (SrcPtrSize == DestPtrSize)
unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();
if (SrcAS == DestTy->getPointerAddressSpace())
return FoldBitCast(CE->getOperand(0), DestTy, *TD);
}
}
Expand All @@ -1021,6 +1022,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
case Instruction::SIToFP:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::AddrSpaceCast:
return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
case Instruction::BitCast:
if (TD)
Expand Down
1 change: 1 addition & 0 deletions lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(inttoptr, IntToPtr);
INSTKEYWORD(ptrtoint, PtrToInt);
INSTKEYWORD(bitcast, BitCast);
INSTKEYWORD(addrspacecast, AddrSpaceCast);
INSTKEYWORD(select, Select);
INSTKEYWORD(va_arg, VAArg);
INSTKEYWORD(ret, Ret);
Expand Down
2 changes: 2 additions & 0 deletions lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2415,6 +2415,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
case lltok::kw_fptrunc:
case lltok::kw_fpext:
case lltok::kw_bitcast:
case lltok::kw_addrspacecast:
case lltok::kw_uitofp:
case lltok::kw_sitofp:
case lltok::kw_fptoui:
Expand Down Expand Up @@ -3303,6 +3304,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_fptrunc:
case lltok::kw_fpext:
case lltok::kw_bitcast:
case lltok::kw_addrspacecast:
case lltok::kw_uitofp:
case lltok::kw_sitofp:
case lltok::kw_fptoui:
Expand Down
1 change: 1 addition & 0 deletions lib/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ namespace lltok {
kw_phi, kw_call,
kw_trunc, kw_zext, kw_sext, kw_fptrunc, kw_fpext, kw_uitofp, kw_sitofp,
kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast,
kw_addrspacecast,
kw_select, kw_va_arg,

kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter,
Expand Down
Loading

0 comments on commit 59d3ae6

Please sign in to comment.