mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 17:12:00 +00:00
[InstCombine] Support opaque pointers in callee bitcast fold
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.
This commit is contained in:
parent
6b3b3ef344
commit
c1b9667148
@ -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()) {
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user