Re: wishlist: support for shorter pointers

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Jonathan Wakely via Gcc
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

2023-06-28 Thread Julian Waters via Gcc
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

2023-06-28 Thread waffl3x via Gcc
>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

2023-06-28 Thread Andrew Pinski via Gcc
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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Krister Walfridsson via Gcc
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

2023-06-28 Thread waffl3x via Gcc
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

2023-06-28 Thread Julian Waters via Gcc
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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread waffl3x via Gcc
> 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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Martin Uecker


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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Michael Matz via Gcc
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

2023-06-28 Thread Richard Earnshaw (lists) via Gcc

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

2023-06-28 Thread Michael Matz via Gcc
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

2023-06-28 Thread Martin Uecker
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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Richard Earnshaw (lists) via Gcc

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

2023-06-28 Thread Martin Uecker
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

2023-06-28 Thread Andrew Pinski via Gcc
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

2023-06-28 Thread Eric Feng via Gcc
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

2023-06-28 Thread GCC Administrator via Gcc
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

2023-06-28 Thread Konstantinos Draziotis via Gcc
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

2023-06-28 Thread Rafał Pietrak via Gcc

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

2023-06-28 Thread Richard Biener via Gcc
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

2023-06-28 Thread Julian Waters via Gcc
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.
>