Andrew Geissler | b7d2861 | 2020-07-24 16:15:54 -0500 | [diff] [blame^] | 1 | From 0d03c0ee5213703ec6d9ffa632fa5298d83adaaa Mon Sep 17 00:00:00 2001 |
| 2 | From: Jakub Jelinek <jakub@redhat.com> |
| 3 | Date: Mon, 13 Jul 2020 18:25:53 +0200 |
| 4 | Subject: [PATCH] ipa-fnsummary: Fix ICE with switch predicates [PR96130] |
| 5 | |
| 6 | The following testcase ICEs since r10-3199. |
| 7 | There is a switch with default label, where the controlling expression has |
| 8 | range just 0..7 and there are case labels for all those 8 values, but |
| 9 | nothing has yet optimized away the default. |
| 10 | Since r10-3199, set_switch_stmt_execution_predicate sets the switch to |
| 11 | default label's edge's predicate to a false predicate and then |
| 12 | compute_bb_predicates propagates the predicates through the cfg, but false |
| 13 | predicates aren't really added. The caller of compute_bb_predicates |
| 14 | in one place handles NULL bb->aux as false predicate: |
| 15 | if (fbi.info) |
| 16 | { |
| 17 | if (bb->aux) |
| 18 | bb_predicate = *(predicate *) bb->aux; |
| 19 | else |
| 20 | bb_predicate = false; |
| 21 | } |
| 22 | else |
| 23 | bb_predicate = true; |
| 24 | but then in two further spots that the patch below is changing |
| 25 | it assumes bb->aux must be non-NULL. Those two spots are guarded by a |
| 26 | condition that is only true if fbi.info is non-NULL, so I think the right |
| 27 | fix is to treat NULL aux as false predicate in those spots too. |
| 28 | |
| 29 | 2020-07-13 Jakub Jelinek <jakub@redhat.com> |
| 30 | |
| 31 | PR ipa/96130 |
| 32 | * ipa-fnsummary.c (analyze_function_body): Treat NULL bb->aux |
| 33 | as false predicate. |
| 34 | |
| 35 | * gcc.dg/torture/pr96130.c: New test. |
| 36 | |
| 37 | (cherry picked from commit 776e48e0931db69f158f40e5cb8e15463d879a42) |
| 38 | --- |
| 39 | gcc/ipa-fnsummary.c | 10 ++++++++-- |
| 40 | gcc/testsuite/gcc.dg/torture/pr96130.c | 26 ++++++++++++++++++++++++++ |
| 41 | 2 files changed, 34 insertions(+), 2 deletions(-) |
| 42 | create mode 100644 gcc/testsuite/gcc.dg/torture/pr96130.c |
| 43 | |
| 44 | diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c |
| 45 | index 045a0ecf766..55a0b272a96 100644 |
| 46 | --- a/gcc/ipa-fnsummary.c |
| 47 | +++ b/gcc/ipa-fnsummary.c |
| 48 | @@ -2766,7 +2766,10 @@ analyze_function_body (struct cgraph_node *node, bool early) |
| 49 | edge ex; |
| 50 | unsigned int j; |
| 51 | class tree_niter_desc niter_desc; |
| 52 | - bb_predicate = *(predicate *) loop->header->aux; |
| 53 | + if (loop->header->aux) |
| 54 | + bb_predicate = *(predicate *) loop->header->aux; |
| 55 | + else |
| 56 | + bb_predicate = false; |
| 57 | |
| 58 | exits = get_loop_exit_edges (loop); |
| 59 | FOR_EACH_VEC_ELT (exits, j, ex) |
| 60 | @@ -2799,7 +2802,10 @@ analyze_function_body (struct cgraph_node *node, bool early) |
| 61 | for (unsigned i = 0; i < loop->num_nodes; i++) |
| 62 | { |
| 63 | gimple_stmt_iterator gsi; |
| 64 | - bb_predicate = *(predicate *) body[i]->aux; |
| 65 | + if (body[i]->aux) |
| 66 | + bb_predicate = *(predicate *) body[i]->aux; |
| 67 | + else |
| 68 | + bb_predicate = false; |
| 69 | for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); |
| 70 | gsi_next (&gsi)) |
| 71 | { |
| 72 | diff --git a/gcc/testsuite/gcc.dg/torture/pr96130.c b/gcc/testsuite/gcc.dg/torture/pr96130.c |
| 73 | new file mode 100644 |
| 74 | index 00000000000..f722b9ad2a9 |
| 75 | --- /dev/null |
| 76 | +++ b/gcc/testsuite/gcc.dg/torture/pr96130.c |
| 77 | @@ -0,0 +1,26 @@ |
| 78 | +/* PR ipa/96130 */ |
| 79 | +/* { dg-do compile } */ |
| 80 | + |
| 81 | +struct S { unsigned j : 3; }; |
| 82 | +int k, l, m; |
| 83 | + |
| 84 | +void |
| 85 | +foo (struct S x) |
| 86 | +{ |
| 87 | + while (l != 5) |
| 88 | + switch (x.j) |
| 89 | + { |
| 90 | + case 1: |
| 91 | + case 3: |
| 92 | + case 4: |
| 93 | + case 6: |
| 94 | + case 2: |
| 95 | + case 5: |
| 96 | + l = m; |
| 97 | + case 7: |
| 98 | + case 0: |
| 99 | + k = 0; |
| 100 | + default: |
| 101 | + break; |
| 102 | + } |
| 103 | +} |
| 104 | -- |
| 105 | 2.18.4 |
| 106 | |