This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
i386 fp compares fix
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Subject: i386 fp compares fix
- From: Jan Hubicka <jh at suse dot cz>
- Date: Fri, 8 Sep 2000 14:43:17 +0200
Hi
The gcc crashes quite mysteriously while compiling bb demo on refusing fp
comparison instructions created in rtl generation pass. The problem is partly
in fp_jcc_? patterns, that should accept memory for CCFP mode comparison, but
they don't since compare code in the IF_THEN_ELSE is always VOIDmode, so I've
changed them to use SELECT_CC_MODE based test instead.
This didn't helped in the all cases, since SELECT_CC_MODE works bit differently
from the expanders, that does use ix86_fp_compare_mode. The main difference is
that ix86_fp_compare_mode returns always CCFPmode in fast_math, but
SELECT_CC_MODE don't. It seems to be correct to modify SELECT_CC_MODE to use
ix86_fp_compare_mode.
The ix86_fp_compare_mode works in strage way too, since it first computes
unordered and then does:
/* ??? If we knew whether invalid-operand exceptions were masked,
we could rely on fcom to raise an exception and take care of
NaNs. But we don't. We could know this from c99 math pragmas. */
if (TARGET_IEEE_FP)
unordered = 1;
So unordered is always 1 for non -ffast-math programs. Isn't that somewhat
overactive?
Honza
Thu Mar 17 00:23:24 CET 2005 Jan Hubicka <jh@suse.cz>
* i386.md (jp_jcc_3, jp_jcc_4): Use SELECT_CC_MODE instead
of CCmode matcher.
* i386.c (ix86_fp_compare_mode): Make global.
* i386-protos.h (ix86_fp_compare_mode): Declare.
*** /c/egcs/gcc/config/i386/i386.md Thu Sep 7 13:32:40 2000
--- i386.md Mon Aug 16 12:42:45 2004
***************
*** 8125,8131 ****
(define_insn "*fp_jcc_3"
[(set (pc)
! (if_then_else (match_operator:CCFP 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(label_ref (match_operand 3 "" ""))
--- 8125,8131 ----
(define_insn "*fp_jcc_3"
[(set (pc)
! (if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(label_ref (match_operand 3 "" ""))
***************
*** 8136,8147 ****
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_4"
[(set (pc)
! (if_then_else (match_operator:CCFP 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(pc)
--- 8136,8149 ----
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
+ && (SELECT_CC_MODE (GET_CODE (operands[0]), operands[1], operands[2])
+ == CCFPmode)
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_4"
[(set (pc)
! (if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(pc)
***************
*** 8152,8157 ****
--- 8154,8161 ----
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
+ && (SELECT_CC_MODE (GET_CODE (operands[0]), operands[1], operands[2])
+ == CCFPmode)
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
"#")
*** /c/egcs/gcc/config/i386/i386.c Tue Aug 29 14:04:10 2000
--- i386.c Mon Aug 16 13:04:21 2004
*************** static void put_condition_code PARAMS ((
*** 390,396 ****
int, int, FILE *));
static enum rtx_code unsigned_comparison PARAMS ((enum rtx_code code));
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 enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
rtx *, rtx *));
static rtx gen_push PARAMS ((rtx));
--- 390,395 ----
*************** ix86_expand_int_compare (code, op0, op1)
*** 4574,4580 ****
/* Figure out whether to use ordered or unordered fp comparisons.
Return the appropriate mode to use. */
! static enum machine_mode
ix86_fp_compare_mode (code)
enum rtx_code code;
{
--- 4573,4579 ----
/* Figure out whether to use ordered or unordered fp comparisons.
Return the appropriate mode to use. */
! enum machine_mode
ix86_fp_compare_mode (code)
enum rtx_code code;
{
*** /c/egcs/gcc/config/i386/i386-protos.h Tue Aug 29 14:04:08 2000
--- i386-protos.h Mon Aug 16 13:03:26 2004
*************** extern int ix86_adjust_cost PARAMS ((rtx
*** 123,128 ****
--- 123,129 ----
extern void ix86_sched_init PARAMS ((FILE *, int));
extern int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int, int));
extern int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
+ extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
#ifdef TREE_CODE
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
*** /c/egcs/gcc/config/i386/i386.h Thu Sep 7 13:32:28 2000
--- i386.h Mon Aug 16 13:03:01 2004
*************** while (0)
*** 2281,2287 ****
#define SELECT_CC_MODE(OP,X,Y) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
! ? (OP) == EQ || (OP) == NE ? CCFPUmode : CCFPmode \
: (OP) == LE || (OP) == GT ? CCmode \
: (Y) != const0_rtx ? CCmode \
: (OP) == EQ || (OP) == NE ? CCZmode : CCNOmode)
--- 2281,2287 ----
#define SELECT_CC_MODE(OP,X,Y) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
! ? ix86_fp_compare_mode (OP) \
: (OP) == LE || (OP) == GT ? CCmode \
: (Y) != const0_rtx ? CCmode \
: (OP) == EQ || (OP) == NE ? CCZmode : CCNOmode)