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

--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jeff Law <[email protected]>:

https://gcc.gnu.org/g:af0cf36fb47a704a02dd2ead5f8db5d140e45351

commit r17-3306-gaf0cf36fb47a704a02dd2ead5f8db5d140e45351
Author: Shreya Munnangi <[email protected]>
Date:   Fri Aug 14 14:53:34 2026 -0600

    [PATCH][RISC-V][PR rtl-optimization/125731] Improving sequences for
conditional xor with a constant

    This is Shreya's work to address pr125731.  I did some testing around this
to
    verify riscv64-elf and riscv32-elf are happy.  Testing on the K1/K3/c920
will
    fire up tonight, but not expecting significant issues there.

    --

    In PR125731,

    We are generating inefficient sequences for conditional xor with a
    constant. Given this testcase,

    long fun_not1 (int a, long b)
    {
        if (!(a & 1))
            b ^= 8;
        return b;
    }

    We are generating:

    fun_not1:
            andi    a5,a0,1
            mv      a0,a1
            bne     a5,zero,.L3
            xori    a0,a1,8
    .L3:
            ret

    However, this can be simplified into a branchless sequence.  One such
sequence:

           andi    a5,a0,1
           li      a4,8
           czero.nez       a5,a4,a5
           xor     a0,a1,a5
           ret

    Another form:

            andi    a0,a0,1
            seqz    t0,a0
            slli    t1,t0,3
            xor     a0,a1,t1
            ret
    -- I've edited Shreya's explanation a bit --

    The if-converter's get_base_reg currently returns NULL if presented with a
    constant and that inhibits if conversion through the noce_try_cond_arith
which
    can generate more efficient sequences than generalized conditional moves. 
So
    the first thing we need to do is support constants in get_base_reg.

    The return value from get_base_reg is used to generate a new pseudo
register,
    so if get_base_reg starts returning constants, then we're going to run into
    problems generating the new pseudo because constants are VOIDmode.

    I changed the name to get_base_reg_or_constant to reflect that we are also
    handling constants, not just returning the base registers of a reg or
subreg.
    The point where the caller uses the return value to get a mode for the new
    pseudo has been changed to get the mode from the other operand of the
binary
    operation.

    Those changes are sufficient to if-convert this example as well as enabling
    more efficient code generation for other cases where we have a conditional
    operation where one operand is a constant.

    Although the newly generated sequence is the same number of insns, it will
be
    much faster if the conditional branch is not easily predictable.

            PR rtl-optimization/125731
    gcc/
            * ifcvt.cc (get_base_reg_or_const): Renamed from get_base_reg.
            Handle CONST_INTs too.
            (noce_try_cond_arith): Use get_base_reg_or_const.  Handle case
where
            get_base_reg_or_const returns a CONST_INT.

    gcc/testsuite
            * gcc.target/riscv/pr125731.c: New test.

Reply via email to