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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
           Keywords|                            |missed-optimization
             Status|UNCONFIRMED                 |NEW
   Target Milestone|---                         |9.4
   Last reconfirmed|                            |2020-10-01

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
  const char a[5];
  int _3;

  <bb 2> [local count: 1073741824]:
  a = "1234";
  _3 = __builtin_memcmp (&a, "1234", 4);

so somehow the const initializer is no longer visible here that makes it
impossible for the generic folding machinery to pick up the opportunity.

I guess 4.8 folded it in GENERIC before the gimplifier(?) lowered the
const initializer.

In particular we're still calling fold_builtin_memcmp via

#0  fold_builtin_memcmp (loc=266991, arg1=<nop_expr 0x7ffff694b1c0>, 
    arg2=<nop_expr 0x7ffff694b1e0>, len=<integer_cst 0x7ffff6941fc0>)
    at /home/rguenther/src/gcc3/gcc/builtins.c:9799
#1  0x0000000000ba58dc in fold_builtin_3 (loc=266991, 
    fndecl=<function_decl 0x7ffff68b8500 __builtin_memcmp>, 
    arg0=<nop_expr 0x7ffff694b1c0>, arg1=<nop_expr 0x7ffff694b1e0>, 
    arg2=<integer_cst 0x7ffff6941fc0>)
    at /home/rguenther/src/gcc3/gcc/builtins.c:10844
#2  0x0000000000ba5a31 in fold_builtin_n (loc=266991, expr=<tree 0x0>, 
    fndecl=<function_decl 0x7ffff68b8500 __builtin_memcmp>, 
    args=0x7ffff6939cd8, nargs=3)
    at /home/rguenther/src/gcc3/gcc/builtins.c:10907
#3  0x0000000000ba61dc in fold_builtin_call_array (loc=266991, 
    fn=<addr_expr 0x7ffff694b1a0>, n=3, argarray=0x7ffff6939cd8)
    at /home/rguenther/src/gcc3/gcc/builtins.c:11040
#4  0x0000000000e2cc44 in fold_build_call_array_loc (loc=266991, 
    type=<integer_type 0x7ffff68255e8 int>, fn=<addr_expr 0x7ffff694b1a0>, 
    nargs=3, argarray=0x7ffff6939cd8)
    at /home/rguenther/src/gcc3/gcc/fold-const.c:13373
#5  0x00000000009f4434 in build_function_call_vec (loc=266991, arg_loc=..., 
    function=<addr_expr 0x7ffff694b1a0>, params=0x7ffff6939cd0 = {...}, 
    origtypes=0x7ffff6939cf8 = {...}, 
    orig_fundecl=<function_decl 0x7ffff68b8500 __builtin_memcmp>)
    at /home/rguenther/src/gcc3/gcc/c/c-typeck.c:3151
#6  0x00000000009f4a3b in c_build_function_call_vec (loc=266991, arg_loc=..., 
    function=<function_decl 0x7ffff68b8500 __builtin_memcmp>, 
    params=0x7ffff6939cd0 = {...}, origtypes=0x7ffff6939cf8 = {...})
    at /home/rguenther/src/gcc3/gcc/c/c-typeck.c:3206
#7  0x0000000000a4ec6b in c_parser_postfix_expression_after_primary (
    parser=0x7ffff7ff5ab0, expr_loc=266991, expr=...)
    at /home/rguenther/src/gcc3/gcc/c/c-parser.c:10549
#8  0x0000000000a4dbec in c_parser_postfix_expression (parser=0x7ffff7ff5ab0)
    at /home/rguenther/src/gcc3/gcc/c/c-parser.c:10222
#9  0x0000000000a4730e in c_parser_unary_expression (parser=0x7ffff7ff5ab0)
    at /home/rguenther/src/gcc3/gcc/c/c-parser.c:8315
#10 0x0000000000a467fc in c_parser_cast_expression (parser=0x7ffff7ff5ab0, 
    after=0x0) at /home/rguenther/src/gcc3/gcc/c/c-parser.c:8154
#11 0x0000000000a44e7a in c_parser_binary_expression (parser=0x7ffff7ff5ab0, 
    after=0x0, omp_atomic_lhs=<tree 0x0>)
    at /home/rguenther/src/gcc3/gcc/c/c-parser.c:7957
#12 0x0000000000a4466d in c_parser_conditional_expression (
    parser=0x7ffff7ff5ab0, after=0x0, omp_atomic_lhs=<tree 0x0>)
    at /home/rguenther/src/gcc3/gcc/c/c-parser.c:7691

but that doesn't do anything fancy, in particular

  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
  if (operand_equal_p (arg1, arg2, 0))
    return omit_one_operand_loc (loc, integer_type_node, integer_zero_node,
len);

doesn't trigger on

(gdb) p debug_generic_expr (arg1)
(const void *) &a
$2 = void
(gdb) p debug_generic_expr (arg2)
(const void *) "1234"
$3 = void

        arg:0 <var_decl 0x7ffff7ff5b40 a type <array_type 0x7ffff6945738>
            readonly addressable used read BLK t5.c:3:14
            size <integer_cst 0x7ffff6941f90 constant 40>
            unit-size <integer_cst 0x7ffff6941f60 constant 5>
            align:8 warn_if_not_align:0 context <function_decl 0x7ffff693d600
f> initial <string_cst 0x7ffff694b0a0>>

and the gimplifier already produces

f ()
{
  int D.1935;
  const char a[5];

  try
    {
      a = "1234";
      D.1935 = __builtin_memcmp (&a, "1234", 4);
      return D.1935;
    }
  finally
    {
      a = {CLOBBER};
    }
}

so iff then this is something for the strlen opt pass which tracks
stores and it becomes sth like

int f (void)
{
  char a[] = "5678910";
  memcpy (a, "1234", 4);
  return __builtin_memcmp (a, "1234", 4);
}

which isn't folded either.

Reply via email to