Re: Deprecating basic asm in a function - What now?
On Sun, Jun 19, 2016 at 11:43 PM, David Wohlferd wrote: > Perhaps this post should be directed toward port maintainers? > > Since several global maintainers have now suggested it, I have created a > patch that deprecates basic asm when used in a function (attached). It > excludes (ie does not deprecate) top level asm, asm in "naked" functions, > asm with empty instruction strings, and extended asm. > > Building gcc using this patch turns up a few places that use this feature, > so I fixed them. Where possible, I used builtins to replace the asm. For > ease-of-review, these changes are in their own patch (attached) and > obviously this patch should be checked in first. > > But before I send these 2 off to gcc-patches, there's a problem. What about > platforms other than x86/x64? I don't speak other assembler languages, and > have no setup with which to test them. > > I could try to provide patches for other platforms, but it would probably be > faster for platform experts to just make the changes themselves, rather than > trying to review my efforts. Especially if they also want to move to > builtins (which I hope they do). > > I could just send the patches and let the chips fall where they may, but if > there's a less disruptive approach, let me know. + /* Acceptable. */ + asm (" "); /* { dg-warning "Deprecated: asm in function without extended syntax" } */ You say it is acceptable but then have a dg-warning on it. Also I think the other place where we should accept basic asm is for "nop" instructions. I have seen people use that heavily. Note really I don't like the idea of deprecating basic asm at all. Thanks, Andrew > > dw > > PS I have done a scan for uses of basic asm to get some idea of the scope of > the remaining work. My results: > > All basic asm in trunk: 1,105 instances. > - Exclude 273 instances with empty strings leaving 832. > - Exclude 271 instances for boehm-gc project leaving 561. > - Exclude 202 instances for testsuite project leaving 359. > - Exclude 282 instances that are (apparently) top-level leaving > > ~77 instances of basic-asm-in-a-function to be fixed for gcc builds. Most > of these are in gcc/config or libgcc/config with just a handful per > platform. Lists available upon request. > > FWIW...
Re: Deprecating basic asm in a function - What now?
On 20/06/16 08:00, Andrew Pinski wrote: > + /* Acceptable. */ > + asm (" "); /* { dg-warning "Deprecated: asm in function without > extended syntax" } */ This is incorrect English. It should be "Deprecated: asm without extended syntax in function" because it's the asm that is missing the extended syntax, not the function. Andrew.
Re: Deprecating basic asm in a function - What now?
On Mon, 20 Jun 2016, Andrew Haley wrote: > On 20/06/16 08:00, Andrew Pinski wrote: > > + /* Acceptable. */ > > + asm (" "); /* { dg-warning "Deprecated: asm in function without > > extended syntax" } */ > > This is incorrect English. It should be > > "Deprecated: asm without extended syntax in function" No diagnostics should start with uppercase letters. (I also disagree with the deprecation.) -- Joseph S. Myers jos...@codesourcery.com
Re: Deprecating basic asm in a function - What now?
On Mon, Jun 20, 2016 at 12:00:16AM -0700, Andrew Pinski wrote: > Also I think the other place where we should accept basic asm is for > "nop" instructions. I have seen people use that heavily. And anything else that means the same as basic asm and as extended asm. > Note really I don't like the idea of deprecating basic asm at all. If basic asm is deprecated, that means some time later it will be removed, at which time an asm without : can be used as extended asm (or we can force everyone to write asm("nop":); if we are silly). Warning about asm without : now is just unnecessary churn (and not just for us, also for all the users of inline asm). Segher
Re: Deprecating basic asm in a function - What now?
On 20/06/16 14:50, Segher Boessenkool wrote: > If basic asm is deprecated, that means some time later it will be > removed, at which time an asm without : can be used as extended asm Not exactly: it'd be an asm with no inputs, no outputs, and no clobbers i.e. no effects. Andrew.
Re: Deprecating basic asm in a function - What now?
On Mon, Jun 20, 2016 at 02:55:58PM +0100, Andrew Haley wrote: > On 20/06/16 14:50, Segher Boessenkool wrote: > > If basic asm is deprecated, that means some time later it will be > > removed, at which time an asm without : can be used as extended asm > > Not exactly: it'd be an asm with no inputs, no outputs, and no > clobbers i.e. no effects. I'm not sure what you mean? It will be treated exactly the same as basic asm (it is now, anyway). And it has an effect, it is volatile after all, not having any outputs? Segher
Re: Deprecating basic asm in a function - What now?
On 20/06/16 15:42, Segher Boessenkool wrote: > On Mon, Jun 20, 2016 at 02:55:58PM +0100, Andrew Haley wrote: >> On 20/06/16 14:50, Segher Boessenkool wrote: >>> If basic asm is deprecated, that means some time later it will be >>> removed, at which time an asm without : can be used as extended asm >> >> Not exactly: it'd be an asm with no inputs, no outputs, and no >> clobbers i.e. no effects. > > I'm not sure what you mean? It will be treated exactly the same as > basic asm (it is now, anyway). And it has an effect, it is volatile > after all, not having any outputs? Well, you didn't say that it was volatile: and unless it really is an asm volatile (not just an asm) an extended asm with no effects is a statement with no effects. Andrew.
Re: Deprecating basic asm in a function - What now?
On Mon, Jun 20, 2016 at 03:49:19PM +0100, Andrew Haley wrote: > On 20/06/16 15:42, Segher Boessenkool wrote: > > On Mon, Jun 20, 2016 at 02:55:58PM +0100, Andrew Haley wrote: > >> On 20/06/16 14:50, Segher Boessenkool wrote: > >>> If basic asm is deprecated, that means some time later it will be > >>> removed, at which time an asm without : can be used as extended asm > >> > >> Not exactly: it'd be an asm with no inputs, no outputs, and no > >> clobbers i.e. no effects. > > > > I'm not sure what you mean? It will be treated exactly the same as > > basic asm (it is now, anyway). And it has an effect, it is volatile > > after all, not having any outputs? > > Well, you didn't say that it was volatile: and unless it really is > an asm volatile (not just an asm) an extended asm with no effects > is a statement with no effects. An extended asm without outputs is always volatile (exactly because it would be useless otherwise). Segher
Re: Deprecating basic asm in a function - What now?
On 20/06/16 15:52, Segher Boessenkool wrote: > On Mon, Jun 20, 2016 at 03:49:19PM +0100, Andrew Haley wrote: >> On 20/06/16 15:42, Segher Boessenkool wrote: >>> On Mon, Jun 20, 2016 at 02:55:58PM +0100, Andrew Haley wrote: On 20/06/16 14:50, Segher Boessenkool wrote: > If basic asm is deprecated, that means some time later it will be > removed, at which time an asm without : can be used as extended asm Not exactly: it'd be an asm with no inputs, no outputs, and no clobbers i.e. no effects. >>> >>> I'm not sure what you mean? It will be treated exactly the same as >>> basic asm (it is now, anyway). And it has an effect, it is volatile >>> after all, not having any outputs? >> >> Well, you didn't say that it was volatile: and unless it really is >> an asm volatile (not just an asm) an extended asm with no effects >> is a statement with no effects. > > An extended asm without outputs is always volatile (exactly because > it would be useless otherwise). Oh, I see what you mean now. Yes, point taken. Andrew.
Re: Deprecating basic asm in a function - What now?
Given how many embedded ports have #defines in external packages for basic asms for instructions such as nop, enable/disable interrupts, other system-level opcodes, etc... I think this is a bad idea. Even glibc would break. #define enable() asm("eint") __asm__ __volatile__ ("fwait");
Re: Deprecating basic asm in a function - What now?
Hi, On Sun, 19 Jun 2016, David Wohlferd wrote: > All basic asm in trunk: 1,105 instances. > - Exclude 273 instances with empty strings leaving 832. > - Exclude 271 instances for boehm-gc project leaving 561. > - Exclude 202 instances for testsuite project leaving 359. > - Exclude 282 instances that are (apparently) top-level leaving > > ~77 instances of basic-asm-in-a-function to be fixed for gcc builds. > Most of these are in gcc/config or libgcc/config with just a handful per > platform. Lists available upon request. Well, I think this quite clearly shows how bad an idea it would be to deprecate basic asm. We are just one project, and ourself and our dependencies already have 77+271 uses of them, not counting the testsuite which also reflects some real world usage. I see zero gain by deprecating them and only churn. What would be the advantage again? Ciao, Michael.
Re: Deprecating basic asm in a function - What now?
On 20/06/16 18:36, Michael Matz wrote: > I see zero gain by deprecating them and only churn. What would be the > advantage again? Correctness. It is very likely that many of these basic asms are not robust in the face of compiler changes because they don't declare their dependencies and therefore work only by accident. There are some correct basic asms. For example, asm("nop") There are some others too, once we've made the change to have basic asms clobber memory. These include syscalls which are implemented by using named register variables. Andrew.
Re: Deprecating basic asm in a function - What now?
Hi, On Mon, 20 Jun 2016, Andrew Haley wrote: > On 20/06/16 18:36, Michael Matz wrote: > > I see zero gain by deprecating them and only churn. What would be the > > advantage again? > > Correctness. As said in the various threads about basic asms, all correctness problems can be solved by making GCC more conservative in handling them (or better said: not making it less conservative). If you talk about cases where basic asms diddle registers expecting GCC to have placed e.g. local variables into specific ones (without using local reg vars, or extended asm) I won't believe any claims ... > It is very likely that many of these basic asms are not > robust ... of them being very likely without proof. They will have stopped working with every change in compilation options or compiler version. In contrast I think those that did survive a couple years in software very likely _are_ correct, under the then documented (or implicit) assumptions. Those usually are: clobbers and uses memory, processor state and fixed registers. > in the face of compiler changes because they don't declare their > dependencies and therefore work only by accident. Then the compiler better won't change into less conservative handling of basic asms. You see, the experiment shows that there's a gazillion uses of basic asms out there. Deprecating them means that each and every one of them (for us alone that's 540 something, including testsuite and boehm) has to be changed from asm("body") into asm("body" : : : "memory") (give and take some syntax for also clobbering flags). Alternatively rewrite the body to actually make use of extended asm. I guarantee you that a non-trivial percentage will be wrong _then_ while they work fine now. Even if it weren't so it still would be silly if GCC simply could regard the former as the latter internally. It would just be change for the sake of it and affecting quite many users without gain. Ciao, Michael.
Re: _Bool and trap representations
On 06/17/2016 02:19 PM, Alexander Cherepanov wrote: On 2016-06-15 17:15, Martin Sebor wrote: There has been quite a bit of discussion among the committee on this subject lately (the last part is the subject of DR #451, though it's discussed in the context of uninitialized objects with indeterminate values). Are there notes from these discussions or something? Notes from discussions during committee meetings are in the meeting minutes that are posted along with other committee documents on the public site. Those that relate to aspects of defect reports are usually captured in the Committee Discussion and Committee Response to the DR. Other than that, committee discussions that take place on the committee mailing list (such as the recent ones on this topic) are archived for reference of committee members (unlike C++, the C archives are not intended to be open to the public). So it seems the discussion you referred to is not public, that's unfortunate. And to clarify what you wrote about stability of valid representations, is padding expected to be stable when it's not specifically set? I.e. is the following optimization supposed to be conforming or not? The standard says that padding bytes take on unspecified values after an assignment to a structure, so the program isn't strictly conforming because its output depends on such a value. At the same time, unspecified values are, in general, expected to be stable. But I think in this case it's only because of the standard's limited vocabulary. The distinction between an unspecified and undefined value was meant to allow for the latter to be a trap representation. But lately an undefined value has also come to mean potentially unstable (some people call such values "wobbly"). If the standard adopted a term for unspecified values that don't need not be stable (say wobbly) I would expect the committee to be comfortable applying it padding bits and allowing the code in the example to produce two different lines. But this is one of the topics still under active discussion. Martin Source code: -- #include int main(int argc, char **argv) { (void)argv; struct { char c; int i; } s = {0, 0}; printf("%d\n", argc ? ((unsigned char *)&s)[1] : 5); printf("%d\n", argc ? ((unsigned char *)&s)[1] : 7); } -- Results: -- $ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out 5 7 -- gcc version: gcc (GCC) 7.0.0 20160616 (experimental) Of course, clang does essentially the same but the testcase is a bit more involved (I can post it if somebody is interested). OTOH clang is more predictable in this area because rules for dealing with undefined values in llvm are more-or-less documented -- http://llvm.org/docs/LangRef.html#undefined-values . I don't see gcc treating padding in long double as indeterminate in the same way as in structs but clang seems to treat them equally.
Re: Return value on MIPS N64 ABI
Thank you. On Mon, Jun 13, 2016 at 6:19 PM, Matthew Fortune wrote: > Heiher writes: >> Looks the return value of TestNewA is passed on $f0/$f2 from disassembly >> code. I don't known why the return value of TestNewB is passed on >> $v0/$v1? a bug? > > I believe this is an area where GNU strays from the N64 ABI definition but > is defacto standard. TestA is a struct of two floating point fields which > is passed and returned in FP registers. TestB is a struct of a struct of > two floating point fields (or at least I think that is the interpretation). > > The ABI does say that this should be flattened and be seen as simply two > floating point fields but GCC does not and passes it in integer registers > instead. Or at least the ABI says this for arguments but not results. > > The relevant bit of the ABI we are not adhering to is 'Structs,unions' on > page 7 which covers arguments, however the corresponding text for results > does not include the part about ignoring the struct field structure > when determining between floating point and integer chunks. > > https://dmz-portal.ba.imgtec.org/mw/images/6/6f/007-2816-005-1.pdf > > FWIW: Clang/LLVM ABI implementation matches GCC in this regard as we run > cross linking tests and use GCC as 'correct'. > > Thanks, > Matthew > >> 229 00012c40 <_Z8TestNewAv>: >> 23012c40: 3c030002lui v1,0x2 >> 23112c44: 0079182ddaddu v1,v1,t9 >> 23212c48: 64638400daddiu v1,v1,-31744 >> 23312c4c: dc628050ld v0,-32688(v1) >> 23412c50: 67bdffe0daddiu sp,sp,-32 >> 23512c54: d4400e68ldc1$f0,3688(v0) >> 23612c58: dc628050ld v0,-32688(v1) >> 23712c5c: 67bd0020daddiu sp,sp,32 >> 23812c60: 03e8jr ra >> 23912c64: d4420e70ldc1$f2,3696(v0) >> 240 >> 241 00012c68 <_Z8TestNewBv>: >> 24212c68: 3c0307f9lui v1,0x7f9 >> 24312c6c: 3c0207f7lui v0,0x7f7 >> 24412c70: 3463ori v1,v1,0x >> 24512c74: 3442ori v0,v0,0x >> 24612c78: 00031cb8dsllv1,v1,0x12 >> 24712c7c: 000214b8dsllv0,v0,0x12 >> 24812c80: 3463cccdori v1,v1,0xcccd >> 24912c84: 3442cccdori v0,v0,0xcccd >> 25012c88: 67bdfff0daddiu sp,sp,-16 >> 25112c8c: 00031c78dsllv1,v1,0x11 >> 25212c90: 00021478dsllv0,v0,0x11 >> 25312c94: 6463999adaddiu v1,v1,-26214 >> 25412c98: 6442999adaddiu v0,v0,-26214 >> 25512c9c: 03e8jr ra >> 25612ca0: 67bd0010daddiu sp,sp,16 >> >> // test.cpp >> // gcc -march=mips64r2 -mabi=64 -O3 -o test test.cpp #include >> >> class TestA >> { >> public: >> double l; >> double h; >> >> TestA(double l, double h) : l(l), h(h) {} }; >> >> class TestB : public TestA >> { >> public: >> TestB(const TestA& a) : TestA(a) {} }; >> >> TestA >> TestNewA(void) >> { >> return TestA(0.1, 0.2); >> } >> >> TestB >> TestNewB(void) >> { >> return TestA(0.1, 0.2); >> } >> >> int >> main(int argch, char *argv[]) >> { >> TestA a = TestNewA(); >> printf("%lf, %lf\n", a.l, a.h); >> >> TestB b = TestNewB(); >> printf("%lf, %lf\n", b.l, b.h); >> >> return 0; >> } -- Best regards! Heiher http://hev.cc