[llvm] 5f55a81 - [Attributor] Implement AAPotentialValues
Shinji Okumura via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 04:58:42 PDT 2020
Author: Shinji Okumura
Date: 2020-08-14T20:51:14+09:00
New Revision: 5f55a8193c2cacd8f8c92f50ac8cab59d79254f9
URL: https://github.com/llvm/llvm-project/commit/5f55a8193c2cacd8f8c92f50ac8cab59d79254f9
DIFF: https://github.com/llvm/llvm-project/commit/5f55a8193c2cacd8f8c92f50ac8cab59d79254f9.diff
LOG: [Attributor] Implement AAPotentialValues
This patch provides an implementation of `AAPotentialValues`.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D85632
Added:
Modified:
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/dereferenceable-1.ll
llvm/test/Transforms/Attributor/liveness.ll
llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
llvm/test/Transforms/Attributor/nonnull.ll
llvm/test/Transforms/Attributor/potential.ll
llvm/test/Transforms/Attributor/range.ll
llvm/test/Transforms/Attributor/value-simplify.ll
llvm/test/Transforms/Attributor/willreturn.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 3f66422edf54..958e20878f3a 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -7286,6 +7286,262 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
<< getAssociatedValue() << "\n");
}
+ static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
+ const APInt &RHS) {
+ ICmpInst::Predicate Pred = ICI->getPredicate();
+ switch (Pred) {
+ case ICmpInst::ICMP_UGT:
+ return LHS.ugt(RHS);
+ case ICmpInst::ICMP_SGT:
+ return LHS.sgt(RHS);
+ case ICmpInst::ICMP_EQ:
+ return LHS.eq(RHS);
+ case ICmpInst::ICMP_UGE:
+ return LHS.uge(RHS);
+ case ICmpInst::ICMP_SGE:
+ return LHS.sge(RHS);
+ case ICmpInst::ICMP_ULT:
+ return LHS.ult(RHS);
+ case ICmpInst::ICMP_SLT:
+ return LHS.slt(RHS);
+ case ICmpInst::ICMP_NE:
+ return LHS.ne(RHS);
+ case ICmpInst::ICMP_ULE:
+ return LHS.ule(RHS);
+ case ICmpInst::ICMP_SLE:
+ return LHS.sle(RHS);
+ default:
+ llvm_unreachable("Invalid ICmp predicate!");
+ }
+ }
+
+ static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
+ uint32_t ResultBitWidth) {
+ Instruction::CastOps CastOp = CI->getOpcode();
+ switch (CastOp) {
+ default:
+ llvm_unreachable("unsupported or not integer cast");
+ case Instruction::Trunc:
+ return Src.trunc(ResultBitWidth);
+ case Instruction::SExt:
+ return Src.sext(ResultBitWidth);
+ case Instruction::ZExt:
+ return Src.zext(ResultBitWidth);
+ case Instruction::BitCast:
+ return Src;
+ }
+ }
+
+ static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
+ const APInt &LHS, const APInt &RHS,
+ bool &SkipOperation, bool &Unsupported) {
+ Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
+ // Unsupported is set to true when the binary operator is not supported.
+ // SkipOperation is set to true when UB occur with the given operand pair
+ // (LHS, RHS).
+ // TODO: we should look at nsw and nuw keywords to handle operations
+ // that create poison or undef value.
+ switch (BinOpcode) {
+ default:
+ Unsupported = true;
+ return LHS;
+ case Instruction::Add:
+ return LHS + RHS;
+ case Instruction::Sub:
+ return LHS - RHS;
+ case Instruction::Mul:
+ return LHS * RHS;
+ case Instruction::UDiv:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.udiv(RHS);
+ case Instruction::SDiv:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.sdiv(RHS);
+ case Instruction::URem:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.urem(RHS);
+ case Instruction::SRem:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.srem(RHS);
+ case Instruction::Shl:
+ return LHS.shl(RHS);
+ case Instruction::LShr:
+ return LHS.lshr(RHS);
+ case Instruction::AShr:
+ return LHS.ashr(RHS);
+ case Instruction::And:
+ return LHS & RHS;
+ case Instruction::Or:
+ return LHS | RHS;
+ case Instruction::Xor:
+ return LHS ^ RHS;
+ }
+ }
+
+ ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = ICI->getOperand(0);
+ Value *RHS = ICI->getOperand(1);
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
+ const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
+
+ // TODO: Handle undef correctly.
+ bool MaybeTrue = false, MaybeFalse = false;
+ for (const APInt &L : LHSAAPVS) {
+ for (const APInt &R : RHSAAPVS) {
+ bool CmpResult = calculateICmpInst(ICI, L, R);
+ MaybeTrue |= CmpResult;
+ MaybeFalse |= !CmpResult;
+ if (MaybeTrue & MaybeFalse)
+ return indicatePessimisticFixpoint();
+ }
+ }
+ if (MaybeTrue)
+ unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
+ if (MaybeFalse)
+ unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = SI->getTrueValue();
+ Value *RHS = SI->getFalseValue();
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ // TODO: Use assumed simplified condition value
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ unionAssumed(LHSAA);
+ unionAssumed(RHSAA);
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
+ auto AssumedBefore = getAssumed();
+ if (!CI->isIntegerCast())
+ return indicatePessimisticFixpoint();
+ assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
+ uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
+ Value *Src = CI->getOperand(0);
+ auto &SrcAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*Src));
+ if (!SrcAA.isValidState())
+ return indicatePessimisticFixpoint();
+ const DenseSet<APInt> &SrcAAPVS = SrcAA.getAssumedSet();
+ for (const APInt &S : SrcAAPVS) {
+ APInt T = calculateCastInst(CI, S, ResultBitWidth);
+ unionAssumed(T);
+ }
+ // TODO: Handle undef correctly.
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = BinOp->getOperand(0);
+ Value *RHS = BinOp->getOperand(1);
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
+ const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
+
+ // TODO: Handle undef correctly
+ for (const APInt &L : LHSAAPVS) {
+ for (const APInt &R : RHSAAPVS) {
+ bool SkipOperation = false;
+ bool Unsupported = false;
+ APInt Result =
+ calculateBinaryOperator(BinOp, L, R, SkipOperation, Unsupported);
+ if (Unsupported)
+ return indicatePessimisticFixpoint();
+ // If SkipOperation is true, we can ignore this operand pair (L, R).
+ if (!SkipOperation)
+ unionAssumed(Result);
+ }
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithPHINode(Attributor &A, PHINode *PHI) {
+ auto AssumedBefore = getAssumed();
+ for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
+ Value *IncomingValue = PHI->getIncomingValue(u);
+ auto &PotentialValuesAA = A.getAAFor<AAPotentialValues>(
+ *this, IRPosition::value(*IncomingValue));
+ if (!PotentialValuesAA.isValidState())
+ return indicatePessimisticFixpoint();
+ unionAssumed(PotentialValuesAA.getAssumed());
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ Value &V = getAssociatedValue();
+ Instruction *I = dyn_cast<Instruction>(&V);
+
+ if (auto *ICI = dyn_cast<ICmpInst>(I))
+ return updateWithICmpInst(A, ICI);
+
+ if (auto *SI = dyn_cast<SelectInst>(I))
+ return updateWithSelectInst(A, SI);
+
+ if (auto *CI = dyn_cast<CastInst>(I))
+ return updateWithCastInst(A, CI);
+
+ if (auto *BinOp = dyn_cast<BinaryOperator>(I))
+ return updateWithBinaryOperator(A, BinOp);
+
+ if (auto *PHI = dyn_cast<PHINode>(I))
+ return updateWithPHINode(A, PHI);
+
+ return indicatePessimisticFixpoint();
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {
STATS_DECLTRACK_FLOATING_ATTR(potential_values)
@@ -7334,6 +7590,37 @@ struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
: AAPotentialValuesFloating(IRP, A) {}
+ /// See AbstractAttribute::initialize(..).
+ void initialize(Attributor &A) override {
+ Value &V = getAssociatedValue();
+
+ if (auto *C = dyn_cast<ConstantInt>(&V)) {
+ unionAssumed(C->getValue());
+ indicateOptimisticFixpoint();
+ return;
+ }
+
+ if (isa<UndefValue>(&V)) {
+ // Collapse the undef state to 0.
+ unionAssumed(
+ APInt(/* numBits */ getAssociatedType()->getIntegerBitWidth(),
+ /* val */ 0));
+ indicateOptimisticFixpoint();
+ return;
+ }
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ Value &V = getAssociatedValue();
+ auto AssumedBefore = getAssumed();
+ auto &AA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(V));
+ const auto &S = AA.getAssumed();
+ unionAssumed(S);
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {
STATS_DECLTRACK_CSARG_ATTR(potential_values)
diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
index 26e6e97d1868..9a995396e516 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=18 -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=18 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=19 -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=21 -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 -enable-new-pm=0 -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
; FIXME: Figure out why we need 16 iterations here.
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 4c2e773497eb..2a24a168263c 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -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=17 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=39 -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=39 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151
; opt -attributor-cgscc -enable-new-pm=0 -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
diff --git a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
index c3bb8f9cd933..eac735d79c01 100644
--- a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
+++ b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -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=7 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=18 -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=21 -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 -enable-new-pm=0 -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
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index ac79f14640fc..9290d32453ba 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -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=9 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -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=17 -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 -enable-new-pm=0 -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
diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll
index d93cb37c6af7..41818fc95924 100644
--- a/llvm/test/Transforms/Attributor/potential.ll
+++ b/llvm/test/Transforms/Attributor/potential.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-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 -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -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=22 -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=20 -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
;
@@ -11,12 +11,6 @@
; bool potential_test1(bool c) { return iszero(c ? 1 : -1); }
define internal i1 @iszero1(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@iszero1
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0
-; IS__TUNIT____-NEXT: ret i1 [[CMP]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -31,9 +25,7 @@ define i1 @potential_test1(i1 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test1
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1
-; IS__TUNIT____-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 [[ARG]])
-; IS__TUNIT____-NEXT: ret i1 [[RET]]
+; IS__TUNIT____-NEXT: ret i1 false
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test1
@@ -57,13 +49,6 @@ define i1 @potential_test1(i1 %c) {
; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); }
define internal i32 @iszero2(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@iszero2
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0
-; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero2
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -77,15 +62,6 @@ define internal i32 @iszero2(i32 %c) {
}
define internal i32 @call_with_two_values(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@call_with_two_values
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 [[C]]) [[ATTR0:#.*]], [[RNG0:!range !.*]]
-; IS__TUNIT____-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]]
-; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) [[ATTR0]], [[RNG0]]
-; IS__TUNIT____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -103,13 +79,10 @@ define internal i32 @call_with_two_values(i32 %c) {
}
define i32 @potential_test2(i1 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test2
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 1) [[ATTR0]], [[RNG1:!range !.*]]
-; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 -1) [[ATTR1:#.*]], [[RNG1]]
-; IS__TUNIT____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
+; IS__TUNIT____-NEXT: ret i32 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test2
@@ -227,10 +200,7 @@ define i32 @potential_test4(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test4
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
-; IS__TUNIT____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2
-; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
+; IS__TUNIT____-NEXT: ret i32 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test4
@@ -250,11 +220,7 @@ define i32 @potential_test5(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test5
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
-; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) [[ATTR0]], [[RNG3:!range !.*]]
-; IS__TUNIT____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
-; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
+; IS__TUNIT____-NEXT: ret i32 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test5
@@ -273,12 +239,19 @@ define i32 @potential_test5(i32 %c) {
}
define i1 @potential_test6(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test6
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
-; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
-; IS__TUNIT____-NEXT: ret i1 [[RET]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test6
+; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0:#.*]], [[RNG0:!range !.*]]
+; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
+; IS__TUNIT_OPM-NEXT: ret i1 [[RET]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test6
+; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG1:!range !.*]]
+; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
+; IS__TUNIT_NPM-NEXT: ret i1 [[RET]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test6
@@ -293,13 +266,21 @@ define i1 @potential_test6(i32 %c) {
}
define i1 @potential_test7(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test7
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
-; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG4:!range !.*]]
-; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
-; IS__TUNIT____-NEXT: ret i1 [[RET]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test7
+; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG0]]
+; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG1:!range !.*]]
+; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
+; IS__TUNIT_OPM-NEXT: ret i1 [[RET]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test7
+; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG1]]
+; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
+; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
+; IS__TUNIT_NPM-NEXT: ret i1 [[RET]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test7
@@ -336,13 +317,6 @@ define internal i32 @return1or3(i32 %c) {
}
define internal i32 @return2or4(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@return2or4
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0
-; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4
-; IS__TUNIT____-NEXT: ret i32 [[RET]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@return2or4
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -380,12 +354,6 @@ define internal i32 @return3or4(i32 %c) {
; propagate argument to callsite argument
define internal i1 @cmp_with_four(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@cmp_with_four
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 4
-; IS__TUNIT____-NEXT: ret i1 [[CMP]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_with_four
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -397,12 +365,6 @@ define internal i1 @cmp_with_four(i32 %c) {
}
define internal i1 @wrapper(i32 %c) {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__TUNIT____-LABEL: define {{[^@]+}}@wrapper
-; IS__TUNIT____-SAME: (i32 [[C:%.*]])
-; IS__TUNIT____-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 [[C]])
-; IS__TUNIT____-NEXT: ret i1 [[RET]]
-;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
@@ -414,14 +376,9 @@ define internal i1 @wrapper(i32 %c) {
}
define i1 @potential_test8() {
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test8()
-; IS__TUNIT____-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 1)
-; IS__TUNIT____-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 3)
-; IS__TUNIT____-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 5)
-; IS__TUNIT____-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]]
-; IS__TUNIT____-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]]
-; IS__TUNIT____-NEXT: ret i1 [[RES135]]
+; IS__TUNIT____-NEXT: ret i1 false
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test8()
@@ -457,8 +414,7 @@ define i1 @potential_test9() {
; IS__TUNIT_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1
; IS__TUNIT_OPM-NEXT: br label [[COND]]
; IS__TUNIT_OPM: end:
-; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[C_0]], 0
-; IS__TUNIT_OPM-NEXT: ret i1 [[RET]]
+; IS__TUNIT_OPM-NEXT: ret i1 false
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test9()
@@ -494,8 +450,7 @@ define i1 @potential_test9() {
; IS__CGSCC_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1
; IS__CGSCC_OPM-NEXT: br label [[COND]]
; IS__CGSCC_OPM: end:
-; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[C_0]], 0
-; IS__CGSCC_OPM-NEXT: ret i1 [[RET]]
+; IS__CGSCC_OPM-NEXT: ret i1 false
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test9()
@@ -533,11 +488,85 @@ end:
ret i1 %ret
}
-; IS__TUNIT____: !0 = !{i32 0, i32 2}
-; IS__TUNIT____: !1 = !{i32 0, i32 3}
-; IS__TUNIT____: !2 = !{i32 1, i32 4}
-; IS__TUNIT____: !3 = !{i32 2, i32 5}
-; IS__TUNIT____: !4 = !{i32 3, i32 5}
-; IS__TUNIT____-NOT: !5
+; Test 10
+; FIXME: potential returned values of @may_return_undef is {1, -1}
+; and returned value of @potential_test10 can be simplified to 0(false)
+
+define internal i32 @may_return_undef(i32 %c) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@may_return_undef
+; IS__TUNIT____-SAME: (i32 [[C:%.*]])
+; IS__TUNIT____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
+; IS__TUNIT____-NEXT: i32 1, label [[A:%.*]]
+; IS__TUNIT____-NEXT: i32 -1, label [[B:%.*]]
+; IS__TUNIT____-NEXT: ]
+; IS__TUNIT____: a:
+; IS__TUNIT____-NEXT: ret i32 1
+; IS__TUNIT____: b:
+; IS__TUNIT____-NEXT: ret i32 -1
+; IS__TUNIT____: otherwise:
+; IS__TUNIT____-NEXT: ret i32 undef
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@may_return_undef
+; IS__CGSCC____-SAME: (i32 [[C:%.*]])
+; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
+; IS__CGSCC____-NEXT: i32 1, label [[A:%.*]]
+; IS__CGSCC____-NEXT: i32 -1, label [[B:%.*]]
+; IS__CGSCC____-NEXT: ]
+; IS__CGSCC____: a:
+; IS__CGSCC____-NEXT: ret i32 1
+; IS__CGSCC____: b:
+; IS__CGSCC____-NEXT: ret i32 -1
+; IS__CGSCC____: otherwise:
+; IS__CGSCC____-NEXT: ret i32 undef
+;
+ switch i32 %c, label %otherwise [i32 1, label %a
+ i32 -1, label %b]
+a:
+ ret i32 1
+b:
+ ret i32 -1
+otherwise:
+ ret i32 undef
+}
+
+define i1 @potential_test10(i32 %c) {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test10
+; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
+; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0
+; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test10
+; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]])
+; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR0]], [[RNG3:!range !.*]]
+; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0
+; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10
+; IS__CGSCC____-SAME: (i32 [[C:%.*]])
+; IS__CGSCC____-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]])
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0
+; IS__CGSCC____-NEXT: ret i1 [[CMP]]
+;
+ %ret = call i32 @may_return_undef(i32 %c)
+ %cmp = icmp eq i32 %ret, 0
+ ret i1 %cmp
+}
+
+; IS__TUNIT_NPM: !0 = !{i32 0, i32 2}
+; IS__TUNIT_NPM: !1 = !{i32 1, i32 4}
+; IS__TUNIT_NPM: !2 = !{i32 3, i32 5}
+; IS__TUNIT_NPM: !3 = !{i32 -1, i32 2}
+; IS__TUNIT_NPM-NOT: !4
+
+; IS__TUNIT_OPM: !0 = !{i32 1, i32 4}
+; IS__TUNIT_OPM: !1 = !{i32 3, i32 5}
+; IS__TUNIT_OPM: !2 = !{i32 -1, i32 2}
+; IS__TUNIT_OPM-NOT: !3
-; NOT_TUNIT____-NOT: !0
+; IS__CGSCC____-NOT: !0
diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index 876c30860b8f..a50dbc17fef9 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -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=17 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=25 -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=31 -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 -enable-new-pm=0 -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
diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index 6da6e3b8ead2..3a487a9ed229 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -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 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -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=17 -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 -enable-new-pm=0 -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
diff --git a/llvm/test/Transforms/Attributor/willreturn.ll b/llvm/test/Transforms/Attributor/willreturn.ll
index dd1c7e940c81..30146f496991 100644
--- a/llvm/test/Transforms/Attributor/willreturn.ll
+++ b/llvm/test/Transforms/Attributor/willreturn.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -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=8 -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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=20 -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=22 -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 -enable-new-pm=0 -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
More information about the llvm-commits
mailing list