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
This commit is contained in:
Richard Henderson 2005-01-22 15:07:53 -08:00 committed by Richard Henderson
parent b8f0658696
commit a059cdb863
3 changed files with 58 additions and 7 deletions

View File

@ -1,3 +1,14 @@
2005-01-22 Richard Henderson <rth@redhat.com>
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 <rth@redhat.com>
* config/i386/i386.md (smaxsf3): Fix mnemonic typo.

View File

@ -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))

View File

@ -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"