Index: src/compiler/load-elimination.cc |
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc |
index 97f1ab0ec548c7aae48c7b75071f39abff3613e6..c1ac0d4c08575ad494b03e9a9ab8ba4d6179f82f 100644 |
--- a/src/compiler/load-elimination.cc |
+++ b/src/compiler/load-elimination.cc |
@@ -4,8 +4,10 @@ |
#include "src/compiler/load-elimination.h" |
+#include "src/compiler/js-graph.h" |
#include "src/compiler/node-properties.h" |
#include "src/compiler/simplified-operator.h" |
+#include "src/types.h" |
namespace v8 { |
namespace internal { |
@@ -45,8 +47,22 @@ Reduction LoadElimination::ReduceLoadField(Node* node) { |
if (access == FieldAccessOf(effect->op())) { |
if (object == NodeProperties::GetValueInput(effect, 0)) { |
Node* const value = NodeProperties::GetValueInput(effect, 1); |
- ReplaceWithValue(node, value); |
- return Replace(value); |
+ Type* stored_value_type = NodeProperties::GetType(value); |
+ Type* load_type = NodeProperties::GetType(node); |
+ // Make sure the replacement's type is a subtype of the node's |
+ // type. Otherwise we could confuse optimizations that were |
+ // based on the original type. |
+ if (stored_value_type->Is(load_type)) { |
+ ReplaceWithValue(node, value); |
+ return Replace(value); |
+ } else { |
+ Node* renamed = graph()->NewNode( |
+ common()->Guard(Type::Intersect(stored_value_type, load_type, |
+ graph()->zone())), |
+ value, NodeProperties::GetControlInput(node)); |
+ ReplaceWithValue(node, renamed); |
+ return Replace(renamed); |
+ } |
} |
// TODO(turbofan): Alias analysis to the rescue? |
return NoChange(); |