[Bug target/114416] calling convention incompatibility with vendor compiler for V9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416 --- Comment #22 from Jakub Kulik --- Eric and Rainer, thank you both very much for all that testing and the fix.
[Bug target/114416] calling convention incompatibility with vendor compiler for V9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416 --- Comment #11 from Jakub Kulik --- > This is a bit of circular reasoning but, if the rule had been crystal clear, > GCC would have implemented it at some point during the last quarter of > century. I see. I guess it's also not a common enough use case to pass small structs with float arrays between programs and libraries (potentially compiled with different compilers). That said, for example libffi implements the ABI as was intended (it's how I originally found this issue).
[Bug target/114416] calling convention incompatibility with vendor compiler for V9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416 --- Comment #10 from Jakub Kulik --- Sorry for longer response. I asked internally again and was told by a colleague who was in the room when the spec was created, that: "the intent was (and is) that the individual elements/atoms/fundamental types that make up a small structure, no matter how those elements/atoms/fundamental types are aggregated within the structure, are passed in registers appropriate for the fundamental type in question. (That is, pointers and integral types are passed in the %o registers, and floating point types are passed in the floating-point registers.) So a structure that contains an array of two floats is treated the same as a structure that contains two floats." That said, he agreed that the spec could perhaps be better written. He also added: Page 3P-11 says this, under "Function Argument Passing": "It is convenient to describe parameter linkage in terms of an array. Conceptually, parameters are assigned into an array of extended words, left-to-right, with an occasional “hole” to satisfy alignment restrictions. Typically, most parameter values will be “promoted” from their memory locations into registers, and most calls are expected to execute this way with less overhead." There is then a diagram that shows the correspondence between parameter registers and the parameter array. On page 3P-12, under "Structure and Union arguments", it says this: "Structure or union types up to eight bytes in size are assigned to one parameter array word, and align to eight-byte boundaries. "Structure or union types larger than eight bytes, and up to sixteen bytes in size are assigned to two consecutive parameter array words, and align according to the alignment requirements of the structure or at least to an eight-byte boundary." So perhaps instead of saying "The individual fields of a structure ... are subject to promotion into registers based on their type using the same rules as apply to scalar values" the spec should have said "The individual parameter array words assigned to a structure ... are subject to promotion into registers based on their type using the same rules as apply to scalar values."
[Bug target/114416] calling convention incompatibility with vendor compiler for V9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416 --- Comment #7 from Jakub Kulik --- Hmm, I just realized that you referred to the same sections, so my previous comment might not make it clearer...
[Bug target/114416] calling convention incompatibility with vendor compiler for V9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416 Jakub Kulik changed: What|Removed |Added CC||jakub.kulik at oracle dot com --- Comment #6 from Jakub Kulik --- Thank you for the proposed fix! I tested it with several programs that I used to find/reproduce the issue and it seems to work now (I talked about this with Rainer initially). As for the ABI being potentially unclear, I am in no way a SPARCv9 ABI expert, so I asked internally, and was told that the ABI should be clear about this case: """ See page 3P-10 (PDF page 46) where it says this: %f0,%f1,%f2,%f3 (%d0, %d2) (%q0) Floating-point return values appear in the floating-point registers. Single-precision values occupy %f0; double-precision values occupy %d0; quad-precision values occupy %q0. (Refer to the SPARCTM Architecture Manual, Version 9 for details on the register numbering scheme). Otherwise, these are scratch registers. and %f0 through %f7 (%d0 through %d6) (%q0 and %q4) Floating-point fields from structure return values with a total size of 32 bytes or less appear in the floating-point registers. Then on page 3P-13 (PDF page 49) it says this: Structure or Union return values Structure and union return types up to thirty-two bytes in size are returned in registers. The registers are assigned as if the value was being passed as the first argument to a function with a known prototype. So we have to refer back to "Structure and Union arguments" on page 3P-12 (PDF page 48) where it says: "Structure or union types are always left-justified, whether stored in registers or memory. *The individual fields of a structure (or containing storage unit in the case of bit fields) are subject to promotion into registers based on their type using the same rules as apply to scalar values* (with the addition that a single-precision floating-point number assigned to the left half of an argument slot will be promoted into the corresponding even-numbered float register.)." [sic; emphasis added.] """
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #12 from Jakub Kulik --- One thing that is still slightly limiting is that the stack size cannot be changed e.g. for individual tests when running the libgo test suite. It might be nice to have some exported interface, such as the already existing SetMaxStack() [1], although I do understand that that would be a bigger change and would make the code using it golang incompatible, which might be a problem. There is probably not much to do about this - I just wanted to mention this limitation. [1] https://pkg.go.dev/runtime/debug#SetMaxStack
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #11 from Jakub Kulik --- So, I looked into it and with the patch attached above seems to work as expected. Stack can be resized like this `GODEBUG=minstacksize=32 ./test`.
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #10 from Jakub Kulik --- Created attachment 53935 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53935=edit Proposed patch with configurable minimal stack size
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #8 from Jakub Kulik --- Sure, this was just a quick first test. That said, GODEBUG is slightly more complex - is there an example of a C code where GODEBUG variables are being used you can point me to (I found only go sources with anything GODEBUG related)? As for the split stack, I will try looking into it and see if it works. Having overhead might solve the issue with no linker support, but it's indeed pretty wasteful (and might break what works currently)...
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #6 from Jakub Kulik --- So, I tested it with the following simple change and it works nicely: --- gcc-12.2.0/libgo/runtime/proc.c +++ gcc-12.2.0/libgo/runtime/proc.c @@ -798,7 +798,15 @@ runtime_malg(bool allocatestack, bool si } newg = allocg(); if(allocatestack) { - stacksize = StackMin; + char* res = getenv("GCCGO_MIN_STACK_SIZE"); + if (res) { + stacksize = atoi(res) * 1024 * 1024; + + if (stacksize < StackMin) + stacksize = StackMin; + } else { + stacksize = StackMin; + } if(signalstack) { stacksize = 32 * 1024; // OS X wants >= 8K, GNU/Linux >= 2K #ifdef SIGSTKSZ As said, it's not the right solution, but it's an improvement. As for the split stack, I am wondering whether it is possible to do it without linker support? IIUIC, gold makes sure then when split stack code calls a non split stack one, much bigger stack is available. But if we make sure that the headroom is big enough all the time, then it might work without the linker support as well.
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #4 from Jakub Kulik --- Thanks for the confirmation. -fsplit-stack on Solaris would be nice, but it's as simple as designating a TLS accessible slot, right? We have our own linker on Solaris and don't use gold, and I am not how feasible it would be to add functionality similar to that of gold. I do like the idea of adjustable min size with an environment variable because that should not be a big change, and all platforms can use it. It's not really the best solution, but better than nothing, I guess.
[Bug go/107491] Gccgo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 --- Comment #2 from Jakub Kulik --- That's what I thought, but I am not sure whether there is supposed to be a different mechanism on other platforms or whether the 4MB stack cap per thread is the maximum I can get on non Linux platform.
[Bug go/107491] New: GccGo stack not resizing on Solaris
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107491 Bug ID: 107491 Summary: GccGo stack not resizing on Solaris Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: go Assignee: ian at airs dot com Reporter: jakub.kulik at oracle dot com Target Milestone: --- Created attachment 53809 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53809=edit simple program with recursion that break on Solaris Question regarding gccgo and stack sizes on Solaris (and other non GNU/Linux systems). When I run a code with (not that deep) recursion (example attached) on Solaris, it segfaults as it overflows the stack. I checked with gdb on both Linux and Solaris and Linux is calling `__morestack` once in a while and Solaris does not. IIUIC, __morestack allocates additional stack when compiled with `-fsplit-stack`, which is "currently only supported on GNU/Linux". As for my question, is this behavior (segfault after 4MB stack is exhausted) expected or is there a different stack resize/overflow prevention on non `-split-stack` platforms that might not be working correctly on Solaris? This is on Oracle Solaris 11.4 and gccgo shipped with gcc 10.4, 11.3 and 12.1. (Golang is fine but that is to be expected as they implement all this in a different way).