We have return VIEW_CONVERT_EXPR<U>( VEC_PERM_EXPR < {<<< Unknown tree: compound_literal_expr V D.1984 = { 0 }; >>>, { 0 }} , {<<< Unknown tree: compound_literal_expr V D.1985 = { 0 }; >>>, { 0 }} , { 0, 0 } > & {(short int) SAVE_EXPR <c>, (short int) SAVE_EXPR <c>});
where we gimplify the init CTORs to _1 = {{ 0 }, { 0 }}; _2 = {{ 0 }, { 0 }}; instead of to vector constants. That later runs into a bug in uniform_vector_p which doesn't handle CTORs of vector elements correctly. The following adjusts uniform_vector_p to handle CTORs of vector elements and also makes sure to simplify the CTORs to VECTOR_CSTs during gimplification by re-ordering the simplification to after CTOR flag recomputation. Bootstrapped and tested on x86_64-unknown-linux-gnu. At this point I'm leaning towards delaying the gimplification change to stage1 - do you agree? Thanks, Richard. 2022-03-25 Richard Biener <rguent...@suse.de> PR middle-end/105049 * gimplify.cc (gimplify_init_constructor): First gimplify, then simplify the result to a VECTOR_CST. * tree.cc (uniform_vector_p): Recurse for VECTOR_CST or CONSTRUCTOR first elements. * gcc/testsuite/gcc.dg/pr105049.c: New testcase. --- gcc/gimplify.cc | 33 ++++++++++++++++----------------- gcc/testsuite/gcc.dg/pr105049.c | 12 ++++++++++++ gcc/tree.cc | 2 ++ 3 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr105049.c diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index f62f150fc08..a866d4e6f56 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -5390,6 +5390,22 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, if (notify_temp_creation) return GS_OK; + /* Vector types use CONSTRUCTOR all the way through gimple + compilation as a general initializer. */ + FOR_EACH_VEC_SAFE_ELT (elts, ix, ce) + { + enum gimplify_status tret; + tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val, + fb_rvalue); + if (tret == GS_ERROR) + ret = GS_ERROR; + else if (TREE_STATIC (ctor) + && !initializer_constant_valid_p (ce->value, + TREE_TYPE (ce->value))) + TREE_STATIC (ctor) = 0; + } + recompute_constructor_flags (ctor); + /* Go ahead and simplify constant constructors to VECTOR_CST. */ if (TREE_CONSTANT (ctor)) { @@ -5412,25 +5428,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts); break; } - - TREE_CONSTANT (ctor) = 0; } - /* Vector types use CONSTRUCTOR all the way through gimple - compilation as a general initializer. */ - FOR_EACH_VEC_SAFE_ELT (elts, ix, ce) - { - enum gimplify_status tret; - tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val, - fb_rvalue); - if (tret == GS_ERROR) - ret = GS_ERROR; - else if (TREE_STATIC (ctor) - && !initializer_constant_valid_p (ce->value, - TREE_TYPE (ce->value))) - TREE_STATIC (ctor) = 0; - } - recompute_constructor_flags (ctor); if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0))) TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p); } diff --git a/gcc/testsuite/gcc.dg/pr105049.c b/gcc/testsuite/gcc.dg/pr105049.c new file mode 100644 index 00000000000..b0518c6a181 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105049.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-tree-forwprop" } */ + +typedef short __attribute__((__vector_size__ (sizeof(short)))) V; +typedef short __attribute__((__vector_size__ (2*sizeof(short)))) U; +char c; + +U +foo (void) +{ + return __builtin_shufflevector ((V){}, (V){}, 0, 0) & c; +} diff --git a/gcc/tree.cc b/gcc/tree.cc index b8017af6cfc..ec200e9a7eb 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -10266,6 +10266,8 @@ uniform_vector_p (const_tree vec) if (i != nelts) return NULL_TREE; + if (TREE_CODE (first) == CONSTRUCTOR || TREE_CODE (first) == VECTOR_CST) + return uniform_vector_p (first); return first; } -- 2.34.1