[tree-ssa] fix opt/10399, again

Richard Henderson rth@redhat.com
Fri Feb 27 23:37:00 GMT 2004


When 10399 was fixed, we removed the problematic code from 
expand_builtin_str[n]cmp, but not simplify_builtin_str[n]cmp.

Sigh.  


r~


        * builtins.c (simplify_builtin_strcmp): Don't export.  Remove
        length parameters.  Remove conversion to memcmp. 
        (simplify_builtin_strncmp): Likewise.
        * expr.h: Don't declare them.
        * tree-ssa-ccp.c (ccp_fold_builtin): Don't call them.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.152.2.51
diff -c -p -d -r1.152.2.51 builtins.c
*** builtins.c	16 Feb 2004 12:35:41 -0000	1.152.2.51
--- builtins.c	27 Feb 2004 22:18:09 -0000
*************** static tree fold_builtin_strncmp (tree);
*** 169,174 ****
--- 169,176 ----
  static tree fold_builtin_signbit (tree);
  
  static tree simplify_builtin_memcmp (tree);
+ static tree simplify_builtin_strcmp (tree);
+ static tree simplify_builtin_strncmp (tree);
  static tree simplify_builtin_strpbrk (tree);
  static tree simplify_builtin_strstr (tree);
  static tree simplify_builtin_strchr (tree);
*************** simplify_builtin (tree exp, int ignore)
*** 7576,7585 ****
        val = simplify_builtin_strncpy (arglist, NULL_TREE);
        break;
      case BUILT_IN_STRCMP:
!       val = simplify_builtin_strcmp (arglist, NULL_TREE, NULL_TREE);
        break;
      case BUILT_IN_STRNCMP:
!       val = simplify_builtin_strncmp (arglist, NULL_TREE, NULL_TREE);
        break;
      case BUILT_IN_STRPBRK:
        val = simplify_builtin_strpbrk (arglist);
--- 7578,7587 ----
        val = simplify_builtin_strncpy (arglist, NULL_TREE);
        break;
      case BUILT_IN_STRCMP:
!       val = simplify_builtin_strcmp (arglist);
        break;
      case BUILT_IN_STRNCMP:
!       val = simplify_builtin_strncmp (arglist);
        break;
      case BUILT_IN_STRPBRK:
        val = simplify_builtin_strpbrk (arglist);
*************** simplify_builtin_memcmp (tree arglist)
*** 8067,8076 ****
     COMPOUND_EXPR in the chain will contain the tree for the simplified
     form of the builtin function call.  */
  
! tree
! simplify_builtin_strcmp (tree arglist, tree len1, tree len2)
  {
!   tree arg1, arg2, fn;
    const char *p1, *p2;
  
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
--- 8069,8078 ----
     COMPOUND_EXPR in the chain will contain the tree for the simplified
     form of the builtin function call.  */
  
! static tree
! simplify_builtin_strcmp (tree arglist)
  {
!   tree arg1, arg2;
    const char *p1, *p2;
  
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
*************** simplify_builtin_strcmp (tree arglist, t
*** 8079,8084 ****
--- 8081,8090 ----
    arg1 = TREE_VALUE (arglist);
    arg2 = TREE_VALUE (TREE_CHAIN (arglist));
  
+   /* If both arguments are equal (and not volatile), return zero.  */
+   if (operand_equal_p (arg1, arg2, 0))
+     return integer_zero_node;
+ 
    p1 = c_getstr (arg1);
    p2 = c_getstr (arg2);
  
*************** simplify_builtin_strcmp (tree arglist, t
*** 8107,8155 ****
        return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
      }
  
!   if (!len1)
!     len1 = c_strlen (arg1, 0);
!   if (len1)
!     len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
! 
!   if (!len2)
!     len2 = c_strlen (arg2, 0);
!   if (len2)
!     len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
! 
!   /* If we don't have a constant length for the first, use the length
!      of the second, if we know it.  We don't require a constant for
!      this case; some cost analysis could be done if both are available
!      but neither is constant.  For now, assume they're equally cheap
!      unless one has side effects.
! 
!      If both strings have constant lengths, use the smaller.  This
!      could arise if optimization results in strcpy being called with
!      two fixed strings, or if the code was machine-generated.  We should
!      add some code to the `memcmp' handler below to deal with such
!      situations, someday.  */
! 
!   if (!len1 || TREE_CODE (len1) != INTEGER_CST)
!     {
!       if (len2 && !TREE_SIDE_EFFECTS (len2))
! 	len1 = len2;
!       else if (len1 == 0)
! 	return 0;
!     }
!   else if (len2 && TREE_CODE (len2) == INTEGER_CST
! 	   && tree_int_cst_lt (len2, len1))
!     len2 = len2;
! 
!   /* If both arguments have side effects, we cannot optimize.  */
!   if (TREE_SIDE_EFFECTS (len1))
!     return 0;
! 
!   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
!   if (!fn)
!     return 0;
! 
!   chainon (arglist, build_tree_list (NULL_TREE, len1));
!   return build_function_call_expr (fn, arglist);
  }
  
  /* Simplify a call to the strncmp builtin.
--- 8113,8119 ----
        return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
      }
  
!   return 0;
  }
  
  /* Simplify a call to the strncmp builtin.
*************** simplify_builtin_strcmp (tree arglist, t
*** 8169,8178 ****
     COMPOUND_EXPR in the chain will contain the tree for the simplified
     form of the builtin function call.  */
  
! tree
! simplify_builtin_strncmp (tree arglist, tree len1, tree len2)
  {
-   tree fn, newarglist, len = 0;
    tree arg1, arg2, arg3;
    const char *p1, *p2;
  
--- 8133,8141 ----
     COMPOUND_EXPR in the chain will contain the tree for the simplified
     form of the builtin function call.  */
  
! static tree
! simplify_builtin_strncmp (tree arglist)
  {
    tree arg1, arg2, arg3;
    const char *p1, *p2;
  
*************** simplify_builtin_strncmp (tree arglist, 
*** 8185,8191 ****
    arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
  
    /* If the len parameter is zero, return zero.  */
!   if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
      {
        /* Evaluate and ignore arg1 and arg2 in case they have
  	 side-effects.  */
--- 8148,8154 ----
    arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
  
    /* If the len parameter is zero, return zero.  */
!   if (integer_zerop (arg3))
      {
        /* Evaluate and ignore arg1 and arg2 in case they have
  	 side-effects.  */
*************** simplify_builtin_strncmp (tree arglist, 
*** 8194,8199 ****
--- 8157,8169 ----
  			   arg2, integer_zero_node));
      }
  
+   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
+   if (operand_equal_p (arg1, arg2, 0))
+     {
+       /* Evaluate and ignore arg3 in case it has side-effects.  */
+       return build (COMPOUND_EXPR, integer_type_node, arg3, integer_zero_node);
+     }
+ 
    p1 = c_getstr (arg1);
    p2 = c_getstr (arg2);
  
*************** simplify_builtin_strncmp (tree arglist, 
*** 8226,8266 ****
        return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
      }
  
!   /* If c_strlen can determine an expression for one of the string
!      lengths, and it doesn't have side effects, then call
!      expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3).  */
! 
!   /* Perhaps one of the strings is really constant, if so prefer
!      that constant length over the other string's length.  */
!   if (p1)
!     len = len1 ? len1 : c_strlen (arg1, 0);
!   else if (p2)
!     len = len2 ? len2 : c_strlen (arg2, 0);
! 
!   /* If we still don't have a len, try either string arg as long
!      as they don't have side effects.  */
!   if (!len && !TREE_SIDE_EFFECTS (arg1))
!     len = c_strlen (arg1, 0);
!   if (!len && !TREE_SIDE_EFFECTS (arg2))
!     len = c_strlen (arg2, 0);
!   /* If we still don't have a length, punt.  */
!   if (!len)
!     return 0;
! 
!   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
!   if (!fn)
!     return 0;
! 
!   /* Add one to the string length.  */
!   len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
! 
!   /* The actual new length parameter is MIN(len,arg3).  */
!   len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
! 
!   newarglist = build_tree_list (NULL_TREE, len);
!   newarglist = tree_cons (NULL_TREE, arg2, newarglist);
!   newarglist = tree_cons (NULL_TREE, arg1, newarglist);
!   return build_function_call_expr (fn, newarglist);
  }
  
  /* Simplify a call to the strcat builtin.
--- 8196,8202 ----
        return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
      }
  
!   return 0;
  }
  
  /* Simplify a call to the strcat builtin.
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.117.2.27
diff -c -p -d -r1.117.2.27 expr.h
*** expr.h	19 Feb 2004 09:05:25 -0000	1.117.2.27
--- expr.h	27 Feb 2004 22:18:09 -0000
*************** extern void record_alias_subset (HOST_WI
*** 372,379 ****
  extern HOST_WIDE_INT new_alias_set (void);
  extern int can_address_p (tree);
  extern tree simplify_builtin_fputs (tree, int, int, tree);
- extern tree simplify_builtin_strcmp (tree, tree, tree);
- extern tree simplify_builtin_strncmp (tree, tree, tree);
  extern tree simplify_builtin_strcpy (tree, tree);
  extern tree simplify_builtin_strncpy (tree, tree);
  
--- 372,377 ----
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.143
diff -c -p -d -r1.1.2.143 tree-ssa-ccp.c
*** tree-ssa-ccp.c	25 Feb 2004 03:22:47 -0000	1.1.2.143
--- tree-ssa-ccp.c	27 Feb 2004 22:18:09 -0000
*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2068,2076 ****
      case BUILT_IN_STRNCPY:
        strlen_arg = 2;
        break;
-     case BUILT_IN_STRCMP:
-     case BUILT_IN_STRNCMP:
-       strlen_arg = 3;
      default:
        return NULL_TREE;
      }
--- 2068,2073 ----
*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2102,2111 ****
        return simplify_builtin_strcpy (arglist, strlen_val[1]);
      case BUILT_IN_STRNCPY:
        return simplify_builtin_strncpy (arglist, strlen_val[1]);
-     case BUILT_IN_STRCMP:
-       return simplify_builtin_strcmp (arglist, strlen_val[0], strlen_val[1]);
-     case BUILT_IN_STRNCMP:
-       return simplify_builtin_strncmp (arglist, strlen_val[0], strlen_val[1]);
      case BUILT_IN_FPUTS:
        return simplify_builtin_fputs (arglist,
  				     TREE_CODE (stmt) != MODIFY_EXPR, 0,
--- 2099,2104 ----



More information about the Gcc-patches mailing list