Index: include/llvm/CodeGen/TargetLowering.h =================================================================== --- include/llvm/CodeGen/TargetLowering.h +++ include/llvm/CodeGen/TargetLowering.h @@ -238,6 +238,12 @@ return MVT::getIntegerVT(DL.getPointerSizeInBits(AS)); } + /// Return the type for the index that used for address calculation. The size + /// of the index is taken the data layout. + MVT getIndexTy(const DataLayout &DL, uint32_t AS = 0) const { + return MVT::getIntegerVT(DL.getIndexSizeInBits(AS)); + } + /// Return the type for frame index, which is determined by /// the alloca address space specified through the data layout. MVT getFrameIndexTy(const DataLayout &DL) const { Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2068,7 +2068,7 @@ } case Instruction::GetElementPtr: { // Generate a symbolic expression for the byte address - APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0); + APInt OffsetAI(getDataLayout().getIndexTypeSizeInBits(CE->getType()), 0); cast(CE)->accumulateConstantOffset(getDataLayout(), OffsetAI); const MCExpr *Base = lowerConstant(CE->getOperand(0)); Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1268,7 +1268,11 @@ // Look through casts and constant offset GEPs. These mostly come from // inalloca. - APInt Offset(DL.getTypeSizeInBits(Address->getType()), 0); + Type *AddrTy = Address->getType(); + unsigned OffsetTypeSize = AddrTy->isPtrOrPtrVectorTy() ? + DL.getIndexTypeSizeInBits(Address->getType()) : + DL.getTypeSizeInBits(Address->getType()); + APInt Offset(OffsetTypeSize, 0); Address = Address->stripAndAccumulateInBoundsConstantOffsets(DL, Offset); // Check if the variable is a static alloca or a byval or inalloca Index: lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- lib/CodeGen/TargetLoweringBase.cpp +++ lib/CodeGen/TargetLoweringBase.cpp @@ -689,7 +689,7 @@ MVT TargetLoweringBase::getScalarShiftAmountTy(const DataLayout &DL, EVT) const { - return MVT::getIntegerVT(8 * DL.getPointerSize(0)); + return MVT::getIntegerVT(8 * DL.getIndexSize(0)); } EVT TargetLoweringBase::getShiftAmountTy(EVT LHSTy, const DataLayout &DL, @@ -698,7 +698,7 @@ if (LHSTy.isVector()) return LHSTy; return LegalTypes ? getScalarShiftAmountTy(DL, LHSTy) - : getPointerTy(DL); + : getIndexTy(DL); } bool TargetLoweringBase::canOpTrap(unsigned Op, EVT VT) const { Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1727,7 +1727,7 @@ // cast to be exposed to other transforms. unsigned AS = CI.getAddressSpace(); if (CI.getOperand(0)->getType()->getScalarSizeInBits() != - DL.getPointerSizeInBits(AS)) { + DL.getIndexSizeInBits(AS)) { Type *Ty = DL.getIntPtrType(CI.getContext(), AS); if (CI.getType()->isVectorTy()) // Handle vectors of pointers. Ty = VectorType::get(Ty, CI.getType()->getVectorNumElements()); Index: test/Transforms/InstCombine/ptr-int-cast_custom_gep.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/ptr-int-cast_custom_gep.ll @@ -0,0 +1,58 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "E-p:40:64:64:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" + +define i1 @test1(i32 *%x) nounwind { +entry: +; CHECK: test1 +; CHECK: ptrtoint i32* %x to i32 + %0 = ptrtoint i32* %x to i1 + ret i1 %0 +} + +define i32* @test2(i128 %x) nounwind { +entry: +; CHECK: test2 +; CHECK: inttoptr i32 %0 to i32* + %0 = inttoptr i128 %x to i32* + ret i32* %0 +} + +; PR3574 +; CHECK: f0 +; CHECK: %t1 = zext i32 %a0 to i64 +; CHECK: ret i64 %t1 +define i64 @f0(i32 %a0) nounwind { + %t0 = inttoptr i32 %a0 to i8* + %t1 = ptrtoint i8* %t0 to i64 + ret i64 %t1 +} + +define <4 x i32> @test4(<4 x i8*> %arg) nounwind { +; CHECK-LABEL: @test4( +; CHECK: ptrtoint <4 x i8*> %arg to <4 x i32> + %p1 = ptrtoint <4 x i8*> %arg to <4 x i32> + ret <4 x i32> %p1 +} + +define <4 x i128> @test5(<4 x i8*> %arg) nounwind { +; CHECK-LABEL: @test5( +; CHECK: ptrtoint <4 x i8*> %arg to <4 x i32> +; CHECK: zext <4 x i32> %1 to <4 x i128> + %p1 = ptrtoint <4 x i8*> %arg to <4 x i128> + ret <4 x i128> %p1 +} + +define <4 x i8*> @test6(<4 x i32> %arg) nounwind { +; CHECK-LABEL: @test6( +; CHECK: inttoptr <4 x i32> %arg to <4 x i8*> + %p1 = inttoptr <4 x i32> %arg to <4 x i8*> + ret <4 x i8*> %p1 +} + +define <4 x i8*> @test7(<4 x i128> %arg) nounwind { +; CHECK-LABEL: @test7( +; CHECK: trunc <4 x i128> %arg to <4 x i32> +; CHECK: inttoptr <4 x i32> %1 to <4 x i8*> + %p1 = inttoptr <4 x i128> %arg to <4 x i8*> + ret <4 x i8*> %p1 +}