Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1446,8 +1446,11 @@ // trunc or zext to the intptr_t type, then inttoptr of it. This allows the // cast to be exposed to other transforms. unsigned AS = CI.getAddressSpace(); + Type *EltTy = CI.getType()->getPointerElementType(); if (CI.getOperand(0)->getType()->getScalarSizeInBits() != - DL.getPointerSizeInBits(AS)) { + DL.getPointerSizeInBits(AS) && + // The size of a pointer to code is not defined by a DataLayout + !EltTy->isFunctionTy() && !EltTy->isLabelTy()) { 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/combine-func-ptr.ll =================================================================== --- test/Transforms/InstCombine/combine-func-ptr.ll +++ test/Transforms/InstCombine/combine-func-ptr.ll @@ -0,0 +1,16 @@ +; RUN: opt -O3 -S %s | FileCheck %s +; +; The 64 bit function pointer should not be truncated even with 32 bit pointer size in address space 0 +; +; CHECK-NOT: trunc + +target datalayout = "e-p:32:64-p1:64:64" + +define spir_kernel void @combine_func_ptr(i8 addrspace(1)* %ptr) { +entry: + %0 = ptrtoint i8 addrspace(1)* %ptr to i64 + %1 = inttoptr i64 %0 to i32 ()* + %call = tail call spir_func i32 %1() + ret void +} +