diff --git a/gcc/stor-layout.h b/gcc/stor-layout.h index e7768921c22..589ce33c950 100644 --- a/gcc/stor-layout.h +++ b/gcc/stor-layout.h @@ -36,7 +36,6 @@ extern void place_field (record_layout_info, tree); extern void compute_record_mode (tree); extern void finish_bitfield_layout (tree); extern void finish_record_layout (record_layout_info, int); -extern unsigned int element_precision (const_tree); extern void finalize_size_functions (void); extern void fixup_unsigned_type (tree); extern void initialize_sizetypes (void); diff --git a/gcc/testsuite/gcc.dg/torture/pr111000.c b/gcc/testsuite/gcc.dg/torture/pr111000.c new file mode 100644 index 00000000000..e6821e1618d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr111000.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ + +volatile int a = 68; +int b, d, e; +int main() +{ + int t = a; + for (; d <= 6; d++) { + for (b = 0; b <= 6; b++) { + if (t >= 31) + e = d; + else if (d > (647 >> t)) + e = d; + else + e = 0; + } + } + if (e != 6) + __builtin_abort(); + return 0; +} diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc index 49aeb685773..396963b6754 100644 --- a/gcc/tree-ssa-loop-im.cc +++ b/gcc/tree-ssa-loop-im.cc @@ -400,6 +400,24 @@ movement_possibility_1 (gimple *stmt) || gimple_could_trap_p (stmt)) return MOVE_PRESERVE_EXECUTION; + if (is_gimple_assign (stmt)) + { + auto code = gimple_assign_rhs_code (stmt); + tree type = TREE_TYPE (gimple_assign_rhs1 (stmt)); + /* For shifts and rotates and possibly out-of-bound shift operands + we currently cannot rewrite them into something unconditionally + well-defined. */ + if ((code == LSHIFT_EXPR + || code == RSHIFT_EXPR + || code == LROTATE_EXPR + || code == RROTATE_EXPR) + && (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST + /* We cannot use ranges at 'stmt' here. */ + || wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (stmt)), + element_precision (type)))) + ret = MOVE_PRESERVE_EXECUTION; + } + /* Non local loads in a transaction cannot be hoisted out. Well, unless the load happens on every path out of the loop, but we don't take this into account yet. */ diff --git a/gcc/tree.h b/gcc/tree.h index 31ea52a5d6b..781297c7e77 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2235,6 +2235,7 @@ class auto_suppress_location_wrappers #define SET_TYPE_MODE(NODE, MODE) \ (TYPE_CHECK (NODE)->type_common.mode = (MODE)) +extern unsigned int element_precision (const_tree); extern machine_mode element_mode (const_tree); extern machine_mode vector_type_mode (const_tree); extern unsigned int vector_element_bits (const_tree);