Reland of [turbofan] Insert dummy values when changing from None type.

This reverts commit a55fdb1e7c, relands
https://codereview.chromium.org/2266823002/.

BUG=chromium:638132

Review-Url: https://codereview.chromium.org/2277283002
Cr-Commit-Position: refs/heads/master@{#38917}
This commit is contained in:
jarin 2016-08-25 09:57:31 -07:00 committed by Commit bot
parent 2101e691ca
commit 2a97b1bcb1
22 changed files with 92 additions and 202 deletions

View File

@ -267,9 +267,7 @@ namespace internal {
V(kWrongArgumentCountForInvokeIntrinsic, \
"Wrong number of arguments for intrinsic") \
V(kShouldNotDirectlyEnterOsrFunction, \
"Should not directly enter OSR-compiled function") \
V(kConversionFromImpossibleValue, \
"Reached conversion from value with empty type (i.e., impossible type)")
"Should not directly enter OSR-compiled function")
#define ERROR_MESSAGES_CONSTANTS(C, T) C,
enum BailoutReason {

View File

@ -707,9 +707,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ stop("kArchDebugBreak");
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));

View File

@ -766,9 +766,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ Debug("kArchDebugBreak", 0, BREAK);
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));

View File

@ -637,9 +637,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ int3();
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.

View File

@ -57,7 +57,6 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny };
V(ArchTableSwitch) \
V(ArchNop) \
V(ArchDebugBreak) \
V(ArchImpossible) \
V(ArchComment) \
V(ArchThrowTerminator) \
V(ArchDeoptimize) \

View File

@ -242,7 +242,6 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
case kArchTruncateDoubleToI:
case kArchStackSlot:
case kArchDebugBreak:
case kArchImpossible:
case kArchComment:
case kIeee754Float64Acos:
case kIeee754Float64Acosh:

View File

@ -348,6 +348,10 @@ enum class FrameStateInputKind { kAny, kStackSlot };
InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
FrameStateInputKind kind,
MachineRepresentation rep) {
if (rep == MachineRepresentation::kNone) {
return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
}
switch (input->opcode()) {
case IrOpcode::kInt32Constant:
case IrOpcode::kInt64Constant:
@ -360,17 +364,13 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
UNREACHABLE();
break;
default:
if (rep == MachineRepresentation::kNone) {
return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
} else {
switch (kind) {
case FrameStateInputKind::kStackSlot:
return g->UseUniqueSlot(input);
case FrameStateInputKind::kAny:
// Currently deopts "wrap" other operations, so the deopt's inputs
// are potentially needed untill the end of the deoptimising code.
return g->UseAnyAtEnd(input);
}
switch (kind) {
case FrameStateInputKind::kStackSlot:
return g->UseUniqueSlot(input);
case FrameStateInputKind::kAny:
// Currently deopts "wrap" other operations, so the deopt's inputs
// are potentially needed untill the end of the deoptimising code.
return g->UseAnyAtEnd(input);
}
}
UNREACHABLE();
@ -1065,19 +1065,6 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
case IrOpcode::kChangeFloat64ToUint32:
return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
case IrOpcode::kImpossibleToWord32:
return MarkAsWord32(node), VisitImpossibleToWord32(node);
case IrOpcode::kImpossibleToWord64:
return MarkAsWord64(node), VisitImpossibleToWord64(node);
case IrOpcode::kImpossibleToFloat32:
return MarkAsFloat32(node), VisitImpossibleToFloat32(node);
case IrOpcode::kImpossibleToFloat64:
return MarkAsFloat64(node), VisitImpossibleToFloat64(node);
case IrOpcode::kImpossibleToTagged:
MarkAsRepresentation(MachineType::PointerRepresentation(), node);
return VisitImpossibleToTagged(node);
case IrOpcode::kImpossibleToBit:
return MarkAsWord32(node), VisitImpossibleToBit(node);
case IrOpcode::kFloat64SilenceNaN:
MarkAsFloat64(node);
if (CanProduceSignalingNaN(node->InputAt(0))) {
@ -1318,42 +1305,6 @@ void InstructionSelector::VisitNode(Node* node) {
}
}
void InstructionSelector::VisitImpossibleToWord32(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
}
void InstructionSelector::VisitImpossibleToWord64(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible,
g.DefineAsConstant(node, Constant(static_cast<int64_t>(0))));
}
void InstructionSelector::VisitImpossibleToFloat32(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0f)));
}
void InstructionSelector::VisitImpossibleToFloat64(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0)));
}
void InstructionSelector::VisitImpossibleToBit(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
}
void InstructionSelector::VisitImpossibleToTagged(Node* node) {
OperandGenerator g(this);
#if V8_TARGET_ARCH_64_BIT
Emit(kArchImpossible,
g.DefineAsConstant(node, Constant(static_cast<int64_t>(0))));
#else // V8_TARGET_ARCH_64_BIT
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
#endif // V8_TARGET_ARCH_64_BIT
}
void InstructionSelector::VisitLoadStackPointer(Node* node) {
OperandGenerator g(this);
Emit(kArchStackPointer, g.DefineAsRegister(node));

View File

@ -145,12 +145,6 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToWord32, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToWord64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToTagged, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToBit, Operator::kNoProperties, 1, 0, 1) \
V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \

View File

@ -302,16 +302,6 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* ChangeUint32ToFloat64();
const Operator* ChangeUint32ToUint64();
// These are changes from impossible values (for example a smi-checked
// string). They can safely emit an abort instruction, which should
// never be reached.
const Operator* ImpossibleToWord32();
const Operator* ImpossibleToWord64();
const Operator* ImpossibleToFloat32();
const Operator* ImpossibleToFloat64();
const Operator* ImpossibleToTagged();
const Operator* ImpossibleToBit();
// These operators truncate or round numbers, both changing the representation
// of the number and mapping multiple input values onto the same output value.
const Operator* TruncateFloat64ToFloat32();

View File

@ -693,9 +693,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ stop("kArchDebugBreak");
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));

View File

@ -702,9 +702,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ stop("kArchDebugBreak");
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));

View File

@ -407,12 +407,6 @@
V(ChangeInt32ToInt64) \
V(ChangeUint32ToFloat64) \
V(ChangeUint32ToUint64) \
V(ImpossibleToBit) \
V(ImpossibleToWord32) \
V(ImpossibleToWord64) \
V(ImpossibleToFloat32) \
V(ImpossibleToFloat64) \
V(ImpossibleToTagged) \
V(TruncateFloat64ToFloat32) \
V(TruncateInt64ToInt32) \
V(RoundFloat64ToInt32) \

View File

@ -1077,9 +1077,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ stop("kArchDebugBreak");
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.

View File

@ -204,10 +204,10 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
}
// Select the correct X -> Tagged operator.
const Operator* op;
if (output_rep == MachineRepresentation::kNone) {
// We should only asisgn this representation if the type is empty.
CHECK(!output_type->IsInhabited());
op = machine()->ImpossibleToTagged();
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->TheHoleConstant();
} else if (output_rep == MachineRepresentation::kBit) {
if (output_type->Is(Type::Boolean())) {
op = simplified()->ChangeBitToTagged();
@ -283,10 +283,10 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
}
// Select the correct X -> Float32 operator.
const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) {
// We should only use kNone representation if the type is empty.
CHECK(!output_type->IsInhabited());
op = machine()->ImpossibleToFloat32();
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Float32Constant(0.0f);
} else if (IsWord(output_rep)) {
if (output_type->Is(Type::Signed32())) {
// int32 -> float64 -> float32
@ -352,10 +352,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
}
// Select the correct X -> Float64 operator.
const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) {
// We should only use kNone representation if the type is empty.
CHECK(!output_type->IsInhabited());
op = machine()->ImpossibleToFloat64();
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Float64Constant(0.0);
} else if (IsWord(output_rep)) {
if (output_type->Is(Type::Signed32())) {
op = machine()->ChangeInt32ToFloat64();
@ -435,10 +435,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
// Select the correct X -> Word32 operator.
const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) {
// We should only use kNone representation if the type is empty.
CHECK(!output_type->IsInhabited());
op = machine()->ImpossibleToWord32();
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int32Constant(0);
} else if (output_rep == MachineRepresentation::kBit) {
return node; // Sloppy comparison -> word32
} else if (output_rep == MachineRepresentation::kFloat64) {
@ -551,10 +551,10 @@ Node* RepresentationChanger::GetBitRepresentationFor(
}
// Select the correct X -> Bit operator.
const Operator* op;
if (output_rep == MachineRepresentation::kNone) {
// We should only use kNone representation if the type is empty.
CHECK(!output_type->IsInhabited());
op = machine()->ImpossibleToBit();
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int32Constant(0);
} else if (output_rep == MachineRepresentation::kTagged) {
op = simplified()->ChangeTaggedToBit();
} else {
@ -566,10 +566,10 @@ Node* RepresentationChanger::GetBitRepresentationFor(
Node* RepresentationChanger::GetWord64RepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) {
if (output_rep == MachineRepresentation::kNone) {
// We should only use kNone representation if the type is empty.
CHECK(!output_type->IsInhabited());
return jsgraph()->graph()->NewNode(machine()->ImpossibleToFloat64(), node);
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int64Constant(0);
} else if (output_rep == MachineRepresentation::kBit) {
return node; // Sloppy comparison -> word64
}

View File

@ -980,9 +980,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ stop("kArchDebugBreak");
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.

View File

@ -311,6 +311,9 @@ class RepresentationSelector {
bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
if (updated) {
for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) {
@ -330,6 +333,9 @@ class RepresentationSelector {
bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
if (updated) {
for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) {
@ -534,9 +540,6 @@ class RepresentationSelector {
TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
info->truncation().description());
VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
}
}
@ -986,8 +989,11 @@ class RepresentationSelector {
for (int i = 0; i < node->InputCount(); i++) {
Node* input = node->InputAt(i);
NodeInfo* input_info = GetInfo(input);
MachineType machine_type(input_info->representation(),
DeoptValueSemanticOf(TypeOf(input)));
Type* input_type = TypeOf(input);
MachineRepresentation rep = input_type->IsInhabited()
? input_info->representation()
: MachineRepresentation::kNone;
MachineType machine_type(rep, DeoptValueSemanticOf(input_type));
DCHECK(machine_type.representation() !=
MachineRepresentation::kWord32 ||
machine_type.semantic() == MachineSemantic::kInt32 ||

View File

@ -1980,28 +1980,6 @@ Type* Typer::Visitor::TypeChangeUint32ToUint64(Node* node) {
return Type::Internal();
}
Type* Typer::Visitor::TypeImpossibleToWord32(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToWord64(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToFloat32(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToFloat64(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToTagged(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToBit(Node* node) { return Type::None(); }
Type* Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
return Type::Intersect(Type::Number(), Type::UntaggedFloat32(), zone());
}

View File

@ -1003,14 +1003,6 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to));
break;
}
case IrOpcode::kImpossibleToWord32:
case IrOpcode::kImpossibleToWord64:
case IrOpcode::kImpossibleToFloat32:
case IrOpcode::kImpossibleToFloat64:
case IrOpcode::kImpossibleToTagged:
case IrOpcode::kImpossibleToBit:
break;
case IrOpcode::kCheckBounds:
CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Unsigned31());

View File

@ -866,9 +866,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ int3();
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.

View File

@ -715,9 +715,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak:
__ int3();
break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.

View File

@ -493,9 +493,9 @@ static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
TEST(SingleChanges) {
CheckChange(IrOpcode::kChangeTaggedToBit, MachineRepresentation::kTagged,
Type::None(), MachineRepresentation::kBit);
Type::Boolean(), MachineRepresentation::kBit);
CheckChange(IrOpcode::kChangeBitToTagged, MachineRepresentation::kBit,
Type::None(), MachineRepresentation::kTagged);
Type::Boolean(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeInt31ToTaggedSigned,
MachineRepresentation::kWord32, Type::Signed31(),
@ -546,7 +546,7 @@ TEST(SingleChanges) {
Type::Unsigned32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kFloat64, Type::None(),
MachineRepresentation::kFloat64, Type::Number(),
MachineRepresentation::kFloat32);
// Int32,Uint32 <-> Float32 require two changes.
@ -570,11 +570,11 @@ TEST(SingleChanges) {
// Float32 <-> Tagged require two changes.
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kChangeFloat64ToTagged,
MachineRepresentation::kFloat32, Type::None(),
MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kTagged);
CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kTagged, Type::None(),
MachineRepresentation::kTagged, Type::Number(),
MachineRepresentation::kFloat32);
}
@ -587,7 +587,7 @@ TEST(SignednessInWord32) {
CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
Type::Unsigned32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
Type::None(), MachineRepresentation::kFloat64);
Type::Signed32(), MachineRepresentation::kFloat64);
CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
Type::Signed32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kTruncateFloat64ToWord32,
@ -600,7 +600,7 @@ TEST(SignednessInWord32) {
CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kWord32, Type::None(),
MachineRepresentation::kWord32, Type::Signed32(),
MachineRepresentation::kFloat32);
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kTruncateFloat64ToWord32,
@ -614,13 +614,11 @@ TEST(Nops) {
// X -> X is always a nop for any single representation X.
for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
r.CheckNop(kMachineTypes[i].representation(), Type::None(),
r.CheckNop(kMachineTypes[i].representation(), Type::Number(),
kMachineTypes[i].representation());
}
// 32-bit floats.
r.CheckNop(MachineRepresentation::kFloat32, Type::None(),
MachineRepresentation::kFloat32);
r.CheckNop(MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kFloat32);
@ -639,14 +637,6 @@ TEST(Nops) {
MachineRepresentation::kWord32);
// kRepBit (result of comparison) is implicitly a wordish thing.
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord8);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord16);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord32);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord64);
r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
MachineRepresentation::kWord8);
r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
@ -662,39 +652,39 @@ TEST(TypeErrors) {
RepresentationChangerTester r;
// Wordish cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kWord8, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord8, Type::Number(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord16, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord16, Type::Number(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord32, Type::Number(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord64, Type::Number(),
MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(),
r.CheckTypeError(MachineRepresentation::kFloat64, Type::Number(),
MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(),
r.CheckTypeError(MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
r.CheckTypeError(MachineRepresentation::kBit, Type::Number(),
MachineRepresentation::kFloat32);
r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
MachineRepresentation::kFloat32);
// Word64 is internal and shouldn't be implicitly converted.
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
MachineRepresentation::kTagged);
r.CheckTypeError(MachineRepresentation::kTagged, Type::None(),
r.CheckTypeError(MachineRepresentation::kTagged, Type::Number(),
MachineRepresentation::kWord64);
r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(),
MachineRepresentation::kWord64);
// Word64 / Word32 shouldn't be implicitly converted.
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
MachineRepresentation::kWord32);
r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
r.CheckTypeError(MachineRepresentation::kWord32, Type::Number(),
MachineRepresentation::kWord64);
r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(),
MachineRepresentation::kWord64);

View File

@ -0,0 +1,26 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function g(x, y) {
return x | y;
}
function f(b) {
if (b) {
var s = g("a", "b") && true;
return s;
}
}
// Prime function g with Smi feedback.
g(1, 2);
g(1, 2);
f(0);
f(0);
%OptimizeFunctionOnNextCall(f);
// Compile inlined function g with string inputs but Smi feedback.
f(1);