public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-3438] c++: Don't shortcut TREE_CONSTANT vector type CONSTRUCTORs in cxx_eval_constant_expression [PR107295
@ 2022-10-21 16:07 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-10-21 16:07 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2cc41601d9a948e8d612a21c3b9a44ce0b977747

commit r13-3438-g2cc41601d9a948e8d612a21c3b9a44ce0b977747
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Oct 21 18:04:54 2022 +0200

    c++: Don't shortcut TREE_CONSTANT vector type CONSTRUCTORs in cxx_eval_constant_expression [PR107295]
    
    The excess precision support broke building skia (dependency of firefox)
    on ia32 (it has something like the a constexpr variable), but as the other
    cases show, it is actually a preexisting problem if one uses casts from
    constants with wider floating point types.
    The problem is that cxx_eval_constant_expression tries to short-cut
    processing of TREE_CONSTANT CONSTRUCTORs if they satisfy
    reduced_constant_expression_p - instead of calling cxx_eval_bare_aggregate
    on them it just verifies flags and if they are TREE_CONSTANT even after
    that, just fold.
    Now, on the testcase we have a TREE_CONSTANT CONSTRUCTOR containing
    TREE_CONSTANT NOP_EXPR of REAL_CST.  And, fold, which isn't recursive,
    doesn't optimize that into VECTOR_CST, while later on we are only able
    to optimize VECTOR_CST arithmetics, not arithmetics with vector
    CONSTRUCTORs.
    The following patch fixes that by rejecting CONSTRUCTORs with vector type
    in reduced_constant_expression_p regardless of whether they have
    CONSTRUCTOR_NO_CLEARING set or not, folding result in cxx_eval_bare_aggregate
    even if nothing has changed but it wasn't non-constant and removing folding
    from the TREE_CONSTANT reduced_constant_expression_p short-cut.
    
    2022-10-21  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/107295
            * constexpr.cc (reduced_constant_expression_p) <case CONSTRUCTOR>:
            Return false for VECTOR_TYPE CONSTRUCTORs even without
            CONSTRUCTOR_NO_CLEARING set on them.
            (cxx_eval_bare_aggregate): If constant but !changed, fold before
            returning VECTOR_TYPE_P CONSTRUCTOR.
            (cxx_eval_constant_expression) <case CONSTRUCTOR>: Don't fold
            TREE_CONSTANT CONSTRUCTOR, just return it.
    
            * g++.dg/ext/vector42.C: New test.

Diff:
---
 gcc/cp/constexpr.cc                 | 21 +++++++++++++--------
 gcc/testsuite/g++.dg/ext/vector42.C | 12 ++++++++++++
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 03663961bb8..c3ee970a724 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3104,12 +3104,12 @@ reduced_constant_expression_p (tree t)
     case CONSTRUCTOR:
       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
       tree field;
+      if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+	/* An initialized vector would have a VECTOR_CST.  */
+	return false;
       if (CONSTRUCTOR_NO_CLEARING (t))
 	{
-	  if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
-	    /* An initialized vector would have a VECTOR_CST.  */
-	    return false;
-	  else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+	  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
 	    {
 	      /* There must be a valid constant initializer at every array
 		 index.  */
@@ -4956,8 +4956,14 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
 	  TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
 	}
     }
-  if (*non_constant_p || !changed)
+  if (*non_constant_p)
     return t;
+  if (!changed)
+    {
+      if (VECTOR_TYPE_P (type))
+	t = fold (t);
+      return t;
+    }
   t = ctx->ctor;
   if (!t)
     t = build_constructor (type, NULL);
@@ -7387,11 +7393,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case CONSTRUCTOR:
       if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
 	{
-	  /* Don't re-process a constant CONSTRUCTOR, but do fold it to
-	     VECTOR_CST if applicable.  */
+	  /* Don't re-process a constant CONSTRUCTOR.  */
 	  verify_constructor_flags (t);
 	  if (TREE_CONSTANT (t))
-	    return fold (t);
+	    return t;
 	}
       r = cxx_eval_bare_aggregate (ctx, t, lval,
 				   non_constant_p, overflow_p);
diff --git a/gcc/testsuite/g++.dg/ext/vector42.C b/gcc/testsuite/g++.dg/ext/vector42.C
new file mode 100644
index 00000000000..e7810971ca1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector42.C
@@ -0,0 +1,12 @@
+// PR c++/107295
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct A {
+  typedef T __attribute__((vector_size (sizeof (int)))) V;
+};
+template <int, typename T> using B = typename A<T>::V;
+template <typename T> using V = B<4, T>;
+using F = V<float>;
+constexpr F a = F () + 0.0f;
+constexpr F b = F () + (float) 0.0;
+constexpr F c = F () + (float) 0.0L;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-21 16:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-21 16:07 [gcc r13-3438] c++: Don't shortcut TREE_CONSTANT vector type CONSTRUCTORs in cxx_eval_constant_expression [PR107295 Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).