From a059cdb8632f1a0a64d0ae2b4ada084ab69cac5e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 22 Jan 2005 15:07:53 -0800 Subject: [PATCH] re PR target/19506 (PovRay produces wrong pictures with -mfpmath=sse -ffast-math.) PR target/19506 * config/i386/i386.md (movsfcc_1_sse_max): Use nonimmediate_operand in both compare operands. (movdfcc_1_sse_max): Likewise. (movsfcc_1_sse): Likewise. Add earlyclobber for scratch. (movdfcc_1_sse): Likewise. * config/i386/i386.c (ix86_split_sse_movcc): Emit copies into the scratch register as needed. From-SVN: r94087 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/i386/i386.c | 42 ++++++++++++++++++++++++++++++++++++++++- gcc/config/i386/i386.md | 12 ++++++------ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 263364d5f9e..10018db6472 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-01-22 Richard Henderson + + PR target/19506 + * config/i386/i386.md (movsfcc_1_sse_max): Use nonimmediate_operand + in both compare operands. + (movdfcc_1_sse_max): Likewise. + (movsfcc_1_sse): Likewise. Add earlyclobber for scratch. + (movdfcc_1_sse): Likewise. + * config/i386/i386.c (ix86_split_sse_movcc): Emit copies into the + scratch register as needed. + 2005-01-22 Richard Henderson * config/i386/i386.md (smaxsf3): Fix mnemonic typo. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index bb7d827cba2..cb6c1bab625 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9920,8 +9920,48 @@ ix86_split_sse_movcc (rtx operands[]) mode = GET_MODE (dest); vmode = GET_MODE (scratch); - emit_insn (gen_rtx_SET (VOIDmode, dest, cmp)); + /* We need to make sure that the TRUE and FALSE operands are out of the + way of the destination. Marking the destination earlyclobber doesn't + work, since we want matching constraints for the actual comparison, so + at some point we always wind up having to do a copy ourselves here. + We very much prefer the TRUE value to be in SCRATCH. If it turns out + that FALSE overlaps DEST, then we invert the comparison so that we + still only have to do one move. */ + if (rtx_equal_p (op_false, dest)) + { + enum rtx_code code; + + if (rtx_equal_p (op_true, dest)) + { + /* ??? Really ought not happen. It means some optimizer managed + to prove the operands were identical, but failed to fold the + conditional move to a straight move. Do so here, because + otherwise we'll generate incorrect code. And since they're + both already in the destination register, nothing to do. */ + return; + } + + x = gen_rtx_REG (mode, REGNO (scratch)); + emit_move_insn (x, op_false); + op_false = op_true; + op_true = x; + code = GET_CODE (cmp); + code = reverse_condition_maybe_unordered (code); + cmp = gen_rtx_fmt_ee (code, mode, XEXP (cmp, 0), XEXP (cmp, 1)); + } + else if (op_true == CONST0_RTX (mode)) + ; + else if (op_false == CONST0_RTX (mode) && !rtx_equal_p (op_true, dest)) + ; + else + { + x = gen_rtx_REG (mode, REGNO (scratch)); + emit_move_insn (x, op_true); + op_true = x; + } + + emit_insn (gen_rtx_SET (VOIDmode, dest, cmp)); dest = simplify_gen_subreg (vmode, dest, mode, 0); if (op_false == CONST0_RTX (mode)) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5ad64fafe30..32a5281acc1 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17443,7 +17443,7 @@ [(set (match_operand:SF 0 "register_operand" "=x") (if_then_else:SF (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm") - (match_operand:SF 1 "register_operand" "0")) + (match_operand:SF 1 "nonimmediate_operand" "0")) (match_dup 1) (match_dup 2)))] "TARGET_SSE_MATH" @@ -17457,9 +17457,9 @@ (match_operator:SF 4 "sse_comparison_operator" [(match_operand:SF 5 "register_operand" "0,0,0") (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")]) - (match_operand:SF 2 "reg_or_0_operand" "C,x,1") + (match_operand:SF 2 "reg_or_0_operand" "C,x,x") (match_operand:SF 3 "reg_or_0_operand" "x,C,x"))) - (clobber (match_scratch:V4SF 1 "=X,X,x"))] + (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))] "TARGET_SSE_MATH" "#" "&& reload_completed" @@ -17512,7 +17512,7 @@ [(set (match_operand:DF 0 "register_operand" "=x") (if_then_else:DF (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm") - (match_operand:DF 1 "register_operand" "0")) + (match_operand:DF 1 "nonimmediate_operand" "0")) (match_dup 1) (match_dup 2)))] "TARGET_SSE2 && TARGET_SSE_MATH" @@ -17526,9 +17526,9 @@ (match_operator:DF 4 "sse_comparison_operator" [(match_operand:DF 5 "register_operand" "0,0,0") (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")]) - (match_operand:DF 2 "reg_or_0_operand" "C,x,1") + (match_operand:DF 2 "reg_or_0_operand" "C,x,x") (match_operand:DF 3 "reg_or_0_operand" "x,C,x"))) - (clobber (match_scratch:V2DF 1 "=X,X,x"))] + (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))] "TARGET_SSE2 && TARGET_SSE_MATH" "#" "&& reload_completed" -- 2.30.2