summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2013-11-15 01:34:59 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2013-11-15 01:34:59 +0000
commit59d3ae6cdc4316ad338cd848251f33a236ccb36c (patch)
treeaec8d2396d4a436295845b109fb15b73279a2186 /lib
parent2b7fef0ad4bfaaf9fd41cda5abda35aab701b598 (diff)
downloadllvm-59d3ae6cdc4316ad338cd848251f33a236ccb36c.tar.gz
llvm-59d3ae6cdc4316ad338cd848251f33a236ccb36c.tar.bz2
llvm-59d3ae6cdc4316ad338cd848251f33a236ccb36c.tar.xz
Add addrspacecast instruction.
Patch by Michele Scandale! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194760 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ConstantFolding.cpp12
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp2
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp14
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp26
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp15
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp8
-rw-r--r--lib/CodeGen/TargetLoweringBase.cpp1
-rw-r--r--lib/IR/AutoUpgrade.cpp42
-rw-r--r--lib/IR/ConstantFold.cpp2
-rw-r--r--lib/IR/Constants.cpp14
-rw-r--r--lib/IR/Core.cpp11
-rw-r--r--lib/IR/Instruction.cpp25
-rw-r--r--lib/IR/Instructions.cpp298
-rw-r--r--lib/IR/Value.cpp3
-rw-r--r--lib/IR/Verifier.cpp25
-rw-r--r--lib/Target/NVPTX/NVPTXGenericToNVVM.cpp2
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp9
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
22 files changed, 374 insertions, 142 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index e093631d8f..3d32232dac 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -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;
}
@@ -995,8 +995,9 @@ 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);
@@ -1004,8 +1005,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
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);
}
}
@@ -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)
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 4c9439a3ec..1e6085b443 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -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);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index ad2cbe39cd..20fa0f4eab 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -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:
@@ -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:
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 086ea95273..786d84d766 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -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,
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index d25b33e9ab..e052e6e5ba 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -128,6 +128,7 @@ static int GetDecodedCastOpcode(unsigned Val) {
case bitc::CAST_PTRTOINT: return Instruction::PtrToInt;
case bitc::CAST_INTTOPTR: return Instruction::IntToPtr;
case bitc::CAST_BITCAST : return Instruction::BitCast;
+ case bitc::CAST_ADDRSPACECAST : return Instruction::AddrSpaceCast;
}
}
static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
@@ -1356,7 +1357,8 @@ error_code BitcodeReader::ParseConstants() {
if (!OpTy)
return Error(InvalidRecord);
Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
- V = ConstantExpr::getCast(Opc, Op, CurTy);
+ V = UpgradeBitCastExpr(Opc, Op, CurTy);
+ if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy);
}
break;
}
@@ -2296,7 +2298,15 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) {
int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
if (Opc == -1 || ResTy == 0)
return Error(InvalidRecord);
- I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+ Instruction *Temp = 0;
+ if ((I = UpgradeBitCastInst(Opc, Op, ResTy, Temp))) {
+ if (Temp) {
+ InstructionList.push_back(Temp);
+ CurBB->getInstList().push_back(Temp);
+ }
+ } else {
+ I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+ }
InstructionList.push_back(I);
break;
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 6f7aa14ed0..02ee917dd5 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -78,6 +78,7 @@ static unsigned GetEncodedCastOpcode(unsigned Opcode) {
case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
case Instruction::BitCast : return bitc::CAST_BITCAST;
+ case Instruction::AddrSpaceCast : return bitc::CAST_ADDRSPACECAST;
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 176e8505a2..fb0e63e9e5 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1507,6 +1507,26 @@ SDValue SelectionDAG::getMDNode(const MDNode *MD) {
return SDValue(N, 0);
}
+/// getAddrSpaceCast - Return an AddrSpaceCastSDNode.
+SDValue SelectionDAG::getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
+ unsigned SrcAS, unsigned DestAS) {
+ SDValue Ops[] = {Ptr};
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::ADDRSPACECAST, getVTList(VT), &Ops[0], 1);
+ ID.AddInteger(SrcAS);
+ ID.AddInteger(DestAS);
+
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+
+ SDNode *N = new (NodeAllocator) AddrSpaceCastSDNode(dl.getIROrder(),
+ dl.getDebugLoc(),
+ VT, Ptr, SrcAS, DestAS);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
/// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type.
@@ -5978,6 +5998,12 @@ GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, unsigned Order,
TheGlobal = GA;
}
+AddrSpaceCastSDNode::AddrSpaceCastSDNode(unsigned Order, DebugLoc dl, EVT VT,
+ SDValue X, unsigned SrcAS,
+ unsigned DestAS)
+ : UnarySDNode(ISD::ADDRSPACECAST, Order, dl, getSDVTList(VT), X),
+ SrcAddrSpace(SrcAS), DestAddrSpace(DestAS) {}
+
MemSDNode::MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
EVT memvt, MachineMemOperand *mmo)
: SDNode(Opc, Order, dl, VTs), MemoryVT(memvt), MMO(mmo) {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e80b63021f..009c590cad 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2938,6 +2938,21 @@ void SelectionDAGBuilder::visitBitCast(const User &I) {
setValue(&I, N); // noop cast.
}
+void SelectionDAGBuilder::visitAddrSpaceCast(const User &I) {
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ const Value *SV = I.getOperand(0);
+ SDValue N = getValue(SV);
+ EVT DestVT = TM.getTargetLowering()->getValueType(I.getType());
+
+ unsigned SrcAS = SV->getType()->getPointerAddressSpace();
+ unsigned DestAS = I.getType()->getPointerAddressSpace();
+
+ if (!TLI.isNoopAddrSpaceCast(SrcAS, DestAS))
+ N = DAG.getAddrSpaceCast(getCurSDLoc(), DestVT, N, SrcAS, DestAS);
+
+ setValue(&I, N);
+}
+
void SelectionDAGBuilder::visitInsertElement(const User &I) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue InVec = getValue(I.getOperand(0));
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 570f927069..835f643cc1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -26,6 +26,7 @@
namespace llvm {
+class AddrSpaceCastInst;
class AliasAnalysis;
class AllocaInst;
class BasicBlock;
@@ -720,6 +721,7 @@ private:
void visitPtrToInt(const User &I);
void visitIntToPtr(const User &I);
void visitBitCast(const User &I);
+ void visitAddrSpaceCast(const User &I);
void visitExtractElement(const User &I);
void visitInsertElement(const User &I);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 47bab32787..c04a08d57f 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -224,6 +224,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::FP_TO_SINT: return "fp_to_sint";
case ISD::FP_TO_UINT: return "fp_to_uint";
case ISD::BITCAST: return "bitcast";
+ case ISD::ADDRSPACECAST: return "addrspacecast";
case ISD::FP16_TO_FP32: return "fp16_to_fp32";
case ISD::FP32_TO_FP16: return "fp32_to_fp16";
@@ -485,6 +486,13 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << " " << offset;
if (unsigned int TF = BA->getTargetFlags())
OS << " [TF=" << TF << ']';
+ } else if (const AddrSpaceCastSDNode *ASC =
+ dyn_cast<AddrSpaceCastSDNode>(this)) {
+ OS << '['
+ << ASC->getSrcAddressSpace()
+ << " -> "
+ << ASC->getDestAddressSpace()
+ << ']';
}
if (unsigned Order = getIROrder())
diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp
index 63743b6c92..30305af211 100644
--- a/lib/CodeGen/TargetLoweringBase.cpp
+++ b/lib/CodeGen/TargetLoweringBase.cpp
@@ -1288,6 +1288,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const {
case PtrToInt: return ISD::BITCAST;
case IntToPtr: return ISD::BITCAST;
case BitCast: return ISD::BITCAST;
+ case AddrSpaceCast: return ISD::ADDRSPACECAST;
case ICmp: return ISD::SETCC;
case FCmp: return ISD::SETCC;
case PHI: return 0;
diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp
index 52434d0196..6f79919f24 100644
--- a/lib/IR/AutoUpgrade.cpp
+++ b/lib/IR/AutoUpgrade.cpp
@@ -447,3 +447,45 @@ void llvm::UpgradeInstWithTBAATag(Instruction *I) {
I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts));
}
}
+
+Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
+ Instruction *&Temp) {
+ if (Opc != Instruction::BitCast)
+ return 0;
+
+ Temp = 0;
+ Type *SrcTy = V->getType();
+ if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
+ SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
+ LLVMContext &Context = V->getContext();
+
+ // We have no information about target data layout, so we assume that
+ // the maximum pointer size is 64bit.
+ Type *MidTy = Type::getInt64Ty(Context);
+ Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy);
+
+ return CastInst::Create(Instruction::IntToPtr, Temp, DestTy);
+ }
+
+ return 0;
+}
+
+Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) {
+ if (Opc != Instruction::BitCast)
+ return 0;
+
+ Type *SrcTy = C->getType();
+ if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
+ SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
+ LLVMContext &Context = C->getContext();
+
+ // We have no information about target data layout, so we assume that
+ // the maximum pointer size is 64bit.
+ Type *MidTy = Type::getInt64Ty(Context);
+
+ return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy),
+ DestTy);
+ }
+
+ return 0;
+}
diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp
index 3319ec5796..f5e225cffc 100644
--- a/lib/IR/ConstantFold.cpp
+++ b/lib/IR/ConstantFold.cpp
@@ -689,6 +689,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
}
case Instruction::BitCast:
return FoldBitCast(V, DestTy);
+ case Instruction::AddrSpaceCast:
+ return 0;
}
}
diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp
index 9067b34312..a8a325ae27 100644
--- a/lib/IR/Constants.cpp
+++ b/lib/IR/Constants.cpp
@@ -1126,6 +1126,7 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const {
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::AddrSpaceCast:
return ConstantExpr::getCast(getOpcode(), Ops[0], Ty);
case Instruction::Select:
return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
@@ -1461,6 +1462,7 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) {
case Instruction::PtrToInt: return getPtrToInt(C, Ty);
case Instruction::IntToPtr: return getIntToPtr(C, Ty);
case Instruction::BitCast: return getBitCast(C, Ty);
+ case Instruction::AddrSpaceCast: return getAddrSpaceCast(C, Ty);
}
}
@@ -1489,6 +1491,11 @@ Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) {
if (Ty->isIntOrIntVectorTy())
return getPtrToInt(S, Ty);
+
+ unsigned SrcAS = S->getType()->getPointerAddressSpace();
+ if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace())
+ return getAddrSpaceCast(S, Ty);
+
return getBitCast(S, Ty);
}
@@ -1662,6 +1669,13 @@ Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) {
return getFoldedCast(Instruction::BitCast, C, DstTy);
}
+Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) {
+ assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
+ "Invalid constantexpr addrspacecast!");
+
+ return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy);
+}
+
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags) {
// Check the operands for consistency first.
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp
index 63cc2f6f06..c70f459118 100644
--- a/lib/IR/Core.cpp
+++ b/lib/IR/Core.cpp
@@ -1033,6 +1033,12 @@ LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
unwrap(ToType)));
}
+LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal,
+ LLVMTypeRef ToType) {
+ return wrap(ConstantExpr::getAddrSpaceCast(unwrap<Constant>(ConstantVal),
+ unwrap(ToType)));
+}
+
LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType) {
return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal),
@@ -2318,6 +2324,11 @@ LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val,
return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name));
}
+LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name) {
+ return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name));
+}
+
LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name) {
return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy),
diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp
index 2b5a0b39c3..a7773c4716 100644
--- a/lib/IR/Instruction.cpp
+++ b/lib/IR/Instruction.cpp
@@ -223,18 +223,19 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case GetElementPtr: return "getelementptr";
// Convert instructions...
- case Trunc: return "trunc";
- case ZExt: return "zext";
- case SExt: return "sext";
- case FPTrunc: return "fptrunc";
- case FPExt: return "fpext";
- case FPToUI: return "fptoui";
- case FPToSI: return "fptosi";
- case UIToFP: return "uitofp";
- case SIToFP: return "sitofp";
- case IntToPtr: return "inttoptr";
- case PtrToInt: return "ptrtoint";
- case BitCast: return "bitcast";
+ case Trunc: return "trunc";
+ case ZExt: return "zext";
+ case SExt: return "sext";
+ case FPTrunc: return "fptrunc";
+ case FPExt: return "fpext";
+ case FPToUI: return "fptoui";
+ case FPToSI: return "fptosi";
+ case UIToFP: return "uitofp";
+ case SIToFP: return "sitofp";
+ case IntToPtr: return "inttoptr";
+ case PtrToInt: return "ptrtoint";
+ case BitCast: return "bitcast";
+ case AddrSpaceCast: return "addrspacecast";
// Other instructions...
case ICmp: return "icmp";
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index 37b6782580..8a6b77ba37 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -2095,7 +2095,9 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode,
case Instruction::SIToFP:
case Instruction::FPToUI:
case Instruction::FPToSI:
- return false; // These always modify bits
+ case Instruction::AddrSpaceCast:
+ // TODO: Target informations may give a more accurate answer here.
+ return false;
case Instruction::BitCast:
return true; // BitCast never modifies bits.
case Instruction::PtrToInt:
@@ -2137,44 +2139,46 @@ unsigned CastInst::isEliminableCastPair(
// ZEXT < Integral Unsigned Integer Any
// SEXT < Integral Signed Integer Any
// FPTOUI n/a FloatPt n/a Integral Unsigned
- // FPTOSI n/a FloatPt n/a Integral Signed
- // UITOFP n/a Integral Unsigned FloatPt n/a
- // SITOFP n/a Integral Signed FloatPt n/a
- // FPTRUNC > FloatPt n/a FloatPt n/a
- // FPEXT < FloatPt n/a FloatPt n/a
+ // FPTOSI n/a FloatPt n/a Integral Signed
+ // UITOFP n/a Integral Unsigned FloatPt n/a
+ // SITOFP n/a Integral Signed FloatPt n/a
+ // FPTRUNC > FloatPt n/a FloatPt n/a
+ // FPEXT < FloatPt n/a FloatPt n/a
// PTRTOINT n/a Pointer n/a Integral Unsigned
// INTTOPTR n/a Integral Unsigned Pointer n/a
- // BITCAST = FirstClass n/a FirstClass n/a
+ // BITCAST = FirstClass n/a FirstClass n/a
+ // ADDRSPCST n/a Pointer n/a Pointer n/a
//
// NOTE: some transforms are safe, but we consider them to be non-profitable.
// For example, we could merge "fptoui double to i32" + "zext i32 to i64",
// into "fptoui double to i64", but this loses information about the range
- // of the produced value (we no longer know the top-part is all zeros).
+ // of the produced value (we no longer know the top-part is all zeros).
// Further this conversion is often much more expensive for typical hardware,
- // and causes issues when building libgcc. We disallow fptosi+sext for the
+ // and causes issues when building libgcc. We disallow fptosi+sext for the
// same reason.
- const unsigned numCastOps =
+ const unsigned numCastOps =
Instruction::CastOpsEnd - Instruction::CastOpsBegin;
static const uint8_t CastResults[numCastOps][numCastOps] = {
- // T F F U S F F P I B -+
- // R Z S P P I I T P 2 N T |
- // U E E 2 2 2 2 R E I T C +- secondOp
- // N X X U S F F N X N 2 V |
- // C T T I I P P C T T P T -+
- { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // Trunc -+
- { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3 }, // ZExt |
- { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3 }, // SExt |
- { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToUI |
- { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToSI |
- { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // UIToFP +- firstOp
- { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // SIToFP |
- { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4 }, // FPTrunc |
- { 99,99,99, 2, 2,99,99,10, 2,99,99, 4 }, // FPExt |
- { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3 }, // PtrToInt |
- { 99,99,99,99,99,99,99,99,99,13,99,12 }, // IntToPtr |
- { 5, 5, 5, 6, 6, 5, 5, 6, 6,11, 5, 1 }, // BitCast -+
+ // 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, 0,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, 1, 0,99,99, 4, 0}, // FPTrunc |
+ { 99,99,99, 2, 2,99,99,10, 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, 6, 6, 5, 5, 6, 6,16, 5, 1,14}, // BitCast |
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+
};
-
+
// If either of the casts are a bitcast from scalar to vector, disallow the
// merging. However, bitcast of A->B->A are allowed.
bool isFirstBitcast = (firstOp == Instruction::BitCast);
@@ -2191,47 +2195,50 @@ unsigned CastInst::isEliminableCastPair(
[secondOp-Instruction::CastOpsBegin];
switch (ElimCase) {
case 0:
- // categorically disallowed
+ // Categorically disallowed.
return 0;
case 1:
- // allowed, use first cast's opcode
+ // Allowed, use first cast's opcode.
return firstOp;
case 2:
- // allowed, use second cast's opcode
+ // Allowed, use second cast's opcode.
return secondOp;
case 3:
- // no-op cast in second op implies firstOp as long as the DestTy
+ // No-op cast in second op implies firstOp as long as the DestTy
// is integer and we are not converting between a vector and a
// non vector type.
if (!SrcTy->isVectorTy() && DstTy->isIntegerTy())
return firstOp;
return 0;
case 4:
- // no-op cast in second op implies firstOp as long as the DestTy
+ // No-op cast in second op implies firstOp as long as the DestTy
// is floating point.
if (DstTy->isFloatingPointTy())
return firstOp;
return 0;
case 5:
- // no-op cast in first op implies secondOp as long as the SrcTy
+ // No-op cast in first op implies secondOp as long as the SrcTy
// is an integer.
if (SrcTy->isIntegerTy())
return secondOp;
return 0;
case 6:
- // no-op cast in first op implies secondOp as long as the SrcTy
+ // No-op cast in first op implies secondOp as long as the SrcTy
// is a floating point.
if (SrcTy->isFloatingPointTy())
return secondOp;
return 0;
case 7: {
+ // Cannot simplify if address spaces are different!
+ if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace())
+ return 0;
+
unsigned MidSize = MidTy->getScalarSizeInBits();
- // Check the address spaces first. If we know they are in the same address
- // space, the pointer sizes must be the same so we can still fold this
- // without knowing the actual sizes as long we know that the intermediate
- // pointer is the largest possible pointer size.
- if (MidSize == 64 &&
- SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace())
+ // We can still fold this without knowing the actual sizes as long we
+ // know that the intermediate pointer is the largest possible
+ // pointer size.
+ // FIXME: Is this always true?
+ if (MidSize == 64)
return Instruction::BitCast;
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size.
@@ -2254,7 +2261,8 @@ unsigned CastInst::isEliminableCastPair(
return firstOp;
return secondOp;
}
- case 9: // zext, sext -> zext, because sext can't sign extend after zext
+ case 9:
+ // zext, sext -> zext, because sext can't sign extend after zext
return Instruction::ZExt;
case 10:
// fpext followed by ftrunc is allowed if the bit size returned to is
@@ -2263,46 +2271,6 @@ unsigned CastInst::isEliminableCastPair(
return Instruction::BitCast;
return 0; // If the types are not the same we can't eliminate it.
case 11: {
- // bitcast followed by ptrtoint is allowed as long as the bitcast is a
- // pointer to pointer cast, and the pointers are the same size.
- PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy);
- PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy);
- if (!SrcPtrTy || !MidPtrTy)
- return 0;
-
- // If the address spaces are the same, we know they are the same size
- // without size information
- if (SrcPtrTy->getAddressSpace() == MidPtrTy->getAddressSpace())
- return secondOp;
-
- if (!SrcIntPtrTy || !MidIntPtrTy)
- return 0;
-
- if (SrcIntPtrTy->getScalarSizeInBits() ==
- MidIntPtrTy->getScalarSizeInBits())
- return secondOp;
-
- return 0;
- }
- case 12: {
- // inttoptr, bitcast -> inttoptr if bitcast is a ptr to ptr cast
- // and the ptrs are to address spaces of the same size
- PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy);
- PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy);
- if (!MidPtrTy || !DstPtrTy)
- return 0;
-
- if (MidPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
- return firstOp;
-
- if (MidIntPtrTy &&
- DstIntPtrTy &&
- MidIntPtrTy->getScalarSizeInBits() ==
- DstIntPtrTy->getScalarSizeInBits())
- return firstOp;
- return 0;
- }
- case 13: {
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
if (!MidIntPtrTy)
return 0;
@@ -2313,8 +2281,65 @@ unsigned CastInst::isEliminableCastPair(
return Instruction::BitCast;
return 0;
}
+ case 12: {
+ // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS
+ // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS
+ if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace())
+ return Instruction::AddrSpaceCast;
+ return Instruction::BitCast;
+ }
+ case 13:
+ // FIXME: this state can be merged with (1), but the following assert
+ // is useful to check the correcteness of the sequence due to semantic
+ // change of bitcast.
+ assert(
+ SrcTy->isPtrOrPtrVectorTy() &&
+ MidTy->isPtrOrPtrVectorTy() &&
+ DstTy->isPtrOrPtrVectorTy() &&
+ SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() &&
+ MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
+ "Illegal addrspacecast, bitcast sequence!");
+ // Allowed, use first cast's opcode
+ return firstOp;
+ case 14:
+ // FIXME: this state can be merged with (2), but the following assert
+ // is useful to check the correcteness of the sequence due to semantic
+ // change of bitcast.
+ assert(
+ SrcTy->isPtrOrPtrVectorTy() &&
+ MidTy->isPtrOrPtrVectorTy() &&
+ DstTy->isPtrOrPtrVectorTy() &&
+ SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() &&
+ MidTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
+ "Illegal bitcast, addrspacecast sequence!");
+ // Allowed, use second cast's opcode
+ return secondOp;
+ case 15:
+ // FIXME: this state can be merged with (1), but the following assert
+ // is useful to check the correcteness of the sequence due to semantic
+ // change of bitcast.
+ assert(
+ SrcTy->isIntOrIntVectorTy() &&
+ MidTy->isPtrOrPtrVectorTy() &&
+ DstTy->isPtrOrPtrVectorTy() &&
+ MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
+ "Illegal inttoptr, bitcast sequence!");
+ // Allowed, use first cast's opcode
+ return firstOp;
+ case 16:
+ // FIXME: this state can be merged with (2), but the following assert
+ // is useful to check the correcteness of the sequence due to semantic
+ // change of bitcast.
+ assert(
+ SrcTy->isPtrOrPtrVectorTy() &&
+ MidTy->isPtrOrPtrVectorTy() &&
+ DstTy->isIntOrIntVectorTy() &&
+ SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() &&
+ "Illegal bitcast, ptrtoint sequence!");
+ // Allowed, use second cast's opcode
+ return secondOp;
case 99:
- // cast combination can't happen (error in input). This is for all cases
+ // Cast combination can't happen (error in input). This is for all cases
// where the MidTy is not the same for the two cast instructions.
llvm_unreachable("Invalid Cast Combination");
default:
@@ -2327,19 +2352,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty,
assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
- case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
- case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore);
- case SExt: return new SExtInst (S, Ty, Name, InsertBefore);
- case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore);
- case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore);
- case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore);
- 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 PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore);
- case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore);
- case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore);
- default: llvm_unreachable("Invalid opcode provided");
+ case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
+ case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore);
+ case SExt: return new SExtInst (S, Ty, Name, InsertBefore);
+ case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore);
+ case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore);
+ case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore);
+ 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 PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore);
+ case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore);
+ case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore);
+ case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertBefore);
+ default: llvm_unreachable("Invalid opcode provided");
}
}
@@ -2348,19 +2374,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty,
assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
- case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd);
- case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd);
- case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd);
- case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd);
- case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd);
- case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd);
- case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd);
- case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd);
- case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd);
- case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd);
- case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd);
- case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd);
- default: llvm_unreachable("Invalid opcode provided");
+ case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd);
+ case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd);
+ case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd);
+ case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd);
+ case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd);
+ case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd);
+ case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd);
+ case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd);
+ case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd);
+ case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd);
+ case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd);
+ case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd);
+ case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertAtEnd);
+ default: llvm_unreachable("Invalid opcode provided");
}
}
@@ -2425,6 +2452,11 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty,
if (Ty->isIntOrIntVectorTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
+
+ Type *STy = S->getType();
+ if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+ return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd);
+
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
}
@@ -2442,6 +2474,11 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty,
if (Ty->isIntOrIntVectorTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
+
+ Type *STy = S->getType();
+ if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+ return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore);
+
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
}
@@ -2687,7 +2724,8 @@ CastInst::getCastOpcode(
return BitCast;
} else if (DestTy->isPointerTy()) {
if (SrcTy->isPointerTy()) {
- // TODO: Address space pointer sizes may not match
+ if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace())
+ return AddrSpaceCast;
return BitCast; // ptr -> ptr
} else if (SrcTy->isIntegerTy()) {
return IntToPtr; // int -> ptr
@@ -2782,13 +2820,27 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) {
case Instruction::BitCast:
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
- if (SrcTy->isPointerTy() != DstTy->isPointerTy())
+ if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy())
return false;
- // Now we know we're not dealing with a pointer/non-pointer mismatch. In all
- // these cases, the cast is okay if the source and destination bit widths
- // are identical.
- return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
+ // For non pointer cases, the cast is okay if the source and destination bit
+ // widths are identical.
+ if (!SrcTy->isPtrOrPtrVectorTy())
+ return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
+
+ // If both are pointers then the address spaces must match and vector of
+ // pointers must have the same number of elements.
+ return SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
+ SrcTy->isVectorTy() == DstTy->isVectorTy() &&
+ (!SrcTy->isVectorTy() ||
+ SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
+
+ case Instruction::AddrSpaceCast:
+ return SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
+ SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
+ SrcTy->isVectorTy() == DstTy->isVectorTy() &&
+ (!SrcTy->isVectorTy() ||
+ SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
}
}
@@ -2935,6 +2987,18 @@ BitCastInst::BitCastInst(
assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast");
}
+AddrSpaceCastInst::AddrSpaceCastInst(
+ Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore
+) : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) {
+ assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast");
+}
+
+AddrSpaceCastInst::AddrSpaceCastInst(
+ Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, AddrSpaceCast, S, Name, InsertAtEnd) {
+ assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast");
+}
+
//===----------------------------------------------------------------------===//
// CmpInst Classes
//===----------------------------------------------------------------------===//
@@ -3553,6 +3617,10 @@ BitCastInst *BitCastInst::clone_impl() const {
return new BitCastInst(getOperand(0), getType());
}
+AddrSpaceCastInst *AddrSpaceCastInst::clone_impl() const {
+ return new AddrSpaceCastInst(getOperand(0), getType());
+}
+
CallInst *CallInst::clone_impl() const {
return new(getNumOperands()) CallInst(*this);
}
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index 6698f832b2..35808a658b 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -365,7 +365,8 @@ static Value *stripPointerCastsAndOffsets(Value *V) {
break;
}
V = GEP->getPointerOperand();
- } else if (Operator::getOpcode(V) == Instruction::BitCast) {
+ } else if (Operator::getOpcode(V) == Instruction::BitCast ||
+ Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
V = cast<Operator>(V)->getOperand(0);
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden())
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 1bb3e3423d..27bc13b95a 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -283,6 +283,7 @@ namespace {
void visitIntToPtrInst(IntToPtrInst &I);
void visitPtrToIntInst(PtrToIntInst &I);
void visitBitCastInst(BitCastInst &I);
+ void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitPHINode(PHINode &PN);
void visitBinaryOperator(BinaryOperator &B);
void visitICmpInst(ICmpInst &IC);
@@ -965,11 +966,9 @@ void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) {
unsigned SrcAS = SrcTy->getPointerAddressSpace();
unsigned DstAS = DestTy->getPointerAddressSpace();
- unsigned SrcASSize = DL->getPointerSizeInBits(SrcAS);
- unsigned DstASSize = DL->getPointerSizeInBits(DstAS);
- Assert1(SrcASSize == DstASSize,
- "Bitcasts between pointers of different address spaces must have "
- "the same size pointers, otherwise use PtrToInt/IntToPtr.", V);
+ Assert1(SrcAS == DstAS,
+ "Bitcasts between pointers of different address spaces is not legal."
+ "Use AddrSpaceCast instead.", V);
}
void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) {
@@ -1455,6 +1454,22 @@ void Verifier::visitBitCastInst(BitCastInst &I) {
visitInstruction(I);
}
+void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
+ Type *SrcTy = I.getOperand(0)->getType();
+ Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isPtrOrPtrVectorTy(),
+ "AddrSpaceCast source must be a pointer", &I);
+ Assert1(DestTy->isPtrOrPtrVectorTy(),
+ "AddrSpaceCast result must be a pointer", &I);
+ Assert1(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(),
+ "AddrSpaceCast must be between different address spaces", &I);
+ if (SrcTy->isVectorTy())
+ Assert1(SrcTy->getVectorNumElements() == DestTy->getVectorNumElements(),
+ "AddrSpaceCast vector pointer number of elements mismatch", &I);
+ visitInstruction(I);
+}
+
/// visitPHINode - Ensure that a PHI node is well formed.
///
void Verifier::visitPHINode(PHINode &PN) {
diff --git a/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp b/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
index 9f92a5b13e..9fb0dd88b7 100644
--- a/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
+++ b/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
@@ -142,7 +142,7 @@ bool GenericToNVVM::runOnModule(Module &M) {
GlobalVariable *GV = I->first;
GlobalVariable *NewGV = I->second;
++I;
- Constant *BitCastNewGV = ConstantExpr::getBitCast(NewGV, GV->getType());
+ Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
// At this point, the remaining uses of GV should be found only in global
// variable initializers, as other uses have been already been removed
// while walking through the instructions in function definitions.
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index a878ea82ea..aa9642056c 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -92,7 +92,7 @@ static SDValue ExtractSubVector(SDValue Vec, unsigned IdxVal,
VecIdx);
return Result;
-
+
}
/// Generate a DAG to grab 128-bits from a vector > 128 bits. This
/// sets things up to match to an AVX VEXTRACTF128 / VEXTRACTI128
@@ -1765,6 +1765,13 @@ bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
return true;
}
+bool X86TargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
+ unsigned DestAS) const {
+ assert(SrcAS != DestAS && "Expected different address spaces!");
+
+ return SrcAS < 256 && DestAS < 256;
+}
+
//===----------------------------------------------------------------------===//
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 07a36f98c2..bc3dd608da 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -775,6 +775,8 @@ namespace llvm {
SDValue BuildFILD(SDValue Op, EVT SrcVT, SDValue Chain, SDValue StackSlot,
SelectionDAG &DAG) const;
+ virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const LLVM_OVERRIDE;
+
/// \brief Reset the operation actions based on target options.
virtual void resetOperationActions();