"Fix" recent povray failure with -mfpmath=sse -ffast-math
Richard Henderson
rth@redhat.com
Tue Jan 18 05:54:00 GMT 2005
On Mon, Jan 17, 2005 at 06:30:15PM +0100, Uros Bizjak wrote:
> This patch will "fix" wrong raytraced pictures from povray when
> -mfpmath=sse -ffast-math is used. It looks like there is something wrong
> with SSE compares for !TARGET_IEEE_FP.
I assume this fixes it. Though it would be a Good Thing if we could
get a reduced testcase affected by this.
I'm not sure what real benefit we get from claiming that we have GE
as a subset of the real UNGE comparison. Seems to me that we'd only
get an observable benefit from matching e.g. LT like so:
(set (match_operand:SF 0 "register_operand" "=x,x")
(lt:SF (match_operand:SF 1 "nonimmediate_operand" "0,x")
(match_operand:SF 2 "nonimmediate_operand" "x,0")))
where alternative 0 prints "lt" and alternative 1 prints "nlt".
But the fact remains that either the current mechanism or the
test above really ought to be valid when there are no NaNs in
the program. I can only assume from this that PovRay actually
does generate or consume NaNs, and that using -ffast-math is
in fact invalid.
But we can't know for sure without a reduced test case.
r~
PS: It would probably behoove PovRay to unmask floating point exceptions
such that if a NaN is generated we get a SIGFPE instead of silently doing
the wrong thing.
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.777
diff -c -p -d -r1.777 i386.c
*** i386.c 14 Jan 2005 00:33:48 -0000 1.777
--- i386.c 18 Jan 2005 05:43:32 -0000
*************** ix86_expand_fp_movcc (rtx operands[])
*** 9768,9779 ****
if (cmode != mode)
return 0;
! /* Massage condition to satisfy sse_comparison_operator. In case we
! are in non-ieee mode, try to canonicalize the destination operand
! to be first in the comparison - this helps reload to avoid extra
! moves. */
if (!sse_comparison_operator (operands[1], VOIDmode)
! || ((COMMUTATIVE_P (operands[1]) || !TARGET_IEEE_FP)
&& rtx_equal_p (operands[0], cmp_op1)))
{
tmp = cmp_op0;
--- 9768,9778 ----
if (cmode != mode)
return 0;
! /* Massage condition to satisfy sse_comparison_operator. Try
! to canonicalize the destination operand to be first in the
! comparison - this helps reload to avoid extra moves. */
if (!sse_comparison_operator (operands[1], VOIDmode)
! || (COMMUTATIVE_P (operands[1])
&& rtx_equal_p (operands[0], cmp_op1)))
{
tmp = cmp_op0;
Index: predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/predicates.md,v
retrieving revision 1.13
diff -c -p -d -r1.13 predicates.md
*** predicates.md 11 Jan 2005 21:33:14 -0000 1.13
--- predicates.md 18 Jan 2005 05:43:32 -0000
***************
*** 759,767 ****
;; predicate.
(define_special_predicate "sse_comparison_operator"
! (ior (match_code "eq,lt,le,unordered,ne,unge,ungt,ordered")
! (and (match_code "uneq,unlt,unle,ltgt,ge,gt")
! (match_test "!TARGET_IEEE_FP"))))
;; Return 1 if OP is a valid comparison operator in valid mode.
(define_predicate "ix86_comparison_operator"
--- 759,765 ----
;; predicate.
(define_special_predicate "sse_comparison_operator"
! (match_code "eq,lt,le,unordered,ne,unge,ungt,ordered"))
;; Return 1 if OP is a valid comparison operator in valid mode.
(define_predicate "ix86_comparison_operator"
More information about the Gcc-patches
mailing list