Hi! My PR85077 + if (VECTOR_TYPE_P (TREE_TYPE (x))) + x = fold (x); cp_fold change apparently broke the following and similar testcases, if split_nonconstant_init splits the initialization into a runtime part and some CONSTRUCTOR, it clears TREE_READONLY on it, and constant_value_1 had code to avoid returning that CONSTRUCTOR as the value if not DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P because that CONSTRUCTOR is only part of the story. With the PR85077 change, such CONSTRUCTORs are turned into VECTOR_CSTs by fold though and constant_value_1 then returns the wrong thing.
Fixed thusly, bootstrapped/regtested on x86_64-linux, ok for trunk and 9.2/8.4? 2019-06-10 Jakub Jelinek <ja...@redhat.com> PR c++/90810 * init.c (constant_value_1): Handle VECTOR_CST DECL_INITIAL for !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P decls like CONSTRUCTOR. * g++.dg/ext/vector37.C: New test. --- gcc/cp/init.c.jj 2019-05-23 12:57:16.624494279 +0200 +++ gcc/cp/init.c 2019-06-10 17:07:34.779366457 +0200 @@ -2339,8 +2339,11 @@ constant_value_1 (tree decl, bool strict || TREE_CODE (init) == STRING_CST))) break; /* Don't return a CONSTRUCTOR for a variable with partial run-time - initialization, since it doesn't represent the entire value. */ - if (TREE_CODE (init) == CONSTRUCTOR + initialization, since it doesn't represent the entire value. + Similarly for VECTOR_CSTs created by cp_folding those + CONSTRUCTORs. */ + if ((TREE_CODE (init) == CONSTRUCTOR + || TREE_CODE (init) == VECTOR_CST) && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) break; /* If the variable has a dynamic initializer, don't use its --- gcc/testsuite/g++.dg/ext/vector37.C.jj 2019-06-10 17:12:29.092801825 +0200 +++ gcc/testsuite/g++.dg/ext/vector37.C 2019-06-10 17:11:35.641630817 +0200 @@ -0,0 +1,29 @@ +// PR c++/90810 +// { dg-do run } + +void +foo (float x, float y) +{ + typedef float __attribute__ ((__vector_size__ (4 * sizeof (float)), __may_alias__)) V; + const V a = { x, x, x, x }, b = { y, y, y, y }; + const V c = a / b; + if (c[0] != 6.0f || c[1] != 6.0f || c[2] != 6.0f || c[3] != 6.0f) + __builtin_abort (); +} + +void +bar (float y) +{ + typedef float __attribute__ ((__vector_size__ (4 * sizeof (float)), __may_alias__)) V; + const V a = { 7.0f, 8.0f, 9.0f, 10.0f }, b = { 1.0f, 2.0f, 3.0f, y }; + const V c = a / b; + if (c[0] != 7.0f || c[1] != 4.0f || c[2] != 3.0f || c[3] != 5.0f) + __builtin_abort (); +} + +int +main () +{ + foo (12.0f, 2.0f); + bar (2.0f); +} Jakub