constant_value = constant->Integer32Value() & 0x1f;
// Left shifts can deoptimize if we shift by > 0 and the result cannot be
// truncated to smi.
- if (instr->representation().IsSmi() && constant_value > 0) {
+ if (instr->representation().IsSmi() &&
+ op == Token::SHL &&
+ constant_value > 0) {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
} else {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32) &&
+ !it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
break;
}
case Token::SAR:
if (shift_count != 0) {
__ mov(result, Operand(left, ASR, shift_count));
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ and_(result, result, Operand(~kSmiTagMask));
+ }
} else {
__ Move(result, left);
}
virtual void UpdateRepresentation(Representation new_rep,
HInferRepresentationPhase* h_infer,
const char* reason) {
- if (new_rep.IsSmi()) new_rep = Representation::Integer32();
+ if (new_rep.IsSmi() && !right()->IsConstant()) {
+ new_rep = Representation::Integer32();
+ }
HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
}
case Token::SAR:
if (shift_count != 0) {
__ sar(ToRegister(left), shift_count);
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ and_(ToRegister(left), ~kSmiTagMask);
+ }
}
break;
case Token::SHR:
constant_value = constant->Integer32Value() & 0x1f;
// Left shifts can deoptimize if we shift by > 0 and the result cannot be
// truncated to smi.
- if (instr->representation().IsSmi() && constant_value > 0) {
+ if (instr->representation().IsSmi() &&
+ op == Token::SHL &&
+ constant_value > 0) {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
} else {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32) &&
+ !it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
break;
}
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
} else {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
- if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32) &&
+ !it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
break;
}