Status: Accepted
Owner: ----
Labels: Type-Bug Priority-Medium

New issue 3487 by [email protected]: "BinaryOpICStub(SHR:Smi*Smi->Number)" produces a smi result (or deoptimizes).
http://code.google.com/p/v8/issues/detail?id=3487

To reproduce, run test.js with --noopt-safe-uint32-operations:

---- test.js ----
function test_shr(left) {
  return ((left >>> 0) >= 0);
}

for (var i = 0; i >= -2; i--) {
  print(test_shr(i));
}
--------

The symptom:
#
# Fatal error in ../src/ic.cc, line 2532
# CHECK(right->IsUndefined() || right->IsBoolean()) failed
#

I've investigated down to what I think is causing this, but I'm not sure what the proper fix is. The bug appears on at least arm, arm64, ia32 and x64. I haven't tested anything else.

I have been unable to reproduce this without --noopt-safe-uint32-operations, but it looks like the bug would still exist in some form.

On the first iteration, the ">>>" operation is compiled to a BinaryOpIC(SHR:Smi*Smi->Smi). Once a negative 'left' is passed, the IC deoptimizes (as it should) and is replaced with a BinaryOpIC(SHR:Smi*Smi->Number). However, the generated code is identical, and the IC still deoptimizes in the case where the result of ">>>" doesn't fit in a smi.

The assertion in ic.cc is hit because a transition is requested, but the new extra_ic_state is the same as the old extra_ic_state: the generated IC should have handled the inputs, but it didn't.

Generated code (for arm64):
--- End code ---
kind = BINARY_OP_IC
major_key = BinaryOpICStub
ic_state = MONOMORPHIC
extra_ic_state = 8901
type = NORMAL
name = BinaryOpICStub(SHR:Smi*Smi->Number)
Instructions (size = 120)
;;; <@0,#0> -------------------- B0 (unreachable/replaced) --------------------
                  ;;; <@4,#3> -------------------- B1 --------------------
                  ;;; <@10,#8> context
                  ;;; <@11,#8> gap
0x260e25e0     0  mov x2, x1
                  ;;; <@12,#15> check-smi
0x260e25e4     4  tbnz w2, #0, #+0x24 (addr 0x260e2608)
                  ;;; <@13,#15> gap
0x260e25e8     8  mov x3, x0
                  ;;; <@14,#16> check-smi
0x260e25ec    12  tbnz w3, #0, #+0x38 (addr 0x260e2624)
                  ;;; <@16,#17> smi-untag
0x260e25f0    16  asr x2, x2, #32
                  ;;; <@18,#18> smi-untag
0x260e25f4    20  asr x3, x3, #32
                  ;;; <@20,#12> shift-i
0x260e25f8    24  lsr w2, w2, w3
0x260e25fc    28  tbnz w2, #31, #+0x30 (addr 0x260e262c)
                  ;;; <@22,#19> smi-tag
0x260e2600    32  lsl x0, x2, #32
                  ;;; <@24,#13> return
0x260e2604    36  ret
                  ... [jump tables omitted] ...

The tbnz instruction at 0x260e25fc deoptimizes if w2 is negative, but instead it should allocate and return a HeapNumber with number-tag-u (or something similar).

The "BinaryOpICStub(SHR:Smi*Smi->Number)" version has a dummy-use before the return, but it generates no code.

--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to