Bug 86083 - handle non-constant assignments in strlen
Summary: handle non-constant assignments in strlen
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 8.0
: P3 enhancement
Target Milestone: ---
Assignee: Martin Sebor
URL:
Keywords: missed-optimization, patch
Depends on:
Blocks: strlen
  Show dependency treegraph
 
Reported: 2018-06-07 17:13 UTC by Martin Sebor
Modified: 2018-06-11 20:02 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-06-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2018-06-07 17:13:55 UTC
As discussed in pr57230, the strlen optimizing pass manages to track string lengths across non-nul constant character stores, it doesn't do the same for non-constant stores even if their value is known to be non-nul (i.e., it's in some range that excludes nul).  It's a trivial enhancement to have the pass consider value ranges and implement the tracking in the non-constant case so that the bodies of both functions below are eliminated and not just that of f().

$ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c
void f (void)
{
  char a[] = "123";

  a[1] = '4';

  if (__builtin_strlen (a) != 3)   // folded
    __builtin_abort ();
}

void g (unsigned i)
{
  char a[] = "123";

  a[1] = '0' + (i % 10);

  if (__builtin_strlen (a) != 3)   // not folded
    __builtin_abort ();
}

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

f ()
{
  <bb 2> [local count: 1073741825]:
  return;

}



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

g (unsigned int i)
{
  char a[4];
  unsigned int _1;
  unsigned char _2;
  unsigned char _3;
  char _4;
  long unsigned int _5;

  <bb 2> [local count: 1073741825]:
  a = "123";
  _1 = i_8(D) % 10;
  _2 = (unsigned char) _1;
  _3 = _2 + 48;
  _4 = (char) _3;
  a[1] = _4;
  _5 = __builtin_strlen (&a);
  if (_5 != 3)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073312327]:
  a ={v} {CLOBBER};
  return;

}
Comment 1 Martin Sebor 2018-06-10 22:14:44 UTC
Patch: https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00539.html
Comment 2 Martin Sebor 2018-06-11 20:02:12 UTC
Author: msebor
Date: Mon Jun 11 20:01:40 2018
New Revision: 261452

URL: https://gcc.gnu.org/viewcvs?rev=261452&root=gcc&view=rev
Log:
PR tree-optimization/86083 - handle non-constant assignments in strlen

gcc/ChangeLog:

	PR tree-optimization/86083
	* tree-ssa-strlen.c (handle_char_store): Use tree_expr_nonzero_p.

gcc/testsuite/ChangeLog:

	PR tree-optimization/86083
	* gcc.dg/strlenopt-44.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/strlenopt-44.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-strlen.c
Comment 3 Martin Sebor 2018-06-11 20:02:28 UTC
Patch committed in r261452.