From: Jakub Jelinek Date: Wed, 27 Jan 2021 19:35:21 +0000 (+0100) Subject: aarch64: Fix up *aarch64_bfxilsi_uxtw [PR98853] X-Git-Tag: releases/gcc-10.3.0~342 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a2c1e22c2501457608f12d5ab560caaca59c425;p=thirdparty%2Fgcc.git aarch64: Fix up *aarch64_bfxilsi_uxtw [PR98853] The https://gcc.gnu.org/legacy-ml/gcc-patches/2018-07/msg01895.html patch that introduced this pattern claimed: Would generate: combine_balanced_int: bfxil w0, w1, 0, 16 uxtw x0, w0 ret But with this patch generates: combine_balanced_int: bfxil w0, w1, 0, 16 ret and it is indeed what it should generate, but it doesn't do that, it emits bfxil x0, x1, 0, 16 instead which doesn't zero extend from 32 to 64 bits, but preserves the bits from the destination register. 2021-01-27 Jakub Jelinek PR target/98853 * config/aarch64/aarch64.md (*aarch64_bfxilsi_uxtw): Use %w0, %w1 and %2 instead of %0, %1 and %2. * gcc.c-torture/execute/pr98853-1.c: New test. * gcc.c-torture/execute/pr98853-2.c: New test. --- diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index da3ab66893a4..7f262e067ce9 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -5918,10 +5918,10 @@ { case 0: operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[3]))); - return "bfxil\\t%0, %1, 0, %3"; + return "bfxil\\t%w0, %w1, 0, %3"; case 1: operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[4]))); - return "bfxil\\t%0, %2, 0, %3"; + return "bfxil\\t%w0, %w2, 0, %3"; default: gcc_unreachable (); } diff --git a/gcc/testsuite/gcc.c-torture/execute/pr98853-1.c b/gcc/testsuite/gcc.c-torture/execute/pr98853-1.c new file mode 100644 index 000000000000..b5a37869fa8f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr98853-1.c @@ -0,0 +1,21 @@ +/* PR target/98853 */ + +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +__attribute__((__noipa__)) unsigned long long +foo (unsigned x, unsigned long long y, unsigned long long z) +{ + __builtin_memcpy (2 + (char *) &x, 2 + (char *) &y, 2); + return x + z; +} +#endif + +int +main () +{ +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + if (foo (0x44444444U, 0x1111111111111111ULL, 0x2222222222222222ULL) + != 0x2222222233336666ULL) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr98853-2.c b/gcc/testsuite/gcc.c-torture/execute/pr98853-2.c new file mode 100644 index 000000000000..2a3b0f2e9ba6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr98853-2.c @@ -0,0 +1,19 @@ +/* PR target/98853 */ + +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 +__attribute__((noipa)) unsigned long long +foo (unsigned long long x, unsigned int y) +{ + return ((unsigned) x & 0xfffe0000U) | (y & 0x1ffff); +} +#endif + +int +main () +{ +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + if (foo (0xdeadbeefcaf2babeULL, 0xdeaffeedU) != 0x00000000caf3feedULL) + __builtin_abort (); +#endif + return 0; +}