Skip to content

Commit 8fdac08

Browse files
committed
tree-optimization/114197 - unexpected if-conversion for vectorization
The following avoids lowering a volatile bitfiled access and in case the if-converted and original loops end up in different outer loops because of simplifcations enabled scrap the result since that is not how the vectorizer expects the loops to be laid out. PR tree-optimization/114197 * tree-if-conv.cc (bitfields_to_lower_p): Do not lower if there are volatile bitfield accesses. (pass_if_conversion::execute): Throw away result if the if-converted and original loops are not nested as expected. * gcc.dg/torture/pr114197.c: New testcase.
1 parent a19ab1c commit 8fdac08

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* { dg-do compile } */
2+
3+
#pragma pack(push)
4+
struct a {
5+
volatile signed b : 8;
6+
};
7+
#pragma pack(pop)
8+
int c;
9+
static struct a d = {5};
10+
void e() {
11+
f:
12+
for (c = 8; c < 55; ++c)
13+
if (!d.b)
14+
goto f;
15+
}

gcc/tree-if-conv.cc

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3701,6 +3701,14 @@ bitfields_to_lower_p (class loop *loop,
37013701
if (dump_file && (dump_flags & TDF_DETAILS))
37023702
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
37033703

3704+
if (TREE_THIS_VOLATILE (op))
3705+
{
3706+
if (dump_file && (dump_flags & TDF_DETAILS))
3707+
fprintf (dump_file, "\t Bitfield NO OK to lower,"
3708+
" the access is volatile.\n");
3709+
return false;
3710+
}
3711+
37043712
if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
37053713
{
37063714
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4031,20 +4039,27 @@ pass_if_conversion::execute (function *fun)
40314039
if (todo & TODO_update_ssa_any)
40324040
update_ssa (todo & TODO_update_ssa_any);
40334041

4034-
/* If if-conversion elided the loop fall back to the original one. */
4042+
/* If if-conversion elided the loop fall back to the original one. Likewise
4043+
if the loops are not nested in the same outer loop. */
40354044
for (unsigned i = 0; i < preds.length (); ++i)
40364045
{
40374046
gimple *g = preds[i];
40384047
if (!gimple_bb (g))
40394048
continue;
4040-
unsigned ifcvt_loop = tree_to_uhwi (gimple_call_arg (g, 0));
4041-
unsigned orig_loop = tree_to_uhwi (gimple_call_arg (g, 1));
4042-
if (!get_loop (fun, ifcvt_loop) || !get_loop (fun, orig_loop))
4049+
auto ifcvt_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 0)));
4050+
auto orig_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 1)));
4051+
if (!ifcvt_loop || !orig_loop)
40434052
{
40444053
if (dump_file)
40454054
fprintf (dump_file, "If-converted loop vanished\n");
40464055
fold_loop_internal_call (g, boolean_false_node);
40474056
}
4057+
else if (loop_outer (ifcvt_loop) != loop_outer (orig_loop))
4058+
{
4059+
if (dump_file)
4060+
fprintf (dump_file, "If-converted loop in different outer loop\n");
4061+
fold_loop_internal_call (g, boolean_false_node);
4062+
}
40484063
}
40494064

40504065
return 0;

0 commit comments

Comments
 (0)