mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 11:35:51 -04:00
[Attributor][FIX] Handle non-pointers when following uses
When we follow uses, e.g., in AAMemoryBehavior or AANoCapture, we need to make sure the value is a pointer before we ask for abstract attributes only valid for pointers. This happens because we follow pointers through calls that do not capture but may return the value.
This commit is contained in:
parent
9dcf889d15
commit
ff6254dc26
@ -5074,10 +5074,14 @@ bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
|
|||||||
// general capturing of the underlying argument. The reason is that the
|
// general capturing of the underlying argument. The reason is that the
|
||||||
// call might the argument "through return", which we allow and for which we
|
// call might the argument "through return", which we allow and for which we
|
||||||
// need to check call users.
|
// need to check call users.
|
||||||
unsigned ArgNo = ICS.getArgumentNo(U);
|
if (U->get()->getType()->isPointerTy()) {
|
||||||
const auto &ArgNoCaptureAA =
|
unsigned ArgNo = ICS.getArgumentNo(U);
|
||||||
A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
|
const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
|
||||||
return !ArgNoCaptureAA.isAssumedNoCapture();
|
*this, IRPosition::callsite_argument(ICS, ArgNo));
|
||||||
|
return !ArgNoCaptureAA.isAssumedNoCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
|
void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
|
||||||
@ -5123,9 +5127,12 @@ void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
|
|||||||
|
|
||||||
// Adjust the possible access behavior based on the information on the
|
// Adjust the possible access behavior based on the information on the
|
||||||
// argument.
|
// argument.
|
||||||
unsigned ArgNo = ICS.getArgumentNo(U);
|
IRPosition Pos;
|
||||||
const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
|
if (U->get()->getType()->isPointerTy())
|
||||||
const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
|
Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U));
|
||||||
|
else
|
||||||
|
Pos = IRPosition::callsite_function(ICS);
|
||||||
|
const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, Pos);
|
||||||
// "assumed" has at most the same bits as the MemBehaviorAA assumed
|
// "assumed" has at most the same bits as the MemBehaviorAA assumed
|
||||||
// and at least "known".
|
// and at least "known".
|
||||||
intersectAssumedBits(MemBehaviorAA.getAssumed());
|
intersectAssumedBits(MemBehaviorAA.getAssumed());
|
||||||
|
@ -342,5 +342,19 @@ entry:
|
|||||||
ret i8* %p
|
ret i8* %p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare i8* @maybe_returned_ptr(i8* readonly %ptr) readonly nounwind
|
||||||
|
declare i8 @maybe_returned_val(i8* %ptr) readonly nounwind
|
||||||
|
declare void @val_use(i8 %ptr) readonly nounwind
|
||||||
|
|
||||||
|
; FIXME: Both pointers should be nocapture
|
||||||
|
define void @ptr_uses(i8* %ptr, i8* %wptr) {
|
||||||
|
; CHECK: define void @ptr_uses(i8* %ptr, i8* nocapture nonnull writeonly dereferenceable(1) %wptr)
|
||||||
|
%call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
|
||||||
|
%call_val = call i8 @maybe_returned_val(i8* %call_ptr)
|
||||||
|
call void @val_use(i8 %call_val)
|
||||||
|
store i8 0, i8* %wptr
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
declare i8* @llvm.launder.invariant.group.p0i8(i8*)
|
declare i8* @llvm.launder.invariant.group.p0i8(i8*)
|
||||||
declare i8* @llvm.strip.invariant.group.p0i8(i8*)
|
declare i8* @llvm.strip.invariant.group.p0i8(i8*)
|
||||||
|
@ -195,3 +195,15 @@ define void @testbyval(i8* %read_only) {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
;}
|
;}
|
||||||
|
|
||||||
|
declare i8* @maybe_returned_ptr(i8* readonly %ptr) readonly nounwind
|
||||||
|
declare i8 @maybe_returned_val(i8* %ptr) readonly nounwind
|
||||||
|
declare void @val_use(i8 %ptr) readonly nounwind
|
||||||
|
|
||||||
|
define void @ptr_uses(i8* %ptr) {
|
||||||
|
; ATTRIBUTOR: define void @ptr_uses(i8* nocapture readonly %ptr)
|
||||||
|
%call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
|
||||||
|
%call_val = call i8 @maybe_returned_val(i8* %call_ptr)
|
||||||
|
call void @val_use(i8 %call_val)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user