"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