aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/builtins.c36
2 files changed, 36 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 36a43a1..ea88fa1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2018-07-20 Qing Zhao <qing.zhao@oracle.com>
+
+ * builtins.c (expand_builtin_memcmp): Delete the last parameter for
+ call to inline_expand_builtin_string_cmp.
+ (expand_builtin_strcmp): Likewise.
+ (expand_builtin_strncmp): Likewise.
+ (inline_string_cmp): Delete the last parameter, change char_type_node
+ to unsigned_char_type_node for strcmp/strncmp, add conversions to the
+ two operands.
+ (inline_expand_builtin_string_cmp): Delete the last parameter, give up
+ the inlining expansion on target where the type of the call has same or
+ narrower precision than unsigned char.
+
2018-07-20 David Malcolm <dmalcolm@redhat.com>
* Makefile.in (OBJS): Add json.o and optinfo-emit-json.o.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index c069d66..493c937 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -119,7 +119,7 @@ static rtx expand_builtin_next_arg (void);
static rtx expand_builtin_va_start (tree);
static rtx expand_builtin_va_end (tree);
static rtx expand_builtin_va_copy (tree);
-static rtx inline_expand_builtin_string_cmp (tree, rtx, bool);
+static rtx inline_expand_builtin_string_cmp (tree, rtx);
static rtx expand_builtin_strcmp (tree, rtx);
static rtx expand_builtin_strncmp (tree, rtx, machine_mode);
static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, scalar_int_mode);
@@ -4472,7 +4472,7 @@ expand_builtin_memcmp (tree exp, rtx target, bool result_eq)
if (!result_eq && fcode != BUILT_IN_BCMP && no_overflow)
{
- result = inline_expand_builtin_string_cmp (exp, target, true);
+ result = inline_expand_builtin_string_cmp (exp, target);
if (result)
return result;
}
@@ -4551,7 +4551,7 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
/* Due to the performance benefit, always inline the calls first. */
rtx result = NULL_RTX;
- result = inline_expand_builtin_string_cmp (exp, target, false);
+ result = inline_expand_builtin_string_cmp (exp, target);
if (result)
return result;
@@ -4670,7 +4670,7 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
/* Due to the performance benefit, always inline the calls first. */
rtx result = NULL_RTX;
- result = inline_expand_builtin_string_cmp (exp, target, false);
+ result = inline_expand_builtin_string_cmp (exp, target);
if (result)
return result;
@@ -6764,22 +6764,24 @@ expand_builtin_goacc_parlevel_id_size (tree exp, rtx target, int ignore)
to: (assume const_str_n is 2, i.e., arg2 is a constant string)
- target = var_str[0] - const_str[0];
+ target = (int) (unsigned char) var_str[0]
+ - (int) (unsigned char) const_str[0];
if (target != 0)
goto ne_label;
...
- target = var_str[length - 2] - const_str[length - 2];
+ target = (int) (unsigned char) var_str[length - 2]
+ - (int) (unsigned char) const_str[length - 2];
if (target != 0)
goto ne_label;
- target = var_str[length - 1] - const_str[length - 1];
+ target = (int) (unsigned char) var_str[length - 1]
+ - (int) (unsigned char) const_str[length - 1];
ne_label:
*/
static rtx
inline_string_cmp (rtx target, tree var_str, const char *const_str,
unsigned HOST_WIDE_INT length,
- int const_str_n, machine_mode mode,
- bool is_memcmp)
+ int const_str_n, machine_mode mode)
{
HOST_WIDE_INT offset = 0;
rtx var_rtx_array
@@ -6788,7 +6790,7 @@ inline_string_cmp (rtx target, tree var_str, const char *const_str,
rtx const_rtx = NULL_RTX;
rtx result = target ? target : gen_reg_rtx (mode);
rtx_code_label *ne_label = gen_label_rtx ();
- tree unit_type_node = is_memcmp ? unsigned_char_type_node : char_type_node;
+ tree unit_type_node = unsigned_char_type_node;
scalar_int_mode unit_mode
= as_a <scalar_int_mode> TYPE_MODE (unit_type_node);
@@ -6802,8 +6804,10 @@ inline_string_cmp (rtx target, tree var_str, const char *const_str,
rtx op0 = (const_str_n == 1) ? const_rtx : var_rtx;
rtx op1 = (const_str_n == 1) ? var_rtx : const_rtx;
+ op0 = convert_modes (mode, unit_mode, op0, 1);
+ op1 = convert_modes (mode, unit_mode, op1, 1);
result = expand_simple_binop (mode, MINUS, op0, op1,
- result, is_memcmp ? 1 : 0, OPTAB_WIDEN);
+ result, 1, OPTAB_WIDEN);
if (i < length - 1)
emit_cmp_and_jump_insns (result, CONST0_RTX (mode), NE, NULL_RTX,
mode, true, ne_label);
@@ -6822,7 +6826,7 @@ inline_string_cmp (rtx target, tree var_str, const char *const_str,
TARGET if that's convenient.
If the call is not been inlined, return NULL_RTX. */
static rtx
-inline_expand_builtin_string_cmp (tree exp, rtx target, bool is_memcmp)
+inline_expand_builtin_string_cmp (tree exp, rtx target)
{
tree fndecl = get_callee_fndecl (exp);
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -6833,6 +6837,12 @@ inline_expand_builtin_string_cmp (tree exp, rtx target, bool is_memcmp)
|| fcode == BUILT_IN_STRNCMP
|| fcode == BUILT_IN_MEMCMP);
+ /* On a target where the type of the call (int) has same or narrower presicion
+ than unsigned char, give up the inlining expansion. */
+ if (TYPE_PRECISION (unsigned_char_type_node)
+ >= TYPE_PRECISION (TREE_TYPE (exp)))
+ return NULL_RTX;
+
tree arg1 = CALL_EXPR_ARG (exp, 0);
tree arg2 = CALL_EXPR_ARG (exp, 1);
tree len3_tree = is_ncmp ? CALL_EXPR_ARG (exp, 2) : NULL_TREE;
@@ -6879,7 +6889,7 @@ inline_expand_builtin_string_cmp (tree exp, rtx target, bool is_memcmp)
/* Now, start inline expansion the call. */
return inline_string_cmp (target, (const_str_n == 1) ? arg2 : arg1,
(const_str_n == 1) ? src_str1 : src_str2, length,
- const_str_n, mode, is_memcmp);
+ const_str_n, mode);
}
/* Expand an expression EXP that calls a built-in function,