Commit c43fa1f5 by Roger Sayle Committed by Roger Sayle

builtins.c (expand_builtin_strcmp): Defend against the possibility that gen_cmpstrsi may fail...


	* builtins.c (expand_builtin_strcmp): Defend against the possibility
	that gen_cmpstrsi may fail: Stabilize the argument list against
	re-evaluation and expand the library call directly using this saved
	argument list if a cmpstrsi sequence can't be generated.
	(expand_builtin_strncmp): Likewise.

	* config/i386/i386.md (cmpstrsi, movstrsi): Disable with -Os.

	* gcc.c-torture/execute/string-opt-8.c: Don't test optimizations
	that inline strncmp as cmpstrsi on i386 when compiled with -Os.

From-SVN: r72380
parent c877353c
2003-10-11 Roger Sayle <roger@eyesopen.com> 2003-10-11 Roger Sayle <roger@eyesopen.com>
* builtins.c (expand_builtin_strcmp): Defend against the possibility
that gen_cmpstrsi may fail: Stabilize the argument list against
re-evaluation and expand the library call directly using this saved
argument list if a cmpstrsi sequence can't be generated.
(expand_builtin_strncmp): Likewise.
* config/i386/i386.md (cmpstrsi, movstrsi): Disable with -Os.
2003-10-11 Roger Sayle <roger@eyesopen.com>
PR optimization/12260 PR optimization/12260
* simplify-rtx.c (simplify_unary_operation): Simplify all unary * simplify-rtx.c (simplify_unary_operation): Simplify all unary
operations through CONST nodes. Optimize (neg (plus X C)) as operations through CONST nodes. Optimize (neg (plus X C)) as
......
...@@ -3281,6 +3281,7 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode) ...@@ -3281,6 +3281,7 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
tree len, len1, len2; tree len, len1, len2;
rtx arg1_rtx, arg2_rtx, arg3_rtx; rtx arg1_rtx, arg2_rtx, arg3_rtx;
rtx result, insn; rtx result, insn;
tree fndecl;
int arg1_align int arg1_align
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
...@@ -3336,24 +3337,36 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode) ...@@ -3336,24 +3337,36 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
&& REGNO (result) >= FIRST_PSEUDO_REGISTER)) && REGNO (result) >= FIRST_PSEUDO_REGISTER))
result = gen_reg_rtx (insn_mode); result = gen_reg_rtx (insn_mode);
/* Stabilize the arguments in case gen_cmpstrsi fails. */
arg1 = save_expr (arg1);
arg2 = save_expr (arg2);
arg1_rtx = get_memory_rtx (arg1); arg1_rtx = get_memory_rtx (arg1);
arg2_rtx = get_memory_rtx (arg2); arg2_rtx = get_memory_rtx (arg2);
arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
GEN_INT (MIN (arg1_align, arg2_align))); GEN_INT (MIN (arg1_align, arg2_align)));
if (!insn) if (insn)
return 0; {
emit_insn (insn);
emit_insn (insn);
/* Return the value in the proper mode for this function. */
mode = TYPE_MODE (TREE_TYPE (exp));
if (GET_MODE (result) == mode)
return result;
if (target == 0)
return convert_to_mode (mode, result, 0);
convert_move (target, result, 0);
return target;
}
/* Return the value in the proper mode for this function. */ /* Expand the library call ourselves using a stabilized argument
mode = TYPE_MODE (TREE_TYPE (exp)); list to avoid re-evaluating the function's arguments twice. */
if (GET_MODE (result) == mode) arglist = build_tree_list (NULL_TREE, arg2);
return result; arglist = tree_cons (NULL_TREE, arg1, arglist);
if (target == 0) fndecl = get_callee_fndecl (exp);
return convert_to_mode (mode, result, 0); exp = build_function_call_expr (fndecl, arglist);
convert_move (target, result, 0); return expand_call (exp, target, target == const0_rtx);
return target;
} }
#endif #endif
return 0; return 0;
...@@ -3436,6 +3449,7 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode) ...@@ -3436,6 +3449,7 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
tree len, len1, len2; tree len, len1, len2;
rtx arg1_rtx, arg2_rtx, arg3_rtx; rtx arg1_rtx, arg2_rtx, arg3_rtx;
rtx result, insn; rtx result, insn;
tree fndecl;
int arg1_align int arg1_align
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
...@@ -3494,24 +3508,38 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode) ...@@ -3494,24 +3508,38 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
&& REGNO (result) >= FIRST_PSEUDO_REGISTER)) && REGNO (result) >= FIRST_PSEUDO_REGISTER))
result = gen_reg_rtx (insn_mode); result = gen_reg_rtx (insn_mode);
/* Stabilize the arguments in case gen_cmpstrsi fails. */
arg1 = save_expr (arg1);
arg2 = save_expr (arg2);
len = save_expr (len);
arg1_rtx = get_memory_rtx (arg1); arg1_rtx = get_memory_rtx (arg1);
arg2_rtx = get_memory_rtx (arg2); arg2_rtx = get_memory_rtx (arg2);
arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
GEN_INT (MIN (arg1_align, arg2_align))); GEN_INT (MIN (arg1_align, arg2_align)));
if (!insn) if (insn)
return 0; {
emit_insn (insn);
emit_insn (insn);
/* Return the value in the proper mode for this function. */
mode = TYPE_MODE (TREE_TYPE (exp));
if (GET_MODE (result) == mode)
return result;
if (target == 0)
return convert_to_mode (mode, result, 0);
convert_move (target, result, 0);
return target;
}
/* Return the value in the proper mode for this function. */ /* Expand the library call ourselves using a stabilized argument
mode = TYPE_MODE (TREE_TYPE (exp)); list to avoid re-evaluating the function's arguments twice. */
if (GET_MODE (result) == mode) arglist = build_tree_list (NULL_TREE, len);
return result; arglist = tree_cons (NULL_TREE, arg2, arglist);
if (target == 0) arglist = tree_cons (NULL_TREE, arg1, arglist);
return convert_to_mode (mode, result, 0); fndecl = get_callee_fndecl (exp);
convert_move (target, result, 0); exp = build_function_call_expr (fndecl, arglist);
return target; return expand_call (exp, target, target == const0_rtx);
} }
#endif #endif
return 0; return 0;
......
...@@ -16129,7 +16129,7 @@ ...@@ -16129,7 +16129,7 @@
(use (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:SI 2 "nonmemory_operand" "")) (use (match_operand:SI 2 "nonmemory_operand" ""))
(use (match_operand:SI 3 "const_int_operand" ""))] (use (match_operand:SI 3 "const_int_operand" ""))]
"" "! optimize_size"
{ {
if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3])) if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
DONE; DONE;
...@@ -16849,7 +16849,7 @@ ...@@ -16849,7 +16849,7 @@
(match_operand:BLK 2 "general_operand" ""))) (match_operand:BLK 2 "general_operand" "")))
(use (match_operand 3 "general_operand" "")) (use (match_operand 3 "general_operand" ""))
(use (match_operand 4 "immediate_operand" ""))] (use (match_operand 4 "immediate_operand" ""))]
"" "! optimize_size"
{ {
rtx addr1, addr2, out, outlow, count, countreg, align; rtx addr1, addr2, out, outlow, count, countreg, align;
......
2003-10-11 Roger Sayle <roger@eyesopen.com> 2003-10-11 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/string-opt-8.c: Don't test optimizations
that inline strncmp as cmpstrsi on i386 when compiled with -Os.
2003-10-11 Roger Sayle <roger@eyesopen.com>
PR optimization/12260 PR optimization/12260
* gcc.c-torture/compile/20031011-2.c: New test case. * gcc.c-torture/compile/20031011-2.c: New test case.
......
...@@ -65,7 +65,7 @@ int main () ...@@ -65,7 +65,7 @@ int main ()
s2 = s1; s3 = s1+4; s2 = s1; s3 = s1+4;
if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5) if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5)
abort(); abort();
#if !defined(__OPTIMIZE__) || defined(__i386__) #if !defined(__OPTIMIZE__) || (defined(__i386__) && !defined(__OPTIMIZE_SIZE__))
/* These tests work on platforms which support cmpstrsi. We test it /* These tests work on platforms which support cmpstrsi. We test it
at -O0 on all platforms to ensure the strncmp logic is correct. */ at -O0 on all platforms to ensure the strncmp logic is correct. */
s2 = s1; s2 = s1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment