Commit 1406ee90 by Uros Bizjak Committed by Uros Bizjak

re PR target/17390 (missing floating point compare optimization)

	PR target/17390
	* config/i386/i386.c (ix86_expand_fp_compare): Expand fp comparison to
	fake fcomi i387 instruction for !TARGET_CMOVE.
	(ix86_expand_branch): Expand natural sequence with one jump for
	all targets, not only TARGET_CMOVE.
	* config/i386/i386.md (*cmpfp_0_cc): New define_insn_and_split
	pattern to implement fake fcomi sequence.  Split instruction after
	reload to correct compare sequences.
	(*cmpfp_xf_cc): Ditto.
	(*cmpfp_<mode>_cc): Ditto.
	(*cmpfp_u_cc): Ditto.
	(*cmpfp_<mode>_cc): Ditto.

testsuite/ChangeLog:

	PR target/17390
	* gcc.target/i386/pr17390.c: New test.

From-SVN: r127742
parent 9f7b7ba4
2007-08-23 Uros Bizjak <ubizjak@gmail.com>
PR target/17390
* config/i386/i386.c (ix86_expand_fp_compare): Expand fp comparison to
fake fcomi i387 instruction for !TARGET_CMOVE.
(ix86_expand_branch): Expand natural sequence with one jump for
all targets, not only TARGET_CMOVE.
* config/i386/i386.md (*cmpfp_0_cc): New define_insn_and_split
pattern to implement fake fcomi sequence. Split instruction after
reload to correct compare sequences.
(*cmpfp_xf_cc): Ditto.
(*cmpfp_<mode>_cc): Ditto.
(*cmpfp_u_cc): Ditto.
(*cmpfp_<mode>_cc): Ditto.
2007-08-23 Richard Guenther <rguenther@suse.de>
* tree-pretty-print.c (dump_generic_node): Annotate
......
......@@ -11471,26 +11471,24 @@ ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch,
ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
/* Do fcomi/sahf based test when profitable. */
if ((TARGET_CMOVE || TARGET_SAHF)
if (ix86_fp_comparison_arithmetics_cost (code) > cost
&& (bypass_code == UNKNOWN || bypass_test)
&& (second_code == UNKNOWN || second_test)
&& ix86_fp_comparison_arithmetics_cost (code) > cost)
&& (second_code == UNKNOWN || second_test))
{
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
tmp);
if (TARGET_CMOVE)
{
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
tmp);
emit_insn (tmp);
}
emit_insn (tmp);
else
{
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
gcc_assert (TARGET_SAHF);
if (!scratch)
scratch = gen_reg_rtx (HImode);
emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
emit_insn (gen_x86_sahf_1 (scratch));
tmp2 = gen_rtx_CLOBBER (VOIDmode, scratch);
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, tmp2)));
}
/* The FP codes work out to act like unsigned. */
......@@ -11717,8 +11715,7 @@ ix86_expand_branch (enum rtx_code code, rtx label)
/* Check whether we will use the natural sequence with one jump. If
so, we can expand jump early. Otherwise delay expansion by
creating compound insn to not confuse optimizers. */
if (bypass_code == UNKNOWN && second_code == UNKNOWN
&& TARGET_CMOVE)
if (bypass_code == UNKNOWN && second_code == UNKNOWN)
{
ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
gen_rtx_LABEL_REF (VOIDmode, label),
......
......@@ -925,6 +925,34 @@
]
(const_string "XF")))])
(define_insn_and_split "*cmpfp_0_cc"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP
(match_operand 1 "register_operand" "f")
(match_operand 2 "const0_operand" "X")))
(clobber (match_operand:HI 0 "register_operand" "=a"))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& TARGET_SAHF && !TARGET_CMOVE
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:HI
[(compare:CCFP (match_dup 1)(match_dup 2))]
UNSPEC_FNSTSW))
(set (reg:CC FLAGS_REG)
(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
""
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
(const_string "SF")
(match_operand:DF 1 "" "")
(const_string "DF")
]
(const_string "XF")))])
(define_insn "*cmpfp_xf"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI
......@@ -938,6 +966,27 @@
(set_attr "unit" "i387")
(set_attr "mode" "XF")])
(define_insn_and_split "*cmpfp_xf_cc"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP
(match_operand:XF 1 "register_operand" "f")
(match_operand:XF 2 "register_operand" "f")))
(clobber (match_operand:HI 0 "register_operand" "=a"))]
"TARGET_80387
&& TARGET_SAHF && !TARGET_CMOVE"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:HI
[(compare:CCFP (match_dup 1)(match_dup 2))]
UNSPEC_FNSTSW))
(set (reg:CC FLAGS_REG)
(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
""
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "XF")])
(define_insn "*cmpfp_<mode>"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI
......@@ -951,6 +1000,27 @@
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
(define_insn_and_split "*cmpfp_<mode>_cc"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP
(match_operand:X87MODEF12 1 "register_operand" "f")
(match_operand:X87MODEF12 2 "nonimmediate_operand" "fm")))
(clobber (match_operand:HI 0 "register_operand" "=a"))]
"TARGET_80387
&& TARGET_SAHF && !TARGET_CMOVE"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:HI
[(compare:CCFP (match_dup 1)(match_dup 2))]
UNSPEC_FNSTSW))
(set (reg:CC FLAGS_REG)
(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
""
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
(define_insn "*cmpfp_u"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI
......@@ -971,6 +1041,34 @@
]
(const_string "XF")))])
(define_insn_and_split "*cmpfp_u_cc"
[(set (reg:CCFPU FLAGS_REG)
(compare:CCFPU
(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")))
(clobber (match_operand:HI 0 "register_operand" "=a"))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& TARGET_SAHF && !TARGET_CMOVE
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:HI
[(compare:CCFPU (match_dup 1)(match_dup 2))]
UNSPEC_FNSTSW))
(set (reg:CC FLAGS_REG)
(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
""
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
(const_string "SF")
(match_operand:DF 1 "" "")
(const_string "DF")
]
(const_string "XF")))])
(define_insn "*cmpfp_<mode>"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI
......@@ -988,6 +1086,33 @@
(set_attr "fp_int_src" "true")
(set_attr "mode" "<MODE>")])
(define_insn_and_split "*cmpfp_<mode>_cc"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP
(match_operand 1 "register_operand" "f")
(match_operator 3 "float_operator"
[(match_operand:X87MODEI12 2 "memory_operand" "m")])))
(clobber (match_operand:HI 0 "register_operand" "=a"))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& TARGET_SAHF && !TARGET_CMOVE
&& TARGET_USE_<MODE>MODE_FIOP
&& (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:HI
[(compare:CCFP
(match_dup 1)
(match_op_dup 3 [(match_dup 2)]))]
UNSPEC_FNSTSW))
(set (reg:CC FLAGS_REG)
(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
""
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "fp_int_src" "true")
(set_attr "mode" "<MODE>")])
;; FP compares, step 2
;; Move the fpsw to ax.
......
2007-08-23 Uros Bizjak <ubizjak@gmail.com>
PR target/17390
* gcc.target/i386/pr17390.c: New test.
2007-08-23 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/fprinf-1.c: Adjust patterns.
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -ffast-math" } */
double sgn (double __x)
{
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0);
}
/* { dg-final { scan-assembler-times "fnstsw" 1 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment