[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:
Johannes Doerfert 2019-10-13 02:24:02 +00:00
parent 67305cbcc3
commit a3ef980c25
3 changed files with 36 additions and 9 deletions

View File

@ -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));

View File

@ -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()) {

View File

@ -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}