re PR target/39423 ([SH] performance regression: lost mov @(disp,Rn))
authorOleg Endo <olegendo@gcc.gnu.org>
Tue, 21 Aug 2012 23:34:54 +0000 (23:34 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Tue, 21 Aug 2012 23:34:54 +0000 (23:34 +0000)
PR target/39423
* config/sh/sh.md (*movhi_index_disp): Add support for SH2A movu.w insn.

PR target/39423
* gcc.target/sh/pr39423-2.c: New.

From-SVN: r190579

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr39423-2.c [new file with mode: 0644]

index 7400fe87f71342737e3694e8f0f1a80bfe4cfaf6..30d23355c5cfcdf085d522673b0f34bf83e48b4f 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/39423
+       * config/sh/sh.md (*movhi_index_disp): Add support for SH2A movu.w insn.
+
 2012-08-21  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR middle-end/54332
index d38fd20a33461f42ee1a88c8fe69ff69c262358c..bc2a6c1a8d2f4e720fc39988944e0c720f69f901 100644 (file)
@@ -5793,12 +5793,35 @@ label:
    (clobber (reg:SI T_REG))]
   "TARGET_SH1"
   "#"
-  "&& 1"
-  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
-             (clobber (reg:SI T_REG))])
-   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
+  "&& can_create_pseudo_p ()"
+  [(const_int 0)]
 {
-  operands[2] = gen_lowpart (HImode, operands[0]);
+  rtx mem = operands[1];
+  rtx plus0_rtx = XEXP (mem, 0);
+  rtx plus1_rtx = XEXP (plus0_rtx, 0);
+  rtx mult_rtx = XEXP (plus1_rtx, 0);
+
+  rtx op_1 = XEXP (mult_rtx, 0);
+  rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
+  rtx op_3 = XEXP (plus1_rtx, 1);
+  rtx op_4 = XEXP (plus0_rtx, 1);
+  rtx op_5 = gen_reg_rtx (SImode);
+  rtx op_6 = gen_reg_rtx (SImode);
+  rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
+
+  emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
+  emit_insn (gen_addsi3 (op_6, op_5, op_3));
+
+  /* On SH2A the movu.w insn can be used for zero extending loads.  */
+  if (TARGET_SH2A)
+    emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
+  else
+    {
+      emit_insn (gen_extendhisi2 (operands[0], op_7));
+      emit_insn (gen_zero_extendhisi2 (operands[0],
+                                      gen_lowpart (HImode, operands[0])));
+    }
+  DONE;
 })
 
 (define_insn_and_split "*movsi_index_disp"
index 9bdd4f8c78784cb0678a7519378a127f3c6f6e31..672438080e141bcddc6ca0ec64dd035241b89896 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/39423
+       * gcc.target/sh/pr39423-2.c: New.
+
 2012-08-21  Marc Glisse  <marc.glisse@inria.fr>
 
        * gcc.dg/tree-ssa/forwprop-19.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/sh/pr39423-2.c b/gcc/testsuite/gcc.target/sh/pr39423-2.c
new file mode 100644 (file)
index 0000000..8e71505
--- /dev/null
@@ -0,0 +1,14 @@
+/* Check that displacement addressing is used for indexed addresses with a
+   small offset, instead of re-calculating the index and that the movu.w
+   instruction is used on SH2A.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */
+/* { dg-final { scan-assembler-not "add\t#1" } } */
+/* { dg-final { scan-assembler "movu.w" } } */
+
+int
+test_00 (unsigned short tab[], int index)
+{
+  return tab[index + 1];
+}