From: Andre Vieira Date: Tue, 18 Oct 2022 09:51:09 +0000 (+0100) Subject: ifcvt: Do not lower bitfields if we can't analyze dr's [PR107275] X-Git-Tag: basepoints/gcc-14~3852 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aae016f99b121b55fc1bcdfc2403fd22f04fa2df;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/testsuite/gcc.dg/vect/pr107275.c b/gcc/testsuite/gcc.dg/vect/pr107275.c new file mode 100644 index 000000000000..16327c46add7 --- /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 01637c5da08d..a83b013d2ad3 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 *refs) basic_block exit_bb = NULL; vec 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 *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 *refs) { edge e; edge_iterator ei; bool res = false; - vec 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 *preds) auto_vec writes_to_lower; bitmap exit_bbs; edge pe; + vec refs; again: rloop = NULL; @@ -3508,6 +3497,7 @@ tree_if_conversion (class loop *loop, vec *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 *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 *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;