This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix simplify-rtx.c ICE with vector float (not (neg)) (PR rtl-optimization/80385)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Eric Botcazou <ebotcazou at adacore dot com>, Bernd Schmidt <bschmidt at redhat dot com>, Jeff Law <law at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 11 Apr 2017 13:20:43 +0200
- Subject: [PATCH] Fix simplify-rtx.c ICE with vector float (not (neg)) (PR rtl-optimization/80385)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3C6D180F9B
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3C6D180F9B
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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.
2017-04-11 Jakub Jelinek <jakub@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