forked from OSchip/llvm-project
[Attributor] Remember only necessary dependences
Before we eagerly put dependences into the QueryMap as soon as we encountered them (via `Attributor::getAAFor<>` or `Attributor::recordDependence`). Now we will wait to see if the dependence is useful, that is if the target is not already in a fixpoint state at the end of the update. If so, there is no need to record the dependence at all. Due to the abstraction via `Attributor::updateAA` we will now also treat the very first update (during attribute creation) as we do subsequent updates. Finally this resolves the problematic usage of QueriedNonFixAA. --- Single run of the Attributor module and then CGSCC pass (oldPM) for SPASS/clause.c (~10k LLVM-IR loc): Before: ``` calls to allocation functions: 554675 (389245/s) temporary memory allocations: 101574 (71280/s) peak heap memory consumption: 28.46MB peak RSS (including heaptrack overhead): 116.26MB total memory leaked: 269.10KB ``` After: ``` calls to allocation functions: 512465 (345559/s) temporary memory allocations: 98832 (66643/s) peak heap memory consumption: 22.54MB peak RSS (including heaptrack overhead): 106.58MB total memory leaked: 269.10KB ``` Difference: ``` calls to allocation functions: -42210 (-727758/s) temporary memory allocations: -2742 (-47275/s) peak heap memory consumption: -5.92MB peak RSS (including heaptrack overhead): 0B total memory leaked: 0B ```
This commit is contained in:
parent
231026a508
commit
95e0d28b71
|
@ -1195,6 +1195,14 @@ struct Attributor {
|
|||
BumpPtrAllocator &Allocator;
|
||||
|
||||
private:
|
||||
/// Run `::update` on \p AA and track the dependences queried while doing so.
|
||||
/// Also adjust the state if we know further updates are not necessary.
|
||||
ChangeStatus updateAA(AbstractAttribute &AA);
|
||||
|
||||
/// Remember the dependences on the top of the dependence stack such that they
|
||||
/// may trigger further updates. (\see DependenceStack)
|
||||
void rememberDependences();
|
||||
|
||||
/// Check \p Pred on all call sites of \p Fn.
|
||||
///
|
||||
/// This method will evaluate \p Pred on call sites and return
|
||||
|
@ -1248,7 +1256,7 @@ private:
|
|||
return AA;
|
||||
}
|
||||
|
||||
AA.update(*this);
|
||||
updateAA(AA);
|
||||
|
||||
if (TrackDependence && AA.getState().isValidState())
|
||||
recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
|
||||
|
@ -1345,8 +1353,23 @@ private:
|
|||
/// impact the call graph.
|
||||
SmallPtrSet<Function *, 8> CGModifiedFunctions;
|
||||
|
||||
/// Set if the attribute currently updated did query a non-fix attribute.
|
||||
bool QueriedNonFixAA;
|
||||
/// Information about a dependence. If FromAA is changed ToAA needs to be
|
||||
/// updated as well.
|
||||
struct DepInfo {
|
||||
const AbstractAttribute *FromAA;
|
||||
const AbstractAttribute *ToAA;
|
||||
DepClassTy DepClass;
|
||||
};
|
||||
|
||||
/// The dependence stack is used to track dependences during an
|
||||
/// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
|
||||
/// recursive we might have multiple vectors of dependences in here. The stack
|
||||
/// size, should be adjusted according to the expected recursion depth and the
|
||||
/// inner dependence vector size to the expected number of dependences per
|
||||
/// abstract attribute. Since the inner vectors are actually allocated on the
|
||||
/// stack we can be generous with their size.
|
||||
using DependenceVector = SmallVector<DepInfo, 8>;
|
||||
SmallVector<DependenceVector *, 16> DependenceStack;
|
||||
|
||||
/// If not null, a set limiting the attribute opportunities.
|
||||
const DenseSet<const char *> *Whitelist;
|
||||
|
|
|
@ -976,21 +976,19 @@ ChangeStatus Attributor::run() {
|
|||
|
||||
// Update all abstract attribute in the work list and record the ones that
|
||||
// changed.
|
||||
for (AbstractAttribute *AA : Worklist)
|
||||
if (!AA->getState().isAtFixpoint() &&
|
||||
for (AbstractAttribute *AA : Worklist) {
|
||||
const auto &AAState = AA->getState();
|
||||
if (!AAState.isAtFixpoint() &&
|
||||
!isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true)) {
|
||||
QueriedNonFixAA = false;
|
||||
if (AA->update(*this) == ChangeStatus::CHANGED) {
|
||||
if (updateAA(*AA) == ChangeStatus::CHANGED) {
|
||||
ChangedAAs.push_back(AA);
|
||||
if (!AA->getState().isValidState())
|
||||
InvalidAAs.insert(AA);
|
||||
} else if (!QueriedNonFixAA) {
|
||||
// If the attribute did not query any non-fix information, the state
|
||||
// will not change and we can indicate that right away.
|
||||
AA->getState().indicateOptimisticFixpoint();
|
||||
}
|
||||
}
|
||||
|
||||
// Use the InvalidAAs vector to propagate invalid states fast transitively
|
||||
// without requiring updates.
|
||||
if (!AAState.isValidState())
|
||||
InvalidAAs.insert(AA);
|
||||
}
|
||||
|
||||
// Add attributes to the changed set if they have been created in the last
|
||||
// iteration.
|
||||
|
@ -1271,6 +1269,31 @@ ChangeStatus Attributor::run() {
|
|||
return ManifestChange;
|
||||
}
|
||||
|
||||
ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
|
||||
// Use a new dependence vector for this update.
|
||||
DependenceVector DV;
|
||||
DependenceStack.push_back(&DV);
|
||||
|
||||
auto &AAState = AA.getState();
|
||||
ChangeStatus CS = AA.update(*this);
|
||||
if (DV.empty()) {
|
||||
// If the attribute did not query any non-fix information, the state
|
||||
// will not change and we can indicate that right away.
|
||||
AAState.indicateOptimisticFixpoint();
|
||||
}
|
||||
|
||||
if (!AAState.isAtFixpoint())
|
||||
rememberDependences();
|
||||
|
||||
// Verify the stack was used properly, that is we pop the dependence vector we
|
||||
// put there earlier.
|
||||
DependenceVector *PoppedDV = DependenceStack.pop_back_val();
|
||||
(void)PoppedDV;
|
||||
assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");
|
||||
|
||||
return CS;
|
||||
}
|
||||
|
||||
/// Create a shallow wrapper for \p F such that \p F has internal linkage
|
||||
/// afterwards. It also sets the original \p F 's name to anonymous
|
||||
///
|
||||
|
@ -1686,18 +1709,29 @@ InformationCache::FunctionInfo::~FunctionInfo() {
|
|||
void Attributor::recordDependence(const AbstractAttribute &FromAA,
|
||||
const AbstractAttribute &ToAA,
|
||||
DepClassTy DepClass) {
|
||||
// If we are outside of an update, thus before the actual fixpoint iteration
|
||||
// started (= when we create AAs), we do not track dependences because we will
|
||||
// put all AAs into the initial worklist anyway.
|
||||
if (DependenceStack.empty())
|
||||
return;
|
||||
if (FromAA.getState().isAtFixpoint())
|
||||
return;
|
||||
DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
|
||||
}
|
||||
|
||||
QueryMapValueTy *&DepAAs = QueryMap[&FromAA];
|
||||
if (!DepAAs)
|
||||
DepAAs = new (Allocator) QueryMapValueTy();
|
||||
void Attributor::rememberDependences() {
|
||||
assert(!DependenceStack.empty() && "No dependences to remember!");
|
||||
|
||||
if (DepClass == DepClassTy::REQUIRED)
|
||||
DepAAs->RequiredAAs.insert(const_cast<AbstractAttribute *>(&ToAA));
|
||||
else
|
||||
DepAAs->OptionalAAs.insert(const_cast<AbstractAttribute *>(&ToAA));
|
||||
QueriedNonFixAA = true;
|
||||
for (DepInfo &DI : *DependenceStack.back()) {
|
||||
QueryMapValueTy *&DepAAs = QueryMap[DI.FromAA];
|
||||
if (!DepAAs)
|
||||
DepAAs = new (Allocator) QueryMapValueTy();
|
||||
|
||||
if (DI.DepClass == DepClassTy::REQUIRED)
|
||||
DepAAs->RequiredAAs.insert(const_cast<AbstractAttribute *>(DI.ToAA));
|
||||
else
|
||||
DepAAs->OptionalAAs.insert(const_cast<AbstractAttribute *>(DI.ToAA));
|
||||
}
|
||||
}
|
||||
|
||||
void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
||||
|
|
|
@ -115,6 +115,7 @@ PIPE_OPERATOR(AAMemoryBehavior)
|
|||
PIPE_OPERATOR(AAMemoryLocation)
|
||||
PIPE_OPERATOR(AAValueConstantRange)
|
||||
PIPE_OPERATOR(AAPrivatizablePtr)
|
||||
PIPE_OPERATOR(AAUndefinedBehavior)
|
||||
|
||||
#undef PIPE_OPERATOR
|
||||
} // namespace llvm
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; 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=3 -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=3 -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 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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=2 -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 -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
|
||||
; PR2498
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; 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=3 -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=3 -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 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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=1 -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 -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
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; 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=1 -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=2 -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=2 -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 -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
|
||||
|
@ -8,15 +8,15 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define i64 @fn2() {
|
||||
; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2()
|
||||
; NOT_TUNIT_NPM-NEXT: entry:
|
||||
; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef)
|
||||
; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2()
|
||||
; IS__TUNIT____-NEXT: entry:
|
||||
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #0, !range !0
|
||||
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2()
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #1, !range !0
|
||||
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2()
|
||||
; IS__CGSCC____-NEXT: entry:
|
||||
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef)
|
||||
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
entry:
|
||||
%conv = sext i32 undef to i64
|
||||
|
@ -26,21 +26,21 @@ entry:
|
|||
}
|
||||
|
||||
define i64 @fn2b(i32 %arg) {
|
||||
; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b
|
||||
; NOT_TUNIT_NPM-SAME: (i32 [[ARG:%.*]])
|
||||
; NOT_TUNIT_NPM-NEXT: entry:
|
||||
; NOT_TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||
; NOT_TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||
; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]])
|
||||
; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2b
|
||||
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
|
||||
; IS__TUNIT____-NEXT: entry:
|
||||
; IS__TUNIT____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||
; IS__TUNIT____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #0, !range !0
|
||||
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b
|
||||
; IS__TUNIT_NPM-SAME: (i32 [[ARG:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||
; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0
|
||||
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b
|
||||
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
|
||||
; IS__CGSCC____-NEXT: entry:
|
||||
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]])
|
||||
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
entry:
|
||||
%conv = sext i32 %arg to i64
|
||||
|
@ -50,15 +50,10 @@ entry:
|
|||
}
|
||||
|
||||
define i64 @fn2c() {
|
||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2c()
|
||||
; IS__TUNIT_OPM-NEXT: entry:
|
||||
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42)
|
||||
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2c()
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #1, !range !0
|
||||
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c()
|
||||
; IS__TUNIT____-NEXT: entry:
|
||||
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #0, !range !0
|
||||
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
|
||||
;
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c()
|
||||
; IS__CGSCC____-NEXT: entry:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; 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=3 -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=3 -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 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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=1 -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 -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
|
||||
;
|
||||
|
|
|
@ -104,27 +104,16 @@ define i1 @c5(i32* %q, i32 %bitno) {
|
|||
declare void @throw_if_bit_set(i8*, i8) readonly
|
||||
|
||||
define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@c6
|
||||
; IS__TUNIT____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #5 personality i32 (...)* @__gxx_personality_v0
|
||||
; IS__TUNIT____-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]])
|
||||
; IS__TUNIT____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
|
||||
; IS__TUNIT____: ret0:
|
||||
; IS__TUNIT____-NEXT: ret i1 false
|
||||
; IS__TUNIT____: ret1:
|
||||
; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
|
||||
; IS__TUNIT____-NEXT: cleanup
|
||||
; IS__TUNIT____-NEXT: ret i1 true
|
||||
;
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@c6
|
||||
; IS__CGSCC____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #4 personality i32 (...)* @__gxx_personality_v0
|
||||
; IS__CGSCC____-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]])
|
||||
; IS__CGSCC____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
|
||||
; IS__CGSCC____: ret0:
|
||||
; IS__CGSCC____-NEXT: ret i1 false
|
||||
; IS__CGSCC____: ret1:
|
||||
; IS__CGSCC____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
|
||||
; IS__CGSCC____-NEXT: cleanup
|
||||
; IS__CGSCC____-NEXT: ret i1 true
|
||||
; CHECK-LABEL: define {{[^@]+}}@c6
|
||||
; CHECK-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #4 personality i32 (...)* @__gxx_personality_v0
|
||||
; CHECK-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]])
|
||||
; CHECK-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
|
||||
; CHECK: ret0:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
; CHECK: ret1:
|
||||
; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
|
||||
; CHECK-NEXT: cleanup
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
invoke void @throw_if_bit_set(i8* %q, i8 %bit)
|
||||
to label %ret0 unwind label %ret1
|
||||
|
|
|
@ -38,7 +38,7 @@ define i8* @test2A(i1 %c, i8* %ret) {
|
|||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[RET]]) ]
|
||||
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
; NOT_CGSCC_OPM: B:
|
||||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[RET]]) ]
|
||||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[RET]]) ]
|
||||
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
;
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
|
||||
|
@ -48,7 +48,7 @@ define i8* @test2A(i1 %c, i8* %ret) {
|
|||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "nonnull"(i8* [[RET]]) ]
|
||||
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
; IS__CGSCC_OPM: B:
|
||||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[RET]]) ]
|
||||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "nonnull"(i8* [[RET]]) ]
|
||||
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
;
|
||||
br i1 %c, label %A, label %B
|
||||
|
@ -69,7 +69,7 @@ define i8* @test2B(i1 %c, i8* %ret) {
|
|||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
; NOT_CGSCC_OPM: B:
|
||||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
;
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
|
||||
|
@ -79,7 +79,7 @@ define i8* @test2B(i1 %c, i8* %ret) {
|
|||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
; IS__CGSCC_OPM: B:
|
||||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "dereferenceable"(i8* [[RET]], i32 4) ]
|
||||
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
|
||||
;
|
||||
br i1 %c, label %A, label %B
|
||||
|
@ -727,18 +727,31 @@ define i8 @parent7(i8* %a) {
|
|||
declare i32 @esfp(...)
|
||||
|
||||
define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
|
||||
; CHECK-LABEL: define {{[^@]+}}@parent8
|
||||
; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #2 personality i8* bitcast (i32 (...)* @esfp to i8*)
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
|
||||
; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
|
||||
; CHECK: cont:
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
; CHECK: exc:
|
||||
; CHECK-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
|
||||
; CHECK-NEXT: filter [0 x i8*] zeroinitializer
|
||||
; CHECK-NEXT: unreachable
|
||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
|
||||
; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #4 personality i8* bitcast (i32 (...)* @esfp to i8*)
|
||||
; NOT_CGSCC_OPM-NEXT: entry:
|
||||
; NOT_CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
|
||||
; NOT_CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
|
||||
; NOT_CGSCC_OPM: cont:
|
||||
; NOT_CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
|
||||
; NOT_CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
|
||||
; NOT_CGSCC_OPM: exc:
|
||||
; NOT_CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
|
||||
; NOT_CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
|
||||
; NOT_CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
|
||||
; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #5 personality i8* bitcast (i32 (...)* @esfp to i8*)
|
||||
; IS__CGSCC_OPM-NEXT: entry:
|
||||
; IS__CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
|
||||
; IS__CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
|
||||
; IS__CGSCC_OPM: cont:
|
||||
; IS__CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
|
||||
; IS__CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
|
||||
; IS__CGSCC_OPM: exc:
|
||||
; IS__CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
|
||||
; IS__CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
|
||||
; IS__CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
|
||||
entry:
|
||||
|
|
|
@ -17,10 +17,15 @@ define i32 @test0(i32* %p) {
|
|||
}
|
||||
|
||||
define i32 @test0-range-check(i32* %p) {
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-range-check
|
||||
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #4, !range !0
|
||||
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-range-check
|
||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
|
||||
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-range-check
|
||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
|
||||
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
|
||||
;
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check
|
||||
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
||||
|
@ -45,52 +50,99 @@ define void @use3(i1, i1, i1) {
|
|||
; TEST0 icmp test
|
||||
define void @test0-icmp-check(i32* %p){
|
||||
; ret = [0, 10)
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-icmp-check
|
||||
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #4, !range !0
|
||||
; IS__TUNIT____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
||||
; IS__TUNIT____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false)
|
||||
; IS__TUNIT____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
||||
; IS__TUNIT____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true)
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false)
|
||||
; IS__TUNIT____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true)
|
||||
; IS__TUNIT____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
||||
; IS__TUNIT____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
|
||||
; IS__TUNIT____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
||||
; IS__TUNIT____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false)
|
||||
; IS__TUNIT____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
||||
; IS__TUNIT____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
||||
; IS__TUNIT____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
|
||||
; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false)
|
||||
; IS__TUNIT____-NEXT: ret void
|
||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-icmp-check
|
||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false)
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
|
||||
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false)
|
||||
; IS__TUNIT_OPM-NEXT: ret void
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-icmp-check
|
||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false)
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
|
||||
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false)
|
||||
; IS__TUNIT_NPM-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check
|
||||
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
||||
|
@ -259,11 +311,17 @@ define i32 @test1(i32* %p) {
|
|||
|
||||
define i1 @test1-check(i32* %p) {
|
||||
;
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1-check
|
||||
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #4, !range !2
|
||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
||||
; IS__TUNIT____-NEXT: ret i1 [[CMP]]
|
||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1-check
|
||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !2
|
||||
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
||||
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1-check
|
||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !2
|
||||
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
||||
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check
|
||||
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
||||
|
@ -566,7 +624,7 @@ define dso_local i32 @test4-g2(i32 %u) {
|
|||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
|
||||
; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #2, !range !3
|
||||
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #1, !range !3
|
||||
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
|
||||
;
|
||||
entry:
|
||||
|
@ -929,8 +987,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
|
|||
;
|
||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee_range_2
|
||||
; IS__TUNIT_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
|
||||
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !4
|
||||
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3, !range !4
|
||||
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #1, !range !4
|
||||
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #1, !range !4
|
||||
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
||||
; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
||||
; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
||||
|
@ -939,8 +997,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
|
|||
;
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_range_2
|
||||
; IS__TUNIT_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
|
||||
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !5
|
||||
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3, !range !5
|
||||
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #1, !range !5
|
||||
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #1, !range !5
|
||||
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
||||
; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
||||
; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; 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=2 -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=2 -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 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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=1 -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 -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
|
||||
|
||||
|
|
|
@ -335,9 +335,7 @@ define void @f1() #0 {
|
|||
ret void
|
||||
}
|
||||
|
||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
||||
; FIXME: Because we do not derive norecurse in the module run anymore, willreturn is missing as well.
|
||||
; IS__TUNIT____-NOT: willreturn
|
||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable willreturn
|
||||
; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable willreturn
|
||||
define void @f2() #0 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f2()
|
||||
|
|
Loading…
Reference in New Issue