Yunqiang Su <yunqiang...@imgtec.com> writes: >> 在 2016年12月22日,23:48,Yunqiang Su <yunqiang...@imgtec.com> 写道: >> >>> >>> 在 2016年12月22日,23:31,Richard Sandiford >>> <rdsandif...@googlemail.com> 写道: >>> >>> Matthew Fortune <matthew.fort...@imgtec.com> writes: >>>> Sandra Loosemore <san...@codesourcery.com> writes: >>>>> On 12/21/2016 11:54 AM, Yunqiang Su wrote: >>>>>> By this patch, I add a build-time option ` --with-unfused-madd4=yes/no', >>>>>> and runtime option -m(no-)unfused-madd4, >>>>>> to disable generate madd.fmt instructions. >>>>> >>>>> Your patch also needs a documentation change so that the new >>>>> command-line option is listed in the GCC manual with other MIPS target >>>>> options. >>>> >>>> Any opinions on option names to control this? Is it best to target >>>> the specific >>>> feature that is non-compliant on loongson or apply a general -mfix-loongson >>>> type option? >>>> >>>> I'm not sure I have a strong opinion either way but there do seem to be >>>> multiple possible variants. >>> >>> Wasn't sure from this thread whether Loongson simply had a fused >>> implementation (without intermediate rounding) or whether the >>> instructions gave numerically incorrect results for some inputs. >> >> I test to define ISA_HAS_FUSED_MADD4 true and >> define ISA_HAS_UNFUSED_MADD4 false, and try to build a test case. >> With ISA_HAS_FUSED_MADD4, the result is about 1e-17, >> and with ISA_HAS_UNFUSED_MADD4, the result is about 1e-17, >> both of the are incorrect (the expect value is 0). >> >> The test case is >> >> #include <stdio.h> >> >> double a = 0.6; >> double b = 0.4; >> double c = 0.6; >> double d = 0.4; >> >> int main(void) >> { >> double x = a * b - c * d; >> printf("%le\n", x); >> return 0; >> } >> >> >>> It sounds from a later thread like it's generating incorrect results, >>> is that right? If so, then FWIW I agree an -mfix option would be more >>> consistent. E.g. one of the -mfix-vr4120 errata was an incorrect >>> integer division result and one of the -mfix-sb1 errata was an incorrect >>> single-precision float division result. The latter case could have been >>> handled by an option to disable DIV.S and DIV.PS, but the -mfix option >>> gave more control. >>> >>> If instead the problem is that the instructions are fused then that's >>> also what the original MIPS 4 parts did, so maybe an option to control >>> fusedness would make sense. >> >> The result to thread it fused or unfused, is different, while neither of them >> is correct. > > ohh, the result are same, and neither is correct. > both of them are 1.332268e-17.
That's the expected result for an implementation in which the subtraction is fused with the first multiplication without intermediate rounding. The second 0.4 * 0.6 isn't exactly representable and rounds down, to a value slightly less than 0.24. Then the fused operation subtracts this value from the exact result of the first 0.4 * 0.6 (0.24), giving a value slightly greater than 0. I see Paul Hua's patch does add Loongson to the list of targets with a fused implementation (should have checked earlier, sorry). So I think after that patch we would do the right thing. (In particular, -ffp-contract=off would then disable the fusing.) Thanks, Richard