]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/62554
authorNick Clifton <nickc@redhat.com>
Thu, 18 Feb 2016 13:00:07 +0000 (13:00 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 18 Feb 2016 13:00:07 +0000 (13:00 +0000)
        PR target/69610
gcc     * config/arm/arm.c (arm_option_override_internal): Disable
        interworking if the target does not support thumb instructions.
        (arm_reload_in_hi): Handle the case where a register to register
        move needs reloading because there is no simple pattern to handle
        it.
        (arm_reload_out_hi): Likewise.

tests   * gcc.target/arm/pr62554.c: New test.
        * gcc.target/arm/pr69610-1.c: New test.
        * gcc.target/arm/pr69610-2.c: New test.

From-SVN: r233518

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr62554.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/pr69610-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/pr69610-2.c [new file with mode: 0644]

index f2ce850cb95a66b1e963cf46d4565e6a74238394..b16cd4c6b919e246efd459bd511608bfbf200b3a 100644 (file)
@@ -1,3 +1,14 @@
+2016-02-18  Nick Clifton  <nickc@redhat.com>
+
+        PR target/62554
+        PR target/69610
+        * config/arm/arm.c (arm_option_override_internal): Disable
+        interworking if the target does not support thumb instructions.
+        (arm_reload_in_hi): Handle the case where a register to register
+        move needs reloading because there is no simple pattern to handle
+        it.
+        (arm_reload_out_hi): Likewise.
+
 2016-02-18  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/69854
index 6b737714d5e09f0ce92cf85c342bf88f59d95dbf..765d0021e8035f23685c25154eaefdd3eb99cc6c 100644 (file)
@@ -2874,6 +2874,14 @@ arm_option_override_internal (struct gcc_options *opts,
 {
   arm_override_options_after_change_1 (opts);
 
+  if (TARGET_INTERWORK && !ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB))
+    {
+      /* The default is to enable interworking, so this warning message would
+        be confusing to users who have just compiled with, eg, -march=armv3.  */
+      /* warning (0, "ignoring -minterwork because target CPU does not support THUMB"); */
+      opts->x_target_flags &= ~MASK_INTERWORK;
+    }
+
   if (TARGET_THUMB_P (opts->x_target_flags)
       && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB)))
     {
@@ -15440,6 +15448,17 @@ arm_reload_in_hi (rtx *operands)
       else
        /* The slot is out of range, or was dressed up in a SUBREG.  */
        base = reg_equiv_address (REGNO (ref));
+
+      /* PR 62554: If there is no equivalent memory location then just move
+        the value as an SImode register move.  This happens when the target
+        architecture variant does not have an HImode register move.  */
+      if (base == NULL)
+       {
+         gcc_assert (REG_P (operands[0]));
+         emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, operands[0], 0),
+                               gen_rtx_SUBREG (SImode, ref, 0)));
+         return;
+       }
     }
   else
     base = find_replacement (&XEXP (ref, 0));
@@ -15557,6 +15576,17 @@ arm_reload_out_hi (rtx *operands)
       else
        /* The slot is out of range, or was dressed up in a SUBREG.  */
        base = reg_equiv_address (REGNO (ref));
+
+      /* PR 62554: If there is no equivalent memory location then just move
+        the value as an SImode register move.  This happens when the target
+        architecture variant does not have an HImode register move.  */
+      if (base == NULL)
+       {
+         gcc_assert (REG_P (outval));
+         emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, ref, 0),
+                               gen_rtx_SUBREG (SImode, outval, 0)));
+         return;
+       }
     }
   else
     base = find_replacement (&XEXP (ref, 0));
@@ -19619,6 +19649,7 @@ output_return_instruction (rtx operand, bool really_return, bool reverse,
          break;
 
        case ARM_FT_INTERWORKED:
+         gcc_assert (arm_arch5 || arm_arch4t);
          sprintf (instr, "bx%s\t%%|lr", conditional);
          break;
 
index 74a99e623a78337ae41536022e630a31447f2bae..103c78d718d94bd3281a438b7a4aae114418995f 100644 (file)
@@ -1,3 +1,11 @@
+2016-02-18  Nick Clifton  <nickc@redhat.com>
+
+        PR target/62554
+        PR target/69610
+        * gcc.target/arm/pr62554.c: New test.
+        * gcc.target/arm/pr69610-1.c: New test.
+        * gcc.target/arm/pr69610-2.c: New test.
+
 2016-02-18  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/69854
diff --git a/gcc/testsuite/gcc.target/arm/pr62554.c b/gcc/testsuite/gcc.target/arm/pr62554.c
new file mode 100644 (file)
index 0000000..4d6501c
--- /dev/null
@@ -0,0 +1,51 @@
+/* Check that pre ARMv4 compilation still works.  */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -O" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef struct
+{
+  char bits;
+  short val;
+} code;
+
+union uu
+{
+  short us;
+  char b[2];
+};
+
+int a, b, c, f, g, h;
+code *d;
+
+code e;
+
+int
+fn1 (void)
+{
+  char i;
+  do
+    if (e.bits)
+      {
+      dodist:
+        f = c;
+        if (e.bits & 6)
+          {
+            ++i;
+            if (g)
+              do
+                {
+                  union uu j;
+                  j.b[1] = a;
+                  h = j.us;
+                }
+              while (fn1);
+          }
+        else
+          {
+            e = d[b];
+            goto dodist;
+          }
+      }
+  while (i);
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr69610-1.c b/gcc/testsuite/gcc.target/arm/pr69610-1.c
new file mode 100644 (file)
index 0000000..a671b93
--- /dev/null
@@ -0,0 +1,14 @@
+/* Check that pre ARMv4 compilation still works.  */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -ftree-ter" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef unsigned short v16u16 __attribute__ ((vector_size (16)));
+typedef unsigned int v16u32 __attribute__ ((vector_size (16)));
+
+unsigned short
+foo (v16u16 v16u16_1, v16u32 v16u32_1)
+{
+  v16u16_1 += (v16u16) v16u32_1;
+  return v16u16_1[5] + v16u32_1[1];
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr69610-2.c b/gcc/testsuite/gcc.target/arm/pr69610-2.c
new file mode 100644 (file)
index 0000000..e932c63
--- /dev/null
@@ -0,0 +1,33 @@
+/* Check that pre ARMv4 compilation still works.  */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -O2 -fno-forward-propagate" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef short v16u16 __attribute__ ((vector_size (16)));
+typedef unsigned v16u32 __attribute__ ((vector_size (16)));
+typedef long long v16u64 __attribute__ ((vector_size (16)));
+
+unsigned
+foo
+  (int
+   u16_0,
+   unsigned
+   u32_0,
+   int
+   u64_0,
+   int
+   u16_1,
+   unsigned
+   u64_1,
+   v16u16
+   v16u16_0,
+   v16u32
+   v16u32_0,
+   v16u64 v16u64_0, v16u16 v16u16_1, v16u32 v16u32_1, v16u64 v16u64_1)
+{
+  v16u16_1[3] -= v16u32_0[0];
+  v16u16_0 -= (v16u16) v16u32_0;
+  return u16_0 + u32_0 + u64_0 + u16_1 +
+        v16u16_0[0] + v16u16_0[2] + v16u16_0[3] + v16u16_0[4] + v16u16_0[5] + v16u32_0[0] + v16u32_0[1] + v16u32_0[3] + v16u64_0[1] +
+        v16u16_1[2] + v16u16_1[3] + v16u16_1[5] + v16u16_1[7] + v16u32_1[0] + v16u32_1[3] + v16u64_1[0] + v16u64_1[1];
+}