This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, i386]: PR target/20421: frndint patterns clobber flags, taken
- From: Uros Bizjak <uros at kss-loka dot si>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 04 Apr 2005 13:36:00 +0200
- Subject: [PATCH, i386]: PR target/20421: frndint patterns clobber flags, taken
Hello!
This patch models FLAGS_REG clobbering of frndint patterns in
(hopefully) the right way. This is a minimum patch that implements
splitting of frndint patterns in exactly the same way as fix_trunc*
(fistp) patterns are handled. As fistp and frndint patterns both need a
mode control word calculation, this patch implements the approach that
was used to fix PR target/12308 for fix_trunc* patterns.
Patch was regtested on i686-pc-linux-gnu, c and c++. Additionally,
povray-3.50c was built with "-mfpmath=387 -ffast-math
-D__NO_MATH_INLINES" and the results of povbench benchmark run were
checked for correctnes.
2005-04-04 Uros Bizjak <uros@kss-loka.si>
PR target/20421
* config/i386/i386.md (frndintxf2_floor, frndintxf2_ceil)
(frndintxf2_trunc, frndintxf2_mask_pm): Add FLAGS_REG clobber.
Allocate local stack slots here. Set ix86_optimize_mode_switching.
flag here. Implement using define_insn_and_split.
(frndintxf2_floor_i387, frndintxf2_ceil_i387, frndintxf2_trunc_i387)
(frndintxf2_mask_pm_i387): New insn patterns.
(floorsf2, floordf2, floorxf2): Remove local stack slot allocations.
Do not set ix86_optimize_mode_switching flag.
(ceilsf2, ceildf2, ceilxf2): Same.
(btruncsf2, btruncdf2, btruncxf2): Same.
(nearbyintsf2, nearbyintdf2, nearbyintxf2): Same.
Uros.
Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.622
diff -u -p -r1.622 i386.md
--- i386.md 1 Apr 2005 03:42:48 -0000 1.622
+++ i386.md 4 Apr 2005 09:46:42 -0000
@@ -16351,7 +16351,33 @@
DONE;
})
-(define_insn "frndintxf2_floor"
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_floor"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_FLOOR))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ ix86_optimize_mode_switching = 1;
+
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "floor")
+ (set_attr "mode" "XF")])
+
+(define_insn "frndintxf2_floor_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_FLOOR))
@@ -16364,6 +16390,16 @@
(set_attr "i387_cw" "floor")
(set_attr "mode" "XF")])
+(define_expand "floorxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "floordf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16373,13 +16409,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_floor (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16394,34 +16426,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_floor (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "floorxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_ceil"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_CEIL))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "ceil")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_ceil"
+(define_insn "frndintxf2_ceil_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_CEIL))
@@ -16434,6 +16473,16 @@
(set_attr "i387_cw" "ceil")
(set_attr "mode" "XF")])
+(define_expand "ceilxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "ceildf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16443,13 +16492,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_ceil (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16464,34 +16509,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_ceil (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "ceilxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_trunc"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_TRUNC))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "trunc")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_trunc"
+(define_insn "frndintxf2_trunc_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_TRUNC))
@@ -16504,6 +16556,16 @@
(set_attr "i387_cw" "trunc")
(set_attr "mode" "XF")])
+(define_expand "btruncxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "btruncdf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16513,13 +16575,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_trunc (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16534,34 +16592,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_trunc (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "btruncxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_mask_pm"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_MASK_PM))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "mask_pm")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_mask_pm"
+(define_insn "frndintxf2_mask_pm_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_MASK_PM))
@@ -16574,6 +16639,17 @@
(set_attr "i387_cw" "mask_pm")
(set_attr "mode" "XF")])
+(define_expand "nearbyintxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
+
+ DONE;
+})
+
(define_expand "nearbyintdf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16583,13 +16659,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_mask_pm (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16604,34 +16676,14 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_mask_pm (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "nearbyintxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
-
- emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
- op2, op3));
- DONE;
-})
-
;; Block operation instructions