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

Reply via email to