tree-optimization/111000 - restrict invariant motion of shifts
The following restricts moving variable shifts to when they are always executed in the loop as we currently do not have an efficient way to rewrite them to something that is unconditionally well-defined and value range analysis will otherwise compute invalid ranges for the shift operand. PR tree-optimization/111000 * stor-layout.h (element_precision): Move .. * tree.h (element_precision): .. here. * tree-ssa-loop-im.cc (movement_possibility_1): Restrict motion of shifts and rotates. * gcc.dg/torture/pr111000.c: New testcase.
This commit is contained in:
parent
551935d118
commit
d118738e71
4 changed files with 40 additions and 1 deletions
|
@ -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);
|
||||
|
|
21
gcc/testsuite/gcc.dg/torture/pr111000.c
Normal file
21
gcc/testsuite/gcc.dg/torture/pr111000.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue