https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109274

Andrew Macleod <amacleod at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #54743|0                           |1
        is obsolete|                            |

--- Comment #12 from Andrew Macleod <amacleod at redhat dot com> ---
Created attachment 54775
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54775&action=edit
new patch

OK, I think I have finally got to the root of the problem.

When trying to communicate cases where the operands of a stmt are symbolically
equivalent, it needed a bit more effort.

compute_operand is the controlling routine, and if op1 and op2 were the same
symbol, it would create a new relation record for op1 == op2 and pass it to
compute_operand_1 and/or compute_operand_2.

The problem is threefold.
1 - for floating point and such, op1 == op2 requires checking that there is no
NAN, which wasn't happening.
2 - Because we cant make that assumption, creating a relation record and
passing it up the GORI chain is incorrect.  Other statements are going to get
that record and use it during their calculation when in fact, we haven't proven
op1 == op2.
3 - We were evaluating the relation of op1 == op2 BEFORE processing the
statement, and utilizing it.  so given:
  if (x != x)
we were creating an x == x record for the stmt, and passing it as (potentially
incorrect) fact down the chain. This exposes the duality of trying to use the
record to represent both the relation between op1 and op2, vs the symbolic
nature of that relation on just the individual statement.

This patch incorporates the original patch where we stop sanitizing
value_relation records, and then fixes the compute_operand sequences.

Instead of creating the record in compute_operand and passing it on, the work
is broken down in compute_operand_1 and compute_operand_2 where we can separate
the current stmt info from what is passed to the next statement.

If the relation record between op1 and op2 does not already exist, and op1 and
op2 are the same symbol, then we pass op1 == op2 locally to the handler for
opX_range, but it does not travel any further than that. This keeps the context
local and will allow the statement to recognize that op1 and op2 are the same
value without impacting other statements, nor introducing side effects.

Before proceeding to the next statement in the chain, we query the handler for
a relation between op1 and op2 (which uses their respective ranges), and if
there is one, a new record is created and passed up the chain.

This is functionally correct because
  if (x != x)
      or
  if (x == x)
will look at the ranges for x, and the floating point operator for
NE_EXPR/EQ_EXPR uses those ranges to determine if there really is a relation
and passes the appropriate result up the chain.

Checked the problematic tests and seems fine.   Full bootstrap/Testing running
over night.

Reply via email to