aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-01-27 20:35:21 +0100
committerJakub Jelinek <jakub@redhat.com>2021-01-27 20:35:21 +0100
commit55163419211c6f17e3e22c68304384eba35782a3 (patch)
tree51dfb5109fbd6778eb0d29cdc122e8c328241dd1
parent7a279bed24e1b2a628767a60a20f3dcf6f1088cb (diff)
downloadgcc-55163419211c6f17e3e22c68304384eba35782a3.zip
gcc-55163419211c6f17e3e22c68304384eba35782a3.tar.gz
gcc-55163419211c6f17e3e22c68304384eba35782a3.tar.bz2
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 <jakub@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.
-rw-r--r--gcc/config/aarch64/aarch64.md4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr98853-1.c21
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr98853-2.c19
3 files changed, 42 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 45d9c6a..e599076 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5724,10 +5724,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 0000000..b5a3786
--- /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 0000000..2a3b0f2
--- /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;
+}