Hi, On 06/01/18 15:20, Jérémy Lal wrote: > This error happens on mipsel only: > https://buildd.debian.org/status/fetch.php?pkg=nodejs&arch=mipsel&ver=8.9.3~dfsg-6&stamp=1515132264&raw=0 > > Maybe it's related to a bug in another package, is it a known issue ? I believe you have hit one of the infamous Loongson FPU "bugs" [1]. This is an extract from the disassembly of nodejs in v8::internal::compiler::Scheduler::ComputeSchedule: > lwc1 $f1,-392(v0) > mul.s $f0,$f0,$f2 > c.le.s $f1,$f0 > bc1t 0x55cd6990 The C code for this is: > float node_hint_multiplier = (flags & Scheduler::kSplitNodes) ? 1.1 : 1; > size_t node_count_hint = node_hint_multiplier * graph->NodeCount(); After the lwc (which loads INT_MAX as a float) we have this in the float registers according to gdb: > f0: 0x44094000 flt: 549 dbl: 3.5336950251869015e+72 > f1: 0x4f000000 flt: 2.14748365e+09 > f2: 0x3f800000 flt: 1 dbl: 1073742078 > f3: 0x41d00000 flt: 26 But after the multiplication we lose the value in f1: > f0: 0x44094000 flt: 549 dbl: 5.6395463852218459e-315 > f1: 0x00000000 flt: 0 > f2: 0x3f800000 flt: 1 dbl: 1073742078 > f3: 0x41d00000 flt: 26 The result of the comparison (c.le.s) then changes and we branch (bc1t) when we should not. The end result is we end up with node_count_hint being set to 0x80000000 which later causes the length_error. In gcc, the Loongson bugs are worked around on mipsel by: - Disabling fused multiply + add instructions completely - Enabling FPXX which (as a side effect) disables use of odd FP registers for single precision arithmetic. In nodejs you allow the use of odd FP registers by compiling with FP32. I think if you add "-mno-odd-spreg" to your CFLAGS (and CXXFLAGS) then you should be able to avoid these issues in C code (and fix this specific bug). Unfortunately avoiding them in JITed code is a lot more complex :/ Yunqiang, should we enable --without-odd-spreg-32 when compiling gcc on mipsel? I think that will also fix this. James --- [1] Extract from Loongson 3A processor manual (google translated from chinese so forgive the english): The GS464 is compatible with the MIPS64 Release 2 release and functionally implements all the FPU instructions specified by the MIPS64 architecture, However, there are some instructions in the implementation of subtle compatibility does not affect but more important difference, the following two points worth the attention of programmers. (1) multiply plus, multiply minus instruction. When executing the four instruction sets of MADD.fmt, MSUB.fmt, NMADD.fmt and NMSUB.fmt, the operation result of GS464 is slightly different from that of MIPS64 processor because GS464 only performs multiply-add operation only at the final result Do precision rounding, and the MIPS64 processor carried out after the operation of a rounding, adding an additional round, resulting in The final result of a minimum difference of 1. (2) Single-precision arithmetic instructions. When the FR bit in the Status control register is 0, abs.s, add.s, ceil.w.d, ceil.w.s, div.s, floor.w.d, floor.w.s, mul.s, neg.s, round.w.d, round.w.s, sqrt.s, sub.s, trunc.w.d, trunc.w.s, mov.s, cvt.d.s, 26 instructions such as cvt.d.w, cvt.s.d, cvt.s.w, cvt.w.d, cvt.w.s, movf.s, movn.s, movt.s, movz.s etc can not be sent by odd numbers Memory, and MIPS64 architecture processor can, at this point, Godson follows MIPS R4000 and MIPSR10000 do Act, slightly different from the provisions of MIPS64. (FR bits in earlier MIPS processors indicate whether the floating-point registers were 16 or 32, The FR bit in MIPS64 indicates whether the floating-point register is 32-bit or 64-bit).
Attachment:
signature.asc
Description: OpenPGP digital signature