]> git.ipfire.org Git - thirdparty/gcc.git/commit
s390: Fix up *vec_cmpgt{,u}<mode><mode>_nocc_emu splitters [PR118696]
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Jan 2025 17:30:10 +0000 (18:30 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 30 Jan 2025 17:30:10 +0000 (18:30 +0100)
commit6a6df260c7cdbf8f40c1245a3c930293a20bf8c0
treeeabc6a8eafb650dae92f6bfa9cb7e8dc36344ddb
parentba6cac82f6806b1f1f61e482031b7f2f4db7b336
s390: Fix up *vec_cmpgt{,u}<mode><mode>_nocc_emu splitters [PR118696]

The following testcase is miscompiled on s390x-linux with e.g. -march=z13
(both -O0 and -O2) starting with r15-7053.
The problem is in the splitters which emulate TImode/V1TImode GT and GTU
comparisons.
For GT we want to do
(ior (gt (hi op1) (hi op2))
     (and (eq (hi op1) (hi op2)) (gtu (lo op1) (lo op2))))
and for GTU similarly except for gtu instead of gt in there.
Now, the splitter emulation is using V2DImode comparisons where on s390x
the hi part is in the first element of the vector, lo part in the second,
and for the gtu case it swaps the elements of the vector.
So, we get the right result in the first element of the result vector.
But vrepg was then broadcasting the second element of the result vector
rather than the first, and the value of the second element of the vector
is instead
(ior (gt (lo op1) (lo op2))
     (and (eq (lo op1) (lo op2)) (gtu (hi op1) (hi op2))))
so something not really usable for the emulated comparison.

The following patch fixes that.  The testcase tries to test behavior of
double-word smin/smax/umin/umax with various cases of the halves of both
operands (one that is sometimes EQ, sometimes GT, sometimes LT, sometimes
GTU, sometimes LTU).

2025-01-30  Jakub Jelinek  <jakub@redhat.com>
    Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>

PR target/118696
* config/s390/vector.md (*vec_cmpgt<mode><mode>_nocc_emu,
*vec_cmpgtu<mode><mode>_nocc_emu): Duplicate the first rather than
second V2DImode element.

* gcc.dg/pr118696.c: New test.
* gcc.target/s390/vector/pr118696.c: New test.
* gcc.target/s390/vector/vec-abs-emu.c: Expect vrepg with 0 as last
operand rather than 1.
* gcc.target/s390/vector/vec-max-emu.c: Likewise.
* gcc.target/s390/vector/vec-min-emu.c: Likewise.
gcc/config/s390/vector.md
gcc/testsuite/gcc.dg/pr118696.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/pr118696.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c