Re: wishlist: support for shorter pointers
Hi Alex! W dniu 28.06.2023 o 03:54, waffl3x pisze: I want to preface this stating that I have little to no experience in compiler development, I am only merely just getting into it. With that said, I have messed around with library design a fair amount, and this seems like something that could be implemented in a library. It might be slightly comfier implemented on the compiler side, but I question how generally it could be implemented. I thought of it a lot, and library implementation is something I'd rather avoid. Before I elaborate, let me put some excerpts of the code in question. GREP-ing the sources for "->next" (list processing) this is how it looks like. I have a lot of code like this scattered around: --- y->next = NULL; if (our) { out->next = a; for (y = t->HD; y && y->next; y = y->next) if (y) y->next = a; fit->HD = a->next; fit->win = a->next; b = a->next; This is from just one source file, which otherwise is "plain C". If I was to put it into a library that use "asm tweaked fancy pointers", a portable fragment of code becomes "target dedicated" - this is undesired. To elaborate: even in (or may be "particularly" in) embedded world, one prefers to have as portable code (to other targets) as possible. And I must say, that such code fragments as quoted are scattered around my sources practically everywhere. If I "convert" them to a library, the entire project becomes "target locked", and in consequences "unmaintainable". Such move practically kills it. Now, let me put the case into numbers: if I use stm32f030 instead of stm32f103, I may end up with just 4kB of RAM. The struct I heavily use here is 32bytes long, but with 16-bit "pointers" it collapses to 16bytes. This structure pops up in many places and within a running system it may reach 100 instances. It's a LOT of space to fight for. -R PS: pls CC the response to my address (as you have done) - I'm not sure if I get mails from the list.
Re: wishlist: support for shorter pointers
On Wed, 28 Jun 2023, 08:14 Rafał Pietrak via Gcc, wrote: > Hi Alex! > > W dniu 28.06.2023 o 03:54, waffl3x pisze: > > I want to preface this stating that I have little to no experience in > compiler > > development, I am only merely just getting into it. With that said, I > have messed around > > with library design a fair amount, and this seems like something that > could be > > implemented in a library. It might be slightly comfier implemented on > the compiler side, > > but I question how generally it could be implemented. > > I thought of it a lot, and library implementation is something I'd > rather avoid. Before I elaborate, let me put some excerpts of the code > in question. GREP-ing the sources for "->next" (list processing) this is > how it looks like. I have a lot of code like this scattered around: > --- > y->next = NULL; > if (our) { out->next = a; > for (y = t->HD; y && y->next; y = y->next) > if (y) y->next = a; > fit->HD = a->next; > fit->win = a->next; > b = a->next; > > This is from just one source file, which otherwise is "plain C". If I > was to put it into a library that use "asm tweaked fancy pointers", a > portable fragment of code becomes "target dedicated" - this is undesired. > If you use a C++ library type for your pointers the syntax above doesn't need to change, and the fancy pointer type can be implemented portable, with customisation for targets where you could use 16 bits for the pointers. > To elaborate: even in (or may be "particularly" in) embedded world, one > prefers to have as portable code (to other targets) as possible. And I > must say, that such code fragments as quoted are scattered around my > sources practically everywhere. If I "convert" them to a library, the > entire project becomes "target locked", and in consequences > "unmaintainable". Not if you use a C++ class type. Such move practically kills it. > > Now, let me put the case into numbers: if I use stm32f030 instead of > stm32f103, I may end up with just 4kB of RAM. The struct I heavily use > here is 32bytes long, but with 16-bit "pointers" it collapses to > 16bytes. This structure pops up in many places and within a running > system it may reach 100 instances. It's a LOT of space to fight for. > > -R > PS: pls CC the response to my address (as you have done) - I'm not sure > if I get mails from the list. >
Re: [PATCH] Basic asm blocks should always be volatile
Hi Andrew, On a Microsoft Windows target the following (placed inside a function of course) will only work correctly if volatile is specified in the basic asm block (or if the attached patch was applied to gcc): asm ("1:" "\n" "\t" ".seh_handler __C_specific_handler, @except" "\n" "\t" ".seh_handlerdata" "\n" "\t" ".long 1" "\n" "\t" ".rva 1b, 2f, 3f, 4f" "\n" "\t" ".seh_code"); { // std::printf("Guarded\n"); RaiseException(EXCEPTION_BREAKPOINT, 0, 0, nullptr); } asm ("nop" "\n" "\t" "2: nop" "\n" "\t" "jmp 5f" "\n" "\t" "3:" "\n" "\t" "push rbp" "\n" "\t" "mov rbp, rsp" "\t" "push r15" "\n" "\t" "mov r15, rcx" "\n"); [] [[gnu::noinline, gnu::used]] () -> long { return EXCEPTION_EXECUTE_HANDLER; }(); asm ("pop r15" "\n" "\t" "pop rbp" "\n" "\t" "ret" "\n" "\t" "nop" "\n" "4:"); { std::printf("Exception\n"); } asm ("5:"); In any case I doubt marking it as volatile in the parser hurts either, since this is the behaviour it's supposed to have best regards, Julian On Wed, Jun 28, 2023 at 12:24 AM Andrew Pinski wrote: > On Tue, Jun 27, 2023 at 9:15 AM Julian Waters > wrote: > > > > Hi Andrew, > > > > That can't be right, on my system a test of asm vs asm volatile with -O3 > and -flto=auto yields very different results, with only the latter being > correct. The patch fixed it and caused gcc to emit correct assembly > > Can you provide a few testcases? Because the gimplifier should always > happen. > > Thanks, > Andrew Pinski > > > > > best regards, > > Julian > > > > On Wed, Jun 28, 2023 at 12:08 AM Andrew Pinski > wrote: > >> > >> On Tue, Jun 27, 2023 at 9:03 AM Julian Waters via Gcc > wrote: > >> > > >> > gcc's documentatation mentions that all basic asm blocks are always > volatile, > >> > yet the parser fails to account for this by only ever setting > >> > volatile_p to true > >> > if the volatile qualifier is found. This patch fixes this by adding a > >> > special case check for extended_p before finish_asm_statement is > called > >> > >> The patch which are you doing will not change the behavior of GCC as > >> GCC already treats them as volatile later on. > >> non-extended inline-asm has no outputs so the following code in the > >> gimplifier will kick in and turn the gimple statement into volatile: > >> gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs > == 0); > >> > >> (note I am about to push a patch which changes the condition slightly > >> to have `asm goto` as volatile). > >> > >> Thanks, > >> Andrew > >> > >> > > >> > From 3094be39e3e65a6a638f05fafd858b89fefde6b5 Mon Sep 17 00:00:00 2001 > >> > From: TheShermanTanker > >> > Date: Tue, 27 Jun 2023 23:56:38 +0800 > >> > Subject: [PATCH] asm not using extended syntax should always be > volatile > >> > > >> > --- > >> > gcc/cp/parser.cc | 3 +++ > >> > 1 file changed, 3 insertions(+) > >> > > >> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > >> > index a6341b9..ef3d06a 100644 > >> > --- a/gcc/cp/parser.cc > >> > +++ b/gcc/cp/parser.cc > >> > @@ -22355,6 +22355,9 @@ cp_parser_asm_definition (cp_parser* parser) > >> >/* Create the ASM_EXPR. */ > >> >if (parser->in_function_body) > >> > { > >> > + if (!extended_p) { > >> > +volatile_p = true; > >> > + } > >> > asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs, > >> > inputs, clobbers, labels, inline_p); > >> > /* If the extended syntax was not used, mark the ASM_EXPR. */ > >> > -- > >> > 2.35.1.windows.2 >
Re: wishlist: support for shorter pointers
>This is from just one source file, which otherwise is "plain C". If I >was to put it into a library that use "asm tweaked fancy pointers", a >portable fragment of code becomes "target dedicated" - this is undesired. I sympathize with your desire to not lock your codebase to a particular target, I agree, it's important to keep it generic. I would definitely design the library to allow customization of the utilities for a given target. I imagine this gets a little difficult if you're setting up registers a certain way, but wrapping some ASM in a function object, and then forcing the call to that object to inline should do the trick there. From there, any code that you want to remain portable would have to take the pointer type by template parameter. Unfortunately, I can imagine the secondary part of this creating problems in an embedded project if you had to instantiate too many different functions from the templates. >--- > y->next = NULL; > if (our) { out->next = a; > for (y = t->HD; y && y->next; y = y->next) > if (y) y->next = a; > fit->HD = a->next; > fit->win = a->next; > b = a->next; > I suspect that this snippet that you shared might not be quite as portable as you think. It looks to me like it relies on type punning. Type punning can indeed be implemented in a well defined manner, in my experience though it rarely is. With that said, strict aliasing is very difficult to understand so I would not be surprised if I was mistaken here, especially since there's not enough code in the snippet to be certain. -Alex
Re: [PATCH] Basic asm blocks should always be volatile
On Wed, Jun 28, 2023 at 12:32 AM Julian Waters wrote: > > Hi Andrew, > > On a Microsoft Windows target the following (placed inside a function of > course) will only work correctly if volatile is specified in the basic asm > block (or if the attached patch was applied to gcc): These inline-asm will never work correctly even with volatile because you change the sp behind the back of GCC and the control flow too. Also I suspect you want gnu::noipa rather than gnu::noinline for the lambda there as I suspect the IPA passes are getting rid of the function call thinking it is just pure/const. Rather than related to the inline-asm being volatile or not. Thanks, Andrew > > asm ("1:" "\n" > "\t" ".seh_handler __C_specific_handler, @except" "\n" > "\t" ".seh_handlerdata" "\n" > "\t" ".long 1" "\n" > "\t" ".rva 1b, 2f, 3f, 4f" "\n" > "\t" ".seh_code"); > > { > // std::printf("Guarded\n"); > RaiseException(EXCEPTION_BREAKPOINT, 0, 0, nullptr); > } > > asm ("nop" "\n" > "\t" "2: nop" "\n" > "\t" "jmp 5f" "\n" > "\t" "3:" "\n" > "\t" "push rbp" "\n" > "\t" "mov rbp, rsp" > "\t" "push r15" "\n" > "\t" "mov r15, rcx" "\n"); > > [] [[gnu::noinline, gnu::used]] () -> long { > return EXCEPTION_EXECUTE_HANDLER; > }(); > > asm ("pop r15" "\n" > "\t" "pop rbp" "\n" > "\t" "ret" "\n" > "\t" "nop" "\n" > "4:"); > > { > std::printf("Exception\n"); > } > > asm ("5:"); > > In any case I doubt marking it as volatile in the parser hurts either, since > this is the behaviour it's supposed to have > > best regards, > Julian > > On Wed, Jun 28, 2023 at 12:24 AM Andrew Pinski wrote: >> >> On Tue, Jun 27, 2023 at 9:15 AM Julian Waters >> wrote: >> > >> > Hi Andrew, >> > >> > That can't be right, on my system a test of asm vs asm volatile with -O3 >> > and -flto=auto yields very different results, with only the latter being >> > correct. The patch fixed it and caused gcc to emit correct assembly >> >> Can you provide a few testcases? Because the gimplifier should always happen. >> >> Thanks, >> Andrew Pinski >> >> > >> > best regards, >> > Julian >> > >> > On Wed, Jun 28, 2023 at 12:08 AM Andrew Pinski wrote: >> >> >> >> On Tue, Jun 27, 2023 at 9:03 AM Julian Waters via Gcc >> >> wrote: >> >> > >> >> > gcc's documentatation mentions that all basic asm blocks are always >> >> > volatile, >> >> > yet the parser fails to account for this by only ever setting >> >> > volatile_p to true >> >> > if the volatile qualifier is found. This patch fixes this by adding a >> >> > special case check for extended_p before finish_asm_statement is called >> >> >> >> The patch which are you doing will not change the behavior of GCC as >> >> GCC already treats them as volatile later on. >> >> non-extended inline-asm has no outputs so the following code in the >> >> gimplifier will kick in and turn the gimple statement into volatile: >> >> gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == >> >> 0); >> >> >> >> (note I am about to push a patch which changes the condition slightly >> >> to have `asm goto` as volatile). >> >> >> >> Thanks, >> >> Andrew >> >> >> >> > >> >> > From 3094be39e3e65a6a638f05fafd858b89fefde6b5 Mon Sep 17 00:00:00 2001 >> >> > From: TheShermanTanker >> >> > Date: Tue, 27 Jun 2023 23:56:38 +0800 >> >> > Subject: [PATCH] asm not using extended syntax should always be volatile >> >> > >> >> > --- >> >> > gcc/cp/parser.cc | 3 +++ >> >> > 1 file changed, 3 insertions(+) >> >> > >> >> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc >> >> > index a6341b9..ef3d06a 100644 >> >> > --- a/gcc/cp/parser.cc >> >> > +++ b/gcc/cp/parser.cc >> >> > @@ -22355,6 +22355,9 @@ cp_parser_asm_definition (cp_parser* parser) >> >> >/* Create the ASM_EXPR. */ >> >> >if (parser->in_function_body) >> >> > { >> >> > + if (!extended_p) { >> >> > +volatile_p = true; >> >> > + } >> >> > asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs, >> >> > inputs, clobbers, labels, inline_p); >> >> > /* If the extended syntax was not used, mark the ASM_EXPR. */ >> >> > -- >> >> > 2.35.1.windows.2
Re: wishlist: support for shorter pointers
Hi Jonathan, W dniu 28.06.2023 o 09:31, Jonathan Wakely pisze: On Wed, 28 Jun 2023, 08:14 Rafał Pietrak via Gcc, [-] how it looks like. I have a lot of code like this scattered around: --- y->next = NULL; if (our) { out->next = a; for (y = t->HD; y && y->next; y = y->next) if (y) y->next = a; fit->HD = a->next; fit->win = a->next; b = a->next; This is from just one source file, which otherwise is "plain C". If I was to put it into a library that use "asm tweaked fancy pointers", a portable fragment of code becomes "target dedicated" - this is undesired. If you use a C++ library type for your pointers the syntax above doesn't need to change, and the fancy pointer type can be implemented portable, with customisation for targets where you could use 16 bits for the pointers. As you can expect from the problem I've stated - I don't know C++, so I'll need some more advice there. But, before I dive into learning C++ (forgive the naive question) isn't it so, that C++ comes with a heavy runtime? One that will bloat my tiny project? Or the bloat comes only when one uses particular elaborated class/inheritance scenarios, and this particular case ( for (...; ...; x = x->next) {} ) will not draw any of that into this project? Not knowing C++ and wanting to check your suggestion (before I start putting time into learning it), can you pls provide me a sample of code, that would replace the following: struct test_s { struct test_s *next; char buff[1]; }; int test_funct(struct test_s *head, char *opt) { struct test_s *x = head; for (; x; x = x->next) { if (!*x->buff) { *x->buff = *opt; break; } } return x; } - and help me compile it into a variant with "normal/natural to architecture" pointers, and a variant with "fancy 16-bit" pointers? Thenx in advance, -R PS: as before - I don't get mails from the list, pls CC responses to me.
Re: wishlist: support for shorter pointers
Hi Alex, W dniu 28.06.2023 o 09:34, waffl3x pisze: [--] --- y->next = NULL; if (our) { out->next = a; for (y = t->HD; y && y->next; y = y->next) if (y) y->next = a; fit->HD = a->next; fit->win = a->next; b = a->next; [---] With that said, strict aliasing is very difficult to understand so I would not be surprised if I was mistaken here, especially since there's not enough code in the snippet to be certain. Shur thing. The snippet is a GREP of the sources - there is no valid continuity between those lines :) I just wanted to point out the amount of constructs scattered around, and thus the necessity to replace the ENTIRE source by a non-portable variant if I was to put in into a C-lib. But may be Johnathan suggestion would work - I'll check it if I get some help with that. -R
types in GIMPLE IR
I have some random questions concerning types in the GIMPLE IR that I would appreciate some clarification on. Type safety --- Some transformations treat 1-bit types as a synonym of _Bool and mix the types in expressions, such as: _2; _Bool _3; _Bool _4; ... _4 = _2 ^ _3; and similarly mixing _Bool and enum enum E:bool { E0, E1 }; in one operation. I had expected this to be invalid... What are the type safety rules in the GIMPLE IR? Somewhat related, gcc.c-torture/compile/pr96796.c performs a VIEW_CONVERT_EXPR from struct S1 { long f3; char f4; } g_3_4; to an int p_51_9 = VIEW_CONVERT_EXPR(g_3_4); That must be wrong? Semantics of "Wide" Booleans, such as , seems to allow more values than 0 and 1. For example, I've seen some IR operations like: _66 = _16 ? _Literal () -1 : 0; But I guess there must be some semantic difference between and a 32-bit int, otherwise the wide Boolean type would not be needed... So what are the difference? /Krister
Re: wishlist: support for shorter pointers
Here's a quick and dirty example of how this function could be rewritten with modern C++. I omitted some necessary details, particularly the implementation of the linked list iterator. I also wrote it out quickly so I can't be certain it's 100% correct, but it should give you an idea of whats possible. // I assume you meant to return a pointer template auto test_funct(Iter iter, Iter end, char opt) { for (; iter != end; ++iter) { // dereferencing iter would get buff if (!*iter) { *iter = opt; break; } } return iter; } I also made an example using the C++ algorithms library. template auto test_funct(Iter begin, Iter end, char opt) { auto iter = std::find_if(begin, end, [](auto buff){return !buff;}); if (iter) { *iter = opt; } return iter; } As I said, there's quite a bit omitted here, to be blunt, implementing both the fancy pointers (especially when I don't know anything about the hardware) and the iterators required would be more of a task than I am willing to do. I'm happy to help but I don't think I should be doing unpaid labor :). These examples would work with anything implementing the C++ iterator interface, as long as you conform to that interface on both sides, most code will be reusable where it is possible. Regarding the C++ runtime, I can't speak authoritatively, but I believe that the C++ runtime is fairly hefty yes. Luckily, plenty of the standard library does not require it. I believe you'll want to look into GCC's freestanding support to get a full picture of what is and is not available. Again, I can't speak authoritatively on the matter, but I think you would be correct to avoid the C++ runtime. There are other pitfalls to beware of, one of my concerns is that templates can cause some degree of bloat to executable size, I imagine one can get around it if they try hard enough though. The most real bottleneck you'll encounter in very large projects is compile time, but that all depends on what you're using, and how much you're using it, and even then there are mitigations for that. I'm happy to answer more questions and help, however I'm concerned this is getting fairly unrelated to GCC. -Alex
Re: [PATCH] Basic asm blocks should always be volatile
Hi Andrew, On the contrary, code compiled with gcc with or without the applied patch operates very differently, with only gcc with the applied patch producing a fully correctly operating program as expected. Even if the above inline assembly blocks never worked due to other optimizations however, the failure mode of the program would be very different from how it fails now: It should fail noisily with an access violation exception due to the malformed assembly, but instead all the assembly which installs an exception handler never makes it into the final program because with anything higher than -O1 gcc deletes all of it (I have verified this with objdump too), so the original point still stands: That gcc is not correctly treating ISO C++ basic asm blocks as volatile. I'm sure a different example than the current one I have now could be brought up, but the fact that the volatile specifier is enough to change the behaviour of the program when it should always be volatile should be enough evidence of something being awry. Thanks for the tip with the lambdas though, I'll do just that best regards, Julian On Wed, Jun 28, 2023 at 3:39 PM Andrew Pinski wrote: > On Wed, Jun 28, 2023 at 12:32 AM Julian Waters > wrote: > > > > Hi Andrew, > > > > On a Microsoft Windows target the following (placed inside a function of > course) will only work correctly if volatile is specified in the basic asm > block (or if the attached patch was applied to gcc): > > These inline-asm will never work correctly even with volatile > because you change the sp behind the back of GCC and the control flow > too. > Also I suspect you want gnu::noipa rather than gnu::noinline for the > lambda there as I suspect the IPA passes are getting rid of the > function call thinking it is just pure/const. > Rather than related to the inline-asm being volatile or not. > > Thanks, > Andrew > > > > > asm ("1:" "\n" > > "\t" ".seh_handler __C_specific_handler, @except" "\n" > > "\t" ".seh_handlerdata" "\n" > > "\t" ".long 1" "\n" > > "\t" ".rva 1b, 2f, 3f, 4f" "\n" > > "\t" ".seh_code"); > > > > { > > // std::printf("Guarded\n"); > > RaiseException(EXCEPTION_BREAKPOINT, 0, 0, nullptr); > > } > > > > asm ("nop" "\n" > > "\t" "2: nop" "\n" > > "\t" "jmp 5f" "\n" > > "\t" "3:" "\n" > > "\t" "push rbp" "\n" > > "\t" "mov rbp, rsp" > > "\t" "push r15" "\n" > > "\t" "mov r15, rcx" "\n"); > > > > [] [[gnu::noinline, gnu::used]] () -> long { > > return EXCEPTION_EXECUTE_HANDLER; > > }(); > > > > asm ("pop r15" "\n" > > "\t" "pop rbp" "\n" > > "\t" "ret" "\n" > > "\t" "nop" "\n" > > "4:"); > > > > { > > std::printf("Exception\n"); > > } > > > > asm ("5:"); > > > > In any case I doubt marking it as volatile in the parser hurts either, > since this is the behaviour it's supposed to have > > > > best regards, > > Julian > > > > On Wed, Jun 28, 2023 at 12:24 AM Andrew Pinski > wrote: > >> > >> On Tue, Jun 27, 2023 at 9:15 AM Julian Waters > wrote: > >> > > >> > Hi Andrew, > >> > > >> > That can't be right, on my system a test of asm vs asm volatile with > -O3 and -flto=auto yields very different results, with only the latter > being correct. The patch fixed it and caused gcc to emit correct assembly > >> > >> Can you provide a few testcases? Because the gimplifier should always > happen. > >> > >> Thanks, > >> Andrew Pinski > >> > >> > > >> > best regards, > >> > Julian > >> > > >> > On Wed, Jun 28, 2023 at 12:08 AM Andrew Pinski > wrote: > >> >> > >> >> On Tue, Jun 27, 2023 at 9:03 AM Julian Waters via Gcc < > gcc@gcc.gnu.org> wrote: > >> >> > > >> >> > gcc's documentatation mentions that all basic asm blocks are > always volatile, > >> >> > yet the parser fails to account for this by only ever setting > >> >> > volatile_p to true > >> >> > if the volatile qualifier is found. This patch fixes this by > adding a > >> >> > special case check for extended_p before finish_asm_statement is > called > >> >> > >> >> The patch which are you doing will not change the behavior of GCC as > >> >> GCC already treats them as volatile later on. > >> >> non-extended inline-asm has no outputs so the following code in the > >> >> gimplifier will kick in and turn the gimple statement into volatile: > >> >> gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || > noutputs == 0); > >> >> > >> >> (note I am about to push a patch which changes the condition slightly > >> >> to have `asm goto` as volatile). > >> >> > >> >> Thanks, > >> >> Andrew > >> >> > >> >> > > >> >> > From 3094be39e3e65a6a638f05fafd858b89fefde6b5 Mon Sep 17 00:00:00 > 2001 > >> >> > From: TheShermanTanker > >> >> > Date: Tue, 27 Jun 2023 23:56:38 +0800 > >> >> > Subject: [PATCH] asm not using extended syntax should always be > volatile > >> >> > > >> >> > --- > >> >> > gcc/cp/parser
Re: wishlist: support for shorter pointers
Hi Alex, W dniu 28.06.2023 o 11:56, waffl3x pisze: Here's a quick and dirty example of how this function could be rewritten with modern C++. I omitted some necessary details, particularly the implementation of the linked list iterator. I also wrote it out quickly so I can't be certain it's 100% correct, but it should give you an idea of whats possible. trying // I assume you meant to return a pointer template auto test_funct(Iter iter, Iter end, char opt) { for (; iter != end; ++iter) { // dereferencing iter would get buff if (!*iter) { *iter = opt; break; } } return iter; } -- TEST.CPP is the above code $ g++ -fpermissive -c test.cpp >>no error, GOOD :) $ g++ -fpermissive -S test.cpp $ cat test.s .file "test.cpp" .text .ident "GCC: (Debian 12.2.0-14) 12.2.0" .section.note.GNU-stack,"",@progbits ---end-of-file-- Hmm... that's disappointing :( nothing was generated. then again. I've noticed that you've changed pointers to indices. I've pondered that for my implementation too but discarded the idea for it will require adjustments by struct-size (array element size) on every access Or may be C++ does a different thing with [object++], then what plain-c does with [variable++]? I's hard to analyze code without basic knowledge of the language :( I also made an example using the C++ algorithms library. template auto test_funct(Iter begin, Iter end, char opt) { auto iter = std::find_if(begin, end, [](auto buff){return !buff;}); if (iter) { *iter = opt; } return iter; } here I got: test2.cpp:3:22: error: ‘find_if’ is not a member of ‘std’ so, it's a nogo for me either. As I said, there's quite a bit omitted here, to be blunt, implementing both the fancy pointers (especially when I don't know anything about the hardware) and the iterators required would be more of a task than I am willing to do. I'm happy to help but I don't think I should be doing unpaid labor :). Fair enough. [-] I'm happy to answer more questions and help, however I'm concerned this is getting fairly unrelated to GCC. From my perspective it is related to GCC (well... ok, to CC in general - it "smells" like an extention to "C-standard" providing additional "funny" semantics to CC. But GCC is a "front-runner" for CC evolution, right? :). Then again. I'm not into drawing anybody into unfruitful and pointless support (for my little project). I only hoped that the problem could be recognized and may be would inspire some developers out there (as it would be silly for me, if I thought its implementation into GCC could happen before my small project ends, right?). Anyway, thanx for the hints and suggestions. -R
Re: wishlist: support for shorter pointers
> Hmm... that's disappointing :( nothing was generated. Function templates are not functions, they are templates of functions, they will not generate any code unless they are instantiated. > then again. I've noticed that you've changed pointers to indices. No, I changed pointers to a template type parameter named Iter. Which is meant to correspond to the C++ iterator interface. Pointers satisfy all of iterators requirements, and classes that satisfy those requirements (by implementing similar semantics to pointers) are also iterators. > Or may be C++ does a different thing with [object++], then > what plain-c does with [variable++]? That's correct, C++ has operator overloading, which allows you to define member functions for classes that are called when the corresponding operator is used. In this case, operator++ (in the imaginary implementation) is overloaded to go to the next element of the linked list. The iterator interface requires operator++ to be overloaded, and should implement similar semantics to using operator++ on a pointer. > I's hard to analyze code without basic knowledge of the language :( Yes, I personally recommend learncpp as a resource for learning C++, that would aid you greatly. C++ is a large language, you would need to invest some time into it to become proficient, in my opinion that investment is hugely worth it though. > I only hoped that the problem could be > recognized and may be would inspire some developers out there Unfortunately, I strongly agree with JWakely that what you requested belongs in library rather than in language additions. If implementing it is too much of a burden (which is understandable since you have no prior experience with C++) then I would suggest checking out Boost to see if they have what you need. I seem to recall them having some sort of fancy pointers in there somewhere. Realistically though, it will take some time to get used to all the C++isms before you would be able to be proficient with anything Boost would provide. I don't mean to be discouraging, I just want to keep your expectations realistic, the learning curve for C++ can be rather high, especially when you're used to C. Good luck! -Alex Sent with Proton Mail secure email. --- Original Message --- On Wednesday, June 28th, 2023 at 6:43 AM, Rafał Pietrak wrote: > Hi Alex, > > W dniu 28.06.2023 o 11:56, waffl3x pisze: > > > Here's a quick and dirty example of how this function could be rewritten > > with > > modern C++. I omitted some necessary details, particularly the > > implementation of the > > linked list iterator. I also wrote it out quickly so I can't be certain > > it's 100% > > correct, but it should give you an idea of whats possible. > > > trying > > > // I assume you meant to return a pointer > > template > > auto test_funct(Iter iter, Iter end, char opt) { > > for (; iter != end; ++iter) { > > // dereferencing iter would get buff > > if (!*iter) { *iter = opt; break; } > > } > > return iter; > > } > > -- TEST.CPP is the above code > $ g++ -fpermissive -c test.cpp > > > > no error, GOOD :) > > $ g++ -fpermissive -S test.cpp > $ cat test.s > .file "test.cpp" > .text > .ident "GCC: (Debian 12.2.0-14) 12.2.0" > .section .note.GNU-stack,"",@progbits > ---end-of-file-- > > Hmm... that's disappointing :( nothing was generated. > > then again. I've noticed that you've changed pointers to indices. I've > pondered that for my implementation too but discarded the idea for it > will require adjustments by struct-size (array element size) on every > access Or may be C++ does a different thing with [object++], then > what plain-c does with [variable++]? > > I's hard to analyze code without basic knowledge of the language :( > > > I also made an example using the C++ algorithms library. > > > > template > > auto test_funct(Iter begin, Iter end, char opt) { > > auto iter = std::find_if(begin, end, [](auto buff){return !buff;}); > > if (iter) { > > *iter = opt; > > } > > return iter; > > } > > > here I got: > test2.cpp:3:22: error: ‘find_if’ is not a member of ‘std’ > so, it's a nogo for me either. > > > As I said, there's quite a bit omitted here, to be blunt, implementing both > > the fancy pointers (especially when I don't know anything about the > > hardware) and > > the iterators required would be more of a task than I am willing to do. I'm > > happy > > to help but I don't think I should be doing unpaid labor :). > > > Fair enough. > > [-] > > > I'm happy to answer more questions and help, however I'm concerned this is > > getting fairly unrelated to GCC. > > > From my perspective it is related to GCC (well... ok, to CC in general > - it "smells" like an extention to "C-standard" providing additional > "funny" semantics to CC. But GCC is a "front-runner" for CC evolution, > right? :). > > Then again. I'm not into drawing anybody into unfruitful and pointless > support
Re: wishlist: support for shorter pointers
Hi Alex, W dniu 28.06.2023 o 14:12, waffl3x pisze: [--] them having some sort of fancy pointers in there somewhere. Realistically though, it will take some time to get used to all the C++isms before you would be able to be proficient with anything Boost would provide. I don't mean to be discouraging, I just want to keep your expectations realistic, the learning curve for C++ can be rather high, especially when you're used to C. Good luck! -Alex OK, thenx again. Bye. -R
Re: wishlist: support for shorter pointers
Sounds like named address spaces to me: https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html Best, Martin Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: > Hello everybody, > > I'm not quite sure if this is correct mailbox for this suggestion (may > be "embedded" would be better), but let me present it first (and while > the examples is from ARM stm32 environment, the issue would equally > apply to i386 or even amd64). So: > > 1. Small MPU (like stm32f103) would normally have small amount of RAM, > and even somewhat larger variant do have its memory "partitioned/ > dedicated" to various subsystems (like CloseCoupledMemory, Ethernet > buffers, USB buffs, etc). > > 2. to address any location within those sections of that memory (or > their entire RAM) it would suffice to use 16-bit pointers. > > 3. still, declaring a pointer in GCC always allocate "natural" size of a > pointer in given architecture. In case of ARM stm32 it would be 32-bits. > > 4. programs using pointers do keep them around in structures. So > programs with heavy use of pointers have those structures like 2 times > larger then necessary if only pointers were 16-bit. And memory in > those devices is scarce. > > 5. the same thing applies to 64-bit world. Programs that don't require > huge memories but do use pointers excessively, MUST take up 64-bit for a > pointer no matter what. > > So I was wondering if it would be feasible for GCC to allow SEGMENT to > be declared as "small" (like 16-bit addressable in 32-bit CPU, or 32-bit > addressable in 64-bit CPU), and ANY pointer declared to reference > location within them would then be appropriately reduced. > > In ARM world, the use of such pointers would require the use of an > additional register (functionally being a "segment base address") to > allow for data access using instructions like: "LD Rx, [Ry, Rz]" - > meaning register index reference. Here Ry is the base of the SEGMENT in > question. Or if (like inside a loop) the structure "pointed to" by Rz > must be often used, just one operation "ADD Rz, Ry" will prep Rz for > subsequent "ordinary" offset operations like: "LD Ra, [Rz, #member]" ... > and reentering the loop by "LDH Rz, [Rz, #next]" does what's required by > "x = x->next". > > Not having any experience in compiler implementations I have no idea if > this is a big or a small change to compiler design. > > -R
Re: wishlist: support for shorter pointers
Hi Martin, W dniu 28.06.2023 o 15:00, Martin Uecker pisze: Sounds like named address spaces to me: https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html Only to same extend, and only in x86 case. The goal of the wish-item I've describe is to shorten pointers. I may be wrong and have misread the specs, but the "address spaces" implementation you've pointed out don't look like doing that. In particular the AVR variant applies to devices that have a "native int" of 16-bits, and those devices (most of them) have address space no larger. So there is no gain. Their pointers cover all their address space and if one wanted to have shorter pointers ... like 12-bits - those wouldn't "nicely fit into register", or 8-bits - those would reduce the "addressable" space to 256 bytes, which is VERY tight for any practical application. Additionally, the AVR case is explained as "only for rodata" - this completely dismisses it from my use. To explain a little more: the functionality I'm looking for is something like x86 implementation of that "address spaces". The key functionality here is the additional register like fs/gs (an address offset register). IMHO the feature/implementation in question would HAVE TO use additional register instead of letting linker adjust them at link time, because those "short" pointers would need to be load-and-stored dynamically and changed dynamically at runtime. That's why I've put an example of ARM instruction that does this. Again IMHO the only "syntactic" feature,that is required for a compiler to do "the right thing" is to make compiler consider segment (segment name, ordinary linker segment name) where a particular pointer target resides. Then if that segment where data (of that pointer) reside is declared "short pointers", then compiler loads and uses additional register pointing to the base of that segment. Quite like intel segments work in hardware. Naturally, although I have hints on such mechanism behavior, I have no skills to even imagine where to tweak the sources to achieve that. -R Best, Martin Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: Hello everybody, I'm not quite sure if this is correct mailbox for this suggestion (may be "embedded" would be better), but let me present it first (and while the examples is from ARM stm32 environment, the issue would equally apply to i386 or even amd64). So: 1. Small MPU (like stm32f103) would normally have small amount of RAM, and even somewhat larger variant do have its memory "partitioned/ dedicated" to various subsystems (like CloseCoupledMemory, Ethernet buffers, USB buffs, etc). 2. to address any location within those sections of that memory (or their entire RAM) it would suffice to use 16-bit pointers. 3. still, declaring a pointer in GCC always allocate "natural" size of a pointer in given architecture. In case of ARM stm32 it would be 32-bits. 4. programs using pointers do keep them around in structures. So programs with heavy use of pointers have those structures like 2 times larger then necessary if only pointers were 16-bit. And memory in those devices is scarce. 5. the same thing applies to 64-bit world. Programs that don't require huge memories but do use pointers excessively, MUST take up 64-bit for a pointer no matter what. So I was wondering if it would be feasible for GCC to allow SEGMENT to be declared as "small" (like 16-bit addressable in 32-bit CPU, or 32-bit addressable in 64-bit CPU), and ANY pointer declared to reference location within them would then be appropriately reduced. In ARM world, the use of such pointers would require the use of an additional register (functionally being a "segment base address") to allow for data access using instructions like: "LD Rx, [Ry, Rz]" - meaning register index reference. Here Ry is the base of the SEGMENT in question. Or if (like inside a loop) the structure "pointed to" by Rz must be often used, just one operation "ADD Rz, Ry" will prep Rz for subsequent "ordinary" offset operations like: "LD Ra, [Rz, #member]" ... and reentering the loop by "LDH Rz, [Rz, #next]" does what's required by "x = x->next". Not having any experience in compiler implementations I have no idea if this is a big or a small change to compiler design. -R
Re: [PATCH] Basic asm blocks should always be volatile
Hello, On Wed, 28 Jun 2023, Julian Waters via Gcc wrote: > On the contrary, code compiled with gcc with or without the applied patch > operates very differently, with only gcc with the applied patch producing a > fully correctly operating program as expected. Even if the above inline > assembly blocks never worked due to other optimizations however, the > failure mode of the program would be very different from how it fails now: > It should fail noisily with an access violation exception due to > the malformed assembly, but instead all the assembly which installs an > exception handler never makes it into the final program because with > anything higher than -O1 gcc deletes all of it (I have verified this with > objdump too), Can you please provide a _full_ compilable testcase (preprocessed). What Andrew says is (supposed to be) correct: ignoring the other problems you're going to see with your asms (even if you make them volatile) GCC should not remove any of the asm statements of them. If something changes when you add 'volatile' by hand then we have another problem lurking somewhere, and adding the parser patch might not fully solve it (even if it changes behaviour for you). Ciao, Michael.
Re: wishlist: support for shorter pointers
On 28/06/2023 15:51, Rafał Pietrak via Gcc wrote: Hi Martin, W dniu 28.06.2023 o 15:00, Martin Uecker pisze: Sounds like named address spaces to me: https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html Only to same extend, and only in x86 case. The goal of the wish-item I've describe is to shorten pointers. I may be wrong and have misread the specs, but the "address spaces" implementation you've pointed out don't look like doing that. In particular the AVR variant applies to devices that have a "native int" of 16-bits, and those devices (most of them) have address space no larger. So there is no gain. Their pointers cover all their address space and if one wanted to have shorter pointers ... like 12-bits - those wouldn't "nicely fit into register", or 8-bits - those would reduce the "addressable" space to 256 bytes, which is VERY tight for any practical application. Additionally, the AVR case is explained as "only for rodata" - this completely dismisses it from my use. To explain a little more: the functionality I'm looking for is something like x86 implementation of that "address spaces". The key functionality here is the additional register like fs/gs (an address offset register). IMHO the feature/implementation in question would HAVE TO use additional register instead of letting linker adjust them at link time, because those "short" pointers would need to be load-and-stored dynamically and changed dynamically at runtime. That's why I've put an example of ARM instruction that does this. Again IMHO the only "syntactic" feature,that is required for a compiler to do "the right thing" is to make compiler consider segment (segment name, ordinary linker segment name) where a particular pointer target resides. Then if that segment where data (of that pointer) reside is declared "short pointers", then compiler loads and uses additional register pointing to the base of that segment. Quite like intel segments work in hardware. Naturally, although I have hints on such mechanism behavior, I have no skills to even imagine where to tweak the sources to achieve that. I think I understand what you're asking for but: 1) You'd need a new ABI specification to handle this, probably involving register assignments (for the 'segment' addresses), the initialization of those at startup, assembler and linker extensions to allow for relocations describing the symbols, etc. 2) Implementations for all of the above (it would be a lot of work - weeks to months, not days). Little existing code, including most of the hand-written assembly routines is likely to be compatible with the register conventions you'd need to define, so all that code would need auditing and alternatives developed. 3) I doubt it would be an overall win in the end. I base the last assertion on the fact that you'd now have three values in many addresses, the base (segment), the pointer and then a final offset. This means quite a bit more code being generated, so you trade smaller pointers in your data section for more code in your code section. For example, struct f { int a; int b; }; int func (struct f *p) { return p->b; } would currently compile to something like ldr r0, [r0, #4] bx lr but with the new, shorter, pointer you'd end up with add r0, r_seg, r0 ldr r0, [r0, #4] bx lr In some cases it might be even worse as you'd end up with zero-extensions of the pointer values as well. R. -R Best, Martin Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: Hello everybody, I'm not quite sure if this is correct mailbox for this suggestion (may be "embedded" would be better), but let me present it first (and while the examples is from ARM stm32 environment, the issue would equally apply to i386 or even amd64). So: 1. Small MPU (like stm32f103) would normally have small amount of RAM, and even somewhat larger variant do have its memory "partitioned/ dedicated" to various subsystems (like CloseCoupledMemory, Ethernet buffers, USB buffs, etc). 2. to address any location within those sections of that memory (or their entire RAM) it would suffice to use 16-bit pointers. 3. still, declaring a pointer in GCC always allocate "natural" size of a pointer in given architecture. In case of ARM stm32 it would be 32-bits. 4. programs using pointers do keep them around in structures. So programs with heavy use of pointers have those structures like 2 times larger then necessary if only pointers were 16-bit. And memory in those devices is scarce. 5. the same thing applies to 64-bit world. Programs that don't require huge memories but do use pointers excessively, MUST take up 64-bit for a pointer no matter what. So I was wondering if it would be feasible for GCC to allow SEGMENT to be declared as "small" (like 16-bit addressable in 32-bit CPU, or 32-bit addressable in 64-bit CPU), and ANY pointer declared to reference location
Re: types in GIMPLE IR
Hello, On Wed, 28 Jun 2023, Krister Walfridsson via Gcc wrote: > Type safety > --- > Some transformations treat 1-bit types as a synonym of _Bool and mix the types > in expressions, such as: > >_2; > _Bool _3; > _Bool _4; > ... > _4 = _2 ^ _3; > > and similarly mixing _Bool and enum > > enum E:bool { E0, E1 }; > > in one operation. > > I had expected this to be invalid... What are the type safety rules in the > GIMPLE IR? Type safety in gimple is defined in terms of type compatiblity, with _many_ exceptions for specific types of statements. Generally stuff is verified in verify_gimple_seq., in this case of a binary assign statement in verify_gimple_assign_binary. As you can see there the normal rules for bread-and-butter binary assigns is simply that RHS, LHS1 and LHS2 must all be type-compatible. T1 and T2 are compatible if conversions from T1 to T2 are useless and conversion from T2 to T1 are also useless. (types_compatible_p) The meat for that is all in gimple-expr.cc:useless_type_conversion_p. For this specific case again we have: /* Preserve conversions to/from BOOLEAN_TYPE if types are not of precision one. */ if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) && TYPE_PRECISION (outer_type) != 1) return false; So, yes, booleans and 1-bit types can be compatible (under certain other conditions, see the function). > Somewhat related, gcc.c-torture/compile/pr96796.c performs a VIEW_CONVERT_EXPR > from > > struct S1 { > long f3; > char f4; > } g_3_4; > > to an int > > p_51_9 = VIEW_CONVERT_EXPR(g_3_4); > > That must be wrong? VIEW_CONVERT_EXPR is _very_ generous. See verify_types_in_gimple_reference: if (TREE_CODE (expr) == VIEW_CONVERT_EXPR) { /* For VIEW_CONVERT_EXPRs which are allowed here too, we only check that their operand is not a register an invariant when requiring an lvalue (this usually means there is a SRA or IPA-SRA bug). Otherwise there is nothing to verify, gross mismatches at most invoke undefined behavior. */ if (require_lvalue && (is_gimple_reg (op) || is_gimple_min_invariant (op))) { error ("conversion of %qs on the left hand side of %qs", get_tree_code_name (TREE_CODE (op)), code_name); debug_generic_stmt (expr); return true; } else if (is_gimple_reg (op) && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op))) { error ("conversion of register to a different size in %qs", code_name); debug_generic_stmt (expr); return true; } } Here the operand is not a register (but a global memory object), so everything goes. It should be said that over the years gimples type system became stricter and stricter, but it started as mostly everything-goes, so making it stricter is a bumpy road that isn't fully travelled yet, because checking types often results in testcase regressions :-) > Semantics of > > "Wide" Booleans, such as , seems to allow more values than > 0 and 1. For example, I've seen some IR operations like: > > _66 = _16 ? _Literal () -1 : 0; > > But I guess there must be some semantic difference between > and a 32-bit int, otherwise the wide Boolean type > would not be needed... So what are the difference? See above, normally conversions to booleans that are wider than 1 bit are _not_ useless (because they require booleanization to true/false). In the above case the not-useless cast is within a COND_EXPR, so it's quite possible that the gimplifier didn't look hard enough to split this out into a proper conversion statement. (The verifier doesn't look inside the expressions of the COND_EXPR, so also doesn't catch this one) If that turns out to be true and the above still happens when -1 is replaced by (say) 42, then it might be possible to construct a wrong-code testcase based on the fact that _66 as boolean should contain only two observable values (true/false), but could then contain 42. OTOH, it might also not be possible to create such testcase, namely when GCC is internally too conservative in handling wide bools :-) In that case we probably have a missed optimization somewhere, which when implemented would enable construction of such wrong-code testcase ;) (I'm saying that -1 should be replaced by something else for a wrong-code testcase, because -1 is special and could justifieably be special-cased in GCC: -1 is the proper arithmetic value for a signed boolean that is "true"). Ciao, Michael.
Re: wishlist: support for shorter pointers
Am Mittwoch, dem 28.06.2023 um 16:44 +0100 schrieb Richard Earnshaw (lists): > On 28/06/2023 15:51, Rafał Pietrak via Gcc wrote: > > Hi Martin, > > > > W dniu 28.06.2023 o 15:00, Martin Uecker pisze: > > > > > > Sounds like named address spaces to me: > > > https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html > > > > Only to same extend, and only in x86 case. > > > > The goal of the wish-item I've describe is to shorten pointers. I may be > > wrong and have misread the specs, but the "address spaces" > > implementation you've pointed out don't look like doing that. In > > particular the AVR variant applies to devices that have a "native int" > > of 16-bits, and those devices (most of them) have address space no > > larger. So there is no gain. Their pointers cover all their address > > space and if one wanted to have shorter pointers ... like 12-bits - > > those wouldn't "nicely fit into register", or 8-bits - those would > > reduce the "addressable" space to 256 bytes, which is VERY tight for any > > practical application. > > > > Additionally, the AVR case is explained as "only for rodata" - this > > completely dismisses it from my use. > > > > To explain a little more: the functionality I'm looking for is something > > like x86 implementation of that "address spaces". The key functionality > > here is the additional register like fs/gs (an address offset register). > > IMHO the feature/implementation in question would HAVE TO use additional > > register instead of letting linker adjust them at link time, because > > those "short" pointers would need to be load-and-stored dynamically and > > changed dynamically at runtime. That's why I've put an example of ARM > > instruction that does this. Again IMHO the only "syntactic" feature,that > > is required for a compiler to do "the right thing" is to make compiler > > consider segment (segment name, ordinary linker segment name) where a > > particular pointer target resides. Then if that segment where data (of > > that pointer) reside is declared "short pointers", then compiler loads > > and uses additional register pointing to the base of that segment. Quite > > like intel segments work in hardware. > > > > Naturally, although I have hints on such mechanism behavior, I have no > > skills to even imagine where to tweak the sources to achieve that. > > > I think I understand what you're asking for but: > 1) You'd need a new ABI specification to handle this, probably involving > register assignments (for the 'segment' addresses), the initialization > of those at startup, assembler and linker extensions to allow for > relocations describing the symbols, etc. > 2) Implementations for all of the above (it would be a lot of work - > weeks to months, not days). Little existing code, including most of the > hand-written assembly routines is likely to be compatible with the > register conventions you'd need to define, so all that code would need > auditing and alternatives developed. > 3) I doubt it would be an overall win in the end. > > I base the last assertion on the fact that you'd now have three values > in many addresses, the base (segment), the pointer and then a final > offset. This means quite a bit more code being generated, so you trade > smaller pointers in your data section for more code in your code > section. For example, > > struct f > { > int a; > int b; > }; > > int func (struct f *p) > { > return p->b; > } > > would currently compile to something like > > ldr r0, [r0, #4] > bx lr > > but with the new, shorter, pointer you'd end up with > > add r0, r_seg, r0 > ldr r0, [r0, #4] > bx lr > > In some cases it might be even worse as you'd end up with > zero-extensions of the pointer values as well. > I do not quite understand why this wouldn't work with named address spaces? __near struct { int x; int y; }; int func (__near struct f *p) { return p->b; } could produce exactly such code? If you need multiple such segments one could have __near0, ..., __near9. Such a pointer could also be converted to a regular pointer, which could reduce code overhead. Martin > R. > > > -R > > > > > > > > Best, > > > Martin > > > > > > Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: > > > > Hello everybody, > > > > > > > > I'm not quite sure if this is correct mailbox for this suggestion (may > > > > be "embedded" would be better), but let me present it first (and while > > > > the examples is from ARM stm32 environment, the issue would equally > > > > apply to i386 or even amd64). So: > > > > > > > > 1. Small MPU (like stm32f103) would normally have small amount of RAM, > > > > and even somewhat larger variant do have its memory "partitioned/ > > > > dedicated" to various subsystems (like CloseCoupledMemory, Ethernet > > > > buffers, USB buffs, etc). > > > > > > > > 2. to address any location within those sections of th
Re: wishlist: support for shorter pointers
Hi Richard, W dniu 28.06.2023 o 17:44, Richard Earnshaw (lists) pisze: [--] I think I understand what you're asking for but: From what I can see below. You do. The case is exactly this. 1) You'd need a new ABI specification to handle this, probably involving register assignments (for the 'segment' addresses), the initialization of those at startup, assembler and linker extensions to allow for relocations describing the symbols, etc. 2) Implementations for all of the above (it would be a lot of work - weeks to months, not days). Little existing code, including most of the hand-written assembly routines is likely to be compatible with the register conventions you'd need to define, so all that code would need auditing and alternatives developed. I was afraid of that ... admittedly, not to the point you explain here. 3) I doubt it would be an overall win in the end. IMHO achieving the goal is worthwhile, although my estimates on the effort is surely not sufficient. I only hope, that it may spark some twist in doing the programming, thusly have a significant influence on future of programming as such. But, may be not. I base the last assertion on the fact that you'd now have three values in many addresses, the base (segment), the pointer and then a final offset. This means quite a bit more code being generated, so you trade smaller pointers in your data section for more code in your code Yes. And this is the actual reality with embedded systems. Atmega can have 128k of Flash, and only 4k of RAM, stm32f070 has 32k of flash and 4k of RAM. Having 1M of flash with just 128k of RAM is common in the "bigger" devices. Most of the time, when I have to choose, I'm better off moving things info flash instead of keeping them in RAM. section. For example, struct f { int a; int b; }; int func (struct f *p) { return p->b; } would currently compile to something like ldr r0, [r0, #4] bx lr but with the new, shorter, pointer you'd end up with add r0, r_seg, r0 ldr r0, [r0, #4] bx lr In some cases it might be even worse as you'd end up with zero-extensions of the pointer values as well. Yes, it would be like this. Only I don't think, that this case would be a real problem, since CPU-s usually have those zero-extended register loads already within their instruction sets. So in reality the cost will be a single ADD instruction before dereference, because the segment register would be initialized outside the loops. -R R. -R Best, Martin Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: Hello everybody, I'm not quite sure if this is correct mailbox for this suggestion (may be "embedded" would be better), but let me present it first (and while the examples is from ARM stm32 environment, the issue would equally apply to i386 or even amd64). So: 1. Small MPU (like stm32f103) would normally have small amount of RAM, and even somewhat larger variant do have its memory "partitioned/ dedicated" to various subsystems (like CloseCoupledMemory, Ethernet buffers, USB buffs, etc). 2. to address any location within those sections of that memory (or their entire RAM) it would suffice to use 16-bit pointers. 3. still, declaring a pointer in GCC always allocate "natural" size of a pointer in given architecture. In case of ARM stm32 it would be 32-bits. 4. programs using pointers do keep them around in structures. So programs with heavy use of pointers have those structures like 2 times larger then necessary if only pointers were 16-bit. And memory in those devices is scarce. 5. the same thing applies to 64-bit world. Programs that don't require huge memories but do use pointers excessively, MUST take up 64-bit for a pointer no matter what. So I was wondering if it would be feasible for GCC to allow SEGMENT to be declared as "small" (like 16-bit addressable in 32-bit CPU, or 32-bit addressable in 64-bit CPU), and ANY pointer declared to reference location within them would then be appropriately reduced. In ARM world, the use of such pointers would require the use of an additional register (functionally being a "segment base address") to allow for data access using instructions like: "LD Rx, [Ry, Rz]" - meaning register index reference. Here Ry is the base of the SEGMENT in question. Or if (like inside a loop) the structure "pointed to" by Rz must be often used, just one operation "ADD Rz, Ry" will prep Rz for subsequent "ordinary" offset operations like: "LD Ra, [Rz, #member]" ... and reentering the loop by "LDH Rz, [Rz, #next]" does what's required by "x = x->next". Not having any experience in compiler implementations I have no idea if this is a big or a small change to compiler design. -R
Re: wishlist: support for shorter pointers
On 28/06/2023 17:07, Martin Uecker wrote: Am Mittwoch, dem 28.06.2023 um 16:44 +0100 schrieb Richard Earnshaw (lists): On 28/06/2023 15:51, Rafał Pietrak via Gcc wrote: Hi Martin, W dniu 28.06.2023 o 15:00, Martin Uecker pisze: Sounds like named address spaces to me: https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html Only to same extend, and only in x86 case. The goal of the wish-item I've describe is to shorten pointers. I may be wrong and have misread the specs, but the "address spaces" implementation you've pointed out don't look like doing that. In particular the AVR variant applies to devices that have a "native int" of 16-bits, and those devices (most of them) have address space no larger. So there is no gain. Their pointers cover all their address space and if one wanted to have shorter pointers ... like 12-bits - those wouldn't "nicely fit into register", or 8-bits - those would reduce the "addressable" space to 256 bytes, which is VERY tight for any practical application. Additionally, the AVR case is explained as "only for rodata" - this completely dismisses it from my use. To explain a little more: the functionality I'm looking for is something like x86 implementation of that "address spaces". The key functionality here is the additional register like fs/gs (an address offset register). IMHO the feature/implementation in question would HAVE TO use additional register instead of letting linker adjust them at link time, because those "short" pointers would need to be load-and-stored dynamically and changed dynamically at runtime. That's why I've put an example of ARM instruction that does this. Again IMHO the only "syntactic" feature,that is required for a compiler to do "the right thing" is to make compiler consider segment (segment name, ordinary linker segment name) where a particular pointer target resides. Then if that segment where data (of that pointer) reside is declared "short pointers", then compiler loads and uses additional register pointing to the base of that segment. Quite like intel segments work in hardware. Naturally, although I have hints on such mechanism behavior, I have no skills to even imagine where to tweak the sources to achieve that. I think I understand what you're asking for but: 1) You'd need a new ABI specification to handle this, probably involving register assignments (for the 'segment' addresses), the initialization of those at startup, assembler and linker extensions to allow for relocations describing the symbols, etc. 2) Implementations for all of the above (it would be a lot of work - weeks to months, not days). Little existing code, including most of the hand-written assembly routines is likely to be compatible with the register conventions you'd need to define, so all that code would need auditing and alternatives developed. 3) I doubt it would be an overall win in the end. I base the last assertion on the fact that you'd now have three values in many addresses, the base (segment), the pointer and then a final offset. This means quite a bit more code being generated, so you trade smaller pointers in your data section for more code in your code section. For example, struct f { int a; int b; }; int func (struct f *p) { return p->b; } would currently compile to something like ldr r0, [r0, #4] bx lr but with the new, shorter, pointer you'd end up with add r0, r_seg, r0 ldr r0, [r0, #4] bx lr In some cases it might be even worse as you'd end up with zero-extensions of the pointer values as well. I do not quite understand why this wouldn't work with named address spaces? __near struct { int x; int y; }; int func (__near struct f *p) { return p->b; } could produce exactly such code? If you need multiple such segments one could have __near0, ..., __near9. Such a pointer could also be converted to a regular pointer, which could reduce code overhead. Martin Named address spaces, as they exist today, don't really do anything (at least, in the Arm port). A pointer is still 32-bits in size, so they become just syntactic sugar. If you're going to use them as 'bases', then you still have to define how the base address is accessed - it doesn't just happen by magic. R. R. -R Best, Martin Am Dienstag, dem 27.06.2023 um 14:26 +0200 schrieb Rafał Pietrak via Gcc: Hello everybody, I'm not quite sure if this is correct mailbox for this suggestion (may be "embedded" would be better), but let me present it first (and while the examples is from ARM stm32 environment, the issue would equally apply to i386 or even amd64). So: 1. Small MPU (like stm32f103) would normally have small amount of RAM, and even somewhat larger variant do have its memory "partitioned/ dedicated" to various subsystems (like CloseCoupledMemory, Ethernet buffers, USB buffs, etc). 2. to address any location within those sections of that memory (or their entire RAM) it would suffic
Re: wishlist: support for shorter pointers
Am Mittwoch, dem 28.06.2023 um 17:49 +0100 schrieb Richard Earnshaw (lists): > On 28/06/2023 17:07, Martin Uecker wrote: > > Am Mittwoch, dem 28.06.2023 um 16:44 +0100 schrieb Richard Earnshaw (lists): > > > On 28/06/2023 15:51, Rafał Pietrak via Gcc wrote: > > > > Hi Martin, > > > > > > > > W dniu 28.06.2023 o 15:00, Martin Uecker pisze: > > > > > > > > > > Sounds like named address spaces to me: > > > > > https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html > > > > > > > > Only to same extend, and only in x86 case. > > > > > > > > The goal of the wish-item I've describe is to shorten pointers. I may be > > > > wrong and have misread the specs, but the "address spaces" > > > > implementation you've pointed out don't look like doing that. In > > > > particular the AVR variant applies to devices that have a "native int" > > > > of 16-bits, and those devices (most of them) have address space no > > > > larger. So there is no gain. Their pointers cover all their address > > > > space and if one wanted to have shorter pointers ... like 12-bits - > > > > those wouldn't "nicely fit into register", or 8-bits - those would > > > > reduce the "addressable" space to 256 bytes, which is VERY tight for any > > > > practical application. > > > > > > > > Additionally, the AVR case is explained as "only for rodata" - this > > > > completely dismisses it from my use. > > > > > > > > To explain a little more: the functionality I'm looking for is something > > > > like x86 implementation of that "address spaces". The key functionality > > > > here is the additional register like fs/gs (an address offset register). > > > > IMHO the feature/implementation in question would HAVE TO use additional > > > > register instead of letting linker adjust them at link time, because > > > > those "short" pointers would need to be load-and-stored dynamically and > > > > changed dynamically at runtime. That's why I've put an example of ARM > > > > instruction that does this. Again IMHO the only "syntactic" feature,that > > > > is required for a compiler to do "the right thing" is to make compiler > > > > consider segment (segment name, ordinary linker segment name) where a > > > > particular pointer target resides. Then if that segment where data (of > > > > that pointer) reside is declared "short pointers", then compiler loads > > > > and uses additional register pointing to the base of that segment. Quite > > > > like intel segments work in hardware. > > > > > > > > Naturally, although I have hints on such mechanism behavior, I have no > > > > skills to even imagine where to tweak the sources to achieve that. > > > > > > > > > I think I understand what you're asking for but: > > > 1) You'd need a new ABI specification to handle this, probably involving > > > register assignments (for the 'segment' addresses), the initialization > > > of those at startup, assembler and linker extensions to allow for > > > relocations describing the symbols, etc. > > > 2) Implementations for all of the above (it would be a lot of work - > > > weeks to months, not days). Little existing code, including most of the > > > hand-written assembly routines is likely to be compatible with the > > > register conventions you'd need to define, so all that code would need > > > auditing and alternatives developed. > > > 3) I doubt it would be an overall win in the end. > > > > > > I base the last assertion on the fact that you'd now have three values > > > in many addresses, the base (segment), the pointer and then a final > > > offset. This means quite a bit more code being generated, so you trade > > > smaller pointers in your data section for more code in your code > > > section. For example, > > > > > > struct f > > > { > > > int a; > > > int b; > > > }; > > > > > > int func (struct f *p) > > > { > > > return p->b; > > > } > > > > > > would currently compile to something like > > > > > > ldr r0, [r0, #4] > > > bx lr > > > > > > but with the new, shorter, pointer you'd end up with > > > > > > add r0, r_seg, r0 > > > ldr r0, [r0, #4] > > > bx lr > > > > > > In some cases it might be even worse as you'd end up with > > > zero-extensions of the pointer values as well. > > > > > > > I do not quite understand why this wouldn't work with > > named address spaces? > > > > __near struct { > > int x; > > int y; > > }; > > > > int func (__near struct f *p) > > { > > return p->b; > > } > > > > could produce exactly such code? If you need multiple > > such segments one could have __near0, ..., __near9. > > > > Such a pointer could also be converted to a regular > > pointer, which could reduce code overhead. > > > > Martin > > Named address spaces, as they exist today, don't really do anything (at > least, in the Arm port). A pointer is still 32-bits in size, so they > become just syntactic sugar. > Sorry, I didn't mean to imply that this works today. But it seems one could use this mechanism to implement
Re: [PATCH] Basic asm blocks should always be volatile
On Wed, Jun 28, 2023 at 8:04 AM Michael Matz wrote: > > Hello, > > On Wed, 28 Jun 2023, Julian Waters via Gcc wrote: > > > On the contrary, code compiled with gcc with or without the applied patch > > operates very differently, with only gcc with the applied patch producing a > > fully correctly operating program as expected. Even if the above inline > > assembly blocks never worked due to other optimizations however, the > > failure mode of the program would be very different from how it fails now: > > It should fail noisily with an access violation exception due to > > the malformed assembly, but instead all the assembly which installs an > > exception handler never makes it into the final program because with > > anything higher than -O1 gcc deletes all of it (I have verified this with > > objdump too), > > Can you please provide a _full_ compilable testcase (preprocessed). What > Andrew says is (supposed to be) correct: ignoring the other > problems you're going to see with your asms (even if you make them > volatile) GCC should not remove any of the asm statements of them. > > If something changes when you add 'volatile' by hand then we have another > problem lurking somewhere, and adding the parser patch might not fully > solve it (even if it changes behaviour for you). By the way I just testcase: ``` void f(void) { asm("#should be volatile"); } ``` The produced gimple (via -fdump-tree-gimple=/dev/stdout) is: ``` void f () { __asm__ __volatile__("#should be volatile"); } ``` Which is 100% volatile. and I tested all the way back to GCC 4.8.0 and it was volatile back then too. So as both Michael and myself have mentioned, we need a full (compilable) testcase, even if it is for mingw or cygwin, we can handle those just fine too. Thanks, Andrew > > > Ciao, > Michael.
Re: Query status of GSoC project: CPyChecker
Hi Steven, Thanks for reaching out. The project is still in very early stages. So far we have taught the analyzer the basic behavior for PyLong_FromLong, PyList_New, and Py_DECREF via known function subclassing. Additionally, Py_INCREF is supported out of the box. Reference count checking functionality remains the priority, but it is not yet fully implemented. Regarding CPython versions, the goal is to just get things working on one version first. I arbitrarily picked 3.9, but happy to consider another version as an initial goal if it’s more helpful to the CPython community. Feel free to check out the repo at https://github.com/efric/gcc-cpython-analyzer for details on the project and to follow along and help out where you are interested. Best, Eric On Tue, Jun 27, 2023 at 6:03 AM Steven Sun wrote: > > Hi Eric, I am Steven (now) from the CPython team. > > How is the project going? Do you have any prototypes > or ideas that can be discussed? Which part will you start at? > > > I recently debugged dozens of Python bugs, some involving > C APIs. I can provide some test cases for you. > > > For the ref count part: > > A major change (immortal objects) is introduced in Python 3.12. > Basically, immortal objects will have the ref count fixed at > a very large number (depending on `sizeof(void*)` ). But I > don't think it is necessary to implement this in the early > stages. > > Some stable API steals reference conditionally (on success), > thus its behavior cannot be simply described by one attribute. > > > For CPython versions: > > Some stable CPython API behavior varied across the minor > release. (eg. 3.10 -> 3.11) For instance, some API accepted > NULL as args for <3.8, but not >=3.8. > > Considering both "GCC" and "CPython" are hard for users to > upgrade, we might want to consider how to live with these > behavioral differences in the first place. > > Versions older than 3 minor releases cannot be touched. (3.13 > now in active development, 3.12, 3.11 for bug fixes, 3.10, 3.9 > security fixes only) So, versions <= 3.10 can be treated as frozen.
gcc-10-20230628 is now available
Snapshot gcc-10-20230628 is now available on https://gcc.gnu.org/pub/gcc/snapshots/10-20230628/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 10 git branch with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-10 revision 8cf948e6d9ab19d54ec0d27357d0c2907a244474 You'll find: gcc-10-20230628.tar.xz Complete GCC SHA256=10499fde8acc04e52b86f6f42995b48db25d03a3bfbefe04f048d890db445e2d SHA1=e498f3332faef8be7aa7c45e38467ab74f5fb0df Diffs from 10-20230621 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-10 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
new mirror greece
Hello, I hope this message finds you well. I'd like to let you know that I have successfully set up a mirror (http/https server) in Greece for gcc. Location : Thessaloniki / Greece Admin Name : K. A. Draziotis Admin Email : drazi...@gmail.com Sponsor Name: Aristotle University of Thessaloniki Sponsor URL : https://auth.gr HTTP/HTTPS URL: fosszone.csd.auth.gr/gnu/gcc KD
Re: wishlist: support for shorter pointers
Hi Richard, W dniu 28.06.2023 o 17:44, Richard Earnshaw (lists) pisze: [---] I think I understand what you're asking for but: 1) You'd need a new ABI specification to handle this, probably involving register assignments (for the 'segment' addresses), the initialization of those at startup, assembler and linker extensions to allow for relocations describing the symbols, etc. I was thinking about that, and it doesn't look as requiring that deep rewrites. ABI spec, that could accomodate the functionality could be as little as one additional attribute to linker segments. Pls consider: 1. having that additional attribute (say "funny-ptr") of a segment. 2. ... from linker one would require only: 2.a) raising an error (fail) if one object has same segment-name WITH that attribute, and another object has that segment WITHOUT one. 2.b) raise an error (fail) if the resulting output segment would be larger then "max" (normally, max=64kB). 3. assembler would only need to be able to declare a segment with the new attribute 4. almost all the implementation changes are within the CC. Those changes can be broken down into a couple of scenarios: 4.a) for the following explanation, instead of __attribute__(section()), I will use shortcut. 4.b) assignment of "normal" to "funny" (char* x; char* y; x = y); here compiler would have to substract segment base address before deposition value at "&x", but for subsequent use of "x", compiler does NOT need to do anything. 4.c) reverse assignment (y = x); here compiler does nothing special, just uses "current/adjusted" value of "x". 4.d) comparation (x == y); compiler does nothing special - at this point, some register will already have "current/adjusted" value of "x". 4.e) comparation to NULL (x; !x; x == NULL); those test have to be done on "unadjusted" value of "x", so if register containing "x" is already adjusted, the base address will have to get substracted from "x" before test. And it may be good to take special care on loops (like "for()"). In case the loop looking like this: "for(;x; x = x->next)" the test is to be done before adjusting the pointer "x" by segment base address for the next loop-cycle, so there is no penalty for that test. I hope I didn't omit any important cases. If so, it doesn't look huge. Now, I'm NOT trying to persuade anybody, that it's "simple" and thus should be worth doing. I'm just doing some "intellectual exercise" with analyzing the challenge. -R
Re: types in GIMPLE IR
On Wed, Jun 28, 2023 at 5:47 PM Michael Matz via Gcc wrote: > > Hello, > > On Wed, 28 Jun 2023, Krister Walfridsson via Gcc wrote: > > > Type safety > > --- > > Some transformations treat 1-bit types as a synonym of _Bool and mix the > > types > > in expressions, such as: > > > >_2; > > _Bool _3; > > _Bool _4; > > ... > > _4 = _2 ^ _3; > > > > and similarly mixing _Bool and enum > > > > enum E:bool { E0, E1 }; > > > > in one operation. > > > > I had expected this to be invalid... What are the type safety rules in the > > GIMPLE IR? > > Type safety in gimple is defined in terms of type compatiblity, with > _many_ exceptions for specific types of statements. Generally stuff is > verified in verify_gimple_seq., in this case of a binary assign statement > in verify_gimple_assign_binary. As you can see there the normal rules for > bread-and-butter binary assigns is simply that RHS, LHS1 and LHS2 must > all be type-compatible. > > T1 and T2 are compatible if conversions from T1 to T2 are useless and > conversion from T2 to T1 are also useless. (types_compatible_p) The meat > for that is all in gimple-expr.cc:useless_type_conversion_p. For this > specific case again we have: > > /* Preserve conversions to/from BOOLEAN_TYPE if types are not > of precision one. */ > if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) >!= (TREE_CODE (outer_type) == BOOLEAN_TYPE)) > && TYPE_PRECISION (outer_type) != 1) > return false; > > So, yes, booleans and 1-bit types can be compatible (under certain other > conditions, see the function). > > > Somewhat related, gcc.c-torture/compile/pr96796.c performs a > > VIEW_CONVERT_EXPR > > from > > > > struct S1 { > > long f3; > > char f4; > > } g_3_4; > > > > to an int > > > > p_51_9 = VIEW_CONVERT_EXPR(g_3_4); > > > > That must be wrong? > > VIEW_CONVERT_EXPR is _very_ generous. See > verify_types_in_gimple_reference: Yep. In general these cases should rather use a BIT_FIELD_REF to select a same sized subpart and only then do the rvalue conversion. But as Micha says below making the IL stricter isn't an easy task. > if (TREE_CODE (expr) == VIEW_CONVERT_EXPR) > { > /* For VIEW_CONVERT_EXPRs which are allowed here too, we only check > that their operand is not a register an invariant when > requiring an lvalue (this usually means there is a SRA or IPA-SRA > bug). Otherwise there is nothing to verify, gross mismatches at > most invoke undefined behavior. */ > if (require_lvalue > && (is_gimple_reg (op) || is_gimple_min_invariant (op))) > { > error ("conversion of %qs on the left hand side of %qs", > get_tree_code_name (TREE_CODE (op)), code_name); > debug_generic_stmt (expr); > return true; > } > else if (is_gimple_reg (op) >&& TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE > (op))) > { > error ("conversion of register to a different size in %qs", > code_name); > debug_generic_stmt (expr); > return true; > } > } > > Here the operand is not a register (but a global memory object), so > everything goes. > > It should be said that over the years gimples type system became stricter > and stricter, but it started as mostly everything-goes, so making it > stricter is a bumpy road that isn't fully travelled yet, because checking > types often results in testcase regressions :-) > > > Semantics of > > > > "Wide" Booleans, such as , seems to allow more values > > than > > 0 and 1. For example, I've seen some IR operations like: > > > > _66 = _16 ? _Literal () -1 : 0; > > > > But I guess there must be some semantic difference between > > and a 32-bit int, otherwise the wide Boolean type > > would not be needed... So what are the difference? > > See above, normally conversions to booleans that are wider than 1 bit are > _not_ useless (because they require booleanization to true/false). In the > above case the not-useless cast is within a COND_EXPR, so it's quite > possible that the gimplifier didn't look hard enough to split this out > into a proper conversion statement. (The verifier doesn't look inside > the expressions of the COND_EXPR, so also doesn't catch this one) Note the above is GIMPLE FE syntax for a constant of a specific type, a regular dump would just show _16 ? -1 : 0; The thing with signed bools is that the two relevant values are -1 (true) and 0 (false), those are used for vector bool components where we also need them to be of wider type (32bits in this case). Richard. > If that turns out to be true and the above still happens when -1 is > replaced by (say) 42, then it might be possible to construct a > wrong-code testcase based on
Re: [PATCH] Basic asm blocks should always be volatile
Hi Andrew, Here is a simpler testcase, with the resulting assembly attached below int main() { asm ("nop" "\n" "\t" "nop" "\n" "\t" "nop"); asm volatile ("nop" "\n" "\t" "nop" "\n" "\t" "nop"); } objdump --disassemble-all -M intel -M intel-mnemonic a.exe > disassembly.txt 0001400028c0 : 1400028c0: 48 83 ec 28 subrsp,0x28 1400028c4: e8 37 ec ff ffcall 140001500 <__main> 1400028c9: 90nop 1400028ca: 90nop 1400028cb: 90nop 1400028cc: 31 c0 xoreax,eax 1400028cd: 48 83 c4 28 addrsp,0x28 1400028ce: c3ret Note how there are only 3 nops above when there should be 6, as the first 3 have been deleted by the compiler. With the patch, the correct 6 nops instead of 3 are compiled into the final code. Of course, the above was compiled with the most extreme optimizations available to stress test the possible bug, -O3, -ffunction-sections -fdata-sections -Wl,--gc-sections -flto=auto. Compiled as C++17 and intel assembly syntax best regards, Julian On Thu, Jun 29, 2023 at 2:46 AM Andrew Pinski wrote: > On Wed, Jun 28, 2023 at 8:04 AM Michael Matz wrote: > > > > Hello, > > > > On Wed, 28 Jun 2023, Julian Waters via Gcc wrote: > > > > > On the contrary, code compiled with gcc with or without the applied > patch > > > operates very differently, with only gcc with the applied patch > producing a > > > fully correctly operating program as expected. Even if the above inline > > > assembly blocks never worked due to other optimizations however, the > > > failure mode of the program would be very different from how it fails > now: > > > It should fail noisily with an access violation exception due to > > > the malformed assembly, but instead all the assembly which installs an > > > exception handler never makes it into the final program because with > > > anything higher than -O1 gcc deletes all of it (I have verified this > with > > > objdump too), > > > > Can you please provide a _full_ compilable testcase (preprocessed). What > > Andrew says is (supposed to be) correct: ignoring the other > > problems you're going to see with your asms (even if you make them > > volatile) GCC should not remove any of the asm statements of them. > > > > If something changes when you add 'volatile' by hand then we have another > > problem lurking somewhere, and adding the parser patch might not fully > > solve it (even if it changes behaviour for you). > > By the way I just testcase: > ``` > void f(void) > { > asm("#should be volatile"); > } > ``` > > The produced gimple (via -fdump-tree-gimple=/dev/stdout) is: > ``` > void f () > { > __asm__ __volatile__("#should be volatile"); > } > ``` > > Which is 100% volatile. and I tested all the way back to GCC 4.8.0 and > it was volatile back then too. > So as both Michael and myself have mentioned, we need a full > (compilable) testcase, even if it is for mingw or cygwin, we can > handle those just fine too. > > Thanks, > Andrew > > > > > > > Ciao, > > Michael. >