From: Jakub Jelinek Date: Mon, 13 Jul 2020 16:25:53 +0000 (+0200) Subject: ipa-fnsummary: Fix ICE with switch predicates [PR96130] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=776e48e0931db69f158f40e5cb8e15463d879a42;p=gcc.git ipa-fnsummary: Fix ICE with switch predicates [PR96130] The following testcase ICEs since r10-3199. There is a switch with default label, where the controlling expression has range just 0..7 and there are case labels for all those 8 values, but nothing has yet optimized away the default. Since r10-3199, set_switch_stmt_execution_predicate sets the switch to default label's edge's predicate to a false predicate and then compute_bb_predicates propagates the predicates through the cfg, but false predicates aren't really added. The caller of compute_bb_predicates in one place handles NULL bb->aux as false predicate: if (fbi.info) { if (bb->aux) bb_predicate = *(predicate *) bb->aux; else bb_predicate = false; } else bb_predicate = true; but then in two further spots that the patch below is changing it assumes bb->aux must be non-NULL. Those two spots are guarded by a condition that is only true if fbi.info is non-NULL, so I think the right fix is to treat NULL aux as false predicate in those spots too. 2020-07-13 Jakub Jelinek PR ipa/96130 * ipa-fnsummary.c (analyze_function_body): Treat NULL bb->aux as false predicate. * gcc.dg/torture/pr96130.c: New test. --- diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 045a0ecf766..55a0b272a96 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -2766,7 +2766,10 @@ analyze_function_body (struct cgraph_node *node, bool early) edge ex; unsigned int j; class tree_niter_desc niter_desc; - bb_predicate = *(predicate *) loop->header->aux; + if (loop->header->aux) + bb_predicate = *(predicate *) loop->header->aux; + else + bb_predicate = false; exits = get_loop_exit_edges (loop); FOR_EACH_VEC_ELT (exits, j, ex) @@ -2799,7 +2802,10 @@ analyze_function_body (struct cgraph_node *node, bool early) for (unsigned i = 0; i < loop->num_nodes; i++) { gimple_stmt_iterator gsi; - bb_predicate = *(predicate *) body[i]->aux; + if (body[i]->aux) + bb_predicate = *(predicate *) body[i]->aux; + else + bb_predicate = false; for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi)) { diff --git a/gcc/testsuite/gcc.dg/torture/pr96130.c b/gcc/testsuite/gcc.dg/torture/pr96130.c new file mode 100644 index 00000000000..f722b9ad2a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr96130.c @@ -0,0 +1,26 @@ +/* PR ipa/96130 */ +/* { dg-do compile } */ + +struct S { unsigned j : 3; }; +int k, l, m; + +void +foo (struct S x) +{ + while (l != 5) + switch (x.j) + { + case 1: + case 3: + case 4: + case 6: + case 2: + case 5: + l = m; + case 7: + case 0: + k = 0; + default: + break; + } +}