| From 0d03c0ee5213703ec6d9ffa632fa5298d83adaaa Mon Sep 17 00:00:00 2001 |
| From: Jakub Jelinek <jakub@redhat.com> |
| Date: Mon, 13 Jul 2020 18:25:53 +0200 |
| Subject: [PATCH] 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 <jakub@redhat.com> |
| |
| PR ipa/96130 |
| * ipa-fnsummary.c (analyze_function_body): Treat NULL bb->aux |
| as false predicate. |
| |
| * gcc.dg/torture/pr96130.c: New test. |
| |
| (cherry picked from commit 776e48e0931db69f158f40e5cb8e15463d879a42) |
| --- |
| gcc/ipa-fnsummary.c | 10 ++++++++-- |
| gcc/testsuite/gcc.dg/torture/pr96130.c | 26 ++++++++++++++++++++++++++ |
| 2 files changed, 34 insertions(+), 2 deletions(-) |
| create mode 100644 gcc/testsuite/gcc.dg/torture/pr96130.c |
| |
| 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; |
| + } |
| +} |
| -- |
| 2.18.4 |
| |