Re: [PATCH] Fold __builtin_str{n}{case}cmp functions (simplified version 4)

2016-10-14 Thread Richard Biener
On Thu, Oct 13, 2016 at 5:24 PM, Martin Liška  wrote:
> Simplified version that just supports only null-terminated strings.
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?

Ok.

Richard.

> Martin


[PATCH] Fold __builtin_str{n}{case}cmp functions (simplified version 4)

2016-10-13 Thread Martin Liška
Simplified version that just supports only null-terminated strings.
Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin
>From 41c49024a02cff43774903206ad77b2ae161e81a Mon Sep 17 00:00:00 2001
From: marxin 
Date: Thu, 13 Oct 2016 10:25:25 +0200
Subject: [PATCH 2/4] Fold __builtin_str{n}{case}cmp functions

gcc/ChangeLog:

2016-10-13  Martin Liska  

	* builtins.c (fold_builtin_strcmp): Remove function.
	(fold_builtin_strncmp): Likewise.
	(fold_builtin_2): Remove call of the function.
	(fold_builtin_3): Likewise.
	* fold-const-call.c (fold_const_call): Add constant folding
	for CFN_BUILT_IN_STRCASECMP and CFN_BUILT_IN_STRNCASECMP.
	* fold-const-call.h (build_cmp_result): Declare the function.
	* gimple-fold.c (gimple_load_first_char): New function.
	(gimple_fold_builtin_string_compare): Likewise.
	(gimple_fold_builtin): Call the function.
---
 gcc/builtins.c| 138 
 gcc/fold-const-call.c |  45 +---
 gcc/fold-const-call.h |   1 +
 gcc/gimple-fold.c | 189 +-
 4 files changed, 226 insertions(+), 147 deletions(-)

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 43a9db0..ed5a635 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -150,8 +150,6 @@ static rtx expand_builtin_fabs (tree, rtx, rtx);
 static rtx expand_builtin_signbit (tree, rtx);
 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
 static tree fold_builtin_memcmp (location_t, tree, tree, tree);
-static tree fold_builtin_strcmp (location_t, tree, tree);
-static tree fold_builtin_strncmp (location_t, tree, tree, tree);
 static tree fold_builtin_isascii (location_t, tree);
 static tree fold_builtin_toascii (location_t, tree);
 static tree fold_builtin_isdigit (location_t, tree);
@@ -7331,136 +7329,6 @@ fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
   return NULL_TREE;
 }
 
-/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
-   Return NULL_TREE if no simplification can be made.  */
-
-static tree
-fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
-{
-  if (!validate_arg (arg1, POINTER_TYPE)
-  || !validate_arg (arg2, POINTER_TYPE))
-return NULL_TREE;
-
-  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
-  if (operand_equal_p (arg1, arg2, 0))
-return integer_zero_node;
-
-  /* If the second arg is "", return *(const unsigned char*)arg1.  */
-  const char *p2 = c_getstr (arg2);
-  if (p2 && *p2 == '\0')
-{
-  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
-  tree cst_uchar_ptr_node
-	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
-
-  return fold_convert_loc (loc, integer_type_node,
-			   build1 (INDIRECT_REF, cst_uchar_node,
-   fold_convert_loc (loc,
-			 cst_uchar_ptr_node,
-			 arg1)));
-}
-
-  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
-  const char *p1 = c_getstr (arg1);
-  if (p1 && *p1 == '\0')
-{
-  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
-  tree cst_uchar_ptr_node
-	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
-
-  tree temp
-	= fold_convert_loc (loc, integer_type_node,
-			build1 (INDIRECT_REF, cst_uchar_node,
-fold_convert_loc (loc,
-		  cst_uchar_ptr_node,
-		  arg2)));
-  return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
-}
-
-  return NULL_TREE;
-}
-
-/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
-   Return NULL_TREE if no simplification can be made.  */
-
-static tree
-fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
-{
-  if (!validate_arg (arg1, POINTER_TYPE)
-  || !validate_arg (arg2, POINTER_TYPE)
-  || !validate_arg (len, INTEGER_TYPE))
-return NULL_TREE;
-
-  /* If the LEN parameter is zero, return zero.  */
-  if (integer_zerop (len))
-return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
-			  arg1, arg2);
-
-  /* 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);
-
-  /* If the second arg is "", and the length is greater than zero,
- return *(const unsigned char*)arg1.  */
-  const char *p2 = c_getstr (arg2);
-  if (p2 && *p2 == '\0'
-  && TREE_CODE (len) == INTEGER_CST
-  && tree_int_cst_sgn (len) == 1)
-{
-  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
-  tree cst_uchar_ptr_node
-	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
-
-  return fold_convert_loc (loc, integer_type_node,
-			   build1 (INDIRECT_REF, cst_uchar_node,
-   fold_convert_loc (loc,
-			 cst_uchar_ptr_node,
-			 arg1)));
-