On 9/23/22 03:21, Tamar Christina wrote:
Hi All,

The following testcase:

int zoo1 (int a, int b, int c, int d)
{
    return (a > b ? c : d) & 1;
}

gets de-optimized by the front-end since somewhere around GCC 4.x due to a fix
that was added to fold_binary_op_with_conditional_arg.

The folding is supposed to succeed only if we have folded at least one of the
branches, however the check doesn't tests that all of the values are
non-constant.  So if one of the operators are a constant it accepts the folding.

This ends up folding

    return (a > b ? c : d) & 1;

into

    return (a > b ? c & 1 : d & 1);

and thus performing the AND twice.

change changes it to reject the folding if one of the arguments are a constant
and if the operations being performed are the same.

Secondly it adds a new match.pd rule to now also fold the opposite direction, so
it now also folds:

    return (a > b ? c & 1 : d & 1);

into

    return (a > b ? c : d) & 1;

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
and <on-goin> issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        * fold-const.cc (fold_binary_op_with_conditional_arg): Add relaxation.
        * match.pd: Add ternary constant fold rule.
        * tree-cfg.cc (verify_gimple_assign_ternary): RHS1 of a COND_EXPR isn't
        a value but an expression itself.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/if-compare_3.c: New test.

OK

jeff


Reply via email to