Index: src/compiler/load-elimination.cc |
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc |
index 97f1ab0ec548c7aae48c7b75071f39abff3613e6..e19368d107623f6975c687b8c455b52d13c2d1a9 100644 |
--- a/src/compiler/load-elimination.cc |
+++ b/src/compiler/load-elimination.cc |
@@ -4,8 +4,11 @@ |
#include "src/compiler/load-elimination.h" |
+#include "src/compiler/common-operator.h" |
+#include "src/compiler/graph.h" |
#include "src/compiler/node-properties.h" |
#include "src/compiler/simplified-operator.h" |
+#include "src/types.h" |
namespace v8 { |
namespace internal { |
@@ -13,7 +16,6 @@ namespace compiler { |
LoadElimination::~LoadElimination() {} |
- |
Reduction LoadElimination::Reduce(Node* node) { |
switch (node->opcode()) { |
case IrOpcode::kLoadField: |
@@ -24,7 +26,6 @@ Reduction LoadElimination::Reduce(Node* node) { |
return NoChange(); |
} |
- |
Reduction LoadElimination::ReduceLoadField(Node* node) { |
DCHECK_EQ(IrOpcode::kLoadField, node->opcode()); |
FieldAccess const access = FieldAccessOf(node->op()); |
@@ -45,8 +46,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(); |