diff mbox

constexpr vector indexing

Message ID alpine.DEB.2.02.1307071743370.12808@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse July 7, 2013, 3:54 p.m. UTC
Hello,

it turns out there wasn't much missing here. I got side-tracked because 
fold_unary_loc doesn't call fold_indirect_ref_1, and fold_indirect_ref_1 
has a too strict comparison type == TREE_TYPE (optype) (should compare 
TYPE_MAIN_VARIANT instead?), but none of that was necessary so I'll leave 
it for another time. The new testcase is not that useful, but I didn't 
remember there was already one with dg-bogus.


Bootstrap+testsuite on x86_64-unknown-linux-gnu.

2013-07-07  Marc Glisse  <marc.glisse@inria.fr>

 	PR c++/53094
gcc/cp/
 	* semantics.c (cxx_eval_bit_field_ref): Handle VECTOR_CST.

gcc/testsuite/
 	* g++.dg/cpp0x/constexpr-53094-1.C: Adjust.
 	* g++.dg/ext/vector24.C: New testcase.

Comments

Gabriel Dos Reis July 7, 2013, 9:46 p.m. UTC | #1
On Sun, Jul 7, 2013 at 10:54 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> it turns out there wasn't much missing here. I got side-tracked because
> fold_unary_loc doesn't call fold_indirect_ref_1, and fold_indirect_ref_1 has
> a too strict comparison type == TREE_TYPE (optype) (should compare
> TYPE_MAIN_VARIANT instead?),

or same_type_p.

> but none of that was necessary so I'll leave it
> for another time. The new testcase is not that useful, but I didn't remember
> there was already one with dg-bogus.
>
>
> Bootstrap+testsuite on x86_64-unknown-linux-gnu.
>
> 2013-07-07  Marc Glisse  <marc.glisse@inria.fr>
>
>         PR c++/53094
> gcc/cp/
>         * semantics.c (cxx_eval_bit_field_ref): Handle VECTOR_CST.

OK.

>
> gcc/testsuite/
>         * g++.dg/cpp0x/constexpr-53094-1.C: Adjust.
>         * g++.dg/ext/vector24.C: New testcase.
>
> --
> Marc Glisse
> Index: testsuite/g++.dg/cpp0x/constexpr-53094-1.C
> ===================================================================
> --- testsuite/g++.dg/cpp0x/constexpr-53094-1.C  (revision 200742)
> +++ testsuite/g++.dg/cpp0x/constexpr-53094-1.C  (working copy)
> @@ -1,6 +1,6 @@
>  // { dg-do compile }
>  // { dg-options "-std=gnu++11" }
>
>  typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4;
>  constexpr V4 v = { 1, 1, 1, 0 };
> -constexpr V4 r = v[0] + v; // { dg-bogus "not a constant expression" "" {
> xfail *-*-* } }
> +constexpr V4 r = v[0] + v;
> Index: testsuite/g++.dg/ext/vector24.C
> ===================================================================
> --- testsuite/g++.dg/ext/vector24.C     (revision 0)
> +++ testsuite/g++.dg/ext/vector24.C     (revision 0)
> @@ -0,0 +1,8 @@
> +// { dg-do compile { target c++11 } }
> +
> +typedef long vec __attribute__((vector_size(2*sizeof(long))));
> +constexpr vec v = { 33, 42 };
> +constexpr auto l0 = v[0];
> +constexpr auto l1 = v[1];
> +static_assert(l0==33,"Fail");
> +static_assert(l1==42,"Fail");
>
> Property changes on: testsuite/g++.dg/ext/vector24.C
> ___________________________________________________________________
> Added: svn:eol-style
>    + native
> Added: svn:keywords
>    + Author Date Id Revision URL
>
> Index: cp/semantics.c
> ===================================================================
> --- cp/semantics.c      (revision 200742)
> +++ cp/semantics.c      (working copy)
> @@ -7179,29 +7179,35 @@ cxx_eval_bit_field_ref (const constexpr_
>    tree whole = cxx_eval_constant_expression (call, orig_whole,
>                                              allow_non_constant, addr,
>                                              non_constant_p, overflow_p);
>    tree start, field, value;
>    unsigned HOST_WIDE_INT i;
>
>    if (whole == orig_whole)
>      return t;
>    /* Don't VERIFY_CONSTANT here; we only want to check that we got a
>       CONSTRUCTOR.  */
> -  if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
> +  if (!*non_constant_p
> +      && TREE_CODE (whole) != VECTOR_CST
> +      && TREE_CODE (whole) != CONSTRUCTOR)
>      {
>        if (!allow_non_constant)
>         error ("%qE is not a constant expression", orig_whole);
>        *non_constant_p = true;
>      }
>    if (*non_constant_p)
>      return t;
>
> +  if (TREE_CODE (whole) == VECTOR_CST)
> +    return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
> +                        TREE_OPERAND (t, 1), TREE_OPERAND (t, 2));
> +
>    start = TREE_OPERAND (t, 2);
>    istart = tree_low_cst (start, 0);
>    isize = tree_low_cst (TREE_OPERAND (t, 1), 0);
>    utype = TREE_TYPE (t);
>    if (!TYPE_UNSIGNED (utype))
>      utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
>    retval = build_int_cst (utype, 0);
>    FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
>      {
>        tree bitpos = bit_position (field);
>
Marc Glisse July 7, 2013, 9:59 p.m. UTC | #2
On Sun, 7 Jul 2013, Gabriel Dos Reis wrote:

> On Sun, Jul 7, 2013 at 10:54 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> Hello,
>>
>> it turns out there wasn't much missing here. I got side-tracked because
>> fold_unary_loc doesn't call fold_indirect_ref_1, and fold_indirect_ref_1 has
>> a too strict comparison type == TREE_TYPE (optype) (should compare
>> TYPE_MAIN_VARIANT instead?),
>
> or same_type_p.

I thought of that, but it is a front-end interface, not accessible from 
fold-const.

>> but none of that was necessary so I'll leave it
>> for another time. The new testcase is not that useful, but I didn't remember
>> there was already one with dg-bogus.
>>
>>
>> Bootstrap+testsuite on x86_64-unknown-linux-gnu.
>>
>> 2013-07-07  Marc Glisse  <marc.glisse@inria.fr>
>>
>>         PR c++/53094
>> gcc/cp/
>>         * semantics.c (cxx_eval_bit_field_ref): Handle VECTOR_CST.
>
> OK.

Thanks.
Jason Merrill July 8, 2013, 4:15 p.m. UTC | #3
On 07/07/2013 11:54 AM, Marc Glisse wrote:
> it turns out there wasn't much missing here. I got side-tracked because
> fold_unary_loc doesn't call fold_indirect_ref_1, and fold_indirect_ref_1
> has a too strict comparison type == TREE_TYPE (optype) (should compare
> TYPE_MAIN_VARIANT instead?), but none of that was necessary so I'll
> leave it for another time.

I think there should be a middle end type comparison function that 
allows a few differences, but that is definitely something for another time.

Jason
diff mbox

Patch

Index: testsuite/g++.dg/cpp0x/constexpr-53094-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-53094-1.C	(revision 200742)
+++ testsuite/g++.dg/cpp0x/constexpr-53094-1.C	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 
 typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4;
 constexpr V4 v = { 1, 1, 1, 0 };
-constexpr V4 r = v[0] + v; // { dg-bogus "not a constant expression" "" { xfail *-*-* } }
+constexpr V4 r = v[0] + v;
Index: testsuite/g++.dg/ext/vector24.C
===================================================================
--- testsuite/g++.dg/ext/vector24.C	(revision 0)
+++ testsuite/g++.dg/ext/vector24.C	(revision 0)
@@ -0,0 +1,8 @@ 
+// { dg-do compile { target c++11 } }
+
+typedef long vec __attribute__((vector_size(2*sizeof(long))));
+constexpr vec v = { 33, 42 };
+constexpr auto l0 = v[0];
+constexpr auto l1 = v[1];
+static_assert(l0==33,"Fail");
+static_assert(l1==42,"Fail");

Property changes on: testsuite/g++.dg/ext/vector24.C
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Author Date Id Revision URL

Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 200742)
+++ cp/semantics.c	(working copy)
@@ -7179,29 +7179,35 @@  cxx_eval_bit_field_ref (const constexpr_
   tree whole = cxx_eval_constant_expression (call, orig_whole,
 					     allow_non_constant, addr,
 					     non_constant_p, overflow_p);
   tree start, field, value;
   unsigned HOST_WIDE_INT i;
 
   if (whole == orig_whole)
     return t;
   /* Don't VERIFY_CONSTANT here; we only want to check that we got a
      CONSTRUCTOR.  */
-  if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
+  if (!*non_constant_p
+      && TREE_CODE (whole) != VECTOR_CST
+      && TREE_CODE (whole) != CONSTRUCTOR)
     {
       if (!allow_non_constant)
 	error ("%qE is not a constant expression", orig_whole);
       *non_constant_p = true;
     }
   if (*non_constant_p)
     return t;
 
+  if (TREE_CODE (whole) == VECTOR_CST)
+    return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
+			 TREE_OPERAND (t, 1), TREE_OPERAND (t, 2));
+
   start = TREE_OPERAND (t, 2);
   istart = tree_low_cst (start, 0);
   isize = tree_low_cst (TREE_OPERAND (t, 1), 0);
   utype = TREE_TYPE (t);
   if (!TYPE_UNSIGNED (utype))
     utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
   retval = build_int_cst (utype, 0);
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
     {
       tree bitpos = bit_position (field);