[Attributor] Use "simplify to constant" in genericValueTraversal

As we replace values with constants interprocedurally, we also need to
do this "look-through" step during the generic value traversal or we
would derive properties from replaced values. While this is often not
problematic, it is when we use the "kind" of a value for reasoning,
e.g., accesses to arguments allow `argmemonly`.
This commit is contained in:
Johannes Doerfert 2020-05-09 23:29:43 -05:00
parent 513ac6e9b0
commit 713ee3aa77
7 changed files with 190 additions and 14 deletions

View File

@ -247,7 +247,7 @@ static bool genericValueTraversal(
Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State, Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
function_ref<bool(Value &, const Instruction *, StateTy &, bool)> function_ref<bool(Value &, const Instruction *, StateTy &, bool)>
VisitValueCB, VisitValueCB,
const Instruction *CtxI, int MaxValues = 16, const Instruction *CtxI, bool UseValueSimplify = true, int MaxValues = 16,
function_ref<Value *(Value *)> StripCB = nullptr) { function_ref<Value *(Value *)> StripCB = nullptr) {
const AAIsDead *LivenessAA = nullptr; const AAIsDead *LivenessAA = nullptr;
@ -324,6 +324,18 @@ static bool genericValueTraversal(
continue; continue;
} }
if (UseValueSimplify && !isa<Constant>(V)) {
bool UsedAssumedInformation = false;
Optional<Constant *> C =
A.getAssumedConstant(*V, QueryingAA, UsedAssumedInformation);
if (!C.hasValue())
continue;
if (Value *NewV = C.getValue()) {
Worklist.push_back({NewV, CtxI});
continue;
}
}
// Once a leaf is reached we inform the user through the callback. // Once a leaf is reached we inform the user through the callback.
if (!VisitValueCB(*V, CtxI, State, Iteration > 1)) if (!VisitValueCB(*V, CtxI, State, Iteration > 1))
return false; return false;
@ -979,7 +991,8 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
const Instruction *CtxI) { const Instruction *CtxI) {
IRPosition RetValPos = IRPosition::value(RV); IRPosition RetValPos = IRPosition::value(RV);
return genericValueTraversal<AAReturnedValues, RVState>( return genericValueTraversal<AAReturnedValues, RVState>(
A, RetValPos, *this, RVS, VisitValueCB, CtxI); A, RetValPos, *this, RVS, VisitValueCB, CtxI,
/* UseValueSimplify */ false);
}; };
// Callback for all "return intructions" live in the associated function. // Callback for all "return intructions" live in the associated function.
@ -4551,7 +4564,8 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
bool Dummy = false; bool Dummy = false;
if (!genericValueTraversal<AAValueSimplify, bool>( if (!genericValueTraversal<AAValueSimplify, bool>(
A, getIRPosition(), *this, Dummy, VisitValueCB, getCtxI())) A, getIRPosition(), *this, Dummy, VisitValueCB, getCtxI(),
/* UseValueSimplify */ false))
if (!askSimplifiedValueForAAValueConstantRange(A)) if (!askSimplifiedValueForAAValueConstantRange(A))
return indicatePessimisticFixpoint(); return indicatePessimisticFixpoint();
@ -6257,6 +6271,7 @@ void AAMemoryLocationImpl::categorizePtrValue(
if (!genericValueTraversal<AAMemoryLocation, AAMemoryLocation::StateType>( if (!genericValueTraversal<AAMemoryLocation, AAMemoryLocation::StateType>(
A, IRPosition::value(Ptr), *this, State, VisitValueCB, getCtxI(), A, IRPosition::value(Ptr), *this, State, VisitValueCB, getCtxI(),
/* UseValueSimplify */ true,
/* MaxValues */ 32, StripGEPCB)) { /* MaxValues */ 32, StripGEPCB)) {
LLVM_DEBUG( LLVM_DEBUG(
dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
@ -6897,7 +6912,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
IntegerRangeState T(getBitWidth()); IntegerRangeState T(getBitWidth());
if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>( if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
A, getIRPosition(), *this, T, VisitValueCB, getCtxI())) A, getIRPosition(), *this, T, VisitValueCB, getCtxI(),
/* UseValueSimplify */ false))
return indicatePessimisticFixpoint(); return indicatePessimisticFixpoint();
return clampStateAndIndicateChange(getState(), T); return clampStateAndIndicateChange(getState(), T);

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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
; Test that we only promote arguments when the caller/callee have compatible ; Test that we only promote arguments when the caller/callee have compatible

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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
; Test that we only promote arguments when the caller/callee have compatible ; Test that we only promote arguments when the caller/callee have compatible

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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
; PR 32917 ; PR 32917

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@ -420,6 +420,19 @@ define void @write_global_via_arg(i32* %GPtr) {
store i32 0, i32* %GPtr, align 4 store i32 0, i32* %GPtr, align 4
ret void ret void
} }
; CHECK: Function Attrs:
; CHECK-NOT: argmemonly
; CHECK-SAME: writeonly
; CHECK-NOT: argmemonly
define internal void @write_global_via_arg_internal(i32* %GPtr) {
; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg_internal()
; CHECK-NEXT: store i32 0, i32* @G, align 4
; CHECK-NEXT: ret void
;
store i32 0, i32* %GPtr, align 4
ret void
}
; CHECK: Function Attrs: ; CHECK: Function Attrs:
; CHECK-SAME: writeonly ; CHECK-SAME: writeonly
@ -441,3 +454,150 @@ define void @writeonly_global_via_arg() {
call void @write_global_via_arg(i32* @G) call void @write_global_via_arg(i32* @G)
ret void ret void
} }
; CHECK: Function Attrs:
; CHECK-SAME: writeonly
define void @writeonly_global_via_arg_internal() {
;
; CHECK-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal()
; CHECK-NEXT: call void @write_global_via_arg_internal()
; CHECK-NEXT: ret void
;
call void @write_global_via_arg_internal(i32* @G)
ret void
}
; CHECK: Function Attrs:
; CHECK-NOT: readnone
; CHECK-SAME: argmemonly
; CHECK-NOT: readnone
define i8 @recursive_not_readnone(i8* %ptr, i1 %c) {
; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone
; CHECK-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: [[ALLOC:%.*]] = alloca i8
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false)
; CHECK-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; CHECK-NEXT: ret i8 [[R]]
; CHECK: f:
; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1
; CHECK-NEXT: ret i8 0
;
%alloc = alloca i8
br i1 %c, label %t, label %f
t:
call i8 @recursive_not_readnone(i8* %alloc, i1 false)
%r = load i8, i8* %alloc
ret i8 %r
f:
store i8 1, i8* %ptr
ret i8 0
}
; CHECK: Function Attrs:
; CHECK-NOT: readnone
; CHECK-SAME: argmemonly
; CHECK-NOT: readnone
define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT____: t:
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false)
; IS__TUNIT____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__TUNIT____-NEXT: ret i8 [[R]]
; IS__TUNIT____: f:
; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: t:
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false)
; IS__CGSCC____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__CGSCC____-NEXT: ret i8 [[R]]
; IS__CGSCC____: f:
; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__CGSCC____-NEXT: ret i8 0
;
%alloc = alloca i8
br i1 %c, label %t, label %f
t:
call i8 @recursive_not_readnone_internal(i8* %alloc, i1 false)
%r = load i8, i8* %alloc
ret i8 %r
f:
store i8 1, i8* %ptr
ret i8 0
}
; CHECK: Function Attrs:
; CHECK-SAME: readnone
define i8 @readnone_caller(i1 %c) {
; CHECK-LABEL: define {{[^@]+}}@readnone_caller
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: [[A:%.*]] = alloca i8
; CHECK-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[A]], i1 [[C]])
; CHECK-NEXT: ret i8 [[R]]
;
%a = alloca i8
%r = call i8 @recursive_not_readnone_internal(i8* %a, i1 %c)
ret i8 %r
}
; CHECK: Function Attrs:
; CHECK-NOT: readnone
; CHECK-SAME: argmemonly
; CHECK-NOT: readnone
define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT____: t:
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false)
; IS__TUNIT____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__TUNIT____-NEXT: ret i8 [[R]]
; IS__TUNIT____: f:
; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: t:
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false)
; IS__CGSCC____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__CGSCC____-NEXT: ret i8 [[R]]
; IS__CGSCC____: f:
; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__CGSCC____-NEXT: ret i8 0
;
%alloc = alloca i8
br i1 %c, label %t, label %f
t:
call i8 @recursive_not_readnone_internal2(i8* %alloc, i1 false)
%r = load i8, i8* %alloc
ret i8 %r
f:
store i8 1, i8* %ptr
ret i8 0
}
; CHECK: Function Attrs:
; CHECK-SAME: readnone
define i8 @readnone_caller2(i1 %c) {
; CHECK-LABEL: define {{[^@]+}}@readnone_caller2
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal2(i8* undef, i1 [[C]])
; CHECK-NEXT: ret i8 [[R]]
;
%r = call i8 @recursive_not_readnone_internal2(i8* undef, i1 %c)
ret i8 %r
}

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; 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 ; 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