mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-04 18:38:37 +00:00
[Attributor][FIX] Carefully handle/ignore/forget argmemonly
When we have an existing `argmemonly` or `inaccessiblememorargmemonly` we used to "know" that information. However, interprocedural constant propagation can invalidate these attributes. We now ignore and remove these attributes for internal functions (which may be affected by IP constant propagation), if we are deriving new attributes for the function.
This commit is contained in:
parent
2251bdf0ea
commit
1e8b1544dc
@ -903,6 +903,11 @@ struct Attributor {
|
||||
Functions.size() == Functions.front()->getParent()->size();
|
||||
}
|
||||
|
||||
/// Return true if we derive attributes for \p Fn
|
||||
bool isRunOn(Function &Fn) const {
|
||||
return Functions.empty() || Functions.count(&Fn);
|
||||
}
|
||||
|
||||
/// Determine opportunities to derive 'default' attributes in \p F and create
|
||||
/// abstract attribute objects for them.
|
||||
///
|
||||
|
@ -6017,14 +6017,25 @@ struct AAMemoryLocationImpl : public AAMemoryLocation {
|
||||
/// See AbstractAttribute::initialize(...).
|
||||
void initialize(Attributor &A) override {
|
||||
intersectAssumedBits(BEST_STATE);
|
||||
getKnownStateFromValue(getIRPosition(), getState());
|
||||
getKnownStateFromValue(A, getIRPosition(), getState());
|
||||
IRAttribute::initialize(A);
|
||||
}
|
||||
|
||||
/// Return the memory behavior information encoded in the IR for \p IRP.
|
||||
static void getKnownStateFromValue(const IRPosition &IRP,
|
||||
static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
|
||||
BitIntegerState &State,
|
||||
bool IgnoreSubsumingPositions = false) {
|
||||
// For internal functions we ignore `argmemonly` and
|
||||
// `inaccessiblememorargmemonly` as we might break it via interprocedural
|
||||
// constant propagation. It is unclear if this is the best way but it is
|
||||
// unlikely this will cause real performance problems. If we are deriving
|
||||
// attributes for the anchor function we even remove the attribute in
|
||||
// addition to ignoring it.
|
||||
bool UseArgMemOnly = true;
|
||||
Function *AnchorFn = IRP.getAnchorScope();
|
||||
if (AnchorFn && A.isRunOn(*AnchorFn))
|
||||
UseArgMemOnly = !AnchorFn->hasLocalLinkage();
|
||||
|
||||
SmallVector<Attribute, 2> Attrs;
|
||||
IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
|
||||
for (const Attribute &Attr : Attrs) {
|
||||
@ -6036,11 +6047,17 @@ struct AAMemoryLocationImpl : public AAMemoryLocation {
|
||||
State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
|
||||
break;
|
||||
case Attribute::ArgMemOnly:
|
||||
State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
|
||||
if (UseArgMemOnly)
|
||||
State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
|
||||
else
|
||||
IRP.removeAttrs({Attribute::ArgMemOnly});
|
||||
break;
|
||||
case Attribute::InaccessibleMemOrArgMemOnly:
|
||||
State.addKnownBits(
|
||||
inverseLocation(NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
|
||||
if (UseArgMemOnly)
|
||||
State.addKnownBits(inverseLocation(
|
||||
NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
|
||||
else
|
||||
IRP.removeAttrs({Attribute::InaccessibleMemOrArgMemOnly});
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected attribute!");
|
||||
|
@ -5,6 +5,8 @@
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
@G = external dso_local global i32, align 4
|
||||
|
||||
; CHECK: Function Attrs: inaccessiblememonly
|
||||
declare noalias i8* @malloc(i64) inaccessiblememonly
|
||||
|
||||
@ -397,7 +399,6 @@ define void @callerE(i8* %arg) {
|
||||
ret void
|
||||
}
|
||||
|
||||
@G = external dso_local global i32, align 4
|
||||
|
||||
; CHECK: Function Attrs:
|
||||
; CHECK-SAME: writeonly
|
||||
@ -601,3 +602,25 @@ define i8 @readnone_caller2(i1 %c) {
|
||||
%r = call i8 @recursive_not_readnone_internal2(i8* undef, i1 %c)
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
; CHECK: Function Attrs:
|
||||
; CHECK-NOT: argmemonly
|
||||
define internal void @argmemonly_before_ipconstprop(i32* %p) argmemonly {
|
||||
; CHECK-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop()
|
||||
; CHECK-NEXT: store i32 0, i32* @G, align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
store i32 0, i32* %p
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: Function Attrs:
|
||||
; CHECK-NOT: argmemonly
|
||||
define void @argmemonky_caller() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@argmemonky_caller()
|
||||
; CHECK-NEXT: call void @argmemonly_before_ipconstprop()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @argmemonly_before_ipconstprop(i32* @G)
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user