Prefer to use strlen call instead of inline expansion (PR target/88809).
authorMartin Liska <mliska@suse.cz>
Thu, 2 May 2019 07:57:38 +0000 (09:57 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Thu, 2 May 2019 07:57:38 +0000 (07:57 +0000)
2019-05-02  Martin Liska  <mliska@suse.cz>

PR target/88809
* config/i386/i386.c (ix86_expand_strlen): Use strlen call.
With -minline-all-stringops use inline expansion using 4B loop.
* doc/invoke.texi: Document the change of
-minline-all-stringops.
2019-05-02  Martin Liska  <mliska@suse.cz>

PR target/88809
* gcc.target/i386/pr88809.c: New test.
* gcc.target/i386/pr88809-2.c: New test.

From-SVN: r270787

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr88809-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr88809.c [new file with mode: 0644]

index 7f6ccd98c1117689a5c5483f12532ddf4ab122f2..1883e4df91ff7d3959cf4e17df00f81b6fa82d4f 100644 (file)
@@ -1,3 +1,11 @@
+2019-05-02  Martin Liska  <mliska@suse.cz>
+
+       PR target/88809
+       * config/i386/i386.c (ix86_expand_strlen): Use strlen call.
+       With -minline-all-stringops use inline expansion using 4B loop.
+       * doc/invoke.texi: Document the change of
+       -minline-all-stringops.
+
 2019-05-01  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/88797
index 43ee77606e530f0dead119cbc51cfe8e2a58114d..e7ee83d63726db16b868c25df4bf04b2e69bc09e 100644 (file)
@@ -28270,68 +28270,34 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
 bool
 ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
 {
-  rtx addr, scratch1, scratch2, scratch3, scratch4;
-
-  /* The generic case of strlen expander is long.  Avoid it's
-     expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
-
-  if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
-      && !TARGET_INLINE_ALL_STRINGOPS
-      && !optimize_insn_for_size_p ()
-      && (!CONST_INT_P (align) || INTVAL (align) < 4))
-    return false;
-
-  addr = force_reg (Pmode, XEXP (src, 0));
-  scratch1 = gen_reg_rtx (Pmode);
-
-  if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
-      && !optimize_insn_for_size_p ())
-    {
+if (TARGET_UNROLL_STRLEN
+          && TARGET_INLINE_ALL_STRINGOPS
+          && eoschar == const0_rtx
+          && optimize > 1)
+    {
+      /* The generic case of strlen expander is long.  Avoid it's
+        expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
+      rtx addr = force_reg (Pmode, XEXP (src, 0));
       /* Well it seems that some optimizer does not combine a call like
-         foo(strlen(bar), strlen(bar));
-         when the move and the subtraction is done here.  It does calculate
-         the length just once when these instructions are done inside of
-         output_strlen_unroll().  But I think since &bar[strlen(bar)] is
-         often used and I use one fewer register for the lifetime of
-         output_strlen_unroll() this is better.  */
+        foo(strlen(bar), strlen(bar));
+        when the move and the subtraction is done here.  It does calculate
+        the length just once when these instructions are done inside of
+        output_strlen_unroll().  But I think since &bar[strlen(bar)] is
+        often used and I use one fewer register for the lifetime of
+        output_strlen_unroll() this is better.  */
 
       emit_move_insn (out, addr);
 
       ix86_expand_strlensi_unroll_1 (out, src, align);
 
       /* strlensi_unroll_1 returns the address of the zero at the end of
-         the string, like memchr(), so compute the length by subtracting
-         the start address.  */
+        the string, like memchr(), so compute the length by subtracting
+        the start address.  */
       emit_insn (ix86_gen_sub3 (out, out, addr));
+      return true;
     }
   else
-    {
-      rtx unspec;
-
-      /* Can't use this if the user has appropriated eax, ecx, or edi.  */
-      if (fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
-        return false;
-      /* Can't use this for non-default address spaces.  */
-      if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src)))
-       return false;
-
-      scratch2 = gen_reg_rtx (Pmode);
-      scratch3 = gen_reg_rtx (Pmode);
-      scratch4 = force_reg (Pmode, constm1_rtx);
-
-      emit_move_insn (scratch3, addr);
-      eoschar = force_reg (QImode, eoschar);
-
-      src = replace_equiv_address_nv (src, scratch3);
-
-      /* If .md starts supporting :P, this can be done in .md.  */
-      unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (4, src, eoschar, align,
-                                                scratch4), UNSPEC_SCAS);
-      emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec));
-      emit_insn (ix86_gen_one_cmpl2 (scratch2, scratch1));
-      emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx));
-    }
-  return true;
+    return false;
 }
 
 /* For given symbol (function) construct code to compute address of it's PLT
index 516eb24eb742cc284369c4b614a86e59a71dea8d..de7e1aaec672efe113d9690c7655185330e1a965 100644 (file)
@@ -28506,8 +28506,9 @@ By default GCC inlines string operations only when the destination is
 known to be aligned to least a 4-byte boundary.  
 This enables more inlining and increases code
 size, but may improve performance of code that depends on fast
-@code{memcpy}, @code{strlen},
-and @code{memset} for short lengths.
+@code{memcpy} and @code{memset} for short lengths.
+The option enables inline expansion of @code{strlen} for all
+pointer alignments.
 
 @item -minline-stringops-dynamically
 @opindex minline-stringops-dynamically
index 45b181a24f89383af398c22553530d805907e4b0..30227ca83b601f18d9c356cf6229317ef24f8b23 100644 (file)
@@ -1,3 +1,9 @@
+2019-05-02  Martin Liska  <mliska@suse.cz>
+
+       PR target/88809
+       * gcc.target/i386/pr88809.c: New test.
+       * gcc.target/i386/pr88809-2.c: New test.
+
 2019-05-01  Dominique d'Humieres  <dominiq@gcc.gnu.org>
 
        PR fortran/60144
diff --git a/gcc/testsuite/gcc.target/i386/pr88809-2.c b/gcc/testsuite/gcc.target/i386/pr88809-2.c
new file mode 100644 (file)
index 0000000..b8ef51d
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR target/88809 */
+/* { dg-options "-Os" } */
+
+unsigned int foo (const char *ptr)
+{
+  return __builtin_strlen (ptr);
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]strlen" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr88809.c b/gcc/testsuite/gcc.target/i386/pr88809.c
new file mode 100644 (file)
index 0000000..20844dd
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR target/88809 */
+/* { dg-options "-O" } */
+
+unsigned int foo (const char *ptr)
+{
+  return __builtin_strlen (ptr);
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]strlen" } } */