tree-dse: Fix mem* head trimming if call has lhs [PR94130]

As the testcase shows, if DSE decides to head trim {mem{set,cpy,move},strncpy}
and the call has lhs, it is incorrect to leave the lhs as is, because it
will then point to the adjusted address (base + head_trim) instead of the
original base.
The following patch fixes that by dropping the lhs of the call and assigning
lhs the original base in a following statement.

2020-03-12  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/94130
	* tree-ssa-dse.c: Include gimplify.h.
	(increment_start_addr): If stmt has lhs, drop the lhs from call and
	set it after the call to the original value of the first argument.
	Formatting fixes.
	(decrement_count): Formatting fix.

	* gcc.c-torture/execute/pr94130.c: New test.
This commit is contained in:
Jakub Jelinek 2020-03-12 09:34:00 +01:00
parent 4069adf4bb
commit 349ab34dc6
4 changed files with 44 additions and 6 deletions

View File

@ -1,3 +1,12 @@
2020-03-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94130
* tree-ssa-dse.c: Include gimplify.h.
(increment_start_addr): If stmt has lhs, drop the lhs from call and
set it after the call to the original value of the first argument.
Formatting fixes.
(decrement_count): Formatting fix.
2020-03-11 Delia Burduv <delia.burduv@arm.com>
* config/arm/arm-builtins.c

View File

@ -1,5 +1,8 @@
2020-03-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94130
* gcc.c-torture/execute/pr94130.c: New test.
PR c++/93907
* g++.dg/cpp2a/concepts-using2.C (cc): Use long long instead of
__int128 if __SIZEOF_INT128__ isn't defined.

View File

@ -0,0 +1,16 @@
/* PR tree-optimization/94130 */
int
main ()
{
int a[8];
char *b = __builtin_memset (a, 0, sizeof (a));
a[0] = 1;
a[1] = 2;
a[2] = 3;
if (b != (char *) a)
__builtin_abort ();
else
asm volatile ("" : : "g" (a) : "memory");
return 0;
}

View File

@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-dse.h"
#include "builtins.h"
#include "gimple-fold.h"
#include "gimplify.h"
/* This file implements dead store elimination.
@ -422,29 +423,38 @@ decrement_count (gimple *stmt, int decrement)
gcc_assert (TREE_CODE (*countp) == INTEGER_CST);
*countp = wide_int_to_tree (TREE_TYPE (*countp), (TREE_INT_CST_LOW (*countp)
- decrement));
}
static void
increment_start_addr (gimple *stmt, tree *where, int increment)
{
if (tree lhs = gimple_call_lhs (stmt))
if (where == gimple_call_arg_ptr (stmt, 0))
{
gassign *newop = gimple_build_assign (lhs, unshare_expr (*where));
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
gsi_insert_after (&gsi, newop, GSI_SAME_STMT);
gimple_call_set_lhs (stmt, NULL_TREE);
update_stmt (stmt);
}
if (TREE_CODE (*where) == SSA_NAME)
{
tree tem = make_ssa_name (TREE_TYPE (*where));
gassign *newop
= gimple_build_assign (tem, POINTER_PLUS_EXPR, *where,
= gimple_build_assign (tem, POINTER_PLUS_EXPR, *where,
build_int_cst (sizetype, increment));
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
gsi_insert_before (&gsi, newop, GSI_SAME_STMT);
*where = tem;
update_stmt (gsi_stmt (gsi));
update_stmt (stmt);
return;
}
*where = build_fold_addr_expr (fold_build2 (MEM_REF, char_type_node,
*where,
build_int_cst (ptr_type_node,
increment)));
*where,
build_int_cst (ptr_type_node,
increment)));
}
/* STMT is builtin call that writes bytes in bitmap ORIG, some bytes are dead