From mboxrd@z Thu Jan 1 00:00:00 1970 From: Richard Henderson To: egcs@cygnus.com Subject: alpha failure on 920810-1 Date: Mon, 27 Apr 1998 01:41:00 -0000 Message-id: <19980427014147.34497@dot.cygnus.com> X-SW-Source: 1998-04/msg01063.html 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 * 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)