diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2022-10-18 10:51:09 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2022-10-18 10:51:09 +0100 |
commit | aae016f99b121b55fc1bcdfc2403fd22f04fa2df (patch) | |
tree | 5201b2a1487018d2062b4eaa26ad70c35a25d702 /gcc | |
parent | a23225fb4f764dfc3e3e729c7d7238f03f282aaa (diff) | |
download | gcc-aae016f99b121b55fc1bcdfc2403fd22f04fa2df.zip gcc-aae016f99b121b55fc1bcdfc2403fd22f04fa2df.tar.gz gcc-aae016f99b121b55fc1bcdfc2403fd22f04fa2df.tar.bz2 |
ifcvt: Do not lower bitfields if we can't analyze dr's [PR107275]
The ifcvt dead code elimination code was not built to deal with inline
assembly, loops with such would never be if-converted in the past since we can't
do data-reference analysis on them and vectorization would eventually fail. For
this reason we now also do not lower bitfields if the data-reference analysis
fails, as we would not end up vectorizing it. As a consequence this also fixes
this PR as the dead code elimination will not run for such cases and wrongfully
eliminate inline assembly statements.
gcc/ChangeLog:
PR tree-optimization/107275
* tree-if-conv.cc (if_convertible_loop_p_1): Move
find_data_references_in_loop call from here...
(if_convertible_loop_p): And move data-reference vector initialization
from here...
(tree_if_conversion):... to here.
gcc/testsuite/ChangeLog:
* gcc.dg/vect/pr107275.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr107275.c | 15 | ||||
-rw-r--r-- | gcc/tree-if-conv.cc | 30 |
2 files changed, 30 insertions, 15 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr107275.c b/gcc/testsuite/gcc.dg/vect/pr107275.c new file mode 100644 index 0000000..16327c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr107275.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +struct st +{ + int a : 1; +}; + +void +foo (struct st *s, int n) +{ + for (int i = 0; i < n; ++i) + { + s[i].a = i; + __asm__ __volatile__ ("":::"memory"); + } +} diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 01637c5..a83b013 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -1416,9 +1416,6 @@ if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs) basic_block exit_bb = NULL; vec<basic_block> region; - if (find_data_references_in_loop (loop, refs) == chrec_dont_know) - return false; - calculate_dominance_info (CDI_DOMINATORS); for (i = 0; i < loop->num_nodes; i++) @@ -1541,12 +1538,11 @@ if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs) - if its basic blocks and phi nodes are if convertible. */ static bool -if_convertible_loop_p (class loop *loop) +if_convertible_loop_p (class loop *loop, vec<data_reference_p> *refs) { edge e; edge_iterator ei; bool res = false; - vec<data_reference_p> refs; /* Handle only innermost loop. */ if (!loop || loop->inner) @@ -1578,15 +1574,7 @@ if_convertible_loop_p (class loop *loop) if (loop_exit_edge_p (loop, e)) return false; - refs.create (5); - res = if_convertible_loop_p_1 (loop, &refs); - - data_reference_p dr; - unsigned int i; - for (i = 0; refs.iterate (i, &dr); i++) - free (dr->aux); - - free_data_refs (refs); + res = if_convertible_loop_p_1 (loop, refs); delete innermost_DR_map; innermost_DR_map = NULL; @@ -3499,6 +3487,7 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) auto_vec <gassign *, 4> writes_to_lower; bitmap exit_bbs; edge pe; + vec<data_reference_p> refs; again: rloop = NULL; @@ -3508,6 +3497,7 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) need_to_predicate = false; need_to_rewrite_undefined = false; any_complicated_phi = false; + refs.create (5); /* Apply more aggressive if-conversion when loop or its outer loop were marked with simd pragma. When that's the case, we try to if-convert @@ -3537,11 +3527,14 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) goto cleanup; } + if (find_data_references_in_loop (loop, &refs) == chrec_dont_know) + goto cleanup; + if (loop->num_nodes > 2) { need_to_ifcvt = true; - if (!if_convertible_loop_p (loop) || !dbg_cnt (if_conversion_tree)) + if (!if_convertible_loop_p (loop, &refs) || !dbg_cnt (if_conversion_tree)) goto cleanup; if ((need_to_predicate || any_complicated_phi) @@ -3658,6 +3651,13 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) todo |= TODO_cleanup_cfg; cleanup: + data_reference_p dr; + unsigned int i; + for (i = 0; refs.iterate (i, &dr); i++) + free (dr->aux); + + refs.truncate (0); + if (ifc_bbs) { unsigned int i; |