diff mbox

[GCC/ARM,stage4] Fix PR80082: LDRD erronously used for 64bit load on ARMv7-R

Message ID a4400219-c2ef-474a-ef4b-a93ba85d6cd9@foss.arm.com
State New
Headers show

Commit Message

Thomas Preudhomme March 22, 2017, 10:25 a.m. UTC
Hi,

Currently GCC is happy to use LDRD to perform a 64bit load on ARMv7-R,
as shown by the testcase on this patch. However, LDRD is only atomic
when LPAE extensions is available, which they are not for ARMv7-R. This
commit solve the issue by introducing a new feature bit to distinguish
LPAE extensions instead of deducing it from div instruction
availability.

ChangeLog entries are as follow:

*** gcc/ChangeLog ***

	PR target/80082
	* config/arm/arm-isa.h (isa_bit_lpae): New feature bit.
	(ISA_ARMv7ve): Add isa_bit_lpae to the definition.
	* config/arm/arm-protos.h (arm_arch7ve): Rename into ...
	(arm_arch_lpae): This.
	* config/arm/arm.c (arm_arch7ve): Rename into ...
	(arm_arch_lpae): This.  Define it in term of isa_bit_lpae.
	* config/arm/arm.h (TARGET_HAVE_LPAE): Redefine in term of
	arm_arch_lpae.

*** gcc/testsuite/ChangeLog ***

	PR target/80082
	* gcc.target/arm/atomic_loaddi_10.c: New testcase.
	* gcc.target/arm/atomic_loaddi_11.c: Likewise.


Boostrapped for -march=armv7ve and no testsuite regression.

Is this ok for stage4?

Best regards,

Thomas

Comments

Richard Earnshaw (lists) March 22, 2017, 10:34 a.m. UTC | #1
On 22/03/17 10:25, Thomas Preudhomme wrote:
> Hi,
> 
> Currently GCC is happy to use LDRD to perform a 64bit load on ARMv7-R,
> as shown by the testcase on this patch. However, LDRD is only atomic
> when LPAE extensions is available, which they are not for ARMv7-R. This
> commit solve the issue by introducing a new feature bit to distinguish
> LPAE extensions instead of deducing it from div instruction
> availability.
> 
> ChangeLog entries are as follow:
> 
> *** gcc/ChangeLog ***
> 
>     PR target/80082
>     * config/arm/arm-isa.h (isa_bit_lpae): New feature bit.
>     (ISA_ARMv7ve): Add isa_bit_lpae to the definition.
>     * config/arm/arm-protos.h (arm_arch7ve): Rename into ...
>     (arm_arch_lpae): This.
>     * config/arm/arm.c (arm_arch7ve): Rename into ...
>     (arm_arch_lpae): This.  Define it in term of isa_bit_lpae.
>     * config/arm/arm.h (TARGET_HAVE_LPAE): Redefine in term of
>     arm_arch_lpae.
> 
> *** gcc/testsuite/ChangeLog ***
> 
>     PR target/80082
>     * gcc.target/arm/atomic_loaddi_10.c: New testcase.
>     * gcc.target/arm/atomic_loaddi_11.c: Likewise.
> 
> 
> Boostrapped for -march=armv7ve and no testsuite regression.
> 
> Is this ok for stage4?
> 

OK.  Can you do backports for gcc-5 and -6 please.


R.

> Best regards,
> 
> Thomas
> 
> fix_ldrd_64bit_atomic_armv7r.patch
> 
> 
> diff --git a/gcc/config/arm/arm-isa.h b/gcc/config/arm/arm-isa.h
> index 6050bca95587f68a3671dd2144cf845b83da3692..7d1e23be0a22ea3d04368a73538d606eef3ae092 100644
> --- a/gcc/config/arm/arm-isa.h
> +++ b/gcc/config/arm/arm-isa.h
> @@ -58,6 +58,7 @@ enum isa_feature
>      isa_bit_VFPv3,	/* Vector floating point v3.  */
>      isa_bit_VFPv4,	/* Vector floating point v4.  */
>      isa_bit_FPv5,	/* Floating point v5.  */
> +    isa_bit_lpae,	/* ARMv7-A LPAE.  */
>      isa_bit_FP_ARMv8,	/* ARMv8 floating-point extension.  */
>      isa_bit_neon,	/* Advanced SIMD instructions.  */
>      isa_bit_fp16conv,	/* Conversions to/from fp16 (VFPv3 extension).  */
> @@ -116,7 +117,7 @@ enum isa_feature
>     integer SIMD instructions that are in ARMv6T2.  */
>  #define ISA_ARMv7	ISA_ARMv6m, isa_bit_thumb2, isa_bit_ARMv7
>  #define ISA_ARMv7a	ISA_ARMv7, isa_bit_notm, isa_bit_ARMv6k
> -#define ISA_ARMv7ve	ISA_ARMv7a, isa_bit_adiv, isa_bit_tdiv
> +#define ISA_ARMv7ve	ISA_ARMv7a, isa_bit_adiv, isa_bit_tdiv, isa_bit_lpae
>  #define ISA_ARMv7r	ISA_ARMv7a, isa_bit_tdiv
>  #define ISA_ARMv7m	ISA_ARMv7, isa_bit_tdiv
>  #define ISA_ARMv7em	ISA_ARMv7m, isa_bit_ARMv7em
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 680a1e6236411c0e27888dc4379fe93ef2ed39e2..cf8b43714d8cfc1aa6b648fc7f57d2234fd74927 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -391,8 +391,8 @@ extern int arm_arch6m;
>  /* Nonzero if this chip supports the ARM 7 extensions.  */
>  extern int arm_arch7;
>  
> -/* Nonzero if this chip supports the ARM 7ve extensions.  */
> -extern int arm_arch7ve;
> +/* Nonzero if this chip supports the Large Physical Address Extension.  */
> +extern int arm_arch_lpae;
>  
>  /* Nonzero if instructions not present in the 'M' profile can be used.  */
>  extern int arm_arch_notm;
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index e95eda358a54ca0804cfbb9acc0801835c3d7bfb..4dab73d37be8465fe6f504232e3ee83548beef95 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -251,7 +251,7 @@ extern tree arm_fp16_type_node;
>  				  || (arm_arch8 && !arm_arch_notm))
>  
>  /* Nonzero if this chip supports LPAE.  */
> -#define TARGET_HAVE_LPAE (arm_arch7ve)
> +#define TARGET_HAVE_LPAE (arm_arch_lpae)
>  
>  /* Nonzero if this chip supports ldrex{bh} and strex{bh}.  */
>  #define TARGET_HAVE_LDREXBH ((arm_arch6k && TARGET_ARM)		\
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 511e16377640894c143e905faace17c72044b5aa..b24143e32e2f100000f3b150f7ed0df4fabb3cc8 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -841,8 +841,8 @@ int arm_arch6m = 0;
>  /* Nonzero if this chip supports the ARM 7 extensions.  */
>  int arm_arch7 = 0;
>  
> -/* Nonzero if this chip supports the ARM 7ve extensions.  */
> -int arm_arch7ve = 0;
> +/* Nonzero if this chip supports the Large Physical Address Extension.  */
> +int arm_arch_lpae = 0;
>  
>  /* Nonzero if instructions not present in the 'M' profile can be used.  */
>  int arm_arch_notm = 0;
> @@ -3365,8 +3365,7 @@ arm_option_override (void)
>    arm_arch_crc = bitmap_bit_p (arm_active_target.isa, isa_bit_crc32);
>    arm_arch_cmse = bitmap_bit_p (arm_active_target.isa, isa_bit_cmse);
>    arm_fp16_inst = bitmap_bit_p (arm_active_target.isa, isa_bit_fp16);
> -  arm_arch7ve
> -    = (arm_arch6k && arm_arch7 && arm_arch_thumb_hwdiv && arm_arch_arm_hwdiv);
> +  arm_arch_lpae = bitmap_bit_p (arm_active_target.isa, isa_bit_lpae);
>    if (arm_fp16_inst)
>      {
>        if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
> diff --git a/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c b/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..ecc3d06d0c9f5966daa3ce7e2d52e09d14e0cbc8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target arm_arch_v7ve_ok } */
> +/* { dg-options "-O2" } */
> +/* { dg-add-options arm_arch_v7ve } */
> +
> +#include <stdatomic.h>
> +
> +atomic_llong x = 0;
> +
> +atomic_llong get_x()
> +{
> +  return atomic_load(&x);
> +}
> +
> +/* { dg-final { scan-assembler "ldrd" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c b/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..275669bd76356dc7c7b6a5373792d9a5089ede51
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target arm_arch_v7r_ok } */
> +/* { dg-options "-O2" } */
> +/* { dg-add-options arm_arch_v7r } */
> +
> +#include <stdatomic.h>
> +
> +atomic_llong x = 0;
> +
> +atomic_llong get_x()
> +{
> +  return atomic_load(&x);
> +}
> +
> +/* { dg-final { scan-assembler-not "ldrd" } } */
>
diff mbox

Patch

diff --git a/gcc/config/arm/arm-isa.h b/gcc/config/arm/arm-isa.h
index 6050bca95587f68a3671dd2144cf845b83da3692..7d1e23be0a22ea3d04368a73538d606eef3ae092 100644
--- a/gcc/config/arm/arm-isa.h
+++ b/gcc/config/arm/arm-isa.h
@@ -58,6 +58,7 @@  enum isa_feature
     isa_bit_VFPv3,	/* Vector floating point v3.  */
     isa_bit_VFPv4,	/* Vector floating point v4.  */
     isa_bit_FPv5,	/* Floating point v5.  */
+    isa_bit_lpae,	/* ARMv7-A LPAE.  */
     isa_bit_FP_ARMv8,	/* ARMv8 floating-point extension.  */
     isa_bit_neon,	/* Advanced SIMD instructions.  */
     isa_bit_fp16conv,	/* Conversions to/from fp16 (VFPv3 extension).  */
@@ -116,7 +117,7 @@  enum isa_feature
    integer SIMD instructions that are in ARMv6T2.  */
 #define ISA_ARMv7	ISA_ARMv6m, isa_bit_thumb2, isa_bit_ARMv7
 #define ISA_ARMv7a	ISA_ARMv7, isa_bit_notm, isa_bit_ARMv6k
-#define ISA_ARMv7ve	ISA_ARMv7a, isa_bit_adiv, isa_bit_tdiv
+#define ISA_ARMv7ve	ISA_ARMv7a, isa_bit_adiv, isa_bit_tdiv, isa_bit_lpae
 #define ISA_ARMv7r	ISA_ARMv7a, isa_bit_tdiv
 #define ISA_ARMv7m	ISA_ARMv7, isa_bit_tdiv
 #define ISA_ARMv7em	ISA_ARMv7m, isa_bit_ARMv7em
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 680a1e6236411c0e27888dc4379fe93ef2ed39e2..cf8b43714d8cfc1aa6b648fc7f57d2234fd74927 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -391,8 +391,8 @@  extern int arm_arch6m;
 /* Nonzero if this chip supports the ARM 7 extensions.  */
 extern int arm_arch7;
 
-/* Nonzero if this chip supports the ARM 7ve extensions.  */
-extern int arm_arch7ve;
+/* Nonzero if this chip supports the Large Physical Address Extension.  */
+extern int arm_arch_lpae;
 
 /* Nonzero if instructions not present in the 'M' profile can be used.  */
 extern int arm_arch_notm;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index e95eda358a54ca0804cfbb9acc0801835c3d7bfb..4dab73d37be8465fe6f504232e3ee83548beef95 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -251,7 +251,7 @@  extern tree arm_fp16_type_node;
 				  || (arm_arch8 && !arm_arch_notm))
 
 /* Nonzero if this chip supports LPAE.  */
-#define TARGET_HAVE_LPAE (arm_arch7ve)
+#define TARGET_HAVE_LPAE (arm_arch_lpae)
 
 /* Nonzero if this chip supports ldrex{bh} and strex{bh}.  */
 #define TARGET_HAVE_LDREXBH ((arm_arch6k && TARGET_ARM)		\
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 511e16377640894c143e905faace17c72044b5aa..b24143e32e2f100000f3b150f7ed0df4fabb3cc8 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -841,8 +841,8 @@  int arm_arch6m = 0;
 /* Nonzero if this chip supports the ARM 7 extensions.  */
 int arm_arch7 = 0;
 
-/* Nonzero if this chip supports the ARM 7ve extensions.  */
-int arm_arch7ve = 0;
+/* Nonzero if this chip supports the Large Physical Address Extension.  */
+int arm_arch_lpae = 0;
 
 /* Nonzero if instructions not present in the 'M' profile can be used.  */
 int arm_arch_notm = 0;
@@ -3365,8 +3365,7 @@  arm_option_override (void)
   arm_arch_crc = bitmap_bit_p (arm_active_target.isa, isa_bit_crc32);
   arm_arch_cmse = bitmap_bit_p (arm_active_target.isa, isa_bit_cmse);
   arm_fp16_inst = bitmap_bit_p (arm_active_target.isa, isa_bit_fp16);
-  arm_arch7ve
-    = (arm_arch6k && arm_arch7 && arm_arch_thumb_hwdiv && arm_arch_arm_hwdiv);
+  arm_arch_lpae = bitmap_bit_p (arm_active_target.isa, isa_bit_lpae);
   if (arm_fp16_inst)
     {
       if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
diff --git a/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c b/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c
new file mode 100644
index 0000000000000000000000000000000000000000..ecc3d06d0c9f5966daa3ce7e2d52e09d14e0cbc8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/atomic_loaddi_10.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v7ve_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v7ve } */
+
+#include <stdatomic.h>
+
+atomic_llong x = 0;
+
+atomic_llong get_x()
+{
+  return atomic_load(&x);
+}
+
+/* { dg-final { scan-assembler "ldrd" } } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c b/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c
new file mode 100644
index 0000000000000000000000000000000000000000..275669bd76356dc7c7b6a5373792d9a5089ede51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/atomic_loaddi_11.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v7r_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v7r } */
+
+#include <stdatomic.h>
+
+atomic_llong x = 0;
+
+atomic_llong get_x()
+{
+  return atomic_load(&x);
+}
+
+/* { dg-final { scan-assembler-not "ldrd" } } */