This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Optimize "a || b" into "(a | b) != 0"
- From: Roger Sayle <roger at eyesopen dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 18 May 2002 00:48:30 -0600 (MDT)
- Subject: Re: [PATCH] Optimize "a || b" into "(a | b) != 0"
On 18 May 2002, Alexandre Oliva wrote:
> On May 18, 2002, Roger Sayle <roger@eyesopen.com> wrote:
>
> > The following patch converts "(a != 0) || (b != 0)" into the
> > equivalent "(a | b) != 0" and converts "(a == 0) && (b == 0)"
> > into the equivalent "(a | b) == 0". These transformations are
> > only applied when BRANCH_COST >= 2 and "b" can be evaluated
> > unconditionally and its operands are simple.
>
> These transformations are only valid if b is guaranteed not to have
> side effects nor trap. Think short circuiting, when the first test
> guarantees the second won't invoke undefined behavior. If you apply
> the transformation, you may break valid programs, unless there's some
> code not shown in the patch context that rules out such complex
> expressions.
Indeed there is. The first test in the function fold_truthop
begins "if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))".
The actual hunk of the patch is strategically placed in a block
where we'd already committed to evaluating both left and right
subexpressions and then using TRUTH_AND_EXPR or TRUTH_OR_EXPR
to combine the results to implement the original TRUTH_ANDIF_EXPR
or TRUTH_ORIF_EXPR.
The comment immdiately preceding the hunk of the patch reads:
/* If the RHS can be evaluated unconditionally and its operands are
simple, it wins to evaluate the RHS unconditionally on machines
with expensive branches. In this case, this isn't a comparison
that can be merged. Avoid doing this if the RHS is a floating-point
comparison since those can trap. */
So even trapping floating point comparisons have been ruled out,
which is also the reason my patch didn't explicitly have to check
for INTEGRAL_TYPE_P.
Roger
--