| Index: src/compiler/ia32/instruction-selector-ia32.cc | 
| diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc | 
| index 63a36712ea3dc4a8ce3286aa3c02bb81bf46bb2c..3d2a5360c8ac3d0def91efe0521d75627d851384 100644 | 
| --- a/src/compiler/ia32/instruction-selector-ia32.cc | 
| +++ b/src/compiler/ia32/instruction-selector-ia32.cc | 
| @@ -1172,6 +1172,26 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 
| VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 
| } | 
|  | 
| +bool InferMachineRepresentation(Node* node, | 
| +                                MachineRepresentation* representation) { | 
| +  if (node->opcode() == IrOpcode::kLoad) { | 
| +    *representation = LoadRepresentationOf(node->op()).representation(); | 
| +    return true; | 
| +  } | 
| +  if (node->opcode() != IrOpcode::kInt32Constant) { | 
| +    return false; | 
| +  } | 
| +  int32_t value = OpParameter<int32_t>(node->op()); | 
| +  if (is_int8(value)) { | 
| +    *representation = MachineRepresentation::kWord8; | 
| +  } else if (is_int16(value)) { | 
| +    *representation = MachineRepresentation::kWord16; | 
| +  } else { | 
| +    *representation = MachineRepresentation::kWord32; | 
| +  } | 
| +  return true; | 
| +} | 
| + | 
| // Tries to match the size of the given opcode to that of the operands, if | 
| // possible. | 
| InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, | 
| @@ -1179,20 +1199,22 @@ InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, | 
| if (opcode != kIA32Cmp && opcode != kIA32Test) { | 
| return opcode; | 
| } | 
| -  // Currently, if one of the two operands is not a Load, we don't know what its | 
| -  // machine representation is, so we bail out. | 
| -  // TODO(epertoso): we can probably get some size information out of immediates | 
| -  // and phi nodes. | 
| -  if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { | 
| +  // We only do this if at least one of the two operands is a load. | 
| +  // TODO(epertoso): we can probably get some size information out of phi nodes. | 
| +  if (left->opcode() != IrOpcode::kLoad && right->opcode() != IrOpcode::kLoad) { | 
| +    return opcode; | 
| +  } | 
| +  MachineRepresentation left_representation, right_representation; | 
| +  if (!InferMachineRepresentation(left, &left_representation) || | 
| +      !InferMachineRepresentation(right, &right_representation)) { | 
| return opcode; | 
| } | 
| -  // If the load representations don't match, both operands will be | 
| +  // If the representations don't match, both operands will be | 
| // zero/sign-extended to 32bit. | 
| -  LoadRepresentation left_representation = LoadRepresentationOf(left->op()); | 
| -  if (left_representation != LoadRepresentationOf(right->op())) { | 
| +  if (left_representation != right_representation) { | 
| return opcode; | 
| } | 
| -  switch (left_representation.representation()) { | 
| +  switch (left_representation) { | 
| case MachineRepresentation::kBit: | 
| case MachineRepresentation::kWord8: | 
| return opcode == kIA32Cmp ? kIA32Cmp8 : kIA32Test8; | 
| @@ -1240,10 +1262,33 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, | 
|  | 
| // Match immediates on right side of comparison. | 
| if (g.CanBeImmediate(right)) { | 
| -    if (g.CanBeMemoryOperand(opcode, node, left)) { | 
| -      // TODO(epertoso): we should use `narrowed_opcode' here once we match | 
| -      // immediates too. | 
| -      return VisitCompareWithMemoryOperand(selector, opcode, left, | 
| +    if (g.CanBeMemoryOperand(narrowed_opcode, node, left)) { | 
| +      // If we're truncating the immediate (32 bits to 16 or 8), comparison | 
| +      // semantics should take the signedness/unsignedness of the op into | 
| +      // account. | 
| +      if (narrowed_opcode != opcode && | 
| +          LoadRepresentationOf(left->op()).IsUnsigned()) { | 
| +        switch (cont->condition()) { | 
| +          case FlagsCondition::kSignedLessThan: | 
| +            cont->OverwriteAndNegateIfEqual(FlagsCondition::kUnsignedLessThan); | 
| +            break; | 
| +          case FlagsCondition::kSignedGreaterThan: | 
| +            cont->OverwriteAndNegateIfEqual( | 
| +                FlagsCondition::kUnsignedGreaterThan); | 
| +            break; | 
| +          case FlagsCondition::kSignedLessThanOrEqual: | 
| +            cont->OverwriteAndNegateIfEqual( | 
| +                FlagsCondition::kUnsignedLessThanOrEqual); | 
| +            break; | 
| +          case FlagsCondition::kSignedGreaterThanOrEqual: | 
| +            cont->OverwriteAndNegateIfEqual( | 
| +                FlagsCondition::kUnsignedGreaterThanOrEqual); | 
| +            break; | 
| +          default: | 
| +            break; | 
| +        } | 
| +      } | 
| +      return VisitCompareWithMemoryOperand(selector, narrowed_opcode, left, | 
| g.UseImmediate(right), cont); | 
| } | 
| return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), | 
|  |