diff options
author | Xionghu Luo <luoxhu@linux.ibm.com> | 2021-10-27 21:21:20 -0500 |
---|---|---|
committer | Xionghu Luo <luoxhu@linux.ibm.com> | 2021-10-27 21:21:20 -0500 |
commit | 9222481ffc69a6c0b73ec81e1bf04289fa3db0ed (patch) | |
tree | 1f5849ca2b67e1a1233eaebe0b17cc63501cbb19 /gcc/tree-vrp.c | |
parent | 5720c450fab749664b32dbcd14d0a66f8ba57e5f (diff) | |
download | gcc-9222481ffc69a6c0b73ec81e1bf04289fa3db0ed.zip gcc-9222481ffc69a6c0b73ec81e1bf04289fa3db0ed.tar.gz gcc-9222481ffc69a6c0b73ec81e1bf04289fa3db0ed.tar.bz2 |
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 <luoxhu@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 <luoxhu@linux.ibm.com>
PR target/94613
* gcc.target/powerpc/pr94613.c: New test.
Diffstat (limited to 'gcc/tree-vrp.c')
0 files changed, 0 insertions, 0 deletions