This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
i386.md: fp_jcc_3 and TARGET_CMOVE
- To: gcc-patches at gcc dot gnu dot org
- Subject: i386.md: fp_jcc_3 and TARGET_CMOVE
- From: Clinton Popetz <cpopetz at cygnus dot com>
- Date: Wed, 31 May 2000 12:18:27 -0500
Compiling the following:
int
foo(double st)
{
if (st)
return 0;
}
with -march=i686 -O1 -ffast-math will give an ICE. We'll get:
(jump_insn 12 11 29 (parallel[
(set (pc)
(if_then_else (eq:CCFP (reg/v:DF 8 st(0))
(mem/u:DF (symbol_ref/u:SI ("*.LC0")) 0))
(label_ref 21)
(pc)))
(clobber (reg:CCFP 18 fpsr))
(clobber (reg:CCFP 17 flags))
(clobber (reg:HI 0 ax))
] ) 257 {*fp_jcc_3} (insn_list 4 (insn_list 4 (nil)))
(expr_list:REG_DEAD (reg/v:DF 8 st(0))
(expr_list:REG_UNUSED (reg:CCFP 18 fpsr)
(expr_list:REG_UNUSED (reg:CCFP 17 flags)
(nil)))))
which won't be split until final. Then ix86_prepare_fp_compare_args
will see that ix86_use_fcomi_compare returns true and try to call
force_reg on the MEM, which we can't do that late.
I'm not sure of a good place to fix this. The below patch works for
me. Alternatively, ix86_use_fcomi_compare could be modified to check
the operands and return false if we need a new reg and no_new_pseudos
is set.
-Clint
Wed May 31 12:03:25 2000 Clinton Popetz <cpopetz@cygnus.com>
* config/i386/i386.c (ix86_use_fcomi_compare): Make global.
* config/i386/i386-protos.h (ix86_use_fcomi_compare): Declare.
* config/i386/i386.md (*fp_jcc_3): Require the second operand
to be a REG if we can use FCOMI.
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386-protos.h,v
retrieving revision 1.19
diff -c -2 -p -r1.19 i386-protos.h
*** i386-protos.h 2000/04/27 14:56:46 1.19
--- i386-protos.h 2000/05/31 16:45:44
*************** extern int ix86_unary_operator_ok PARAMS
*** 100,103 ****
--- 100,104 ----
extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
extern rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx));
+ extern int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx));
extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
Index: i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.159
diff -c -2 -p -r1.159 i386.c
*** i386.c 2000/04/27 14:56:46 1.159
--- i386.c 2000/05/31 16:45:47
*************** static enum rtx_code unsigned_comparison
*** 393,397 ****
static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
static enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
- static int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
rtx *, rtx *));
--- 393,396 ----
*************** ix86_fp_compare_mode (code)
*** 4540,4544 ****
/* Return true if we should use an FCOMI instruction for this fp comparison. */
! static int
ix86_use_fcomi_compare (code)
enum rtx_code code;
--- 4539,4543 ----
/* Return true if we should use an FCOMI instruction for this fp comparison. */
! int
ix86_use_fcomi_compare (code)
enum rtx_code code;
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.156
diff -c -2 -p -r1.156 i386.md
*** i386.md 2000/05/27 20:23:15 1.156
--- i386.md 2000/05/31 16:45:51
***************
*** 7154,7158 ****
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
! && GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
--- 7154,7160 ----
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
! && GET_MODE (operands[1]) == GET_MODE (operands[2])
! && (GET_CODE (operands[2]) == REG ||
! !ix86_use_fcomi_compare (GET_CODE (operands[0])))"
"#")