[ARM] PR71607: Fix ICE when loading constant
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Fri, 5 May 2017 15:41:28 +0000 (15:41 +0000)
committerThomas Preud'homme <thopre01@gcc.gnu.org>
Fri, 5 May 2017 15:41:28 +0000 (15:41 +0000)
2017-05-05  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Prakhar Bahuguna  <prakhar.bahuguna@arm.com>

    gcc/
    PR target/71607
    * config/arm/arm.md (use_literal_pool): Remove.
    (64-bit immediate split): No longer takes cost into consideration
    if arm_disable_literal_pool is enabled.
    * config/arm/arm.c (arm_tls_referenced_p): Add diagnostic if TLS is
    used when arm_disable_literal_pool is enabled.
    (arm_max_const_double_inline_cost): Remove use of
    arm_disable_literal_pool.
    (push_minipool_fix): Add assert.
    (arm_reorg): Add return if arm_disable_literal_pool is enabled.
    * config/arm/vfp.md (no_literal_pool_df_immediate): New.
    (no_literal_pool_sf_immediate): New.

2017-05-05  Andre Vieira  <andre.simoesdiasvieira@arm.com>
        Thomas Preud'homme  <thomas.preudhomme@arm.com>
        Prakhar Bahuguna  <prakhar.bahuguna@arm.com>

    gcc/testsuite/
    PR target/71607
    * gcc.target/arm/thumb2-slow-flash-data.c: Renamed to ...
    * gcc.target/arm/thumb2-slow-flash-data-1.c: ... this.
    * gcc.target/arm/thumb2-slow-flash-data-2.c: New.
    * gcc.target/arm/thumb2-slow-flash-data-3.c: New.
    * gcc.target/arm/thumb2-slow-flash-data-4.c: New.
    * gcc.target/arm/thumb2-slow-flash-data-5.c: New.
    * gcc.target/arm/tls-disable-literal-pool.c: New.

Co-Authored-By: Prakhar Bahuguna <prakhar.bahuguna@arm.com>
Co-Authored-By: Thomas Preud'homme <thomas.preudhomme@arm.com>
From-SVN: r247640

12 files changed:
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/arm/vfp.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c [deleted file]
gcc/testsuite/gcc.target/arm/tls-disable-literal-pool.c [new file with mode: 0644]

index 5aa46fc0fd198ebfd953f4c7fe78ce97110f608b..ff1d4996df19cd03d62ada6b17a4fa66364592f0 100644 (file)
@@ -1,3 +1,19 @@
+2017-05-05  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+           Prakhar Bahuguna  <prakhar.bahuguna@arm.com>
+
+       PR target/71607
+       * config/arm/arm.md (use_literal_pool): Remove.
+       (64-bit immediate split): No longer takes cost into consideration
+       if arm_disable_literal_pool is enabled.
+       * config/arm/arm.c (arm_tls_referenced_p): Add diagnostic if TLS is
+       used when arm_disable_literal_pool is enabled.
+       (arm_max_const_double_inline_cost): Remove use of
+       arm_disable_literal_pool.
+       (push_minipool_fix): Add assert.
+       (arm_reorg): Add return if arm_disable_literal_pool is enabled.
+       * config/arm/vfp.md (no_literal_pool_df_immediate): New.
+       (no_literal_pool_sf_immediate): New.
+
 2017-05-05  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        PR tree-optimization/80613
index e0a7cabcb2ed603aedfb5762cef5a17aa3c28b01..55bfcd227888df67ea1945369169c2c4ff0f467a 100644 (file)
@@ -8691,7 +8691,16 @@ arm_tls_referenced_p (rtx x)
     {
       const_rtx x = *iter;
       if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
-       return true;
+       {
+         /* ARM currently does not provide relocations to encode TLS variables
+            into AArch32 instructions, only data, so there is no way to
+            currently implement these if a literal pool is disabled.  */
+         if (arm_disable_literal_pool)
+           sorry ("accessing thread-local storage is not currently supported "
+                  "with -mpure-code or -mslow-flash-data");
+
+         return true;
+       }
 
       /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
         TLS offsets, not real symbol references.  */
@@ -16399,6 +16408,7 @@ static void
 push_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc,
                   machine_mode mode, rtx value)
 {
+  gcc_assert (!arm_disable_literal_pool);
   Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
 
   fix->insn = insn;
@@ -16450,10 +16460,6 @@ push_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc,
 int
 arm_max_const_double_inline_cost ()
 {
-  /* Let the value get synthesized to avoid the use of literal pools.  */
-  if (arm_disable_literal_pool)
-    return 99;
-
   return ((optimize_size || arm_ld_sched) ? 3 : 4);
 }
 
@@ -17400,6 +17406,11 @@ arm_reorg (void)
   if (!optimize)
     split_all_insns_noflow ();
 
+  /* Make sure we do not attempt to create a literal pool even though it should
+     no longer be necessary to create any.  */
+  if (arm_disable_literal_pool)
+    return ;
+
   minipool_fix_head = minipool_fix_tail = NULL;
 
   /* The first insn must always be a note, or the code below won't
index d50059b28ab057dc8b50fafd7dad660ec1830787..4a2b623e528256835958a510e2d32628477cb680 100644 (file)
               (match_test "arm_restrict_it"))
          (const_string "no")
 
-         (and (eq_attr "use_literal_pool" "yes")
-              (match_test "arm_disable_literal_pool"))
-         (const_string "no")
-
          (eq_attr "arch_enabled" "no")
          (const_string "no")]
         (const_string "yes")))
        (match_operand:ANY64 1 "immediate_operand" ""))]
   "TARGET_32BIT
    && reload_completed
-   && (arm_const_double_inline_cost (operands[1])
-       <= arm_max_const_double_inline_cost ())"
+   && (arm_disable_literal_pool
+       || (arm_const_double_inline_cost (operands[1])
+          <= arm_max_const_double_inline_cost ()))"
   [(const_int 0)]
   "
   arm_split_constant (SET, SImode, curr_insn,
index befdea9edd90f1b8c6cb81cb833c07bd2454fa80..d8f77e2ffe4fdb7c952d6a5ac947d91f89ce259d 100644 (file)
 ;; fmdhr et al (VFPv1)
 ;; Support for xD (single precision only) variants.
 ;; fmrrs, fmsrr
+
+;; Split an immediate DF move to two immediate SI moves.
+(define_insn_and_split "no_literal_pool_df_immediate"
+  [(set (match_operand:DF 0 "s_register_operand" "")
+       (match_operand:DF 1 "const_double_operand" ""))]
+  "TARGET_THUMB2 && arm_disable_literal_pool
+  && !(TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
+       && vfp3_const_double_rtx (operands[1]))"
+  "#"
+  "&& !reload_completed"
+  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
+   (set (subreg:SI (match_dup 1) 4) (match_dup 3))
+   (set (match_dup 0) (match_dup 1))]
+  "
+  long buf[2];
+  real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
+  operands[2] = GEN_INT ((int) buf[0]);
+  operands[3] = GEN_INT ((int) buf[1]);
+  operands[1] = gen_reg_rtx (DFmode);
+  ")
+
+;; Split an immediate SF move to one immediate SI move.
+(define_insn_and_split "no_literal_pool_sf_immediate"
+  [(set (match_operand:SF 0 "s_register_operand" "")
+       (match_operand:SF 1 "const_double_operand" ""))]
+  "TARGET_THUMB2 && arm_disable_literal_pool
+  && !(TARGET_HARD_FLOAT && vfp3_const_double_rtx (operands[1]))"
+  "#"
+  "&& !reload_completed"
+  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
+   (set (match_dup 0) (match_dup 1))]
+  "
+  long buf;
+  real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
+  operands[2] = GEN_INT ((int) buf);
+  operands[1] = gen_reg_rtx (SFmode);
+  ")
index a3012e82f3c0d20b3d1ef801a8b7db591e76784c..8606518de582d2bbc1b54dcd62f5dbe574c32047 100644 (file)
@@ -1,3 +1,16 @@
+2017-05-05  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+           Thomas Preud'homme  <thomas.preudhomme@arm.com>
+           Prakhar Bahuguna  <prakhar.bahuguna@arm.com>
+
+       PR target/71607
+       * gcc.target/arm/thumb2-slow-flash-data.c: Renamed to ...
+       * gcc.target/arm/thumb2-slow-flash-data-1.c: ... this.
+       * gcc.target/arm/thumb2-slow-flash-data-2.c: New.
+       * gcc.target/arm/thumb2-slow-flash-data-3.c: New.
+       * gcc.target/arm/thumb2-slow-flash-data-4.c: New.
+       * gcc.target/arm/thumb2-slow-flash-data-5.c: New.
+       * gcc.target/arm/tls-disable-literal-pool.c: New.
+
 2017-05-05  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        PR tree-optimization/80613
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c
new file mode 100644 (file)
index 0000000..089a72b
--- /dev/null
@@ -0,0 +1,73 @@
+/* The option -mslow-flash-data is just for performance tuning, it
+   doesn't totally disable the use of literal pools.  But for below
+   simple cases, the use of literal pool should be replaced by
+   movw/movt or read-only constant pool.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2 -mthumb -mslow-flash-data" } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+       {
+         a += *labelref;
+         i += 1;
+       }
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
new file mode 100644 (file)
index 0000000..6e76043
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+
+float f (float);
+
+const float max = 0.01f;
+
+int
+g (float in)
+{
+  if (f (in) + f (in) < max)
+    return 0;
+  return 1;
+}
+
+double foo (void)
+{
+  return 0xF1EC7A5239123AF;
+}
+
+double bar (void)
+{
+  return 0.0f;
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
new file mode 100644 (file)
index 0000000..fe7a12b
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-march=armv7e-m -mfloat-abi=hard -mthumb -mslow-flash-data" } */
+
+/* From PR71607 */
+
+float b;
+void fn1 ();
+
+float
+fn2 ()
+{
+  return 1.1f;
+}
+
+void
+fn3 ()
+{
+  float a[2];
+  a[1] = b;
+  fn1 (a);
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c
new file mode 100644 (file)
index 0000000..cc5aea4
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+
+double __attribute__ ((target ("fpu=fpv5-d16")))
+foo (void)
+{
+  return 1.0f;
+}
+
+float __attribute__ ((target ("fpu=fpv5-d16")))
+bar (void)
+{
+  return 1.0f;
+}
+
+float __attribute__ ((target ("fpu=fpv5-sp-d16")))
+baz (void)
+{
+  return 1.0f;
+}
+
+/* { dg-final { scan-assembler-times "#1\\.0e\\+0" 3 } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c
new file mode 100644 (file)
index 0000000..b9161c4
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+
+double __attribute__ ((target ("fpu=fpv5-sp-d16")))
+foo (void)
+{
+  return 1.0f;
+}
+
+/* { dg-final { scan-assembler-not "#1\\.0e\\+0" } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c
deleted file mode 100644 (file)
index 089a72b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* The option -mslow-flash-data is just for performance tuning, it
-   doesn't totally disable the use of literal pools.  But for below
-   simple cases, the use of literal pool should be replaced by
-   movw/movt or read-only constant pool.  */
-
-/* { dg-do compile } */
-/* { dg-require-effective-target arm_cortex_m } */
-/* { dg-require-effective-target arm_thumb2_ok } */
-/* { dg-options "-O2 -mthumb -mslow-flash-data" } */
-
-float sf;
-double df;
-long long l;
-static char *p = "Hello World";
-
-float
-testsf (float *p)
-{
-  if (*p > 1.1234f)
-    return 2.1234f;
-  else
-    return 3.1234f;
-}
-
-double
-testdf (double *p)
-{
-  if (*p > 4.1234)
-    return 2.1234;
-  else
-    return 3.1234;
-}
-
-long long
-testll (long long *p)
-{
-  if (*p > 0x123456789ABCDEFll)
-    return 0x111111111ll;
-  else
-    return 0x222222222ll;
-}
-
-char *
-testchar ()
-{
-  return p + 4;
-}
-
-int
-foo (int a, int b)
-{
-  int i;
-  volatile int *labelref = &&label1;
-
-  if (a > b)
-    {
-      while (i < b)
-       {
-         a += *labelref;
-         i += 1;
-       }
-      goto *labelref;
-    }
-  else
-    b = b + 3;
-
-  a = a * b;
-
-label1:
-  return a + b;
-}
-
-/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/tls-disable-literal-pool.c b/gcc/testsuite/gcc.target/arm/tls-disable-literal-pool.c
new file mode 100644 (file)
index 0000000..fe14a6b
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-mslow-flash-data" } */
+
+__thread int x = 0;
+
+int
+bar ()
+{
+  return x;
+}
+
+/* { dg-error "accessing thread-local storage is not currently supported with -mpure-code or -mslow-flash-data" "" { target *-*-* } 12 } */