Hi!

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.

The following patch fixes that, bootstrapped/regtested on aarch64-linux,
ok for trunk (and later backports)?

2021-01-27  Jakub Jelinek  <ja...@redhat.com>

        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.

--- gcc/config/aarch64/aarch64.md.jj    2021-01-04 10:25:46.435147744 +0100
+++ gcc/config/aarch64/aarch64.md       2021-01-27 15:13:13.993275204 +0100
@@ -5724,10 +5724,10 @@ (define_insn "*aarch64_bfxilsi_uxtw"
     {
       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 ();
     }
--- gcc/testsuite/gcc.c-torture/execute/pr98853-1.c.jj  2021-01-27 
15:26:15.544335342 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr98853-1.c     2021-01-27 
15:28:37.877710203 +0100
@@ -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;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr98853-2.c.jj  2021-01-27 
19:35:52.312351623 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr98853-2.c     2021-01-27 
19:37:51.369515183 +0100
@@ -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;
+}

        Jakub

Reply via email to