Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>Setting gimple_call_set_fndecl of a random method call to
>__bultin_unreachable can't work properly, the method call probably
>passes in arguments that __builtin_unreachable doesn't expect, and if
>the method call has LHS, we'll ICE, because __builtin_unreachable
>doesn't
>have a LHS.  Fixed by not doing anything for fold_stmt_inplace and
>for fold_stmt just adding a new __buitin_unreachable () call before the
>method call, DCE will DTRT then and we don't have to bother with adding
>some dummy stmt to set up the lhs etc.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

You could re-set the number of arguments and the LHS though.

But with a LHS and a not dead consumer both approaches will probably ice. You'd 
need to replace all uses with a default def.

Richard.

>2013-12-30  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/59622
>       * gimple-fold.c (gimple_fold_call): Don't replace OBJ_TYPE_REF
>       call fndecl with 0 possible targets with BUILT_IN_UNREACHABLE,
>       instead only for !inplace add a __builtin_unreachable () call
>       before the call.
>
>       * g++.dg/opt/pr59622.C: New test.
>
>--- gcc/gimple-fold.c.jj       2013-12-18 17:32:59.000000000 +0100
>+++ gcc/gimple-fold.c  2013-12-30 11:36:38.093211391 +0100
>@@ -1184,13 +1184,19 @@ gimple_fold_call (gimple_stmt_iterator *
>           = possible_polymorphic_call_targets (callee, &final);
>         if (final && targets.length () <= 1)
>           {
>-            tree fndecl;
>             if (targets.length () == 1)
>-              fndecl = targets[0]->decl;
>-            else
>-              fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
>-            gimple_call_set_fndecl (stmt, fndecl);
>-            changed = true;
>+              {
>+                gimple_call_set_fndecl (stmt, targets[0]->decl);
>+                changed = true;
>+              }
>+            else if (!inplace)
>+              {
>+                tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
>+                gimple new_stmt = gimple_build_call (fndecl, 0);
>+                gimple_set_location (new_stmt, gimple_location (stmt));
>+                gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
>+                return true;
>+              }
>           }
>       }
>     }
>--- gcc/testsuite/g++.dg/opt/pr59622.C.jj      2013-12-30 11:44:04.934893747
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr59622.C 2013-12-30 11:43:38.000000000
>+0100
>@@ -0,0 +1,19 @@
>+// PR tree-optimization/59622
>+// { dg-do compile }
>+// { dg-options "-O2" }
>+
>+namespace
>+{
>+  struct A
>+  {
>+    virtual int foo ();
>+    int bar () { return foo (); }
>+  };
>+}
>+
>+int
>+baz ()
>+{
>+  A a;
>+  return a.bar ();
>+}
>
>       Jakub


Reply via email to