This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix vector handling in simplify-rtx.c (PR rtl-optimization/82973)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jeff Law <law at redhat dot com>, Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 Dec 2017 23:18:50 +0100
- Subject: [PATCH] Fix vector handling in simplify-rtx.c (PR rtl-optimization/82973)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
In rtl.texi we say:
@findex const_vector
@item (const_vector:@var{m} [@var{x0} @var{x1} @dots{}])
Represents a vector constant. The square brackets stand for the vector
containing the constant elements. @var{x0}, @var{x1} and so on are
the @code{const_int}, @code{const_wide_int}, @code{const_double} or
@code{const_fixed} elements.
and it is a very reasonable requirement.
simplify_const_{unary,binary}_operation can violate that though, because
the recursion can return also other expressions, like in this case
a (mult (const_double) (const_double)) that can't be simplified because
of -frounding-math. We need to punt on those.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-12-20 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/82973
* simplify-rtx.c (simplify_const_unary_operation): Don't optimize into
CONST_VECTOR if some element isn't simplified into CONST_{,WIDE_}INT,
CONST_DOUBLE or CONST_FIXED.
(simplify_const_binary_operation): Likewise. Use CONST_FIXED_P macro
instead of GET_CODE == CONST_FIXED.
(simplify_subreg): Use CONST_FIXED_P macro instead of
GET_CODE == CONST_FIXED.
* gfortran.dg/pr82973.f90: New test.
--- gcc/simplify-rtx.c.jj 2017-12-19 18:09:05.000000000 +0100
+++ gcc/simplify-rtx.c 2017-12-20 18:29:55.190089315 +0100
@@ -1776,7 +1776,12 @@ simplify_const_unary_operation (enum rtx
rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
CONST_VECTOR_ELT (op, i),
GET_MODE_INNER (opmode));
- if (!x)
+ /* Only CONST_INT, CONST_WIDE_INT, CONST_DOUBLE or CONST_FIXED
+ is valid inside of CONST_VECTOR. */
+ if (!x
+ || !(CONST_SCALAR_INT_P (x)
+ || CONST_DOUBLE_AS_FLOAT_P (x)
+ || CONST_FIXED_P (x)))
return 0;
RTVEC_ELT (v, i) = x;
}
@@ -4006,7 +4011,12 @@ simplify_const_binary_operation (enum rt
rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
CONST_VECTOR_ELT (op0, i),
CONST_VECTOR_ELT (op1, i));
- if (!x)
+ /* Only CONST_INT, CONST_WIDE_INT, CONST_DOUBLE or CONST_FIXED
+ is valid inside of CONST_VECTOR. */
+ if (!x
+ || !(CONST_SCALAR_INT_P (x)
+ || CONST_DOUBLE_AS_FLOAT_P (x)
+ || CONST_FIXED_P (x)))
return 0;
RTVEC_ELT (v, i) = x;
}
@@ -4017,11 +4027,11 @@ simplify_const_binary_operation (enum rt
if (VECTOR_MODE_P (mode)
&& code == VEC_CONCAT
&& (CONST_SCALAR_INT_P (op0)
- || GET_CODE (op0) == CONST_FIXED
+ || CONST_FIXED_P (op0)
|| CONST_DOUBLE_AS_FLOAT_P (op0))
&& (CONST_SCALAR_INT_P (op1)
|| CONST_DOUBLE_AS_FLOAT_P (op1)
- || GET_CODE (op1) == CONST_FIXED))
+ || CONST_FIXED_P (op1)))
{
unsigned n_elts = GET_MODE_NUNITS (mode);
rtvec v = rtvec_alloc (n_elts);
@@ -6193,7 +6203,7 @@ simplify_subreg (machine_mode outermode,
if (CONST_SCALAR_INT_P (op)
|| CONST_DOUBLE_AS_FLOAT_P (op)
- || GET_CODE (op) == CONST_FIXED
+ || CONST_FIXED_P (op)
|| GET_CODE (op) == CONST_VECTOR)
{
/* simplify_immed_subreg deconstructs OP into bytes and constructs
--- gcc/testsuite/gfortran.dg/pr82973.f90.jj 2017-12-20 18:53:14.392540473 +0100
+++ gcc/testsuite/gfortran.dg/pr82973.f90 2017-12-20 18:52:47.000000000 +0100
@@ -0,0 +1,31 @@
+! PR rtl-optimization/82973
+! { dg-do compile }
+! { dg-options "-Ofast -frounding-math" }
+
+program pr82973
+ integer, parameter :: n=16
+ real, dimension(n) :: ar, br, modulo_result, floor_result
+ integer, dimension(n) :: ai, bi , imodulo_result, ifloor_result
+ ai(1:4) = 5
+ ai(5:8) = -5
+ ai(9:12) = 1
+ ai(13:16) = -1
+ bi(1:4) = (/ 3,-3, 1, -1/)
+ bi(5:8) = bi(1:4)
+ bi(9:12) = bi(1:4)
+ bi(13:16) = bi(1:4)
+ ar = ai
+ br = bi
+ modulo_result = modulo(ar,br)
+ imodulo_result = modulo(ai,bi)
+ floor_result = ar-floor(ar/br)*br
+ ifloor_result = nint(real(ai-floor(real(ai)/real(bi))*bi))
+ do i=1,n
+ if (modulo_result(i) /= floor_result(i)) then
+ call abort()
+ end if
+ if (imodulo_result(i) /= ifloor_result(i)) then
+ call abort ()
+ end if
+ end do
+end program pr82973
Jakub