From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id AC424385737A; Wed, 11 May 2022 06:21:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC424385737A MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r9-10092] rs6000: Fix up easy_vector_constant_msb handling [PR101384] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/releases/gcc-9 X-Git-Oldrev: 26c58b164fd78db4ce25f0183ed0225c08018f3f X-Git-Newrev: 883690ff6bd8e4f16c871b307cebb13d6c14edcb Message-Id: <20220511062139.AC424385737A@sourceware.org> Date: Wed, 11 May 2022 06:21:39 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 May 2022 06:21:39 -0000 https://gcc.gnu.org/g:883690ff6bd8e4f16c871b307cebb13d6c14edcb commit r9-10092-g883690ff6bd8e4f16c871b307cebb13d6c14edcb Author: Jakub Jelinek Date: Tue Jul 20 16:41:29 2021 +0200 rs6000: Fix up easy_vector_constant_msb handling [PR101384] The following gcc.dg/pr101384.c testcase is miscompiled on powerpc64le-linux. easy_altivec_constant has code to try construct vector constants with different element sizes, perhaps different from CONST_VECTOR's mode. But as written, that works fine for vspltis[bhw] cases, but not for the vspltisw x,-1; vsl[bhw] x,x,x case, because that creates always a V16QImode, V8HImode or V4SImode constant containing broadcasted constant with just the MSB set. The vspltis_constant function etc. expects the vspltis[bhw] instructions where the small [-16..15] or even [-32..30] constant is sign-extended to the remaining step bytes, but that is not the case for the 0x80...00 constants, with step 1 we can't handle e.g. { 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff } vectors but do want to handle e.g. { 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80 } and similarly with copies 1 we do want to handle e.g. { 0x80808080, 0x80808080, 0x80808080, 0x80808080 }. This is a simpler version of the fix for backports, which limits the EASY_VECTOR_MSB case matching to step == 1 && copies == 1, because that is the only case the splitter handles correctly. 2021-07-20 Jakub Jelinek PR target/101384 * config/rs6000/rs6000.c (vspltis_constant): Accept EASY_VECTOR_MSB only if step and copies are equal to 1. * gcc.dg/pr101384.c: New test. (cherry picked from commit dc386b020869ad0095cf58f8c76a40ea457e7a2c) Diff: --- gcc/config/rs6000/rs6000.c | 2 +- gcc/testsuite/gcc.dg/pr101384.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a6e683fe2df..84d93f79343 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -6081,7 +6081,7 @@ vspltis_constant (rtx op, unsigned step, unsigned copies) /* Also check if are loading up the most significant bit which can be done by loading up -1 and shifting the value left by -1. */ - else if (EASY_VECTOR_MSB (splat_val, inner)) + else if (EASY_VECTOR_MSB (splat_val, inner) && step == 1 && copies == 1) ; else diff --git a/gcc/testsuite/gcc.dg/pr101384.c b/gcc/testsuite/gcc.dg/pr101384.c new file mode 100644 index 00000000000..7030c0a481e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101384.c @@ -0,0 +1,39 @@ +/* PR target/101384 */ +/* { dg-do run } */ +/* { dg-options "-O2 -Wno-psabi -w" } */ + +typedef unsigned char __attribute__((__vector_size__ (16))) U; +typedef unsigned short __attribute__((__vector_size__ (8 * sizeof (short)))) V; + +U u; +V v; + +__attribute__((noipa)) U +foo (void) +{ + U y = (U) { 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, + 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff } + u; + return y; +} + +__attribute__((noipa)) V +bar (void) +{ + V y = (V) { 0x8000, 0xffff, 0x8000, 0xffff, + 0x8000, 0xffff, 0x8000, 0xffff } + v; + return y; +} + +int +main () +{ + U x = foo (); + for (unsigned i = 0; i < 16; i++) + if (x[i] != ((i & 3) ? 0xff : 0x80)) + __builtin_abort (); + V y = bar (); + for (unsigned i = 0; i < 8; i++) + if (y[i] != ((i & 1) ? 0xffff : 0x8000)) + __builtin_abort (); + return 0; +}