[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #21 from rguenther at suse dot de  ---
On Thu, 2 Sep 2021, petro.karashchenko at gmail dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085
> 
> --- Comment #20 from Petro Karashchenko  
> ---
> I just checked next case
> 
> typedef int tolerant_int __attribute__((aligned(1)));
> tolerant_int var;
> 
> int foo(void)
> {
>   return var;
> }
> --
> arm-none-eabi-gcc -save-temps -Wall -Wextra -c -mcpu=arm7tdmi -mthumb test.c
> -O0
> --
> .cpu arm7tdmi
> .eabi_attribute 20, 1
> .eabi_attribute 21, 1
> .eabi_attribute 23, 3
> .eabi_attribute 24, 1
> .eabi_attribute 25, 1
> .eabi_attribute 26, 1
> .eabi_attribute 30, 6
> .eabi_attribute 34, 0
> .eabi_attribute 18, 4
> .file   "test.c"
> .text
> .comm   var,4,1
> .align  1
> .global foo
> .arch armv4t
> .syntax unified
> .code   16
> .thumb_func
> .fpu softvfp
> .type   foo, %function
> foo:
> @ Function supports interworking.
> @ args = 0, pretend = 0, frame = 0
> @ frame_needed = 1, uses_anonymous_args = 0
> push{r7, lr}
> add r7, sp, #0
> ldr r3, .L3
> ldr r3, [r3]
> movsr0, r3
> mov sp, r7
> @ sp needed
> pop {r7}
> pop {r1}
> bx  r1
> .L4:
> .align  2
> .L3:
> .word   var
> .size   foo, .-foo
> .ident  "GCC: (GNU Tools for Arm Embedded Processors 9-2019-q4-major)
> 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]"
> -
> 
> So seems the alignment decrease does not work on types.

It works on trunk.  There were bugs fixed for arm "recently"
(your 9.2.1 is nearly two years old).

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #20 from Petro Karashchenko  
---
I just checked next case

typedef int tolerant_int __attribute__((aligned(1)));
tolerant_int var;

int foo(void)
{
  return var;
}
--
arm-none-eabi-gcc -save-temps -Wall -Wextra -c -mcpu=arm7tdmi -mthumb test.c
-O0
--
.cpu arm7tdmi
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 6
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file   "test.c"
.text
.comm   var,4,1
.align  1
.global foo
.arch armv4t
.syntax unified
.code   16
.thumb_func
.fpu softvfp
.type   foo, %function
foo:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
push{r7, lr}
add r7, sp, #0
ldr r3, .L3
ldr r3, [r3]
movsr0, r3
mov sp, r7
@ sp needed
pop {r7}
pop {r1}
bx  r1
.L4:
.align  2
.L3:
.word   var
.size   foo, .-foo
.ident  "GCC: (GNU Tools for Arm Embedded Processors 9-2019-q4-major)
9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]"
-

So seems the alignment decrease does not work on types.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #19 from Petro Karashchenko  
---
Sorry my bad again. Just checked with GCC 11 man page

When used on a struct, or struct member, the aligned attribute can only
increase the alignment; in order to decrease it, the packed attribute must be
specified as well. When used as part of a typedef, the aligned attribute can
both increase and decrease alignment, and specifying the packed attribute
generates a warning.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #18 from Petro Karashchenko  
---
Yes. So I just checked GCC man and see that

The aligned attribute can only increase the alignment; but you can decrease it
by specifying packed as well. See below.

Note that the effectiveness of aligned attributes may be limited by inherent
limitations in your linker. On many systems, the linker is only able to arrange
for variables to be aligned up to a certain maximum alignment. (For some
linkers, the maximum supported alignment may be very very small.) If your
linker is only able to align variables up to a maximum of 8 byte alignment,
then specifying aligned(16) in an __attribute__ will still only provide you
with 8 byte alignment. See your linker documentation for further information.

So

typedef int tolerant_int __attribute__((aligned(1)));
extern tolerant_int possibly_misaligned_data;

"possibly_misaligned_data" will still be 4 bytes aligned.

The real problem is that "packed" can be applied only to struct or union type
definition, I can't just do

typedef int tolerant_int __attribute__((packed));
extern tolerant_int possibly_misaligned_data;

So it will simply not work and I need to wrap a variable into a struct or
union.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #17 from rguenther at suse dot de  ---
On Thu, 2 Sep 2021, petro.karashchenko at gmail dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085
> 
> --- Comment #16 from Petro Karashchenko  
> ---
> Again based on your description even if we go with putting "tolerance" on the
> type should not work because in "typedef int tolerant_int
> __attribute__((aligned(1)));" the "int" default alignment is 4 and we apply
> "1", so according to "The @code{aligned} attribute specifies a MINIMUM
> alignment for the variable or structure field, measured in bytes." the 
> compiler
> should use the MAX of all alignments of the type MAX(4,1) is 4 and not 1.
> 
> So
> typedef int int_1 __attribute__((aligned(1)));
> typedef int_1 int_2 __attribute__((aligned(2)));
> typedef int_2 int_4 __attribute__((aligned(4)));
> typedef int_4 int_8 __attribute__((aligned(8)));
> typedef int_8 int_16 __attribute__((aligned(16)));
> 
> int_16 a;
> 
> Then a should get aligned on 16 and not on 1.

It is (aligned to 16).

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #16 from Petro Karashchenko  
---
Again based on your description even if we go with putting "tolerance" on the
type should not work because in "typedef int tolerant_int
__attribute__((aligned(1)));" the "int" default alignment is 4 and we apply
"1", so according to "The @code{aligned} attribute specifies a MINIMUM
alignment for the variable or structure field, measured in bytes." the compiler
should use the MAX of all alignments of the type MAX(4,1) is 4 and not 1.

So
typedef int int_1 __attribute__((aligned(1)));
typedef int_1 int_2 __attribute__((aligned(2)));
typedef int_2 int_4 __attribute__((aligned(4)));
typedef int_4 int_8 __attribute__((aligned(8)));
typedef int_8 int_16 __attribute__((aligned(16)));

int_16 a;

Then a should get aligned on 16 and not on 1.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #15 from rguenther at suse dot de  ---
On Thu, 2 Sep 2021, petro.karashchenko at gmail dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085
> 
> --- Comment #13 from Petro Karashchenko  
> ---
> Sorry that I brought some confusion. I was reading some latest comments and
> didn't fully payed attention to a ticket description. The reason for my 
> comment
> is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662 that was closed as a
> duplicate of this issue.
> 
> For the variable alignment vs type alignment when it is specified your
> statement seems to be correct, however I agree that it still has a lot of open
> points. For example what should be the code if we put variable into a 
> structure
> 
> typedef int __attribute__((vector_size(16))) v4si; 
> 
> struct {
>   v4si a __attribute__((aligned(4)));
> } b;
> 
> Should it still get aligned on 16 bytes or 4 bytes?
> 
> In my case I was seeking for a way to generate alignment tolerant code without
> using
> struct {
>   int a;
> } __attribute__((packed));
> 
> Obviously "int a __attribute__((packed));" does not work, so I tried to solve
> it via "__attribute__((aligned(1)))" attribute.

I don't think it makes much sense to generate alignment "tolerant" code
for declarations, so when it is about indirect accesses via pointers
then simply use a pointer to a type with appropriate alignment.  Then
the access will be "tolerant" but when the compiler sees the object
accessed is actually of bigger alignment it isn't forced to honor
your "tolerant" minimum alignment.

When you're facing the situation that you have to access data at
some symbol and that symbol can end up with alignment less than
what its type specifies then you cannot just do

extern int possibly_misaligned_data __attribute__((aligned(1)));

which seems to be the case kernel folks run into with hppa.  Instead
you have to put the "tolerance" on the type again:

typedef int tolerant_int __attribute__((aligned(1)));
extern tolerant_int possibly_misaligned_data;

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #14 from Petro Karashchenko  
---
Probably I need to fill a ticket to allow "packed" to be applied for variables
and not only to a types of structure fields.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #13 from Petro Karashchenko  
---
Sorry that I brought some confusion. I was reading some latest comments and
didn't fully payed attention to a ticket description. The reason for my comment
is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662 that was closed as a
duplicate of this issue.

For the variable alignment vs type alignment when it is specified your
statement seems to be correct, however I agree that it still has a lot of open
points. For example what should be the code if we put variable into a structure

typedef int __attribute__((vector_size(16))) v4si; 

struct {
  v4si a __attribute__((aligned(4)));
} b;

Should it still get aligned on 16 bytes or 4 bytes?

In my case I was seeking for a way to generate alignment tolerant code without
using
struct {
  int a;
} __attribute__((packed));

Obviously "int a __attribute__((packed));" does not work, so I tried to solve
it via "__attribute__((aligned(1)))" attribute.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #12 from Richard Biener  ---
(In reply to Petro Karashchenko from comment #11)
> Sorry but based on
> 
> @cindex @code{aligned} variable attribute
> @item aligned
> @itemx aligned (@var{alignment})
> The @code{aligned} attribute specifies a MINIMUM alignment for the variable
> or structure field, measured in bytes.  When specified, @var{alignment} must
> be an integer constant power of 2.  Specifying no @var{alignment} argument
> implies the maximum alignment for the target, which is often, but by no
> means always, 8 or 16 bytes.
> 
> I do not see any statement saying that giving a lower alignment is invalid.
> I see "attribute specifies a MINIMUM alignment" so "int i
> __attribute__((aligned(1)));" specifies that between 1 and 4 the 1 should be
> chosen as a "MINIMUM".
> 
> The statement "must be an integer constant power of 2" is also valid because
> 1 is a 0 power of 2. So no questions here.
> 
> "Thus IMHO this bug is invalid." -- I do not see any strong argument on
> this. All prerequisites from a description are met, so this is a pure bug.

The testcase of the description is

typedef int __attribute__((vector_size(16))) v4si; 

v4si a4 __attribute__((aligned(4)));

that creates a variable with minimum alignment 4 (as seen in the assembly
output).  But you give the variable a type of 'v4si' which has larger
alignment and thus is in conflict with the alignment for the storage you
specified.  That automatically runs into the standard mandated rule that
any access has to be aligned according to its type.

The expectation that accesses should be unaligned is wrong unless you
also use an unaligned type.

That GCC creates an object with the desired alignment isn't wrong - you told it
so.

As I said the conflict should probably be diagnosed as it results in unexpected
behavior.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread petro.karashchenko at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #11 from Petro Karashchenko  
---
Sorry but based on

@cindex @code{aligned} variable attribute
@item aligned
@itemx aligned (@var{alignment})
The @code{aligned} attribute specifies a MINIMUM alignment for the variable
or structure field, measured in bytes.  When specified, @var{alignment} must
be an integer constant power of 2.  Specifying no @var{alignment} argument
implies the maximum alignment for the target, which is often, but by no
means always, 8 or 16 bytes.

I do not see any statement saying that giving a lower alignment is invalid.
I see "attribute specifies a MINIMUM alignment" so "int i
__attribute__((aligned(1)));" specifies that between 1 and 4 the 1 should be
chosen as a "MINIMUM".

The statement "must be an integer constant power of 2" is also valid because 1
is a 0 power of 2. So no questions here.

"Thus IMHO this bug is invalid." -- I do not see any strong argument on this.
All prerequisites from a description are met, so this is a pure bug.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-02 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--- Comment #10 from Richard Biener  ---
The implementation issue is that

extern int var __attribute__((aligned(1)));

has DECL_ALIGN of 8 but the type still has alignment of 32, so when you
take the address and dereference it you'll get a ref with 32 bit alignment.

For aligned attributes that increase alignment that's not a correctness issue
but for aligned attributes decreasing alignment it becomes a problem.

If we want to make the above work reliably we have to arrange for the
type of 'var' to be adjusted by the aligned attribute on the decl.  But
IMHO diagnosing alignment decreasing attributes on decls would be
appropriate.  The docs clearly say (emphasis mine):

@cindex @code{aligned} variable attribute
@item aligned
@itemx aligned (@var{alignment})
The @code{aligned} attribute specifies a MINIMUM alignment for the variable
or structure field, measured in bytes.  When specified, @var{alignment} must
be an integer constant power of 2.  Specifying no @var{alignment} argument
implies the maximum alignment for the target, which is often, but by no
means always, 8 or 16 bytes.

so giving a larger alignment is valid.

Likewise for

extern int i __attribute__((aligned(1)));

the alignment of 'i' is known to be at least 1 from the attribute but
we also know that 'int' is aligned to 4 and thus can use that larger alignment.

Thus IMHO this bug is invalid.  You have to reduce the alignment of the type
which is another alignment constraint seen by the compiler.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Andrew Pinski  changed:

   What|Removed |Added

 CC||andrew.bennett at imgtec dot 
com

--- Comment #9 from Andrew Pinski  ---
*** Bug 71106 has been marked as a duplicate of this bug. ***

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #8 from Andrew Pinski  ---
An obvious workaround is to have a type which is also aligned to what you want
the global to be aligned to and that will work.

typedef int __attribute__((vector_size(16))) v4si; 
typedef v4si __attribute__((aligned(4))) v4sia4; 
v4sia4 a4 __attribute__((aligned(4))); 

or:
typedef int __attribute__((aligned(1))) inta1;
inta1 __attribute__((aligned(1))) var;

or for the case in PR 102162 :

typedef unsigned int u32a1  __attribute__((__aligned__(1)));

 extern u32a1  output_len __attribute__((__aligned__(1)));

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Andrew Pinski  changed:

   What|Removed |Added

 CC||danglin at gcc dot gnu.org

--- Comment #7 from Andrew Pinski  ---
*** Bug 102162 has been marked as a duplicate of this bug. ***

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #6 from Andrew Pinski  ---
A simpler testcase is:

int __attribute__((aligned(1))) var;

int foo(void)
{
  return var;
}

- CUT ---
Compile this on a strict alignment target and you get the wrong code.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Andrew Pinski  changed:

   What|Removed |Added

 CC||petro.karashchenko at gmail 
dot co
   ||m

--- Comment #5 from Andrew Pinski  ---
*** Bug 94662 has been marked as a duplicate of this bug. ***

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Andrew Pinski  changed:

   What|Removed |Added

   Keywords||wrong-code

--- Comment #4 from Andrew Pinski  ---
PR 102162 just ran into this same problem on hppa-linux-gnu even inside the
Linux kernel.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2021-09-01 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2021-09-02
 Ever confirmed|0   |1

--- Comment #3 from Andrew Pinski  ---
Confirmed.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2018-11-19 Thread krebbel at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

--- Comment #2 from Andreas Krebbel  ---
(In reply to Richard Biener from comment #1)
...
> which is bogus again unless the caller already had pre-existing attrs
> on the MEM.  I guess using
> 
>   attrs.align = refattrs ? MAX (refattrs.align, obj_align) : obj_align;
> 
> fixes your issue?  Or are you objectp == true?  I think an INDIRECT_REF never
> happens today.

Yes, it does. objectp is true as well. t is a var decl.

[Bug middle-end/88085] User alignments on var decls not respected if smaller than type alignment

2018-11-19 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085

Richard Biener  changed:

   What|Removed |Added

 CC||rguenth at gcc dot gnu.org

--- Comment #1 from Richard Biener  ---
ISTR you have to use packed to decrease alignment.  OTOH

  /* We can set the alignment from the type if we are making an object or if
 this is an INDIRECT_REF.  */
  if (objectp || TREE_CODE (t) == INDIRECT_REF)
attrs.align = MAX (attrs.align, TYPE_ALIGN (type));

is fishy but so is the preceeding

  /* Otherwise, default values from the mode of the MEM reference.  */
  else
{
...
  /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type;
 if T is an object, always compute the object alignment below.  */
  if (TYPE_P (t))
attrs.align = defattrs->align;
  else
attrs.align = BITS_PER_UNIT;

IMHO alignment setting should be left to the callers and it should be
conservative here (the objectp == true case can probably be preserved).

Note we already set the alignment later in a correct way if ! TYPE_P
but likewise using

  attrs.align = MAX (attrs.align, obj_align);

which is bogus again unless the caller already had pre-existing attrs
on the MEM.  I guess using

  attrs.align = refattrs ? MAX (refattrs.align, obj_align) : obj_align;

fixes your issue?  Or are you objectp == true?  I think an INDIRECT_REF never
happens today.