@@ -310,7 +310,7 @@ add_clause (conditions conditions, struc
if (false_predicate_p (p))
return;
- /* No one should be sily enough to add false into nontrivial clauses. */
+ /* No one should be silly enough to add false into nontrivial clauses. */
gcc_checking_assert (!(clause & (1 << predicate_false_condition)));
/* Look where to insert the clause. At the same time prune out
@@ -372,9 +372,13 @@ add_clause (conditions conditions, struc
}
- /* We run out of variants. Be conservative in positive direction. */
+ /* We run out of variants. Conservatively turn clause into true
+ predicate. */
if (i2 == MAX_CLAUSES)
- return;
+ {
+ p->clause[0] = 0;
+ return;
+ }
/* Keep clauses in decreasing order. This makes equivalence testing easy. */
p->clause[i2 + 1] = 0;
if (insert_here >= 0)
@@ -412,6 +416,8 @@ and_predicates (conditions conditions,
{
gcc_checking_assert (i < MAX_CLAUSES);
add_clause (conditions, &out, p2->clause[i]);
+ if (true_predicate_p (&out))
+ break;
}
return out;
}
@@ -459,6 +465,8 @@ or_predicates (conditions conditions,
{
gcc_checking_assert (i < MAX_CLAUSES && j < MAX_CLAUSES);
add_clause (conditions, &out, p->clause[i] | p2->clause[j]);
+ if (true_predicate_p (&out))
+ return out;
}
return out;
}
@@ -1035,7 +1043,7 @@ inline_node_removal_hook (struct cgraph_
memset (info, 0, sizeof (inline_summary_t));
}
-/* Remap predicate P of former function to be predicate of duplicated functoin.
+/* Remap predicate P of former function to be predicate of duplicated function.
POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
INFO is inline summary of the duplicated node. */
@@ -0,0 +1,47 @@
+/* PR ipa/60013 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef long int jmp_buf[64];
+extern int _setjmp (jmp_buf) __attribute__ ((__nothrow__));
+struct S { int a, b, c; };
+extern struct S *baz (struct S *);
+static jmp_buf j;
+
+static inline int
+bar (int b, int d)
+{
+ return (b & d) < 0;
+}
+
+struct S *
+foo (int a, struct S *b, struct S *c, struct S *d)
+{
+ if (b->a == 0)
+ {
+ switch (a)
+ {
+ case 8:
+ return baz (b);
+ case 7:
+ bar (b->c, c->b);
+ return 0;
+ case 6:
+ case 5:
+ case 4:
+ return baz (c);
+ case 3:
+ case 2:
+ return baz (d);
+ }
+ return 0;
+ }
+ if (b->a == 1)
+ {
+ if (baz (c))
+ return c;
+ else if (_setjmp (j))
+ baz (b);
+ }
+ return 0;
+}