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]

[RFA:] cse.c:cse_insn: Fix gcc.c-torture/compile/simd-1.c formmix-knuth-mmixware


This fixes
FAIL: gcc.c-torture/compile/simd-1.c,  -O1
FAIL: gcc.c-torture/compile/simd-1.c,  -O2
FAIL: gcc.c-torture/compile/simd-1.c,  -O3 -fomit-frame-pointer
FAIL: gcc.c-torture/compile/simd-1.c,  -O3 -g
FAIL: gcc.c-torture/compile/simd-1.c,  -Os
for mmix-knuth-mmixware.

The comment above a certain code block, at cse.c:6167 (cse_insn) says:

           If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
           narrower than M2, and both M1 and M2 are the same number of words,
           we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
           make that equivalence as well.

In simd-1.c we deal with vectors.  In this case, we have (using
names from the comment):
M1 = DI
M2 = V2SI
FOO = 268
BAR = (const_int 0)

that is, the (set ...)-insn to enter equivalence values for is:

(insn 9 8 11 0 0x4015a040 (set (subreg:DI (reg/v:V2SI 268) 0)
        (const_int 0 [0x0])) 3 {movdi} (nil)
    (expr_list:REG_EQUAL (const_vector:V2SI [
                (const_int 0 [0x0])
                (const_int 0 [0x0])
            ])
        (nil)))

and as the comment says, the code that follows is supposed to
enter the subreg-"mirroring" equivalence for each of already
known equivalences kept in a list.  One of them, with BAR =
(const_vector:V2SI [
        (const_int 0 [0x0])
        (const_int 0 [0x0])
    ])
looks something like this:

(set (reg:V2SI 268)
     (subreg:V2SI (const_vector:V2SI [(const_int 0 [0x0])
                                    (const_int 0 [0x0])]))

The problem is with simplifying that subreg, through the call
(cse.c:6212):
                new_src = simplify_gen_subreg (new_mode, elt->exp,
                                               GET_MODE (dest), byte);
where new_mode = V2SImode,
elt->exp = [BAR above],
GET_MODE (dest) = DImode

and the sanity checks in simplify_gen_subreg immediately catch
that "GET_MODE (op) != innermode && GET_MODE (op) != VOIDmode":
i.e. DImode != GET_MODE ((const_vector:V2SI ...)) && VOIDmode !=
GET_MODE ((const_vector:V2SI ...)) and then abort.

The sanity check could perhaps handle const_vector exactly like
VOIDmode constants, but the rest of the code in
simplify_gen_subreg must then also be modified to handle that
correctly.  That seems excessive.  Instead, let's not try and
enter an equivalence where the mode does not match the
destination.

The const_vector:V2SI equivalence comes from a simplified subreg
entered the same way at a previous iteration on the list of
existing equivalences, namely based on elt->exp = (const_int 0).
But since that constant is a trivial VOIDmode constant,
simplify_gen_subreg liked it and thus made up the const_vector
FOO above as a simplification of (subreg:V2SI (const_int 0))
(interpreting the (const_int 0) in DImode -- parameter innermode
in simplify_gen_subreg).

Tested mmix-knuth-mmixware, bootstrapped and tested
i686-pc-linux-gnu (except Ada) no regressions.

	* cse.c (cse_insn): When adding equivalences for subregs in
	destinations, avoid mode combinations that simplify_gen_subreg
	can't handle.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.231
diff -p -c -r1.231 cse.c
*** cse.c	10 Jul 2002 15:08:04 -0000	1.231
--- cse.c	12 Aug 2002 23:25:38 -0000
*************** cse_insn (insn, libcall_insn)
*** 6203,6208 ****
--- 6203,6215 ----
  		    && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
  		  continue;

+ 		/* For simplify_gen_subreg to accept it, the mode of the
+ 		   equivalence must be the same as the mode of the
+ 		   destination or a VOIDmode constant.  */
+ 		if (GET_MODE (elt->exp) != VOIDmode
+ 		    && GET_MODE (elt->exp) != GET_MODE (dest))
+ 		  continue;
+
  		/* Calculate big endian correction for the SUBREG_BYTE
  		   (or equivalent).  We have already checked that M1
  		   ( GET_MODE (dest) ) is not narrower than M2 (new_mode).  */

brgds, H-P


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