diff mbox

Fix PR78224

Message ID alpine.LSU.2.11.1611071456180.5294@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Nov. 7, 2016, 1:59 p.m. UTC
The following fixes an ICE with call cdce where it fails to handle
PHIs in the fallthru destination of a call with EH.  My simple fix is
to simply split the fallthru edge if the dest may contain PHI nodes.

This may also remove the need to free dominance info (hope there's
a testcase for that -- I'll leave the branches alone).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-11-07  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/78224
	* tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds):
	Split the fallthru edge in case its successor may have PHIs.
	Do not free dominance info.

	* g++.dg/torture/pr78224.C: New testcase.
diff mbox

Patch

Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(revision 241893)
+++ gcc/tree-call-cdce.c	(working copy)
@@ -807,15 +807,20 @@  shrink_wrap_one_built_in_call_with_conds
 	 can_guard_call_p.  */
       join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs);
       gcc_assert (join_tgt_in_edge_from_call);
-      free_dominance_info (CDI_DOMINATORS);
+      /* We don't want to handle PHIs.  */
+      if (EDGE_COUNT (join_tgt_in_edge_from_call->dest->preds) > 1)
+	join_tgt_bb = split_edge (join_tgt_in_edge_from_call);
+      else
+	join_tgt_bb = join_tgt_in_edge_from_call->dest;
     }
   else
-    join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
+    {
+      join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
+      join_tgt_bb = join_tgt_in_edge_from_call->dest;
+    }
 
   bi_call_bsi = gsi_for_stmt (bi_call);
 
-  join_tgt_bb = join_tgt_in_edge_from_call->dest;
-
   /* Now it is time to insert the first conditional expression
      into bi_call_bb and split this bb so that bi_call is
      shrink-wrapped.  */
Index: gcc/testsuite/g++.dg/torture/pr78224.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr78224.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr78224.C	(working copy)
@@ -0,0 +1,51 @@ 
+// { dg-do compile }
+
+extern "C"{
+  float sqrtf(float);
+}
+
+inline float squareroot(const float f)
+{
+  return sqrtf(f);
+}
+
+inline int squareroot(const int f)
+{
+  return static_cast<int>(sqrtf(static_cast<float>(f)));
+}
+
+template <class T>
+class vector2d
+{
+public:
+  vector2d(T nx, T ny) : X(nx), Y(ny) {}
+  T getLength() const { return squareroot( X*X + Y*Y ); }
+  T X;
+  T Y;
+};
+
+vector2d<int> getMousePos();
+
+class Client
+{
+public:
+  Client();
+  ~Client();
+};
+
+void the_game(float turn_amount)
+{
+  Client client;
+  bool first = true;
+
+  while (1) {
+      if (first) {
+        first = false;
+      } else {
+        int dx = getMousePos().X;
+        int dy = getMousePos().Y;
+
+        turn_amount = vector2d<float>(dx, dy).getLength();
+      }
+  }
+}