The pool lookup logic for bigints was broken in the code generation for NODE_NEGATE.
It searched for positive bigints instead of negative ones, leading to two problems.
- It reused the same pool entry for negative bigints if the positive one was already present.
For example:
def f puts(36893488147419102235) puts(-36893488147419102235) end f
Will print:
36893488147419102235
36893488147419102235
After the fix, it will print:
36893488147419102235
-36893488147419102235
Codegen before fix:
irep 0x7f954ff49cd0 nregs=5 nlocals=2 pools=1 syms=1 reps=0 ilen=20
file: (mirb)
4 000 ENTER 0:0:0:0:0:0:0 (0x0)
5 004 LOADL R3 L[0] <--------- SAME
5 007 SSEND R2 :puts n=1
6 011 LOADL R3 L[0] <--------- SAME
6 014 SSEND R2 :puts n=1
6 018 RETURN R2
Codegen after fix:
irep 0x7fcdfbf0f310 nregs=5 nlocals=2 pools=2 syms=1 reps=0 ilen=20
file: (mirb)
4 000 ENTER 0:0:0:0:0:0:0 (0x0)
5 004 LOADL R3 L[0] <--------- DIFFERENT
5 007 SSEND R2 :puts n=1
6 011 LOADL R3 L[1] <--------- DIFFERENT
6 014 SSEND R2 :puts n=1
6 018 RETURN R2
- It generates new pool entries for negative bigints even if it is already present.
For example:
def f puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) puts(-36893488147419102235) end f
Codegen before fix:
irep 0x7f9550b04390 nregs=5 nlocals=2 pools=10 syms=1 reps=0 ilen=76
file: (mirb)
17 000 ENTER 0:0:0:0:0:0:0 (0x0)
18 004 LOADL R3 L[0] <--------- NEW POOL ENTRY
18 007 SSEND R2 :puts n=1
19 011 LOADL R3 L[1] <--------- NEW POOL ENTRY
19 014 SSEND R2 :puts n=1
20 018 LOADL R3 L[2] <--------- NEW POOL ENTRY
20 021 SSEND R2 :puts n=1
21 025 LOADL R3 L[3] <--------- NEW POOL ENTRY
21 028 SSEND R2 :puts n=1
22 032 LOADL R3 L[4] <--------- NEW POOL ENTRY
22 035 SSEND R2 :puts n=1
23 039 LOADL R3 L[5] <--------- NEW POOL ENTRY
23 042 SSEND R2 :puts n=1
24 046 LOADL R3 L[6] <--------- NEW POOL ENTRY
24 049 SSEND R2 :puts n=1
25 053 LOADL R3 L[7] <--------- NEW POOL ENTRY
25 056 SSEND R2 :puts n=1
26 060 LOADL R3 L[8] <--------- NEW POOL ENTRY
26 063 SSEND R2 :puts n=1
27 067 LOADL R3 L[9] <--------- NEW POOL ENTRY
27 070 SSEND R2 :puts n=1
27 074 RETURN R2
Codegen after fix:
irep 0x7f9cbfe04360 nregs=5 nlocals=2 pools=1 syms=1 reps=0 ilen=76
file: (mirb)
12 000 ENTER 0:0:0:0:0:0:0 (0x0)
13 004 LOADL R3 L[0] <--------- SAME
13 007 SSEND R2 :puts n=1
14 011 LOADL R3 L[0] <--------- SAME
14 014 SSEND R2 :puts n=1
15 018 LOADL R3 L[0] <--------- SAME
15 021 SSEND R2 :puts n=1
16 025 LOADL R3 L[0] <--------- SAME
16 028 SSEND R2 :puts n=1
17 032 LOADL R3 L[0] <--------- SAME
17 035 SSEND R2 :puts n=1
18 039 LOADL R3 L[0] <--------- SAME
18 042 SSEND R2 :puts n=1
19 046 LOADL R3 L[0] <--------- SAME
19 049 SSEND R2 :puts n=1
20 053 LOADL R3 L[0] <--------- SAME
20 056 SSEND R2 :puts n=1
21 060 LOADL R3 L[0] <--------- SAME
21 063 SSEND R2 :puts n=1
22 067 LOADL R3 L[0] <--------- SAME
22 070 SSEND R2 :puts n=1
22 074 RETURN R2