Hi, Per PR72747, A statement such as "v = vec_splats (1);" correctly initializes a vector. However, a statement such as "v[1] = v[0] = vec_splats (1);" initializes both v[1] and v[0] to random garbage.
It has been determined that this is occurring because we did not emit the actual initialization statement before our final exit from gimplify_init_constructor, at which time we lose the expression when we assign *expr_p to either NULL or object. This problem affected both constant and non-constant initializers. Corrected this by moving the logic to emit the statement up earlier within the if/else logic. Bootstrapped and make check ran without regressions on powerpc64le-unknown-linux-gnu. OK for trunk? Thanks, -Will gcc: 2016-10-26 Will Schmidt <will_schm...@vnet.ibm.com> PR middle-end/72747 * gimplify.c (gimplify_init_constructor): Move emit of constructor assignment to earlier in the if/else logic. testsuite: 2016-10-26 Will Schmidt <will_schm...@vnet.ibm.com> PR middle-end/72747 * c-c++-common/pr72747-1.c: New test. * c-c++-common/pr72747-2.c: Likewise. Index: gcc/gimplify.c =================================================================== --- gcc/gimplify.c (revision 241600) +++ gcc/gimplify.c (working copy) @@ -4730,24 +4730,23 @@ if (ret == GS_ERROR) return GS_ERROR; - else if (want_value) + /* If we have gimplified both sides of the initializer but have + not emitted an assignment, do so now. */ + if (*expr_p) { + tree lhs = TREE_OPERAND (*expr_p, 0); + tree rhs = TREE_OPERAND (*expr_p, 1); + gassign *init = gimple_build_assign (lhs, rhs); + gimplify_seq_add_stmt (pre_p, init); + } + if (want_value) + { *expr_p = object; return GS_OK; } else { - /* If we have gimplified both sides of the initializer but have - not emitted an assignment, do so now. */ - if (*expr_p) - { - tree lhs = TREE_OPERAND (*expr_p, 0); - tree rhs = TREE_OPERAND (*expr_p, 1); - gassign *init = gimple_build_assign (lhs, rhs); - gimplify_seq_add_stmt (pre_p, init); - *expr_p = NULL; - } - + *expr_p = NULL; return GS_ALL_DONE; } } Index: gcc/testsuite/c-c++-common/pr72747-1.c =================================================================== --- gcc/testsuite/c-c++-common/pr72747-1.c (revision 0) +++ gcc/testsuite/c-c++-common/pr72747-1.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -fdump-tree-gimple" } */ + +/* PR 72747: Test that cascaded definition is happening for constant vectors. */ + +#include <altivec.h> + +int main (int argc, char *argv[]) +{ + __vector int v1,v2; + v1 = v2 = vec_splats ((int) 42); + return 0; +} +/* { dg-final { scan-tree-dump-times " v2 = { 42, 42, 42, 42 }" 1 "gimple" } } */ + Index: gcc/testsuite/c-c++-common/pr72747-2.c =================================================================== --- gcc/testsuite/c-c++-common/pr72747-2.c (revision 0) +++ gcc/testsuite/c-c++-common/pr72747-2.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-c -maltivec -fdump-tree-gimple" } */ + +/* PR 72747: test that cascaded definition is happening for non constants. */ + +void foo () +{ + extern int i; + __vector int v,w; + v = w = (vector int) { i }; +} + +int main (int argc, char *argv[]) +{ + return 0; +} +/* { dg-final { scan-tree-dump-times " w = {i.0_1}" 1 "gimple" } } */