This relaxes the condition for the match.pd pattern doing vector ctor element extracts to not require type identity but only size equality. Since we vectorize pointer data as unsigned integer data such mismatches have to be tolerated to optimize scalar code uses of vector results.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. 2021-03-26 Richard Biener <rguent...@suse.de> PR tree-optimization/99776 * match.pd (bit_field_ref (ctor)): Relax element extract type compatibility checks. * gcc.dg/tree-ssa/ssa-fre-91.c: New testcase. --- gcc/match.pd | 18 +++++++++++++----- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c diff --git a/gcc/match.pd b/gcc/match.pd index 66788ba6a86..bb1d6231de1 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6168,9 +6168,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2) (if (VECTOR_TYPE_P (TREE_TYPE (@0)) - && (types_match (type, TREE_TYPE (TREE_TYPE (@0))) + && tree_fits_uhwi_p (TYPE_SIZE (type)) + && ((tree_to_uhwi (TYPE_SIZE (type)) + == tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0))))) || (VECTOR_TYPE_P (type) - && types_match (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0)))))) + && (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type))) + == tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0)))))))) (with { tree ctor = (TREE_CODE (@0) == SSA_NAME @@ -6226,10 +6229,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) if (!CONSTANT_CLASS_P (e)) constant_p = false; } - res = (constant_p ? build_vector_from_ctor (type, vals) - : build_constructor (type, vals)); + tree evtype = (types_match (TREE_TYPE (type), + TREE_TYPE (TREE_TYPE (ctor))) + ? type + : build_vector_type (TREE_TYPE (TREE_TYPE (ctor)), + count)); + res = (constant_p ? build_vector_from_ctor (evtype, vals) + : build_constructor (evtype, vals)); } - { res; }))))) + (view_convert { res; })))))) /* The bitfield references a single constructor element. */ (if (k.is_constant (&const_k) && idx + n <= (idx / const_k + 1) * const_k) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c new file mode 100644 index 00000000000..4999a3b66ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fre4" } */ + +extern void foo(void); + +static int a[2], b, *c[2]; + +int main() { + for (b = 0; b < 2; b++) + c[b] = &a[1]; + if (!c[0]) + foo(); + return 0; +} + +/* Even when vectorizing we should eliminate the call to foo. */ +/* { dg-final { scan-tree-dump-not "foo" "fre4" } } */ -- 2.26.2