Skip to content

Commit

Permalink
[InstCombine] Support opaque pointers in callee bitcast fold
Browse files Browse the repository at this point in the history
To make this actually trigger, we also need to check whether the
function types differ, which is a hidden cast under opaque pointers.
The transform is somewhat less relevant there because it is
primarily about pointer bitcasts, but it can also happen with other
bit- or pointer-castable types.

Byval handling is easier with opaque pointers because there is no
need to adjust the byval type, we only need to make sure that it's
still a pointer.
  • Loading branch information
nikic committed Mar 3, 2022
1 parent 6b3b3ef commit c1b9667
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
26 changes: 17 additions & 9 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Function>(Callee) && transformConstExprCastCall(Call))
Function *CalleeF = dyn_cast<Function>(Callee);
if ((!CalleeF || CalleeF->getFunctionType() != Call.getFunctionType()) &&
transformConstExprCastCall(Call))
return nullptr;

if (Function *CalleeF = dyn_cast<Function>(Callee)) {
if (CalleeF) {
// Remove the convergent attr on calls when the callee is not convergent.
if (Call.isConvergent() && !CalleeF->isConvergent() &&
!CalleeF->isIntrinsic()) {
Expand Down Expand Up @@ -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<PointerType>(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;
}
}
}

Expand Down Expand Up @@ -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));
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/Transforms/InstCombine/opaque-ptr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit c1b9667

Please sign in to comment.