On Tue, 11 Apr 2017, Jakub Jelinek wrote: > Hi! > > The x86 intrinsics allow andnot on MODE_VECTOR_FLOAT modes, but > such modes have NULL CONSTM1_RTX and are not appropriate for the > transformation anyway. > > The following patch fixes that, ok if bootstrap/regtest passes? > Or would you prefer to replace the > && CONSTM1_RTX (mode) > check with e.g. > && (MODE_CLASS (mode) == MODE_INT > || MODE_CLASS (mode) == MODE_VECTOR_INT) > (dunno if we want to handle that way also partial int modes or not, > no experience with those)? > The transformation relies on 2's complement, so certainly doesn't apply > to floating modes (scalar or vector), but even MODE_COMPLEX_INT doesn't > have CONSTM1_RTX.
I think the patch is ok as-is. Richard. > 2017-04-11 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/80385 > * simplify-rtx.c (simplify_unary_operation_1): Don't transform > (not (neg X)) into (plus X -1) for complex or non-integral modes. > > * g++.dg/opt/pr80385.C: New test. > > --- gcc/simplify-rtx.c.jj 2017-04-04 07:32:57.000000000 +0200 > +++ gcc/simplify-rtx.c 2017-04-11 12:26:05.550834274 +0200 > @@ -932,8 +932,10 @@ simplify_unary_operation_1 (enum rtx_cod > && XEXP (op, 1) == constm1_rtx) > return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode); > > - /* Similarly, (not (neg X)) is (plus X -1). */ > - if (GET_CODE (op) == NEG) > + /* Similarly, (not (neg X)) is (plus X -1). Only do this for > + modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT > + and MODE_VECTOR_INT. */ > + if (GET_CODE (op) == NEG && CONSTM1_RTX (mode)) > return simplify_gen_binary (PLUS, mode, XEXP (op, 0), > CONSTM1_RTX (mode)); > > --- gcc/testsuite/g++.dg/opt/pr80385.C.jj 2017-04-11 12:36:36.421806796 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr80385.C 2017-04-11 12:36:11.000000000 > +0200 > @@ -0,0 +1,14 @@ > +// PR rtl-optimization/80385 > +// { dg-do compile { target { i?86-*-* x86_64-*-* } } } > +// { dg-options "-Ofast -msse2" } > + > +#include <x86intrin.h> > + > +__m128 a, e; > +struct A { __m128 b; A (); A (__m128 x) : b(x) {} }; > +A operator+ (A, A); > +A operator- (A) { __m128 c = -a; return c; } > +A foo (A x) { __m128 d = x.b; return _mm_andnot_ps (d, e); } > +struct B { A n[1]; }; > +void bar (B x) { A f = foo (x.n[0]); A g = f + A (); } > +void baz () { B h; B i; A j; i.n[0] = -j; h = i; B k = h; bar (k); } > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)