diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 573a8db8479f..eedc79f43cd4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2834,10 +2834,12 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) { // If the callee is a pointer to a function, attempt to move any casts to the // arguments of the call/callbr/invoke. Value *Callee = Call.getCalledOperand(); - if (!isa(Callee) && transformConstExprCastCall(Call)) + Function *CalleeF = dyn_cast(Callee); + if ((!CalleeF || CalleeF->getFunctionType() != Call.getFunctionType()) && + transformConstExprCastCall(Call)) return nullptr; - if (Function *CalleeF = dyn_cast(Callee)) { + if (CalleeF) { // Remove the convergent attr on calls when the callee is not convergent. if (Call.isConvergent() && !CalleeF->isConvergent() && !CalleeF->isIntrinsic()) { @@ -3167,13 +3169,18 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) { // sized type and the sized type has to have the same size as the old type. if (ParamTy != ActTy && CallerPAL.hasParamAttr(i, Attribute::ByVal)) { PointerType *ParamPTy = dyn_cast(ParamTy); - if (!ParamPTy || !ParamPTy->getPointerElementType()->isSized()) + if (!ParamPTy) return false; - Type *CurElTy = Call.getParamByValType(i); - if (DL.getTypeAllocSize(CurElTy) != - DL.getTypeAllocSize(ParamPTy->getPointerElementType())) - return false; + if (!ParamPTy->isOpaque()) { + Type *ParamElTy = ParamPTy->getNonOpaquePointerElementType(); + if (!ParamElTy->isSized()) + return false; + + Type *CurElTy = Call.getParamByValType(i); + if (DL.getTypeAllocSize(CurElTy) != DL.getTypeAllocSize(ParamElTy)) + return false; + } } } @@ -3232,9 +3239,10 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) { Args.push_back(NewArg); // Add any parameter attributes. - if (CallerPAL.hasParamAttr(i, Attribute::ByVal)) { + if (CallerPAL.hasParamAttr(i, Attribute::ByVal) && + !ParamTy->isOpaquePointerTy()) { AttrBuilder AB(FT->getContext(), CallerPAL.getParamAttrs(i)); - AB.addByValAttr(NewArg->getType()->getPointerElementType()); + AB.addByValAttr(ParamTy->getNonOpaquePointerElementType()); ArgAttrs.push_back(AttributeSet::get(Ctx, AB)); } else ArgAttrs.push_back(CallerPAL.getParamAttrs(i)); diff --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll index 1826cfdf43bb..56ee71e13ea7 100644 --- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll +++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll @@ -493,3 +493,26 @@ define void @dse(ptr %p) { store i8 1, ptr %p ret void } + +declare void @call_i64(i64) +declare void @call_byval(i64, ptr byval(i64)) + +define void @call_cast_ptr_to_int(ptr %p) { +; CHECK-LABEL: @call_cast_ptr_to_int( +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64 +; CHECK-NEXT: call void @call_i64(i64 [[TMP1]]) +; CHECK-NEXT: ret void +; + call void @call_i64(ptr %p) + ret void +} + +define void @call_cast_byval(ptr %p, ptr %p2) { +; CHECK-LABEL: @call_cast_byval( +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64 +; CHECK-NEXT: call void @call_byval(i64 [[TMP1]], ptr byval(double) [[P2:%.*]]) +; CHECK-NEXT: ret void +; + call void @call_byval(ptr %p, ptr byval(double) %p2) + ret void +}