llvm.org GIT mirror llvm / 110f9f2
NewGVN: Fix PR 34430 - we need to look through predicateinfo copies to detect self-cycles of phi nodes. We also need to not ignore certain types of arguments when testing whether the phi has a backedge or was originally constant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312510 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Berlin 2 years ago
2 changed file(s) with 80 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
850850 ExpressionAllocator.Deallocate(E);
851851 }
852852
853 // If V is a predicateinfo copy, get the thing it is a copy of.
854 static Value *getCopyOf(const Value *V) {
855 if (auto *II = dyn_cast(V))
856 if (II->getIntrinsicID() == Intrinsic::ssa_copy)
857 return II->getOperand(0);
858 return nullptr;
859 }
860
853861 // Return true if V is really PN, even accounting for predicateinfo copies.
854 static bool isCopyOfSelf(const Value *V, const PHINode *PN) {
855 if (V == PN)
856 return V;
857 if (auto *II = dyn_cast(V))
858 if (II->getIntrinsicID() == Intrinsic::ssa_copy && II->getOperand(0) == PN)
859 return true;
860 return false;
862 static bool isCopyOfPHI(const Value *V, const PHINode *PN) {
863 return V == PN || getCopyOf(V) == PN;
864 }
865
866 static bool isCopyOfAPHI(const Value *V) {
867 auto *CO = getCopyOf(V);
868 return CO && isa(CO);
861869 }
862870
863871 PHIExpression *NewGVN::createPHIExpression(Instruction *I, bool &HasBackedge,
889897
890898 // Filter out unreachable phi operands.
891899 auto Filtered = make_filter_range(PHIOperands, [&](const Use *U) {
892 if (isCopyOfSelf(*U, PN))
900 auto *BB = PN->getIncomingBlock(*U);
901 if (isCopyOfPHI(*U, PN))
893902 return false;
894 if (!ReachableEdges.count({PN->getIncomingBlock(*U), PHIBlock}))
903 if (!ReachableEdges.count({BB, PHIBlock}))
895904 return false;
896905 // Things in TOPClass are equivalent to everything.
897906 if (ValueToClass.lookup(*U) == TOPClass)
898907 return false;
908 OriginalOpsConstant = OriginalOpsConstant && isa(*U);
909 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
899910 return lookupOperandLeader(*U) != PN;
900911 });
901 std::transform(Filtered.begin(), Filtered.end(), op_inserter(E),
902 [&](const Use *U) -> Value * {
903 auto *BB = PN->getIncomingBlock(*U);
904 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
905 OriginalOpsConstant =
906 OriginalOpsConstant && isa(*U);
907 return lookupOperandLeader(*U);
908 });
912 std::transform(
913 Filtered.begin(), Filtered.end(), op_inserter(E),
914 [&](const Use *U) -> Value * { return lookupOperandLeader(*U); });
909915 return E;
910916 }
911917
989995 addAdditionalUsers(V, I);
990996 return createVariableOrConstant(CC->getLeader());
991997 }
992
993998 if (CC->getDefiningExpr()) {
994999 // If we simplified to something else, we need to communicate
9951000 // that we're users of the value we simplified to.
16101615 if (SCC.size() == 1)
16111616 InstCycleState.insert({I, ICS_CycleFree});
16121617 else {
1613 bool AllPhis =
1614 llvm::all_of(SCC, [](const Value *V) { return isa(V); });
1618 bool AllPhis = llvm::all_of(SCC, [](const Value *V) {
1619 return isa(V) || isCopyOfAPHI(V);
1620 });
16151621 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
16161622 for (auto *Member : SCC)
16171623 if (auto *MemberPhi = dyn_cast(Member))
16311637 // This is really shorthand for "this phi cannot cycle due to forward
16321638 // change in value of the phi is guaranteed not to later change the value of
16331639 // the phi. IE it can't be v = phi(undef, v+1)
1634 bool AllConstant = true;
1635 auto *E =
1636 cast(createPHIExpression(I, HasBackedge, AllConstant));
1640 bool OriginalOpsConstant = true;
1641 auto *E = cast(
1642 createPHIExpression(I, HasBackedge, OriginalOpsConstant));
16371643 // We match the semantics of SimplifyPhiNode from InstructionSimplify here.
16381644 // See if all arguments are the same.
16391645 // We track if any were undef because they need special handling.
16591665 deleteExpression(E);
16601666 return createDeadExpression();
16611667 }
1662 unsigned NumOps = 0;
16631668 Value *AllSameValue = *(Filtered.begin());
16641669 ++Filtered.begin();
16651670 // Can't use std::equal here, sadly, because filter.begin moves.
1666 if (llvm::all_of(Filtered, [&](Value *Arg) {
1667 ++NumOps;
1668 return Arg == AllSameValue;
1669 })) {
1671 if (llvm::all_of(Filtered, [&](Value *Arg) { return Arg == AllSameValue; })) {
16701672 // In LLVM's non-standard representation of phi nodes, it's possible to have
16711673 // phi nodes with cycles (IE dependent on other phis that are .... dependent
16721674 // on the original phi node), especially in weird CFG's where some arguments
16811683 // multivalued phi, and we need to know if it's cycle free in order to
16821684 // evaluate whether we can ignore the undef. The other parts of this are
16831685 // just shortcuts. If there is no backedge, or all operands are
1684 // constants, or all operands are ignored but the undef, it also must be
1685 // cycle free.
1686 if (!AllConstant && HasBackedge && NumOps > 0 &&
1686 // constants, it also must be cycle free.
1687 if (HasBackedge && !OriginalOpsConstant &&
16871688 !isa(AllSameValue) && !isCycleFree(I))
16881689 return E;
16891690
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; ModuleID = 'bugpoint-reduced-simplified.bc'
2 ; RUN: opt < %s -newgvn -S | FileCheck %s
3 source_filename = "bugpoint-output-e4c7d0f.bc"
4
5 ; Make sure we still properly resolve phi cycles when they involve predicateinfo copies of phis.
6 define void @hoge() local_unnamed_addr #0 {
7 ; CHECK-LABEL: @hoge(
8 ; CHECK-NEXT: bb:
9 ; CHECK-NEXT: br i1 undef, label [[BB6:%.*]], label [[BB1:%.*]]
10 ; CHECK: bb1:
11 ; CHECK-NEXT: br label [[BB6]]
12 ; CHECK: bb2:
13 ; CHECK-NEXT: br i1 true, label [[BB3:%.*]], label [[BB6]]
14 ; CHECK: bb3:
15 ; CHECK-NEXT: br label [[BB4:%.*]]
16 ; CHECK: bb4:
17 ; CHECK-NEXT: br i1 undef, label [[BB2:%.*]], label [[BB6]]
18 ; CHECK: bb6:
19 ; CHECK-NEXT: br label [[BB4]]
20 ;
21 bb:
22 br i1 undef, label %bb6, label %bb1
23
24 bb1: ; preds = %bb
25 br label %bb6
26
27 bb2: ; preds = %bb4
28 %tmp = icmp slt i8 %tmp5, 7
29 br i1 %tmp, label %bb3, label %bb6
30
31 bb3: ; preds = %bb2
32 br label %bb4
33
34 bb4: ; preds = %bb6, %bb3
35 %tmp5 = phi i8 [ %tmp5, %bb3 ], [ %tmp7, %bb6 ]
36 br i1 undef, label %bb2, label %bb6
37
38 bb6: ; preds = %bb4, %bb2, %bb1, %bb
39 %tmp7 = phi i8 [ %tmp5, %bb4 ], [ %tmp5, %bb2 ], [ 5, %bb1 ], [ undef, %bb ]
40 br label %bb4
41 }
42
43 attributes #0 = { norecurse noreturn nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
44
45 !llvm.ident = !{!0}
46
47 !0 = !{!"clang version 6.0.0 (http://llvm.org/git/clang.git e649d902285b23af8ba58cb92a739f3bad2723df) (/Users/dannyb/sources/llvm-clean 0abfd30028cbb294ff2c2dd5e2df4ec3fdb6c591)"}