https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71304

            Bug ID: 71304
           Summary: missing strlen optimizations after string truncation
                    by assigning NUL
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

Somewhat related to bug 71303 (also in tree-ssa-strlen.c), GCC manages to
optimize the call to strlen after a call to strcpy (in function f below) but it
misses the same opportunity after the equivalent modification of the string by
overwriting its second element by the NUL character (function g).

It ought to be possible to have the NUL store create (at least) two new strinfo
entries from the one into which it's stored: one for the part up to the
inserted NUL, and the empty string formed by the NUL (and possibly also one for
the remainder from the character just after the NUL until the final NUL).  With
this approach both functions in the test case below are optimized identically.

$ cat t.c && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -O2 -S -Wall
-Wextra -fdump-tree-optimized=/dev/stdout -o/dev/stdout t.c
int f (void)
{
  char s[] = "12345";
  __builtin_strcpy (s, "1");
  return __builtin_strlen (s);
}

int g (void)
{
  char s[] = "12345";
  s [1] = '\0';
  return __builtin_strlen (s);
}
        .file   "t.c"
        .machine power8
        .abiversion 2

;; Function f (f, funcdef_no=0, decl_uid=2297, cgraph_uid=0, symbol_order=0)

f ()
{
  <bb 2>:
  return 1;

}


        .section        ".text"
        .align 2
        .p2align 4,,15
        .globl f
        .type   f, @function
f:
        li 3,1
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0
        .size   f,.-f

;; Function g (g, funcdef_no=1, decl_uid=2301, cgraph_uid=1, symbol_order=1)

g ()
{
  char s[6];
  long unsigned int _1;
  int _5;

  <bb 2>:
  s = "12345";
  s[1] = 0;
  _1 = __builtin_strlen (&s);
  _5 = (int) _1;
  s ={v} {CLOBBER};
  return _5;

}


        .align 2
        .p2align 4,,15
        .globl g
        .type   g, @function
g:
.LCF1:
0:      addis 2,12,.TOC.-.LCF1@ha
        addi 2,2,.TOC.-.LCF1@l
        .localentry     g,.-g
        mflr 0
        addis 9,2,.LC0@toc@ha           # gpr load fusion, type int
        lwz 9,.LC0@toc@l(9)
        std 0,16(1)
        stdu 1,-48(1)
        stw 9,32(1)
        addis 9,2,.LC0+4@toc@ha         # gpr load fusion, type short
        lhz 9,.LC0+4@toc@l(9)
        addi 3,1,32
        sth 9,36(1)
        li 9,0
        stb 9,33(1)
        bl strlen
        nop
        addi 1,1,48
        ld 0,16(1)
        extsw 3,3
        mtlr 0
        blr
        .long 0
        .byte 0,0,0,1,128,0,0,0
        .size   g,.-g
        .section        .rodata.str1.8,"aMS",@progbits,1
        .align 3
.LC0:
        .string "12345"
        .ident  "GCC: (GNU) 7.0.0 20160523 (experimental)"
        .section        .note.GNU-stack,"",@progbits

Reply via email to