Index: lib/Analysis/IPA/InlineCost.cpp =================================================================== --- lib/Analysis/IPA/InlineCost.cpp +++ lib/Analysis/IPA/InlineCost.cpp @@ -250,7 +250,7 @@ if (!TD) return false; - unsigned IntPtrWidth = TD->getPointerSizeInBits(); + unsigned IntPtrWidth = TD->getPointerTypeSizeInBits(GEP.getType()); assert(IntPtrWidth == Offset.getBitWidth()); for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP); @@ -390,24 +390,27 @@ } bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) { + Type *Ty = I.getType(); + Value *Op = I.getOperand(0); // Propagate constants through ptrtoint. - Constant *COp = dyn_cast(I.getOperand(0)); + Constant *COp = dyn_cast(Op); if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); + COp = SimplifiedValues.lookup(Op); if (COp) - if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) { + if (Constant *C = ConstantExpr::getPtrToInt(COp, Ty)) { SimplifiedValues[&I] = C; return true; } // Track base/offset pairs when converted to a plain integer provided the // integer is large enough to represent the pointer. - unsigned IntegerSize = I.getType()->getScalarSizeInBits(); - if (TD && IntegerSize == TD->getPointerSizeInBits()) { - std::pair BaseAndOffset - = ConstantOffsetPtrs.lookup(I.getOperand(0)); - if (BaseAndOffset.first) + unsigned IntegerSize = Ty->getScalarSizeInBits(); + unsigned AS = Op->getType()->getPointerAddressSpace(); + if (TD && IntegerSize == TD->getPointerSizeInBits(AS)) { + std::pair BaseAndOffset = ConstantOffsetPtrs.lookup(Op); + if (BaseAndOffset.first) { ConstantOffsetPtrs[&I] = BaseAndOffset; + } } // This is really weird. Technically, ptrtoint will disable SROA. However, @@ -419,7 +422,7 @@ // disable SROA (ext) w/o some later use that we would see and disable. Value *SROAArg; DenseMap::iterator CostIt; - if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt)) + if (lookupSROAArgAndCost(Op, SROAArg, CostIt)) SROAArgValues[&I] = SROAArg; return TargetTransformInfo::TCC_Free == TTI.getUserCost(&I); @@ -440,7 +443,7 @@ // modifications provided the integer is not too large. Value *Op = I.getOperand(0); unsigned IntegerSize = Op->getType()->getScalarSizeInBits(); - if (TD && IntegerSize == TD->getPointerSizeInBits()) { + if (TD && IntegerSize == TD->getPointerTypeSizeInBits(I.getType())) { std::pair BaseAndOffset = ConstantOffsetPtrs.lookup(Op); if (BaseAndOffset.first) ConstantOffsetPtrs[&I] = BaseAndOffset; @@ -861,7 +864,8 @@ if (!TD || !V->getType()->isPointerTy()) return 0; - unsigned IntPtrWidth = TD->getPointerSizeInBits(); + unsigned AS = V->getType()->getPointerAddressSpace(); + unsigned IntPtrWidth = TD->getPointerSizeInBits(AS); APInt Offset = APInt::getNullValue(IntPtrWidth); // Even though we don't look through PHI nodes, we could be called on an @@ -885,7 +889,7 @@ assert(V->getType()->isPointerTy() && "Unexpected operand type!"); } while (Visited.insert(V)); - Type *IntPtrTy = TD->getIntPtrType(V->getContext()); + Type *IntPtrTy = TD->getIntPtrType(V->getContext(), AS); return cast(ConstantInt::get(IntPtrTy, Offset)); } @@ -925,7 +929,8 @@ // size of the byval type by the target's pointer size. PointerType *PTy = cast(CS.getArgument(I)->getType()); unsigned TypeSize = TD->getTypeSizeInBits(PTy->getElementType()); - unsigned PointerSize = TD->getPointerSizeInBits(); + unsigned AS = PTy->getAddressSpace(); + unsigned PointerSize = TD->getPointerSizeInBits(AS); // Ceiling division. unsigned NumStores = (TypeSize + PointerSize - 1) / PointerSize; @@ -1046,7 +1051,7 @@ // We never want to inline functions that contain an indirectbr. This is // incorrect because all the blockaddress's (in static global initializers // for example) would be referring to the original function, and this - // indirect jump would jump from the inlined copy of the function into the + // indirect jump would jump from the inlined copy of the function into the // original function which is extremely undefined behavior. // FIXME: This logic isn't really right; we can safely inline functions // with indirectbr's as long as no other function or global references the @@ -1115,7 +1120,7 @@ } } - // If this is a noduplicate call, we can still inline as long as + // If this is a noduplicate call, we can still inline as long as // inlining this would cause the removal of the caller (so the instruction // is not actually duplicated, just moved). if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall) Index: test/Transforms/Inline/ptr-diff.ll =================================================================== --- test/Transforms/Inline/ptr-diff.ll +++ test/Transforms/Inline/ptr-diff.ll @@ -1,6 +1,6 @@ ; RUN: opt -inline < %s -S -o - -inline-threshold=10 | FileCheck %s -target datalayout = "p:32:32" +target datalayout = "p:32:32-p1:64:64-n32" define i32 @outer1() { ; CHECK-LABEL: @outer1( @@ -29,6 +29,33 @@ ret i32 %t } +define i32 @outer1_as1(i32 addrspace(1)* %ptr) { +; CHECK-LABEL: @outer1_as1( +; CHECK: call +; CHECK: ret i32 + %ptr1 = getelementptr inbounds i32 addrspace(1)* %ptr, i32 0 + %ptr2 = getelementptr inbounds i32 addrspace(1)* %ptr, i32 42 + %result = call i32 @inner1_as1(i32 addrspace(1)* %ptr1, i32 addrspace(1)* %ptr2) + ret i32 %result +} + +; Make sure that the address space's larger size makes the ptrtoints +; not no-ops preventing inlining +define i32 @inner1_as1(i32 addrspace(1)* %begin, i32 addrspace(1)* %end) { + %begin.i = ptrtoint i32 addrspace(1)* %begin to i32 + %end.i = ptrtoint i32 addrspace(1)* %end to i32 + %distance = sub i32 %end.i, %begin.i + %icmp = icmp sle i32 %distance, 42 + br i1 %icmp, label %then, label %else + +then: + ret i32 3 + +else: + %t = load i32 addrspace(1)* %begin + ret i32 %t +} + ; Make sure that assertion isn't hit when ptrtoint is used with an ; integer size different from the pointer size define i32 @outer1_ptrtoint_larger() {