diff mbox series

Arm: Fix ldrd offset range [PR115153]

Message ID PAWPR08MB89824FFDA84799541EF2460383FF2@PAWPR08MB8982.eurprd08.prod.outlook.com
State New
Headers show
Series Arm: Fix ldrd offset range [PR115153] | expand

Commit Message

Wilco Dijkstra June 3, 2024, 1:40 p.m. UTC
The valid offset range of LDRD in arm_legitimate_index_p is increased to
-1024..1020 if NEON is enabled since VALID_NEON_DREG_MODE includes DImode.
Fix this by moving the LDRD check earlier.

Passes bootstrap & regress, OK for commit?

gcc:
        PR target/115153
        * config/arm/arm.cc (arm_legitimate_index_p): Move LDRD case before NEON.
        (thumb2_legitimate_index_p): Update comments.

gcc/testsuite:
        PR target/115153
        * gcc.target/arm/pr115153.c: Add new test.

---
diff mbox series

Patch

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index ea0c963a4d67ecd70e1571624e84dfe46d757df9..d260ebe0734d424942a773386986a02fe6d1803c 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -8852,6 +8852,28 @@  arm_legitimate_index_p (machine_mode mode, rtx index, RTX_CODE outer,
 	    && INTVAL (index) > -1024
 	    && (INTVAL (index) & 3) == 0);
 
+  if (arm_address_register_rtx_p (index, strict_p)
+      && (GET_MODE_SIZE (mode) <= 4))
+    return 1;
+
+  /* This handles DFmode only if !TARGET_HARD_FLOAT.  */
+  if (mode == DImode || mode == DFmode)
+    {
+      if (code == CONST_INT)
+	{
+	  HOST_WIDE_INT val = INTVAL (index);
+
+	  /* Assume we emit ldrd or 2x ldr if !TARGET_LDRD.
+	     If vldr is selected it uses arm_coproc_mem_operand.  */
+	  if (TARGET_LDRD)
+	    return val > -256 && val < 256;
+	  else
+	    return val > -4096 && val < 4092;
+	}
+
+      return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p);
+    }
+
   /* For quad modes, we restrict the constant offset to be slightly less
      than what the instruction format permits.  We do this because for
      quad mode moves, we will actually decompose them into two separate
@@ -8864,7 +8886,7 @@  arm_legitimate_index_p (machine_mode mode, rtx index, RTX_CODE outer,
 	    && (INTVAL (index) & 3) == 0);
 
   /* We have no such constraint on double mode offsets, so we permit the
-     full range of the instruction format.  */
+     full range of the instruction format.  Note DImode is included here.  */
   if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
     return (code == CONST_INT
 	    && INTVAL (index) < 1024
@@ -8877,27 +8899,6 @@  arm_legitimate_index_p (machine_mode mode, rtx index, RTX_CODE outer,
 	    && INTVAL (index) > -1024
 	    && (INTVAL (index) & 3) == 0);
 
-  if (arm_address_register_rtx_p (index, strict_p)
-      && (GET_MODE_SIZE (mode) <= 4))
-    return 1;
-
-  if (mode == DImode || mode == DFmode)
-    {
-      if (code == CONST_INT)
-	{
-	  HOST_WIDE_INT val = INTVAL (index);
-
-	  /* Assume we emit ldrd or 2x ldr if !TARGET_LDRD.
-	     If vldr is selected it uses arm_coproc_mem_operand.  */
-	  if (TARGET_LDRD)
-	    return val > -256 && val < 256;
-	  else
-	    return val > -4096 && val < 4092;
-	}
-
-      return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p);
-    }
-
   if (GET_MODE_SIZE (mode) <= 4
       && ! (arm_arch4
 	    && (mode == HImode
@@ -9000,7 +9001,7 @@  thumb2_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
 	    && (INTVAL (index) & 3) == 0);
 
   /* We have no such constraint on double mode offsets, so we permit the
-     full range of the instruction format.  */
+     full range of the instruction format.  Note DImode is included here.  */
   if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
     return (code == CONST_INT
 	    && INTVAL (index) < 1024
@@ -9011,6 +9012,7 @@  thumb2_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
       && (GET_MODE_SIZE (mode) <= 4))
     return 1;
 
+  /* This handles DImode if !TARGET_NEON, and DFmode if !TARGET_VFP_BASE.  */
   if (mode == DImode || mode == DFmode)
     {
       if (code == CONST_INT)
diff --git a/gcc/testsuite/gcc.target/arm/pr115153.c b/gcc/testsuite/gcc.target/arm/pr115153.c
new file mode 100644
index 0000000000000000000000000000000000000000..db1cd93b3d31b33a9800dac0d8dbe73e058e4073
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr115153.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -marm" } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+**	add	r0, r0, #256
+**	ldrd	r0, r1, \[r0\]
+**	bx	lr
+*/
+long long f1 (long long *p)
+{
+  return __atomic_load_n (p + 32, __ATOMIC_RELAXED);
+}