|
| 1 | +https://gcc.gnu.org/PR111860 |
| 2 | +https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=9ed6b22eb4188c57bb3f5cdba5a7effa95395186 |
| 3 | + |
| 4 | +From 9ed6b22eb4188c57bb3f5cdba5a7effa95395186 Mon Sep 17 00:00:00 2001 |
| 5 | +From: Tamar Christina < [email protected]> |
| 6 | +Date: Mon, 23 Oct 2023 14:07:20 +0100 |
| 7 | +Subject: [PATCH] middle-end: don't keep .MEM guard nodes for PHI nodes who |
| 8 | + dominate loop [PR111860] |
| 9 | + |
| 10 | +The previous patch tried to remove PHI nodes that dominated the first loop, |
| 11 | +however the correct fix is to only remove .MEM nodes. |
| 12 | + |
| 13 | +This patch thus makes the condition a bit stricter and only tries to remove |
| 14 | +MEM phi nodes. |
| 15 | + |
| 16 | +I couldn't figure out a way to easily determine if a particular PHI is vUSE |
| 17 | +related, so the patch does: |
| 18 | + |
| 19 | +1. check if the definition is a vDEF and not defined in main loop. |
| 20 | +2. check if the definition is a PHI and not defined in main loop. |
| 21 | +3. check if the definition is a default definition. |
| 22 | + |
| 23 | +For no 2 and 3 we may misidentify the PHI, in both cases the value is defined |
| 24 | +outside of the loop version block which also makes it ok to remove. |
| 25 | + |
| 26 | +gcc/ChangeLog: |
| 27 | + |
| 28 | + PR tree-optimization/111860 |
| 29 | + * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): |
| 30 | + Drop .MEM nodes only. |
| 31 | + |
| 32 | +gcc/testsuite/ChangeLog: |
| 33 | + |
| 34 | + PR tree-optimization/111860 |
| 35 | + * gcc.dg/vect/pr111860-2.c: New test. |
| 36 | + * gcc.dg/vect/pr111860-3.c: New test. |
| 37 | +--- |
| 38 | + gcc/testsuite/gcc.dg/vect/pr111860-2.c | 17 +++++++++++++++++ |
| 39 | + gcc/testsuite/gcc.dg/vect/pr111860-3.c | 17 +++++++++++++++++ |
| 40 | + gcc/tree-vect-loop-manip.cc | 21 ++++++++++++++++++++- |
| 41 | + 3 files changed, 54 insertions(+), 1 deletion(-) |
| 42 | + create mode 100644 gcc/testsuite/gcc.dg/vect/pr111860-2.c |
| 43 | + create mode 100644 gcc/testsuite/gcc.dg/vect/pr111860-3.c |
| 44 | + |
| 45 | +diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-2.c b/gcc/testsuite/gcc.dg/vect/pr111860-2.c |
| 46 | +new file mode 100644 |
| 47 | +index 000000000000..07f64ffb5318 |
| 48 | +--- /dev/null |
| 49 | ++++ b/gcc/testsuite/gcc.dg/vect/pr111860-2.c |
| 50 | +@@ -0,0 +1,17 @@ |
| 51 | ++/* { dg-do compile } */ |
| 52 | ++/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */ |
| 53 | ++int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd; |
| 54 | ++ |
| 55 | ++int |
| 56 | ++buffer_ctrl (long ret, int i) |
| 57 | ++{ |
| 58 | ++ switch (buffer_ctrl_cmd) |
| 59 | ++ { |
| 60 | ++ case 1: |
| 61 | ++ buffer_ctrl_ctx_0 = 0; |
| 62 | ++ for (; i; i++) |
| 63 | ++ if (buffer_ctrl_p1) |
| 64 | ++ ret++; |
| 65 | ++ } |
| 66 | ++ return ret; |
| 67 | ++} |
| 68 | +diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-3.c b/gcc/testsuite/gcc.dg/vect/pr111860-3.c |
| 69 | +new file mode 100644 |
| 70 | +index 000000000000..07f64ffb5318 |
| 71 | +--- /dev/null |
| 72 | ++++ b/gcc/testsuite/gcc.dg/vect/pr111860-3.c |
| 73 | +@@ -0,0 +1,17 @@ |
| 74 | ++/* { dg-do compile } */ |
| 75 | ++/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */ |
| 76 | ++int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd; |
| 77 | ++ |
| 78 | ++int |
| 79 | ++buffer_ctrl (long ret, int i) |
| 80 | ++{ |
| 81 | ++ switch (buffer_ctrl_cmd) |
| 82 | ++ { |
| 83 | ++ case 1: |
| 84 | ++ buffer_ctrl_ctx_0 = 0; |
| 85 | ++ for (; i; i++) |
| 86 | ++ if (buffer_ctrl_p1) |
| 87 | ++ ret++; |
| 88 | ++ } |
| 89 | ++ return ret; |
| 90 | ++} |
| 91 | +diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc |
| 92 | +index d67c94700144..43ca985c53ce 100644 |
| 93 | +--- a/gcc/tree-vect-loop-manip.cc |
| 94 | ++++ b/gcc/tree-vect-loop-manip.cc |
| 95 | +@@ -1626,12 +1626,31 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, |
| 96 | + edge temp_e = redirect_edge_and_branch (exit, new_preheader); |
| 97 | + flush_pending_stmts (temp_e); |
| 98 | + } |
| 99 | +- |
| 100 | + /* Record the new SSA names in the cache so that we can skip materializing |
| 101 | + them again when we fill in the rest of the LCSSA variables. */ |
| 102 | + for (auto phi : new_phis) |
| 103 | + { |
| 104 | + tree new_arg = gimple_phi_arg (phi, 0)->def; |
| 105 | ++ |
| 106 | ++ if (!SSA_VAR_P (new_arg)) |
| 107 | ++ continue; |
| 108 | ++ /* If the PHI MEM node dominates the loop then we shouldn't create |
| 109 | ++ a new LC-SSSA PHI for it in the intermediate block. */ |
| 110 | ++ /* A MEM phi that consitutes a new DEF for the vUSE chain can either |
| 111 | ++ be a .VDEF or a PHI that operates on MEM. And said definition |
| 112 | ++ must not be inside the main loop. Or we must be a parameter. |
| 113 | ++ In the last two cases we may remove a non-MEM PHI node, but since |
| 114 | ++ they dominate both loops the removal is unlikely to cause trouble |
| 115 | ++ as the exits must already be using them. */ |
| 116 | ++ if (virtual_operand_p (new_arg) |
| 117 | ++ && (SSA_NAME_IS_DEFAULT_DEF (new_arg) |
| 118 | ++ || !flow_bb_inside_loop_p (loop, |
| 119 | ++ gimple_bb (SSA_NAME_DEF_STMT (new_arg))))) |
| 120 | ++ { |
| 121 | ++ auto gsi = gsi_for_stmt (phi); |
| 122 | ++ remove_phi_node (&gsi, true); |
| 123 | ++ continue; |
| 124 | ++ } |
| 125 | + new_phi_args.put (new_arg, gimple_phi_result (phi)); |
| 126 | + |
| 127 | + if (TREE_CODE (new_arg) != SSA_NAME) |
| 128 | +-- |
| 129 | +2.39.3 |
0 commit comments