tree-optimization: [PR108684] ICE in verify_ssa due to simple_dce_from_worklist

In simple_dce_from_worklist, we were removing an inline-asm which had a vdef.
We should not be removing inline-asm which have a vdef as this code
does not check to the store.
This fixes that oversight. This was a latent bug exposed recently
by both VRP and removal of stores to static starting to use
simple_dce_from_worklist.

Committed as approved.
Bootstrapped and tested on x86_64-linux-gnu with no regressions.

	PR tree-optimization/108684

gcc/ChangeLog:

	* tree-ssa-dce.cc (simple_dce_from_worklist):
	Check all ssa names and not just non-vdef ones
	before accepting the inline-asm.
	Call unlink_stmt_vdef on the statement before
	removing it.

gcc/testsuite/ChangeLog:

	* gcc.c-torture/compile/dce-inline-asm-1.c: New test.
	* gcc.c-torture/compile/dce-inline-asm-2.c: New test.
	* gcc.dg/tree-ssa/pr108684-1.c: New test.

co-authored-by: Andrew Macleod  <amacleod@redhat.com>
This commit is contained in:
Andrew Pinski 2023-02-07 23:09:40 +00:00
parent b9f8935e11
commit 6a5cb782d1
4 changed files with 52 additions and 2 deletions

View file

@ -0,0 +1,15 @@
/* PR tree-optimization/108684 */
/* This used to ICE as when we remove the store to
`t`, we also would remove the inline-asm which
had a VDEF on it but we didn't update the
VUSE that was later on. */
static int t;
int f (int *a)
{
int t1;
asm (" " : "=X" (t1) : : "memory");
t = t1;
return *a;
}

View file

@ -0,0 +1,16 @@
/* PR tree-optimization/108684 */
/* This used to ICE as when we removed the
__builtin_unreachable in VRP, as we
would also remove the branch and the
inline-asm. The inline-asm had a VDEF on it,
which we didn't update further along and
not have the VDEF on the return statement
updated. */
int f (int a)
{
asm (" " : "=X" (a) : : "memory");
if (a)
return 0;
__builtin_unreachable();
}

View file

@ -0,0 +1,18 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
static int t;
int f (int *a)
{
int t1, t2 = 0;
asm ("shouldshowupstill %1" : "=r" (t1), "=m"(t2) : : );
t = t1;
return t2;
}
/* Check to make sure DCE does not remove the inline-asm as it writes to t2. */
/* We used to DCE this inline-asm when removing the store to t. */
/* { dg-final { scan-assembler "shouldshowupstill" } } */
/* { dg-final { scan-tree-dump-times "shouldshowupstill" 1 "optimized" } } */

View file

@ -2108,9 +2108,9 @@ simple_dce_from_worklist (bitmap worklist)
/* The defining statement needs to be defining only this name.
ASM is the only statement that can define more than one
(non-virtual) name. */
name. */
if (is_a<gasm *>(t)
&& !single_ssa_def_operand (t, SSA_OP_DEF))
&& !single_ssa_def_operand (t, SSA_OP_ALL_DEFS))
continue;
/* Don't remove statements that are needed for non-call
@ -2140,6 +2140,7 @@ simple_dce_from_worklist (bitmap worklist)
remove_phi_node (&gsi, true);
else
{
unlink_stmt_vdef (t);
gsi_remove (&gsi, true);
release_defs (t);
}