On Sun, Sep 02, 2012 at 10:18:15PM -0700, Andrew Pinski wrote:
>   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.
> @@ -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;
>  }
>  

That is too hackish and lists way too few builtins.
If you rely on nonnull attribute marked builtins, I'd say you want
flags = gimple_call_return_flags (stmt);
if ((flags & ERF_RETURNS_ARG)
    && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
  {
    /* Test nonnull attribute on the decl, either argument-less or
       on the (flags & ERF_RETURN_ARG_MASK)th argument.  */
  }
Or at least handle builtins e.g. CCP handles as pass-thru arg1:
BUILT_IN_MEMCPY, BUILT_IN_MEMMOVE, BUILT_IN_MEMSET, BUILT_IN_STRCPY,
BUILT_IN_STRNCPY, BUILT_IN_MEMCPY_CHK, BUILT_IN_MEMMOVE_CHK,
BUILT_IN_MEMSET_CHK, BUILT_IN_STRCPY_CHK, BUILT_IN_STRNCPY_CHK
(which reminds me that some of these apparently aren't marked
with ATTR_RET1_NOTHROW_NONNULL_LEAF, why?).

> @@ -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;
> +               }
> +         }
> +     }
> +    }

Again, what you are looking for here?  Passing pointers to nonnull
attributes, or something more specific?  What exactly?  There are tons of
builtins that behave similarly to memcpy/memmove/strcmp/memcmp.

        Jakub

Reply via email to