This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Committed] PR 17853: New VECTOR_STORE_FLAG_VALUE target macro


The following patch resolves PR rtl-optimization/17853, which is an
ICE on valid compiling MMX code on mainline.  Rather than continue to
argue with Stuart Hastings as to the correct way to fix the problem,
http://gcc.gnu.org/ml/gcc-patches/2004-10/msg00339.html, it's easier
to it myself.

The core problem is that GCC now supports vector comparison operators
that return a vector of results, i.e. (eg:V8QI (reg:V8QI X) (reg:V8QI Y)).
Unfortunately, support for these new operators hasn't been added to the
RTL optimizers, that continue to transform these comparison operators as
though they returned a scalar Boolean result.   This leads to an ICE in
the attached testcase, where (eq:V8QI (foo) (foo)) is constant folded to
const1_rtx, which naturally has the wrong mode.

Stuart's proposed work-arounds were to disable all constant folding of
vector operations in combine and/or CSE.  Whilst this indeed cures the
testcase, it clearly isn't a long term solution, as ideally GCC should
eventually be able to perform constant folding on far more vector ops
than it currently does.

It turns out that just disabling the problematic simplification of
vector comparison operations (and *just* the comparision simplifications)
is a two line tweak to simplify_relational_operation in simplify-rtx.c.

However, the patch below implements a more complete solution of adding
initial support for constant folding vector comparison operations in
the RTL optimizers.  Indeed as hinted by Jan Hubicka, it introduces a
new target macro VECTOR_STORE_FLAG_VALUE that may be used by a backend
to specify the vector element to be used to represent "true" in a vector
of comparison results.  Typically, this can be defined as either
const1_rtx or constm1_rtx.

For example, my reading of the MMX documentation suggests that constm1_rtx
is appropriate for i386.h.  However, I'm unsure about interactions with
SSE and SSE2, so I'll leave it to the backend maintainers to actually
provide suitable definitions of VECTOR_STORE_FLAG_VALUE for their targets.


Comments on Stuart's testcase;  I've turned it into a compile test instead
of an execute test to still allow testing it on x86 targets without MMX
instructions (using dg-do run would fail on some matching targets).  I've
also tidied up the return type of main.  Finally, the ChangeLog entry is
corrected to list the name of the modified files relative to the location
of the ChangeLog entry (i.e. gcc.dg/foo.c, not gcc/testsuite/gcc.dg/foo.c).


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and "make dvi", and regression
tested with a top-level "make -k check" with no new failures.

Committed to mainline CVS.



2004-10-09  Roger Sayle  <roger@eyesopen.com>

	PR rtl-optimization/17853
	* simplify-rtx.c (simplify_relational_operation): Correct comment.
	Reorganize handling of comparison operations with floating point
	results (always return 0.0 even without FLOAT_STORE_FLAG_VALUE).
	Likewise, introduce support for comparison operations with vector
	result types, introducing a new VECTOR_STORE_FLAG_VALUE target macro.

	* doc/rtl.texi: Document new VECTOR_STORE_FLAG_VALUE target macro.
	* doc/tm.texi: Likewise.

2004-10-09  Stuart Hastings  <stuart@apple.com>
	    Roger Sayle  <roger@eyesopen.com>

	PR rtl-optimization/17853
	* gcc.dg/i386-mmx-5.c: New testcase.


Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.204
diff -c -3 -p -r1.204 simplify-rtx.c
*** simplify-rtx.c	9 Sep 2004 17:19:16 -0000	1.204
--- simplify-rtx.c	9 Oct 2004 15:32:25 -0000
*************** simplify_plus_minus (enum rtx_code code,
*** 2679,2685 ****

  /* Like simplify_binary_operation except used for relational operators.
     MODE is the mode of the result. If MODE is VOIDmode, both operands must
!    also be VOIDmode.

     CMP_MODE specifies in which mode the comparison is done in, so it is
     the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
--- 2679,2685 ----

  /* Like simplify_binary_operation except used for relational operators.
     MODE is the mode of the result. If MODE is VOIDmode, both operands must
!    not also be VOIDmode.

     CMP_MODE specifies in which mode the comparison is done in, so it is
     the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
*************** simplify_relational_operation (enum rtx_
*** 2699,2717 ****
    tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    if (tem)
      {
- #ifdef FLOAT_STORE_FLAG_VALUE
        if (GET_MODE_CLASS (mode) == MODE_FLOAT)
  	{
            if (tem == const0_rtx)
              return CONST0_RTX (mode);
!           else if (GET_MODE_CLASS (mode) == MODE_FLOAT)
! 	    {
! 	      REAL_VALUE_TYPE val;
! 	      val = FLOAT_STORE_FLAG_VALUE (mode);
! 	      return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
! 	    }
! 	}
  #endif

        return tem;
      }
--- 2699,2743 ----
    tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    if (tem)
      {
        if (GET_MODE_CLASS (mode) == MODE_FLOAT)
  	{
            if (tem == const0_rtx)
              return CONST0_RTX (mode);
! #ifdef FLOAT_STORE_FLAG_VALUE
! 	  {
! 	    REAL_VALUE_TYPE val;
! 	    val = FLOAT_STORE_FLAG_VALUE (mode);
! 	    return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
! 	  }
! #else
! 	  return NULL_RTX;
! #endif
! 	}
!       if (VECTOR_MODE_P (mode))
! 	{
! 	  if (tem == const0_rtx)
! 	    return CONST0_RTX (mode);
! #ifdef VECTOR_STORE_FLAG_VALUE
! 	  {
! 	    int i, units;
! 	    rtvec c;
!
! 	    rtx val = VECTOR_STORE_FLAG_VALUE (mode);
! 	    if (val == NULL_RTX)
! 	      return NULL_RTX;
! 	    if (val == const1_rtx)
! 	      return CONST1_RTX (mode);
!
! 	    units = GET_MODE_NUNITS (mode);
! 	    v = rtvec_alloc (units);
! 	    for (i = 0; i < units; i++)
! 	      RTVEC_ELT (v, i) = val;
! 	    return gen_rtx_raw_CONST_VECTOR (mode, v);
! 	  }
! #else
! 	  return NULL_RTX;
  #endif
+ 	}

        return tem;
      }
Index: doc/rtl.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/rtl.texi,v
retrieving revision 1.72
diff -c -3 -p -r1.72 rtl.texi
*** doc/rtl.texi	8 Sep 2004 18:45:21 -0000	1.72
--- doc/rtl.texi	9 Oct 2004 15:32:26 -0000
*************** Comparison operators test a relation on
*** 2028,2037 ****
  to represent a machine-dependent nonzero value described by, but not
  necessarily equal to, @code{STORE_FLAG_VALUE} (@pxref{Misc})
  if the relation holds, or zero if it does not, for comparison operators
! whose results have a `MODE_INT' mode, and
  @code{FLOAT_STORE_FLAG_VALUE} (@pxref{Misc}) if the relation holds, or
  zero if it does not, for comparison operators that return floating-point
! values.  The mode of the comparison operation is independent of the mode
  of the data being compared.  If the comparison operation is being tested
  (e.g., the first operand of an @code{if_then_else}), the mode must be
  @code{VOIDmode}.
--- 2028,2040 ----
  to represent a machine-dependent nonzero value described by, but not
  necessarily equal to, @code{STORE_FLAG_VALUE} (@pxref{Misc})
  if the relation holds, or zero if it does not, for comparison operators
! whose results have a `MODE_INT' mode,
  @code{FLOAT_STORE_FLAG_VALUE} (@pxref{Misc}) if the relation holds, or
  zero if it does not, for comparison operators that return floating-point
! values, and a vector of either @code{VECTOR_STORE_FLAG_VALUE} (@pxref{Misc})
! if the relation holds, or of zeros if it does not, for comparison operators
! that return vector results.
! The mode of the comparison operation is independent of the mode
  of the data being compared.  If the comparison operation is being tested
  (e.g., the first operand of an @code{if_then_else}), the mode must be
  @code{VOIDmode}.
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.378
diff -c -3 -p -r1.378 tm.texi
*** doc/tm.texi	6 Oct 2004 22:20:31 -0000	1.378
--- doc/tm.texi	9 Oct 2004 15:32:30 -0000
*************** instructions, or if the value generated
*** 8920,8930 ****
  @defmac FLOAT_STORE_FLAG_VALUE (@var{mode})
  A C expression that gives a nonzero @code{REAL_VALUE_TYPE} value that is
  returned when comparison operators with floating-point results are true.
! Define this macro on machine that have comparison operations that return
  floating-point values.  If there are no such operations, do not define
  this macro.
  @end defmac

  @defmac CLZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
  @defmacx CTZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
  A C expression that evaluates to true if the architecture defines a value
--- 8920,8942 ----
  @defmac FLOAT_STORE_FLAG_VALUE (@var{mode})
  A C expression that gives a nonzero @code{REAL_VALUE_TYPE} value that is
  returned when comparison operators with floating-point results are true.
! Define this macro on machines that have comparison operations that return
  floating-point values.  If there are no such operations, do not define
  this macro.
  @end defmac

+ @defmac VECTOR_STORE_FLAG_VALUE (@var{mode})
+ A C expression that gives a rtx representing the non-zero true element
+ for vector comparisons.  The returned rtx should be valid for the inner
+ mode of @var{mode} which is guaranteed to be a vector mode.  Define
+ this macro on machines that have vector comparison operations that
+ return a vector result.  If there are no such operations, do not define
+ this macro.  Typically, this macro is defined as @code{const1_rtx} or
+ @code{constm1_rtx}.  This macro may return @code{NULL_RTX} to prevent
+ the compiler optimizing such vector comparison operations for the
+ given mode.
+ @end defmac
+
  @defmac CLZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
  @defmacx CTZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
  A C expression that evaluates to true if the architecture defines a value


/* PR rtl-optimization/17853 */
/* Contributed by Stuart Hastings <stuart@apple.com> */
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -mmmx" } */
#include <mmintrin.h>
#include <stdlib.h>

__m64 global_mask;

int main()
{
    __m64 zero = _mm_setzero_si64();
    __m64 mask = _mm_cmpeq_pi8( zero, zero );
    mask = _mm_unpacklo_pi8( mask, zero );
    global_mask = mask;
    return 0;
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]