2020-01-15 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/93262
+ * tree-ssa-dse.c (maybe_trim_memstar_call): For *_chk builtins,
+ perform head trimming only if the last argument is constant,
+ either all ones, or larger or equal to head trim, in the latter
+ case decrease the last argument by head_trim.
+
PR tree-optimization/93249
* tree-ssa-dse.c: Include builtins.h and gimple-fold.h.
(maybe_trim_memstar_call): Move head_trim and tail_trim vars to
2020-01-15 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/93262
+ * gcc.c-torture/execute/builtins/pr93262-chk.c: New test.
+ * gcc.c-torture/execute/builtins/pr93262-chk-lib.c: New file.
+ * gcc.c-torture/execute/builtins/pr93262-chk.x: New file.
+
PR tree-optimization/93249
* gcc.c-torture/execute/pr93249.c: New test.
--- /dev/null
+/* PR tree-optimization/93262 */
+
+extern void abort (void);
+typedef __SIZE_TYPE__ size_t;
+extern void *memcpy (void *, const void *, size_t);
+extern void *memset (void *, int, size_t);
+
+#include "chk.h"
+
+char b[32] = "def";
+char a[32] = "abc";
+char c[32] = "ghi";
+int l1;
+
+__attribute__((noipa, noinline, noclone, optimize ("tree-dse"))) void
+foo (char *b)
+{
+ memcpy (a, b, 48);
+ memset (a, ' ', 16);
+}
+
+__attribute__((noipa, noinline, noclone, optimize ("tree-dse"))) void
+bar (void)
+{
+ memset (a, ' ', 48);
+ memset (a, '0', 16);
+}
+
+void
+main_test (void)
+{
+#ifndef __OPTIMIZE__
+ /* Object size checking is only intended for -O[s123]. */
+ return;
+#endif
+ __asm ("" : "=r" (l1) : "0" (l1));
+ chk_calls = 0;
+ chk_fail_allowed = 1;
+ /* Runtime checks. */
+ if (__builtin_setjmp (chk_fail_buf) == 0)
+ {
+ foo ("0123456789abcdeffedcba9876543210ghijklmnopqrstuv");
+ if (!l1)
+ abort ();
+ }
+ if (__builtin_setjmp (chk_fail_buf) == 0)
+ {
+ bar ();
+ if (!l1)
+ abort ();
+ }
+ if (chk_calls != 2)
+ abort ();
+ return 0;
+}
/* Head trimming requires adjusting all the arguments. */
if (head_trim)
{
+ /* For __*_chk need to adjust also the last argument. */
+ if (gimple_call_num_args (stmt) == 4)
+ {
+ tree size = gimple_call_arg (stmt, 3);
+ if (!tree_fits_uhwi_p (size))
+ break;
+ if (!integer_all_onesp (size))
+ {
+ unsigned HOST_WIDE_INT sz = tree_to_uhwi (size);
+ if (sz < (unsigned) head_trim)
+ break;
+ tree arg = wide_int_to_tree (TREE_TYPE (size),
+ sz - head_trim);
+ gimple_call_set_arg (stmt, 3, arg);
+ }
+ }
tree *dst = gimple_call_arg_ptr (stmt, 0);
increment_start_addr (stmt, dst, head_trim);
tree *src = gimple_call_arg_ptr (stmt, 1);
/* Head trimming requires adjusting all the arguments. */
if (head_trim)
{
+ /* For __*_chk need to adjust also the last argument. */
+ if (gimple_call_num_args (stmt) == 4)
+ {
+ tree size = gimple_call_arg (stmt, 3);
+ if (!tree_fits_uhwi_p (size))
+ break;
+ if (!integer_all_onesp (size))
+ {
+ unsigned HOST_WIDE_INT sz = tree_to_uhwi (size);
+ if (sz < (unsigned) head_trim)
+ break;
+ tree arg = wide_int_to_tree (TREE_TYPE (size),
+ sz - head_trim);
+ gimple_call_set_arg (stmt, 3, arg);
+ }
+ }
tree *dst = gimple_call_arg_ptr (stmt, 0);
increment_start_addr (stmt, dst, head_trim);
decrement_count (stmt, head_trim);