]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix tree-opt/PR106087: ICE with inline-asm with multiple output and assigned only...
authorAndrew Pinski <apinski@marvell.com>
Thu, 7 Jul 2022 22:06:19 +0000 (22:06 +0000)
committerAndrew Pinski <apinski@marvell.com>
Sat, 9 Jul 2022 01:17:46 +0000 (01:17 +0000)
The problem here is that when we mark the ssa name that was referenced in the now removed
dead store (to a write only static variable), the inline-asm would also be removed
even though it was defining another ssa name. This fixes the problem by checking
to make sure that the statement was only defining one ssa name.

Committed as approved after a bootstrapped and tested on x86_64 with no regressions.

PR tree-optimization/106087

gcc/ChangeLog:

* tree-ssa-dce.cc (simple_dce_from_worklist): Check
to make sure the statement is only defining one operand.

gcc/testsuite/ChangeLog:

* gcc.c-torture/compile/inline-asm-1.c: New test.

gcc/testsuite/gcc.c-torture/compile/inline-asm-1.c [new file with mode: 0644]
gcc/tree-ssa-dce.cc

diff --git a/gcc/testsuite/gcc.c-torture/compile/inline-asm-1.c b/gcc/testsuite/gcc.c-torture/compile/inline-asm-1.c
new file mode 100644 (file)
index 0000000..0044cb7
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR tree-opt/106087,
+   simple_dce_from_worklist would delete the
+   inline-asm when it was still being referenced
+   by the other ssa name. */
+
+static int t;
+
+int f(void)
+{
+  int tt, tt1;
+  asm("":"=r"(tt), "=r"(tt1));
+  t = tt1;
+  return tt;
+}
index bc5335826732c367a4b7b1a0f2f8ea4015679e42..daf0782b0e13e42e0d121791a1d0921c0edaaacb 100644 (file)
@@ -2061,6 +2061,13 @@ simple_dce_from_worklist (bitmap worklist)
       if (gimple_has_side_effects (t))
        continue;
 
+      /* The defining statement needs to be defining only this name.
+        ASM is the only statement that can define more than one
+        (non-virtual) name. */
+      if (is_a<gasm *>(t)
+         && !single_ssa_def_operand (t, SSA_OP_DEF))
+       continue;
+
       /* Don't remove statements that are needed for non-call
         eh to work.  */
       if (stmt_unremovable_because_of_non_call_eh_p (cfun, t))