Article View: gnu.gcc.bug
Article #330GCC 2.2.2's operand_equal_p has confusing comments
From: Paul Eggert
Date: Tue, 11 Aug 1992 04:36
Date: Tue, 11 Aug 1992 04:36
108 lines
4821 bytes
4821 bytes
When I was preparing the patch that I just sent you for the bug ``GCC 2.2.2
wrongly optimizes X?X:0 to X when X is IEEE -0.0'', I was confused by the
comments for operand_equal_p. This function does not test whether two
operands will compare equal using C's == operation; it tests whether the two
operands are indistinguishable (i.e. they cannot be distinguished by any
operation e.g. because they have the same bit pattern). This distinction is
important in the case of IEEE floating point, because -0.0 and 0.0 are
distinguishable but -0.0 == 0.0; and on the other hand, two NaN values may be
indistinguishable, but NaN != NaN always. I see that this confusion leads to
some overly defensive code, where operand_equal_p sometimes reports that two
IEEE floating point values are different, even though they are bitwise
identical.
Here is a patch that clarifies the function of operand_equal_p, and removes
the overly defensive code. This patch will cause GCC 2.2.2 to generate better
code in some obscure circumstances, but the main justification for this patch
is clarity.
Also, the last changed line of this patch corrects a misspelled comment by
substituting ``if'' for ``is''.
Tue Aug 11 04:23:35 1992 Paul Eggert (eggert@twinsun.com)
* fold-const.c (operand_equal_p): Make it clear that this function
tests for indistinguishable values, not for equality as computed by
`=='; the distinction is important for IEEE NaNs and -0.0.
===================================================================
RCS file: fold-const.c,v
retrieving revision 2.2.2.2
diff -c -r2.2.2.2 fold-const.c
*** fold-const.c 1992/08/11 04:02:51 2.2.2.2
--- fold-const.c 1992/08/11 04:23:35
***************
*** 1512,1519 ****
}
}
! /* Return nonzero if two operands are necessarily equal.
! If ONLY_CONST is non-zero, only return non-zero for constants. */
int
operand_equal_p (arg0, arg1, only_const)
--- 1512,1524 ----
}
}
! /* Return nonzero if two operands are necessarily equal.
! If ONLY_CONST is non-zero, only return non-zero for constants.
! This function tests whether the operands are indistinguishable;
! it does not test whether they are equal using C's == operation.
! The distinction is important for IEEE floating point, because
! (1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
! (2) two NaNs may be indistinguishable, but NaN!=NaN. */
int
operand_equal_p (arg0, arg1, only_const)
***************
*** 1549,1566 ****
&& TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1))
return 1;
! /* Detect when real constants are equal.
! But reject weird values because we can't be sure what to do with them. */
if (TREE_CODE (arg0) == TREE_CODE (arg1)
! && TREE_CODE (arg0) == REAL_CST
! && !bcmp (&TREE_REAL_CST (arg0), &TREE_REAL_CST (arg1),
! sizeof (REAL_VALUE_TYPE))
! /* Some people say these are not necessary.
! But they do little harm, and taking them out would be risky.
! So leave them and let's not spend any more time on them--rms. */
! && !REAL_VALUE_ISINF (TREE_REAL_CST (arg0))
! && !REAL_VALUE_ISNAN (TREE_REAL_CST (arg0)))
! return 1;
if (only_const)
return 0;
--- 1554,1564 ----
&& TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1))
return 1;
! /* Detect when real constants are equal. */
if (TREE_CODE (arg0) == TREE_CODE (arg1)
! && TREE_CODE (arg0) == REAL_CST)
! return !bcmp (&TREE_REAL_CST (arg0), &TREE_REAL_CST (arg1),
! sizeof (REAL_VALUE_TYPE));
if (only_const)
return 0;
***************
*** 3040,3046 ****
/* Fold &x - &x. This can happen from &x.foo - &x.
This is unsafe for certain floats even in non-IEEE formats.
In IEEE, it is unsafe because it does wrong for NaNs.
! Also note that operand_equal_p is always false is an operand
is volatile. */
if (operand_equal_p (arg0, arg1,
--- 3038,3044 ----
/* Fold &x - &x. This can happen from &x.foo - &x.
This is unsafe for certain floats even in non-IEEE formats.
In IEEE, it is unsafe because it does wrong for NaNs.
! Also note that operand_equal_p is always false if an operand
is volatile. */
if (operand_equal_p (arg0, arg1,
Technical Details
Message-ID:
<9208110436.AA24388@farside.twinsun.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggertShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggert From: eggert@twinsun.COM (Paul Eggert) Subject: GCC 2.2.2's operand_equal_p has confusing comments Message-ID: <9208110436.AA24388@farside.twinsun.com> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 11 Aug 1992 04:36:54 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 109