[Bug libgcc/59714] New: complex division is inaccurate on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714 Bug ID: 59714 Summary: complex division is inaccurate on aarch64 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: michael.hudson at linaro dot org Hi, it seems details in the rounding of complex division are wrong: ubuntu@arm64:~$ cat cplx.c #include int main(int argc, char** argv) { __complex double c = 1.0 + 3.0i; printf("%g\n", __imag__ (c/c)); } ubuntu@arm64:~$ gcc cplx.c -o cplx ubuntu@arm64:~$ ./cplx -1.66533e-17 This is because libgcc2.c is compiled in a way that lets the compiler used fused multiply add instructions. It shouldn't be! (in this particular case, it's because if x is the closest float64 to 1/3, evaluating "3*x - 1" using fnmsub does not yield 0 because of the lack of intermediate rounding. Evaluating 3*x, rounding it, and then subtracting 1 does yield 0).
[Bug libgcc/59714] complex division is inaccurate on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714 --- Comment #2 from Michael Hudson-Doyle --- Oh right. I saw that bug but didn't read enough of the comments to see that the same thing was mentioned. I still think fma is inappropriate for this function...
[Bug libgcc/59714] complex division is surprising on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714 --- Comment #4 from Michael Hudson-Doyle --- OK, so I should stop talking about accurate and instead talk about surprising :-) I think it is pretty surprising that x/x != 1+0i for (I think) all x where the ratio between the real and imaginary parts is not a power of 2 (put another way, an error of 1ulp when the accurate result is 0 is more surprising than when the accurate result is non-zero). In general, fma makes it hard to reason about expressions like "a*b-c*d" -- which of the multiplications is being done at the higher precision? But I guess arguing to fp-contract to default to off is a war I don't want to get into fighting.
[Bug target/59744] New: miscompilation of unsigned comparison on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59744 Bug ID: 59744 Summary: miscompilation of unsigned comparison on aarch64 Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: michael.hudson at linaro dot org Hi, This slightly strangely written program (it's distilled down from frame_offset_overflow in the gcc source itself) should print "bigger" if the first argument is bigger than 10 (or negative, but let's ignore that please): #include #include int a[2] = { 10, 20 }; int is_bigger (long offset, int index) { unsigned long size = -offset; if (size > a[index]) { printf("bigger\n"); return 1; } return 0; } int main (int argc, char** argv) { long v; v = atol(argv[1]); is_bigger(-v, 0); return 0; } When compiled at -O1 or above (and with inlining disabled at -O2 and above), though, it bungles the 0 case: (t-doko)mwhudson@arm64:~$ gcc-4.9 -O3 test.c -o test -fno-inline -Wall (t-doko)mwhudson@arm64:~$ ./test 1 (t-doko)mwhudson@arm64:~$ ./test 11 bigger (t-doko)mwhudson@arm64:~$ ./test 0 bigger (t-doko)mwhudson@arm64:~$ gcc-4.9 -O0 test.c -o test -Wall (t-doko)mwhudson@arm64:~$ ./test 1 (t-doko)mwhudson@arm64:~$ ./test 11 bigger (t-doko)mwhudson@arm64:~$ ./test 0 (t-doko)mwhudson@arm64:~$ What's going on? Here's the disassembly of is_bigger (at O3): 00400608 : 400608: b082adrpx2, 411000 <_GLOBAL_OFFSET_TABLE_+0x28> 40060c: 91010042add x2, x2, #0x40 400610: a9bf7bfdstp x29, x30, [sp,#-16]! 400614: 5283mov w3, #0x0// #0 400618: 910003fdmov x29, sp 40061c: b8a1d841ldrsw x1, [x2,w1,sxtw #2] 400620: ab3fcmn x1, x0 400624: 54a2b.cs400638 400628: 9000adrpx0, 40 <_init-0x3f8> 40062c: 911b6000add x0, x0, #0x6d8 400630: 9790bl 400470 400634: 52800023mov w3, #0x1// #1 400638: 2a0303e0mov w0, w3 40063c: a8c17bfdldp x29, x30, [sp],#16 400640: d65f03c0ret Basically it seems that the condition "-offset > val" is being compiled as "val + offset does not overflow", which is not valid for offset == 0.
[Bug target/59744] miscompilation of unsigned comparison on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59744 --- Comment #4 from Michael Hudson-Doyle --- Hi, thanks for the super fast fix. Could it be backported to 4.8? git cherry-pick gives a conflict in aarch64.md which is probably easy to fix if you know how this code works: (define_insn "*compare_neg" <<< HEAD [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:GPI 0 "register_operand" "r") (neg:GPI (match_operand:GPI 1 "register_operand" "r"] ||| parent of 46b590a... PR target/9744 [(set (reg:CC_SWP CC_REGNUM) (compare:CC_SWP (neg:GPI (match_operand:GPI 0 "register_operand" "r")) (match_operand:GPI 1 "register_operand" "r")))] === [(set (reg:CC_Z CC_REGNUM) (compare:CC_Z (neg:GPI (match_operand:GPI 0 "register_operand" "r")) (match_operand:GPI 1 "register_operand" "r")))] >>> 46b590a... PR target/9744 "" "cmn\\t%0, %1" [(set_attr "v8type" "alus") (set_attr "mode" "")] )
[Bug target/59744] miscompilation of unsigned comparison on aarch64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59744 --- Comment #7 from Michael Hudson-Doyle --- I saw the problem with Linaro GCC 4.8, but haven't tried the vanilla 4.8 branch. If the committed test case doesn't fail, I'll believe that it is not a problem. Sorry for the noise.
[Bug target/59799] New: aarch64_pass_by_reference never passes arrays by value, contrary to ABI documentation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59799 Bug ID: 59799 Summary: aarch64_pass_by_reference never passes arrays by value, contrary to ABI documentation Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: michael.hudson at linaro dot org It's always possible I'm totally misunderstanding something here, but it seems that this code: /* Arrays always passed by reference. */ if (TREE_CODE (type) == ARRAY_TYPE) return true; in gcc/config/aarch64/aarch64.c does not agree with the rules from "Procedure Call Standard for the ARM 64-bit Architecture" (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf). As far as I can see the rules on page 18 and 19 make no distinction between arrays and structs and they can both be passed in registers when small enough.
[Bug target/59799] aarch64_pass_by_reference never passes arrays by value, contrary to ABI documentation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59799 --- Comment #6 from Michael Hudson-Doyle --- Created attachment 31861 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31861&action=edit Simple fix This very simple patch (just deleting the offending lines) makes the go test case that was failing pass. I'm running a complete test suite run now, will update on how it looks when it's done.
[Bug target/59799] aarch64_pass_by_reference never passes arrays by value, contrary to ABI documentation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59799 --- Comment #7 from Michael Hudson-Doyle --- There are no additional failures with this patch (and the only additional pass is libgo's reflect test).
[Bug target/59799] aarch64_pass_by_reference never passes arrays by value, contrary to ABI documentation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59799 --- Comment #11 from Michael Hudson-Doyle --- Er yes, this was fixed before 4.9.0.
[Bug go/61877] [5 Regression]: reflect: cannot use []string as type string in Call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61877 --- Comment #3 from Michael Hudson-Doyle --- The problem is that the call to "m.Call" at https://gcc.gnu.org/viewcvs/gcc/trunk/libgo/go/reflect/makefunc.go?revision=212853&view=markup#l133 needs, in this case, to be a call to "m.CallSlice". I don't know how it can know when it needs to do that though.
[Bug go/61877] [5 Regression]: reflect: cannot use []string as type string in Call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61877 --- Comment #4 from Michael Hudson-Doyle --- Created attachment 33639 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33639&action=edit proposed fix This fix works for me. I can't find any tests of this behaviour -- casting the result of (*reflect.Value).Interface to an actual pointer type and then calling it. Am I just being blind?
[Bug go/61877] [5 Regression]: reflect: cannot use []string as type string in Call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61877 --- Comment #6 from Michael Hudson-Doyle --- Created attachment 33640 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33640&action=edit my test cases I think the patch works because when the compiler sees a call to a variadic function, it generates a regular call with a slice as the last parameter. I'm attaching a test case that I wrote -- it passes with my patch and fails without it, so I think my patch has at last something going for it... It also seems the intel case is broken on this test case on mainline. If I hack it to take the ffi case, it works with my patch. Also 4.9 works, which confuses me a little -- I didn't think the intel code path had changed here (but haven't actually checked).
[Bug go/61877] [5 Regression]: reflect: cannot use []string as type string in Call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61877 --- Comment #10 from Michael Hudson-Doyle --- I've proposed a fix https://codereview.appspot.com/152840043