Hi!

As discussed in the PR and on IRC, some places in gimple-fold.c/match.pd
rely on the fact that if gimple_builtin_call_types_compatible_p
succeeds, then it should be ok to pass arguments and read lhs without
type conversions.  But, currently this function uses validate_type, which is
a very weak type compatibility check.

This patch instead requires standard middle-end type compatibility.
Bootstrap/regtest of the gimple.c portion of the patch revealed a bug in
value-prof.c, which has been passing constant last argument to various
stringop functions in incompatible type to what the builtin wants, so I've
fixed that too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-01-13  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/69156
        * gimple.c (validate_type): Removed.
        (gimple_builtin_call_types_compatible_p): Use
        useless_type_conversion_p instead of validate_type.
        * value-prof.c (gimple_stringop_fixed_value): Fold
        icall_size to correct type.

        * gcc.dg/pr69156.c: New test.

--- gcc/gimple.c.jj     2016-01-04 14:55:53.000000000 +0100
+++ gcc/gimple.c        2016-01-13 13:15:07.194943810 +0100
@@ -2445,24 +2445,6 @@ gimple_ior_addresses_taken (bitmap addre
 }
 
 
-/* Return true if TYPE1 and TYPE2 are compatible enough for builtin
-   processing.  */
-
-static bool
-validate_type (tree type1, tree type2)
-{
-  if (INTEGRAL_TYPE_P (type1)
-      && INTEGRAL_TYPE_P (type2))
-    ;
-  else if (POINTER_TYPE_P (type1)
-          && POINTER_TYPE_P (type2))
-    ;
-  else if (TREE_CODE (type1)
-          != TREE_CODE (type2))
-    return false;
-  return true;
-}
-
 /* Return true when STMTs arguments and return value match those of FNDECL,
    a decl of a builtin function.  */
 
@@ -2473,7 +2455,8 @@ gimple_builtin_call_types_compatible_p (
 
   tree ret = gimple_call_lhs (stmt);
   if (ret
-      && !validate_type (TREE_TYPE (ret), TREE_TYPE (TREE_TYPE (fndecl))))
+      && !useless_type_conversion_p (TREE_TYPE (ret),
+                                    TREE_TYPE (TREE_TYPE (fndecl))))
     return false;
 
   tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
@@ -2484,7 +2467,7 @@ gimple_builtin_call_types_compatible_p (
       if (!targs)
        return true;
       tree arg = gimple_call_arg (stmt, i);
-      if (!validate_type (TREE_TYPE (arg), TREE_VALUE (targs)))
+      if (!useless_type_conversion_p (TREE_VALUE (targs), TREE_TYPE (arg)))
        return false;
       targs = TREE_CHAIN (targs);
     }
--- gcc/value-prof.c.jj 2016-01-04 14:55:53.000000000 +0100
+++ gcc/value-prof.c    2016-01-13 13:14:56.139094912 +0100
@@ -1697,7 +1697,8 @@ gimple_stringop_fixed_value (gcall *vcal
   gimple_set_vuse (vcall_stmt, NULL);
   update_stmt (vcall_stmt);
   icall_stmt = as_a <gcall *> (gimple_copy (vcall_stmt));
-  gimple_call_set_arg (icall_stmt, size_arg, icall_size);
+  gimple_call_set_arg (icall_stmt, size_arg,
+                      fold_convert (optype, icall_size));
   gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
 
   /* Fix CFG. */
--- gcc/testsuite/gcc.dg/pr69156.c.jj   2016-01-13 10:42:50.465247811 +0100
+++ gcc/testsuite/gcc.dg/pr69156.c      2016-01-13 10:42:50.465247811 +0100
@@ -0,0 +1,10 @@
+/* PR tree-optimization/69156 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-ccp" } */
+
+_Bool
+foo ()
+{
+  _Bool (*f) () = __builtin_abs;       /* { dg-warning "initialization from 
incompatible pointer type" } */
+  return f (0);
+}

        Jakub

Reply via email to