alpha failure on 920810-1

Richard Henderson rth@cygnus.com
Mon Apr 27 01:41:00 GMT 1998


Transforming 

    (insn 9 8 10 (set (reg:DF 69)
            (eq:DF (reg/v:DF 68)
                (const_double:DF (cc0) 0 0))) -1 (nil)
        (nil))
    
    (jump_insn 10 9 12 (set (pc)
            (if_then_else (eq (reg:DF 69)
                    (const_double:DF (cc0) 0 0))
                (label_ref 13)
                (pc))) 204 {minsf3+1} (nil)
        (nil))
    
    (insn 12 10 13 (set (reg/v:DF 68)
            (const_double:DF (cc0) 0 0)) -1 (nil)
        (nil))
    
    (code_label 13 12 15 2 "")
    
to 

    (insn 25 23 15 (set (reg/v:DF 68)
            (if_then_else:DF (ne (reg:DF 68)
                    (const_double:DF (cc0) 0 0))
                (reg:DF 48 $f16)
                (reg:DF 72))) -1 (nil)
        (nil))

is not valid on Alpha.  The reason is that the limited comparison
done by the conditional move does not follow all of the IEEE rules
that the comparision insn does, but rather simply test that the
register has no bits set.

The correct transformation would be to retain the compare and base
the conditional move off of that:

    (insn 9 8 10 (set (reg:DF 69)
            (eq:DF (reg/v:DF 68)
                (const_double:DF (cc0) 0 0))) -1 (nil)
        (nil))

    (insn 25 23 15 (set (reg/v:DF 68)
            (if_then_else:DF (ne (reg:DF 69)
                    (const_double:DF (cc0) 0 0))
                (reg:DF 48 $f16)
                (reg:DF 72))) -1 (nil)
        (nil))

The following patch modifies get_condition to recognize this situation,
i.e. compares in an FP mode and a branch in VOIDmode, and to prevent
the two operations from being merged.

I have no idea if this is reasonable for other CCmode-less platforms.

Comments?


r~



Mon Apr 27 01:27:53 1998  Richard Henderson  <rth@cygnus.com>

	* loop.c (get_condition): If comparision insn does the cmp in an
	FP mode, and the jump insn does the cmp in VOIDmode, don't combine.


Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.44
diff -c -p -d -r1.44 loop.c
*** loop.c	1998/04/25 16:09:23	1.44
--- loop.c	1998/04/27 08:27:35
*************** get_condition (jump, earliest)
*** 6961,6966 ****
--- 6961,6967 ----
    rtx op0, op1;
    int reverse_code = 0;
    int did_reverse_condition = 0;
+   enum machine_mode mode;
  
    /* If this is not a standard conditional jump, we can't parse it.  */
    if (GET_CODE (jump) != JUMP_INSN
*************** get_condition (jump, earliest)
*** 6968,6973 ****
--- 6969,6975 ----
      return 0;
  
    code = GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 0));
+   mode = GET_MODE (XEXP (SET_SRC (PATTERN (jump)), 0));
    op0 = XEXP (XEXP (SET_SRC (PATTERN (jump)), 0), 0);
    op1 = XEXP (XEXP (SET_SRC (PATTERN (jump)), 0), 1);
  
*************** get_condition (jump, earliest)
*** 7084,7089 ****
--- 7086,7103 ----
  
        if (x)
  	{
+ 	  /* A separate fp comparision instruction may follow IEEE rules that
+ 	     the jump comparision does not.  Define this case to be when the
+ 	     jump is in VOIDmode and the comparison isn't.  */
+ 	  if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
+ 	      && ! flag_fast_math
+ 	      && mode == VOIDmode && FLOAT_MODE_P (GET_MODE (x)))
+ 	    {
+ 	      did_reverse_condition ^= reverse_code;
+ 	      reverse_code = 0;
+ 	      break;
+ 	    }
+ 
  	  if (GET_RTX_CLASS (GET_CODE (x)) == '<')
  	    code = GET_CODE (x);
  	  if (reverse_code)



More information about the Gcc mailing list