On Wed, Dec 20, 2017 at 10:28:53PM -0700, Jeff Law wrote:
> On 12/20/2017 03:18 PM, Jakub Jelinek wrote:
> > 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  <ja...@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.
> OK.

Richard Sandiford suggested using a renamed
vector_for_vec_constant_duplicate_p predicate instead, so here is what I've
committed instead:

2017-12-21  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/82973
        * emit-rtl.h (valid_for_const_vec_duplicate_p): Rename to ...
        (valid_for_const_vector_p): ... this.
        * emit-rtl.c (valid_for_const_vec_duplicate_p): Rename to ...
        (valid_for_const_vector_p): ... this.  Adjust function comment.
        (gen_vec_duplicate): Adjust caller.
        * optabs.c (expand_vector_broadcast): Likewise.
        * simplify-rtx.c (simplify_const_unary_operation): Don't optimize into
        CONST_VECTOR if some element isn't simplified valid_for_const_vector_p
        constant.
        (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/emit-rtl.h.jj   2017-12-21 09:43:24.000000000 +0100
+++ gcc/emit-rtl.h      2017-12-21 09:59:39.422636912 +0100
@@ -439,7 +439,7 @@ get_max_uid (void)
   return crtl->emit.x_cur_insn_uid;
 }
 
-extern bool valid_for_const_vec_duplicate_p (machine_mode, rtx);
+extern bool valid_for_const_vector_p (machine_mode, rtx);
 extern rtx gen_const_vec_duplicate (machine_mode, rtx);
 extern rtx gen_vec_duplicate (machine_mode, rtx);
 
--- gcc/emit-rtl.c.jj   2017-12-21 09:43:24.000000000 +0100
+++ gcc/emit-rtl.c      2017-12-21 10:01:22.278333211 +0100
@@ -5861,11 +5861,11 @@ init_emit (void)
 #endif
 }
 
-/* Return true if X is a valid element for a duplicated vector constant
-   of the given mode.  */
+/* Return true if X is a valid element for a CONST_VECTOR of the given
+  mode.  */
 
 bool
-valid_for_const_vec_duplicate_p (machine_mode, rtx x)
+valid_for_const_vector_p (machine_mode, rtx x)
 {
   return (CONST_SCALAR_INT_P (x)
          || CONST_DOUBLE_AS_FLOAT_P (x)
@@ -5907,7 +5907,7 @@ gen_const_vec_duplicate (machine_mode mo
 rtx
 gen_vec_duplicate (machine_mode mode, rtx x)
 {
-  if (valid_for_const_vec_duplicate_p (mode, x))
+  if (valid_for_const_vector_p (mode, x))
     return gen_const_vec_duplicate (mode, x);
   return gen_rtx_VEC_DUPLICATE (mode, x);
 }
--- gcc/optabs.c.jj     2017-12-20 20:40:12.000000000 +0100
+++ gcc/optabs.c        2017-12-21 10:01:43.719061449 +0100
@@ -377,7 +377,7 @@ expand_vector_broadcast (machine_mode vm
 
   gcc_checking_assert (VECTOR_MODE_P (vmode));
 
-  if (valid_for_const_vec_duplicate_p (vmode, op))
+  if (valid_for_const_vector_p (vmode, op))
     return gen_const_vec_duplicate (vmode, op);
 
   icode = optab_handler (vec_duplicate_optab, vmode);
--- gcc/simplify-rtx.c.jj       2017-12-21 09:43:24.630981321 +0100
+++ gcc/simplify-rtx.c  2017-12-21 10:03:39.542593616 +0100
@@ -1768,7 +1768,7 @@ 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)
+         if (!x || !valid_for_const_vector_p (mode, x))
            return 0;
          RTVEC_ELT (v, i) = x;
        }
@@ -4030,7 +4030,7 @@ 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)
+         if (!x || !valid_for_const_vector_p (mode, x))
            return 0;
          RTVEC_ELT (v, i) = x;
        }
@@ -4041,11 +4041,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);
@@ -6268,7 +6268,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-21 09:58:50.168261214 
+0100
+++ gcc/testsuite/gfortran.dg/pr82973.f90       2017-12-21 09:58:50.168261214 
+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

Reply via email to