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

--- Comment #15 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Xiong Hu Luo <luo...@gcc.gnu.org>:

https://gcc.gnu.org/g:9222481ffc69a6c0b73ec81e1bf04289fa3db0ed

commit r12-4757-g9222481ffc69a6c0b73ec81e1bf04289fa3db0ed
Author: Xionghu Luo <luo...@linux.ibm.com>
Date:   Wed Oct 27 21:21:20 2021 -0500

    rs6000: Fix wrong code generation for vec_sel [PR94613]

    The vsel instruction is a bit-wise select instruction.  Using an
    IF_THEN_ELSE to express it in RTL is wrong and leads to wrong code
    being generated in the combine pass.  Per element selection is a
    subset of per bit-wise selection,with the patch the pattern is
    written using bit operations.  But there are 8 different patterns
    to define "op0 := (op1 & ~op3) | (op2 & op3)":

    (~op3&op1) | (op3&op2),
    (~op3&op1) | (op2&op3),
    (op3&op2) | (~op3&op1),
    (op2&op3) | (~op3&op1),
    (op1&~op3) | (op3&op2),
    (op1&~op3) | (op2&op3),
    (op3&op2) | (op1&~op3),
    (op2&op3) | (op1&~op3),

    The latter 4 cases does not follow canonicalisation rules, non-canonical
    RTL is invalid RTL in vregs pass.  Secondly, combine pass will swap
    (op1&~op3) to (~op3&op1) by commutative canonical, which could reduce
    it to the FIRST 4 patterns, but it won't swap (op2&op3) | (~op3&op1) to
    (~op3&op1) | (op2&op3), so this patch handles it with 4 patterns with
    different NOT op3 position and check equality inside it.

    Tested pass on P7, P8 and P9.

    gcc/ChangeLog:

    2021-10-28  Xionghu Luo  <luo...@linux.ibm.com>

            PR target/94613
            * config/rs6000/altivec.md (*altivec_vsel<mode>): Change to ...
            (altivec_vsel<mode>): ... this and update define.
            (*altivec_vsel<mode>_uns): Delete.
            (altivec_vsel<mode>2): New define_insn.
            (altivec_vsel<mode>3): Likewise.
            (altivec_vsel<mode>4): Likewise.
            * config/rs6000/rs6000-call.c (altivec_expand_vec_sel_builtin):
New.
            (altivec_expand_builtin): Call altivec_expand_vec_sel_builtin to
expand
            vel_sel.
            * config/rs6000/rs6000.c (rs6000_emit_vector_cond_expr): Use
bit-wise
            selection instead of per element.
            * config/rs6000/vector.md:
            * config/rs6000/vsx.md (*vsx_xxsel<mode>): Change to ...
            (vsx_xxsel<mode>): ... this and update define.
            (*vsx_xxsel<mode>_uns): Delete.
            (vsx_xxsel<mode>2): New define_insn.
            (vsx_xxsel<mode>3): Likewise.
            (vsx_xxsel<mode>4): Likewise.

    gcc/testsuite/ChangeLog:

    2021-10-28  Xionghu Luo  <luo...@linux.ibm.com>

            PR target/94613
            * gcc.target/powerpc/pr94613.c: New test.

Reply via email to