[ARM] Fix Thumb-1 ldm (PR89190)
authorWilco Dijkstra <wdijkstr@arm.com>
Wed, 13 Feb 2019 16:22:25 +0000 (16:22 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Wed, 13 Feb 2019 16:22:25 +0000 (16:22 +0000)
This patch fixes an ICE in the Thumb-1 LDM peepholer.  Thumb-1 LDMs
always update the base register except if the base is loaded.
The current implementation rejects LDMs where the base is not dead,
however this doesn't exclude the case where the base is loaded as
well as dead.  Fix this by explicitly checking whether the base is
loaded.  Also enable LDMs which load the first register.

    gcc/
PR target/89190
* config/arm/arm.c (ldm_stm_operation_p) Set
addr_reg_in_reglist correctly for first register.
(load_multiple_sequence): Remove dead base check.
(gen_ldm_seq): Correctly set write_back for Thumb-1.

    testsuite/
PR target/89190
* gcc.target/arm/pr89190.c: New test.

From-SVN: r268848

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog

index 76cef68bed12ed50b7db5c120dcc85bb19a41dd1..6729c6d38695e4cf7d721c90619979d4d3e4f2a0 100644 (file)
@@ -1,3 +1,11 @@
+2019-02-13  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       PR target/89190
+       * config/arm/arm.c (ldm_stm_operation_p) Set
+       addr_reg_in_reglist correctly for first register.
+       (load_multiple_sequence): Remove dead base check.
+       (gen_ldm_seq): Correctly set write_back for Thumb-1.
+
 2019-02-13  Tamar Christina  <tamar.christina@arm.com>
 
        PR target/88847
index e9aba65c70563f23ba3049702072a59cf555b9ce..f07f4cc47b6cfcea8f44960bf4760ea9a46b8f87 100644 (file)
@@ -13191,6 +13191,9 @@ ldm_stm_operation_p (rtx op, bool load, machine_mode mode,
   if (load && (REGNO (reg) == SP_REGNUM) && (REGNO (addr) != SP_REGNUM))
     return false;
 
+  if (regno == REGNO (addr))
+    addr_reg_in_reglist = true;
+
   for (; i < count; i++)
     {
       elt = XVECEXP (op, 0, i);
@@ -13385,7 +13388,6 @@ load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,
   int unsorted_regs[MAX_LDM_STM_OPS];
   HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];
   int order[MAX_LDM_STM_OPS];
-  rtx base_reg_rtx = NULL;
   int base_reg = -1;
   int i, ldm_case;
 
@@ -13430,7 +13432,6 @@ load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,
          if (i == 0)
            {
              base_reg = REGNO (reg);
-             base_reg_rtx = reg;
              if (TARGET_THUMB1 && base_reg > LAST_LO_REGNUM)
                return 0;
            }
@@ -13489,10 +13490,6 @@ load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,
       *load_offset = unsorted_offsets[order[0]];
     }
 
-  if (TARGET_THUMB1
-      && !peep2_reg_dead_p (nops, base_reg_rtx))
-    return 0;
-
   if (unsorted_offsets[order[0]] == 0)
     ldm_case = 1; /* ldmia */
   else if (TARGET_ARM && unsorted_offsets[order[0]] == 4)
@@ -13868,9 +13865,17 @@ gen_ldm_seq (rtx *operands, int nops, bool sort_regs)
 
   if (TARGET_THUMB1)
     {
-      gcc_assert (peep2_reg_dead_p (nops, base_reg_rtx));
       gcc_assert (ldm_case == 1 || ldm_case == 5);
-      write_back = TRUE;
+
+      /* Thumb-1 ldm uses writeback except if the base is loaded.  */
+      write_back = true;
+      for (i = 0; i < nops; i++)
+       if (base_reg == regs[i])
+         write_back = false;
+
+      /* Ensure the base is dead if it is updated.  */
+      if (write_back && !peep2_reg_dead_p (nops, base_reg_rtx))
+       return false;
     }
 
   if (ldm_case == 5)
@@ -13878,8 +13883,7 @@ gen_ldm_seq (rtx *operands, int nops, bool sort_regs)
       rtx newbase = TARGET_THUMB1 ? base_reg_rtx : gen_rtx_REG (SImode, regs[0]);
       emit_insn (gen_addsi3 (newbase, base_reg_rtx, GEN_INT (offset)));
       offset = 0;
-      if (!TARGET_THUMB1)
-       base_reg_rtx = newbase;
+      base_reg_rtx = newbase;
     }
 
   for (i = 0; i < nops; i++)
index 583b0452d61d9a04ac9e7a69d1a3f6db49804cbb..f1a8295aef93f7b5445a720a857b9e1e18e492a7 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-13  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       PR target/89190
+       * gcc.target/arm/pr89190.c: New test.
+
 2019-02-13  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/89036