Message ID | 20180327091817.GY8577@tucnak |
---|---|
State | New |
Headers | show |
Series | [C++] Improve cp_fold on vector CONSTRUCTORs (PR c++/85077) | expand |
OK. On Tue, Mar 27, 2018 at 5:18 AM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > The following testcase regressed for 8+, because we delayed folding in > SAVE_EXPRs and end up passing a CONSTRUCTOR with V4SFmode and 4x 0.0 > constants in it rather than a VECTOR_CST to the middle-end folder, which > uses real_zerop and thus doesn't recognize the CONSTRUCTOR in > VEC_COND_EXPR <x < { 0, 0, 0, 0 } ? -x : x> as zero and doesn't fold > it into ABS_EXPR. > > We really should move that folding into match.pd, but that is a GCC 9 task. > > Fixed by using fold on vector CONSTRUCTORs, the only thing fold does on > those is exactly the CONSTRUCTOR -> VECTOR_CST folding when possible. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2018-03-27 Jakub Jelinek <jakub@redhat.com> > > PR c++/85077 > * cp-gimplify.c (cp_fold) <case CONSTRUCTOR>: For ctors with vector > type call fold to generate VECTOR_CSTs when possible. > > * g++.dg/ext/vector35.C: New test. > > --- gcc/cp/cp-gimplify.c.jj 2018-03-20 22:05:57.023431462 +0100 > +++ gcc/cp/cp-gimplify.c 2018-03-26 16:08:47.728347579 +0200 > @@ -2504,6 +2504,8 @@ cp_fold (tree x) > CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x) > = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x); > } > + if (VECTOR_TYPE_P (TREE_TYPE (x))) > + x = fold (x); > break; > } > case TREE_VEC: > --- gcc/testsuite/g++.dg/ext/vector35.C.jj 2018-03-26 16:19:39.330809031 +0200 > +++ gcc/testsuite/g++.dg/ext/vector35.C 2018-03-26 16:33:43.997330748 +0200 > @@ -0,0 +1,22 @@ > +// PR c++/85077 > +// { dg-do compile } > +// { dg-options "-Ofast -fdump-tree-forwprop1" } > + > +typedef float V __attribute__((vector_size (4 * sizeof (float)))); > +typedef double W __attribute__((vector_size (2 * sizeof (double)))); > + > +void > +foo (V *y) > +{ > + V x = *y; > + *y = x < 0 ? -x : x; > +} > + > +void > +bar (W *y) > +{ > + W x = *y; > + *y = x < 0 ? -x : x; > +} > + > +// { dg-final { scan-tree-dump-times "ABS_EXPR <" 2 "forwprop1" } } > > Jakub
--- gcc/cp/cp-gimplify.c.jj 2018-03-20 22:05:57.023431462 +0100 +++ gcc/cp/cp-gimplify.c 2018-03-26 16:08:47.728347579 +0200 @@ -2504,6 +2504,8 @@ cp_fold (tree x) CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x) = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x); } + if (VECTOR_TYPE_P (TREE_TYPE (x))) + x = fold (x); break; } case TREE_VEC: --- gcc/testsuite/g++.dg/ext/vector35.C.jj 2018-03-26 16:19:39.330809031 +0200 +++ gcc/testsuite/g++.dg/ext/vector35.C 2018-03-26 16:33:43.997330748 +0200 @@ -0,0 +1,22 @@ +// PR c++/85077 +// { dg-do compile } +// { dg-options "-Ofast -fdump-tree-forwprop1" } + +typedef float V __attribute__((vector_size (4 * sizeof (float)))); +typedef double W __attribute__((vector_size (2 * sizeof (double)))); + +void +foo (V *y) +{ + V x = *y; + *y = x < 0 ? -x : x; +} + +void +bar (W *y) +{ + W x = *y; + *y = x < 0 ? -x : x; +} + +// { dg-final { scan-tree-dump-times "ABS_EXPR <" 2 "forwprop1" } }