This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Improve VPR for some builtins and non pointer checks


On Sun, Sep 2, 2012 at 11:36 PM, Georg-Johann Lay <gjl@gcc.gnu.org> wrote:
> Andrew Pinski schrieb:
>>
>> Hi,
>>   While fixing some code not to have aliasing violations in it, I can
>> across that some builtins were not causing their arguments or their
>> return values being marked as non-null.  This patch implements just
>> that in VPR while allowing to remove some null pointer checks later
>> on.
>>
>> OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>>
>> Thanks,
>> Andrew Pinski
>>
>> ChangeLog:
>>         * tree-vrp.c (vrp_stmt_computes_nonzero): Return true for some
>>         builtins (memcpy and memmove).
>>         (infer_value_range): Infer nonzero for some arguments to
>>         some builtins (memcpy, memmove, strcmp and memcmp).
>>
>> testsuite/ChangeLog:
>>         * gcc.dg/tree-ssa/vrp-builtins1.c: New testcase.
>>
>>
>>
>> Index: tree-vrp.c
>> ===================================================================
>> --- tree-vrp.c  (revision 190868)
>> +++ tree-vrp.c  (working copy)
>> @@ -1057,6 +1057,20 @@ vrp_stmt_computes_nonzero (gimple stmt,
>>         }
>>      }
>>  +  /* With some builtins, we can infer if the pointer return value
>> +     will be non null.  */
>> +  if (flag_delete_null_pointer_checks
>> +      && is_gimple_call (stmt) && gimple_call_fndecl (stmt)
>> +      && DECL_BUILT_IN_CLASS (gimple_call_fndecl (stmt)) ==
>> BUILT_IN_NORMAL)
>> +    {
>> +      switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
>> +       {
>> +         case BUILT_IN_MEMCPY:
>> +         case BUILT_IN_MEMMOVE:
>> +           return true;
>> +       }
>> +    }
>> +
>>    return false;
>>  }
>>  @@ -4231,6 +4245,32 @@ infer_value_range (gimple stmt, tree op,
>>         }
>>      }
>>  +  /* With some builtins, we can infer if the pointer argument
>> +     will be non null.  */
>> +  if (flag_delete_null_pointer_checks
>> +      && is_gimple_call (stmt) && gimple_call_fndecl (stmt))
>> +    {
>> +      tree callee = gimple_call_fndecl (stmt);
>> +      if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
>> +       {
>> +         switch (DECL_FUNCTION_CODE (callee))
>> +           {
>> +             case BUILT_IN_MEMCPY:
>> +             case BUILT_IN_MEMMOVE:
>> +             case BUILT_IN_STRCMP:
>> +             case BUILT_IN_MEMCMP:
>> +               /* The first and second arguments of memcpy and memmove
>> will be non null after the call. */
>> +               if (gimple_call_arg (stmt, 0) == op
>> +                   || gimple_call_arg (stmt, 1) == op)
>> +                 {
>> +                   *val_p = build_int_cst (TREE_TYPE (op), 0);
>> +                   *comp_code_p = NE_EXPR;
>> +                   return true;
>> +                 }
>> +           }
>> +       }
>> +    }
>> +
>>    return false;
>>  }
>>  Index: testsuite/gcc.dg/tree-ssa/vrp-builtins1.c
>> ===================================================================
>> --- testsuite/gcc.dg/tree-ssa/vrp-builtins1.c   (revision 0)
>> +++ testsuite/gcc.dg/tree-ssa/vrp-builtins1.c   (revision 0)
>> @@ -0,0 +1,30 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -fdump-tree-vrp1" } */
>
>
> Shouldn't this xfail for avr and other targets that set
> flag_delete_null_pointer_checks = 0, cf.
> avr.c:avr_option_override() for example.

This is taken care of by the check keeps_null_pointer_checks which
returns true for avr-*-*.

Thanks,
Andrew Pinski


>
> Johann
>
>> +
>> +struct f1
>> +{
>> +char a[4];
>> +};
>> +
>> +int f(int *a, struct f1 b)
>> +{
>> +  int *c = __builtin_memcpy(a, b.a, 4);
>> +  if (c == 0)
>> +    return 0;
>> +  return *a;
>> +}
>> +
>> +
>> +int f1(int *a, struct f1 b)
>> +{
>> +  int *c = __builtin_memcpy(a, b.a, 4);
>> +  if (a == 0)
>> +    return 0;
>> +  return *a;
>> +}
>> +
>> +/* Both the if statements should be folded when the target does not keep
>> around null pointer checks. */
>> +/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp1" {
>> target {   keeps_null_pointer_checks } } } } */
>> +/* { dg-final { scan-tree-dump-times "Folding predicate" 2 "vrp1" {
>> target { ! keeps_null_pointer_checks } } } } */
>> +/* { dg-final { cleanup-tree-dump "vrp1" } } */
>> +
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]