mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-08 21:37:35 +00:00
[Attributor][FIX] Avoid modifying naked/optnone functions
The check for naked/optnone was insufficient for different reasons. We now check before we initialize an abstract attribute and we do it for all abstract attributes. llvm-svn: 374694
This commit is contained in:
parent
67305cbcc3
commit
a3ef980c25
@ -913,15 +913,23 @@ private:
|
||||
// Use the static create method.
|
||||
auto &AA = AAType::createForPosition(IRP, *this);
|
||||
registerAA(AA);
|
||||
AA.initialize(*this);
|
||||
|
||||
// For now we ignore naked and optnone functions.
|
||||
bool Invalidate = Whitelist && !Whitelist->count(&AAType::ID);
|
||||
if (const Function *Fn = IRP.getAnchorScope())
|
||||
Invalidate |= Fn->hasFnAttribute(Attribute::Naked) ||
|
||||
Fn->hasFnAttribute(Attribute::OptimizeNone);
|
||||
|
||||
// Bootstrap the new attribute with an initial update to propagate
|
||||
// information, e.g., function -> call site. If it is not on a given
|
||||
// whitelist we will not perform updates at all.
|
||||
if (Whitelist && !Whitelist->count(&AAType::ID))
|
||||
if (Invalidate) {
|
||||
AA.getState().indicatePessimisticFixpoint();
|
||||
else
|
||||
AA.update(*this);
|
||||
return AA;
|
||||
}
|
||||
|
||||
AA.initialize(*this);
|
||||
AA.update(*this);
|
||||
|
||||
if (TrackDependence && AA.getState().isValidState())
|
||||
QueryMap[&AA].insert(const_cast<AbstractAttribute *>(QueryingAA));
|
||||
|
@ -4847,11 +4847,6 @@ static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
|
||||
else
|
||||
NumFnWithoutExactDefinition++;
|
||||
|
||||
// For now we ignore naked and optnone functions.
|
||||
if (F.hasFnAttribute(Attribute::Naked) ||
|
||||
F.hasFnAttribute(Attribute::OptimizeNone))
|
||||
continue;
|
||||
|
||||
// We look at internal functions only on-demand but if any use is not a
|
||||
// direct call, we have to do it eagerly.
|
||||
if (F.hasLocalLinkage()) {
|
||||
|
@ -545,6 +545,30 @@ define weak_odr void @weak_caller(i32* nonnull %a) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; Expect nonnull
|
||||
; ATTRIBUTOR: define internal void @control(i32* nocapture nonnull readnone align 16 dereferenceable(8) %a)
|
||||
define internal void @control(i32* dereferenceable(4) %a) {
|
||||
call void @use_i32_ptr(i32* %a)
|
||||
ret void
|
||||
}
|
||||
; Avoid nonnull as we do not touch naked functions
|
||||
; ATTRIBUTOR: define internal void @naked(i32* dereferenceable(4) %a)
|
||||
define internal void @naked(i32* dereferenceable(4) %a) naked {
|
||||
call void @use_i32_ptr(i32* %a)
|
||||
ret void
|
||||
}
|
||||
; Avoid nonnull as we do not touch optnone
|
||||
; ATTRIBUTOR: define internal void @optnone(i32* dereferenceable(4) %a)
|
||||
define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
|
||||
call void @use_i32_ptr(i32* %a)
|
||||
ret void
|
||||
}
|
||||
define void @make_live(i32* nonnull dereferenceable(8) %a) {
|
||||
call void @naked(i32* nonnull dereferenceable(8) align 16 %a)
|
||||
call void @control(i32* nonnull dereferenceable(8) align 16 %a)
|
||||
call void @optnone(i32* nonnull dereferenceable(8) align 16 %a)
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "null-pointer-is-valid"="true" }
|
||||
attributes #1 = { nounwind willreturn}
|
||||
|
Loading…
x
Reference in New Issue
Block a user