tree-optimization/100778 - fix placement of trapping vectorized ops
This avoids placing possibly trapping vectorized operations where the corresponding scalar operation was possibly not executed. 2021-01-07 Richard Biener <rguenther@suse.de> PR tree-optimization/100778 * tree-vect-slp.c (vect_schedule_slp_node): Do not place trapping vectorized ops ahead of their scalar BB. * gcc.dg/torture/pr100778.c: New testcase.
This commit is contained in:
parent
9f6aeb85ee
commit
a3aaba6840
31
gcc/testsuite/gcc.dg/torture/pr100778.c
Normal file
31
gcc/testsuite/gcc.dg/torture/pr100778.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* { dg-do run { target *-*-*gnu* } } */
|
||||
/* { dg-additional-options "-fno-tree-sink -fno-math-errno -ftree-vectorize -D_GNU_SOURCE" } */
|
||||
/* { dg-require-effective-target fenv_exceptions } */
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
double a[2];
|
||||
void __attribute__((noipa)) foo ()
|
||||
{
|
||||
double x = a[0];
|
||||
double y = a[1];
|
||||
double norm = __builtin_sqrt (x*x + y*y);
|
||||
if (norm > 1.)
|
||||
{
|
||||
x = x / norm;
|
||||
y = y / norm;
|
||||
}
|
||||
a[0] = x;
|
||||
a[1] = y;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
feenableexcept (FE_INVALID);
|
||||
a[0] = 0.;
|
||||
a[1] = 0.;
|
||||
foo ();
|
||||
if (a[0] != 0. || a[1] != 0.)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
@ -7100,6 +7100,21 @@ vect_schedule_slp_node (vec_info *vinfo,
|
||||
gcc_assert (seen_vector_def);
|
||||
si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
|
||||
}
|
||||
else if (is_a <bb_vec_info> (vinfo)
|
||||
&& gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt)
|
||||
&& gimple_could_trap_p (stmt_info->stmt))
|
||||
{
|
||||
/* We've constrained possibly trapping operations to all come
|
||||
from the same basic-block, if vectorized defs would allow earlier
|
||||
scheduling still force vectorized stmts to the original block.
|
||||
This is only necessary for BB vectorization since for loop vect
|
||||
all operations are in a single BB and scalar stmt based
|
||||
placement doesn't play well with epilogue vectorization. */
|
||||
gcc_assert (dominated_by_p (CDI_DOMINATORS,
|
||||
gimple_bb (stmt_info->stmt),
|
||||
gimple_bb (last_stmt)));
|
||||
si = gsi_after_labels (gimple_bb (stmt_info->stmt));
|
||||
}
|
||||
else if (is_a <gphi *> (last_stmt))
|
||||
si = gsi_after_labels (gimple_bb (last_stmt));
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user