41 lines
1.5 KiB
Diff
41 lines
1.5 KiB
Diff
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60902
|
|
|
|
--- gcc/tree-ssa-threadedge.c 2014/04/23 17:53:56 209715
|
|
+++ gcc/tree-ssa-threadedge.c 2014/04/23 18:04:46 209716
|
|
@@ -387,7 +387,34 @@
|
|
&& (gimple_code (stmt) != GIMPLE_CALL
|
|
|| gimple_call_lhs (stmt) == NULL_TREE
|
|
|| TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
|
|
- continue;
|
|
+ {
|
|
+ /* STMT might still have DEFS and we need to invalidate any known
|
|
+ equivalences for them.
|
|
+
|
|
+ Consider if STMT is a GIMPLE_ASM with one or more outputs that
|
|
+ feeds a conditional inside a loop. We might derive an equivalence
|
|
+ due to the conditional. */
|
|
+ tree op;
|
|
+ ssa_op_iter iter;
|
|
+
|
|
+ if (backedge_seen)
|
|
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
|
|
+ {
|
|
+ /* This call only invalidates equivalences created by
|
|
+ PHI nodes. This is by design to keep the cost of
|
|
+ of invalidation reasonable. */
|
|
+ invalidate_equivalences (op, stack, src_map, dst_map);
|
|
+
|
|
+ /* However, conditionals can imply values for real
|
|
+ operands as well. And those won't be recorded in the
|
|
+ maps. In fact, those equivalences may be recorded totally
|
|
+ outside the threading code. We can just create a new
|
|
+ temporary NULL equivalence here. */
|
|
+ record_temporary_equivalence (op, NULL_TREE, stack);
|
|
+ }
|
|
+
|
|
+ continue;
|
|
+ }
|
|
|
|
/* The result of __builtin_object_size depends on all the arguments
|
|
of a phi node. Temporarily using only one edge produces invalid
|