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> 2007-08-23 Richard Guenther <rguenther@suse.de>
* tree-pretty-print.c (dump_generic_node): Annotate * 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, ...@@ -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); ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
/* Do fcomi/sahf based test when profitable. */ /* 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) && (bypass_code == UNKNOWN || bypass_test)
&& (second_code == UNKNOWN || second_test) && (second_code == UNKNOWN || second_test))
&& ix86_fp_comparison_arithmetics_cost (code) > cost)
{ {
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
tmp);
if (TARGET_CMOVE) if (TARGET_CMOVE)
{ emit_insn (tmp);
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
tmp);
emit_insn (tmp);
}
else else
{ {
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1); gcc_assert (TARGET_SAHF);
tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
if (!scratch) if (!scratch)
scratch = gen_reg_rtx (HImode); scratch = gen_reg_rtx (HImode);
emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2)); tmp2 = gen_rtx_CLOBBER (VOIDmode, scratch);
emit_insn (gen_x86_sahf_1 (scratch));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, tmp2)));
} }
/* The FP codes work out to act like unsigned. */ /* The FP codes work out to act like unsigned. */
...@@ -11717,8 +11715,7 @@ ix86_expand_branch (enum rtx_code code, rtx label) ...@@ -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 /* Check whether we will use the natural sequence with one jump. If
so, we can expand jump early. Otherwise delay expansion by so, we can expand jump early. Otherwise delay expansion by
creating compound insn to not confuse optimizers. */ creating compound insn to not confuse optimizers. */
if (bypass_code == UNKNOWN && second_code == UNKNOWN if (bypass_code == UNKNOWN && second_code == UNKNOWN)
&& TARGET_CMOVE)
{ {
ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1, ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
gen_rtx_LABEL_REF (VOIDmode, label), gen_rtx_LABEL_REF (VOIDmode, label),
......
...@@ -925,6 +925,34 @@ ...@@ -925,6 +925,34 @@
] ]
(const_string "XF")))]) (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" (define_insn "*cmpfp_xf"
[(set (match_operand:HI 0 "register_operand" "=a") [(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI (unspec:HI
...@@ -938,6 +966,27 @@ ...@@ -938,6 +966,27 @@
(set_attr "unit" "i387") (set_attr "unit" "i387")
(set_attr "mode" "XF")]) (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>" (define_insn "*cmpfp_<mode>"
[(set (match_operand:HI 0 "register_operand" "=a") [(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI (unspec:HI
...@@ -951,6 +1000,27 @@ ...@@ -951,6 +1000,27 @@
(set_attr "unit" "i387") (set_attr "unit" "i387")
(set_attr "mode" "<MODE>")]) (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" (define_insn "*cmpfp_u"
[(set (match_operand:HI 0 "register_operand" "=a") [(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI (unspec:HI
...@@ -971,6 +1041,34 @@ ...@@ -971,6 +1041,34 @@
] ]
(const_string "XF")))]) (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>" (define_insn "*cmpfp_<mode>"
[(set (match_operand:HI 0 "register_operand" "=a") [(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI (unspec:HI
...@@ -988,6 +1086,33 @@ ...@@ -988,6 +1086,33 @@
(set_attr "fp_int_src" "true") (set_attr "fp_int_src" "true")
(set_attr "mode" "<MODE>")]) (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 ;; FP compares, step 2
;; Move the fpsw to ax. ;; 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> 2007-08-23 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/fprinf-1.c: Adjust patterns. * 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