[Bug tree-optimization/87623] New: bytes swapped in register when comparing cause fail when comiled with -O1 or higher

2018-10-16 Thread george.thopas at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87623

Bug ID: 87623
   Summary: bytes swapped in register when comparing cause fail
when comiled with  -O1 or higher
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: george.thopas at gmail dot com
  Target Milestone: ---
Target: x86_64-pc-linux-gnu
 Build: gcc version 8.2.0 (Gentoo 8.2.0-r3 p1.4)

- Compare of two single char fields in two structures with different
scalar_storage_order order goes wrong. Reduced test case below.
- Observed in 6.3.1 and reproducible in 8.2.0 , Target x86_64-pc-linux-gnu

---[howto]
passed test:
 $ gcc -O0 test.c
 $ ./a.out 

failed test:
 $ gcc -O1 test.c
 $ ./a.out 
Aborted

-- [code]

/* test.c */
#include 

struct be {
unsigned short pad[1];
unsigned char  a;
unsigned char  b;
} __attribute__((scalar_storage_order("big-endian")));

typedef struct be t_be;

struct le {
unsigned short pad[3];
unsigned char  a;
unsigned char  b;
};

typedef struct le t_le;

int a_or_b_different(t_be *x,t_le *y)
{
   return ((x->a != y->a) ||
   (x->b != y->b));
}

int main(int argc,char *argv[])
{
   t_be x = { .a=1, .b=2  };
   t_le y = { .a=1, .b=2  };

   if (a_or_b_different(&x,&y))
   abort();  
   return 0;
}

--
jbeu@bt9923 ~ $  gcc -v -O1 test.c 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-8.2.0-r3/work/gcc-8.2.0/configure
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr
--bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/8.2.0
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/8.2.0
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/8.2.0/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/8.2.0/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/8.2.0/python
--enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt
--disable-werror --with-system-zlib --enable-nls --without-included-gettext
--enable-checking=release --with-bugurl=https://bugs.gentoo.org/
--with-pkgversion='Gentoo 8.2.0-r3 p1.4' --disable-esp --enable-libstdcxx-time
--enable-shared --enable-threads=posix --enable-__cxa_atexit
--enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64
--disable-altivec --disable-fixed-point --enable-targets=all --enable-libgomp
--disable-libmudflap --disable-libssp --disable-libmpx --disable-systemtap
--enable-vtable-verify --enable-libvtv --enable-lto --without-isl
--enable-libsanitizer --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 8.2.0 (Gentoo 8.2.0-r3 p1.4) 
COLLECT_GCC_OPTIONS='-v' '-O1' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1 -quiet -v bug.c -quiet
-dumpbase bug.c -mtune=generic -march=x86-64 -auxbase bug -O1 -version -o
/tmp/ccdpdLOi.s
GNU C17 (Gentoo 8.2.0-r3 p1.4) version 8.2.0 (x86_64-pc-linux-gnu)
compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version 4.0.1,
MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include-fixed
 /usr/include
End of search list.
GNU C17 (Gentoo 8.2.0-r3 p1.4) version 8.2.0 (x86_64-pc-linux-gnu)
compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version 4.0.1,
MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 91d4bd0e38b68a0f50315f89ba003c77
COLLECT_GCC_OPTIONS='-v' '-O1' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../x86_64-pc-linux-gnu/bin/as
-v --64 -o /tmp/ccsw11XW.o /tmp/ccdpdLOi.s
GNU assembler version 2.31.1 (x86_64-pc-linux-gnu) using BFD version (Gentoo
2.31.1 p3) 2.31.1
COMPILER_PATH=/usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/:/usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gc

[Bug middle-end/87623] bytes swapped in register when comparing cause fail when compiled with -O1 or higher

2018-10-18 Thread george.thopas at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87623

--- Comment #9 from George Thopas  ---
(In reply to Eric Botcazou from comment #8)
> Thanks for reporting the problem.

And thanks for the swift resolution !

[Bug c/100804] New: storage order swapped with specific opt

2021-05-27 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100804

Bug ID: 100804
   Summary: storage order swapped with specific opt
   Product: gcc
   Version: 11.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: george.thopas at gmail dot com
  Target Milestone: ---

/* 
Target: x86_64-pc-linux-gnu gcc versie 10.2.0 (Gentoo 10.2.0-r4 p5) 

failing:
$ gcc -Wall -Wextra -O2 test.c && ./a.out
Aborted

passing:
$ gcc -Wall -Wextra -O3 test.c && ./a.out
$ gcc -Wall -Wextra -O1 test.c && ./a.out
$ gcc -Wall -Wextra -O0 test.c && ./a.out

no fallout with -fno-strict-aliasing -fwrapv
problem goes away with adding either 
-fno-code-hoisting,
-fno-guess-branch-probability,

The example includes an unused string structure which seems to affect 
the problem. The odd thing is that it is never used in this code

Removing the untaken else path makes the problem go away too 

Thanks

*/
#include 
#include 
#include 

#define BE   __attribute__((scalar_storage_order("big-endian")))

struct _str {
char str[10];
};
typedef struct _str t_str;

struct _le {
char  is_val;
union {
int   val;
t_str str;
} data;
};

typedef struct _le t_le;

union _be_data {
int   val;
t_str str;
} BE;

typedef union _be_data t_be_data;

struct _be {
char  is_val;
t_be_data data;
} BE;

typedef struct _be t_be;

void validate(t_be * in)
{
t_le chk = { is_val:1, data: { val:0x12345678 } };
t_le out = { };

out.is_val = in->is_val;
if (out.is_val)
out.data.val = in->data.val;
else
out.data.str = in->data.str;

if (out.data.val != chk.data.val)
abort();
}

int main(void)
{
t_be val = { is_val:1, data: { val:0x12345678 } };
validate(&val);
return 0;
}

[Bug c/100804] storage order swapped with specific opt

2021-05-27 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100804

--- Comment #2 from George Thopas  ---
After looking at the updated documentation and trying the an update kernel with
warning it still leaves some things open. 

The updated documentation says:

"Moreover, the use of type punning or aliasing to toggle the storage order
is not supported; that is to say, if a given scalar object can be accessed
through distinct types that assign a different storage order to it, then the
behaviour is undefined"

- In my example the new warning fires on a struct only having chars. I don't
see how that is applicable here or how a char array could have a different
storage
order in either big or little endian.  

- Regardless of that fact. That field is also never accessed in my example code 
Al 2 fields of the structs actually read are consistently be (in)
and the one written is (out) le.  The ones compare are of the same type. 

Thanks again

[Bug c/100920] New: bogus warn on -Wscalar-storage-order

2021-06-04 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100920

Bug ID: 100920
   Summary: bogus warn on -Wscalar-storage-order
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: george.thopas at gmail dot com
  Target Milestone: ---

/* 
 * trying to use -Wscalar-storage-order on latest git version
 *
 * https://gcc.gnu.org/g:401bd4adcfda9965363b1ac3ba7e1580f15d6883
 *
 * below test exposes what looks like 2 wrong warnings  
 * a warning on an union where everything is big-endian 
 * a warning on type less void pointer
 *
 * gcc -Werror test.c
 *   
 * Thanks
 */
include 

struct s_1 {
int val;
} __attribute__((scalar_storage_order("big-endian")));

typedef struct s_1 t_1;

struct s_2 {
char val;
} __attribute__((scalar_storage_order("big-endian")));

typedef struct s_2 t_2;

struct s12 {
t_1 a[1];
t_2 b[1]; 
} __attribute__((scalar_storage_order("big-endian")));

typedef struct s12 t_s12;

/* Warning while everything is big-endian */
union u12 {
t_1 a[1];
t_2 b[1];
} __attribute__((scalar_storage_order("big-endian")));

typedef union u12 t_u12;

int main(void)
{
/* warning while assigning from a type less void pointer */
t_s12 *msg1 = __builtin_alloca(10);
t_u12 *msg2 = __builtin_alloca(10);
msg1->a[0].val=0;
msg2->a[0].val=0;
return 0;

[Bug c/100920] bogus warnings with -Wscalar-storage-order

2021-06-05 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100920

--- Comment #2 from George Thopas  ---
(In reply to Eric Botcazou from comment #1)
> The warning on the union is indeed an oversight, but the other is
> conservatively correct, although we may make a special case for
> __builtin_alloca.

Hi Eric, first of all, thanks for looking into this. 

It may not be immediately obvious from my example but the the builtin_alloca is
not the only problem. 

Any malloc/calloc has the same effect. Even if one requires casts at alloc
time, any free will trigger the same warning.

t_s12 *msg1 = (t_s12)malloc(10);
free(msg1);

I don't understand what the incompatibility reported is with void pointers.  To
my understanding they are type-less and can't be dereferenced.

[Bug c/100920] bogus warnings with -Wscalar-storage-order

2021-06-07 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100920

--- Comment #6 from George Thopas  ---
(In reply to Eric Botcazou from comment #5)
> Thanks for reporting the problem.

Thanks for the swift fix. It nicely resolves it for the malloc/alloca ... 
It doesn't seem to do anything for the rest of the common idioms however
when I extend  the testcase.

int main()
{
t_s12 *msg1 = __builtin_alloca(10);
t_u12 *msg2 = __builtin_alloca(10);
int same;

msg1 = malloc (sizeof (t_s12));
msg2 = malloc (sizeof (t_u12));

memset(msg1, 0, sizeof(t_s12));
memcpy(msg2, &msg1, sizeof(t_s12));
same = memcmp(msg2, msg1, sizeof(t_s12));
free(msg1);

return same;
}

[Bug c/100920] bogus warnings with -Wscalar-storage-order

2021-06-08 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100920

--- Comment #9 from George Thopas  ---
/*
Hi Eric,

1) I noticed there's a typo in the test, (which is my fault) and may give
   unexpected behavior later on

memcpy(msg2, &msg1, sizeof(t_s12));
 => should be  memcpy(msg2, msg1, sizeof(t_s12));

2) Trying to get a platform built free of these warning, I still see quite some
which match below example.  
Raising one for these cases is really problematic. Functions using void in
stead of an explicit type are explicitly saying that the type does not matter.
There never is a warning for any other type where you pass them. so
I hope  you can give this one another go.

Thanks again for your patience.

*/


#include 
#include 

#define SIZE 10

struct be {
int a;
int b; 
} __attribute__((scalar_storage_order("big-endian")));

typedef struct be t_be;

struct le {
int a;
int b; 
} __attribute__((scalar_storage_order("little-endian")));

typedef struct le t_le;


void memset2(void *s, char c, int n)
{
   char *d=(char *)s;
   for(int i=0;i

[Bug c/100653] usage of scalar_storage_order produces incorrect result

2021-06-15 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100653

--- Comment #9 from George Thopas  ---
Created attachment 51025
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51025&action=edit
avoid eliminating fields with different endianess as equal

Short story :
Ran a bisect to find why this always works in the gcc-6 branch and has
different behaviour outside. Found out what happens (see below) and attached a
2-line patch for what I assume is missing.  Works for me but is it the 'right
thing'(tm) todo ?  

Thanks.

Long story:
I started digging into this in the hope to get a better understanding
In the last 3 years I've never seen this on the gcc-6 branch. 
Even though there's a tons of code and mixed endianess structures and 
unions validation. If I missed it, I at least needed to know at least why. 

The bisect ended up giving commit e7a3e0c653be4bd32f116dae06438896b7dc915b.
Reverting it for test purposes in gcc-7/gcc-8 just confirmed it is the 
right trigger.

There's obviously nothing wrong with that commit but at least it gave me 
a clue what to look for. To my understanding of the code :
The RPO change affects evaluation order when merging and eliminating blocks.
In the case of the example, the compiler ends up checking if both fields 
of the union are the same and can be merged/eliminated. Their both in the same
location. The code currently considers different signedness and bails out, but
not different  endianness and eliminates one depending one evaluation order. 
Whatever one that is.

[Bug c/101925] New: reversed storage order when compiling with -O3 only

2021-08-15 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101925

Bug ID: 101925
   Summary: reversed storage order when compiling with -O3 only
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: george.thopas at gmail dot com
  Target Milestone: ---

/*
 reversed storage order when compiling with -O3 only. 
 this time sets up an all big-endian struct 
 from an all little-endian one
 no warnings 

 Target: x86_64-pc-linux-gnu
 gcc versie 11.1.0 (Gentoo 11.1.0-r2 p3) 
 gcc-trunk too

 $ gcc -Wall -Wextra -O3 test.c 
 $ ./a.out 
 Abort 

 */


#define BIG_ENDIAN   __attribute__((scalar_storage_order("big-endian")))

/* host order version (little endian)*/
struct _ip6_addr {
union {
char addr8[16];
int  addr32[4];
} u;
};

typedef struct _ip6_addr t_ip6_addr;

struct _net_addr {
char is_v4;
union {
intaddr;
t_ip6_addr addr6;
} u;
};

typedef struct _net_addr t_net_addr;

/* big endian version */
struct _be_ip6_addr {
union {
char addr8[16];
} BIG_ENDIAN u;
} BIG_ENDIAN;

typedef struct _be_ip6_addr t_be_ip6_addr;

struct _be_net_addr {
char is_v4;
union {
t_be_ip6_addr addr6;
int   addr;
} BIG_ENDIAN u;
} BIG_ENDIAN;

typedef struct _be_net_addr t_be_net_addr;

/* convert */
t_be_ip6_addr be_ip6_addr(const t_ip6_addr ip6)
{
t_be_ip6_addr rc = {
.u.addr8[0] = ip6.u.addr8[0],
.u.addr8[1] = ip6.u.addr8[1],
.u.addr8[2] = ip6.u.addr8[2],
.u.addr8[3] = ip6.u.addr8[3],
.u.addr8[4] = ip6.u.addr8[4],
.u.addr8[5] = ip6.u.addr8[5],
.u.addr8[6] = ip6.u.addr8[6],
.u.addr8[7] = ip6.u.addr8[7],
.u.addr8[8] = ip6.u.addr8[8],
.u.addr8[9] = ip6.u.addr8[9],
.u.addr8[10] = ip6.u.addr8[10],
.u.addr8[11] = ip6.u.addr8[11],
.u.addr8[12] = ip6.u.addr8[12],
.u.addr8[13] = ip6.u.addr8[13],
.u.addr8[14] = ip6.u.addr8[14],
.u.addr8[15] = ip6.u.addr8[15],
};
return rc;
}

t_be_net_addr be_net_addr(const t_net_addr ip)
{
t_be_net_addr rc = {.is_v4 = ip.is_v4 };
if (ip.is_v4) {
rc.u.addr = ip.u.addr;
} else {
rc.u.addr6 = be_ip6_addr(ip.u.addr6);
}
return rc;
}

int main(void)
{
t_be_net_addr out = { };

t_net_addr in = {
.is_v4 = 0,
.u.addr6.u.addr8 =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
};

out = be_net_addr(in);

// actually first 4 bytes are swapped
if (in.u.addr6.u.addr8[0] != out.u.addr6.u.addr8[0])
__builtin_abort();

return 0;
}

[Bug c/118836] New: sso warning dependend on -fno-builtin

2025-02-11 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118836

Bug ID: 118836
   Summary: sso warning dependend on -fno-builtin
   Product: gcc
   Version: 14.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: george.thopas at gmail dot com
  Target Milestone: ---

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100920 introduced some logic
to suppress scalar-storage-order warnings when using memcpy/memset/...

However when required to compile with -fno-builtin this won't work and will
still gives scalar-storage-order warnings 

Thank you.


example : compiling gcc/testsuite/ gcc.dg/sso-14.c

bash$ gcc -Wall -fno-builtin sso-14.c 

sso-14.c: In function 'main':
sso-14.c:51:11: warning: passing argument 1 of 'memset' from incompatible
scalar storage order [-Wscalar-storage-order]
   51 |   memset (msg1, 0, sizeof (t_s12));
  |   ^~~~
sso-14.c:52:11: warning: passing argument 1 of 'memcpy' from incompatible
scalar storage order [-Wscalar-storage-order]
   52 |   memcpy (msg2, &msg1, sizeof (t_s12));
  |   ^~~~
sso-14.c:53:18: warning: passing argument 1 of 'memcmp' from incompatible
scalar storage order [-Wscalar-storage-order]
   53 |   same = memcmp (msg1, msg2, sizeof (t_s12));
  |  ^~~~
sso-14.c:53:24: warning: passing argument 2 of 'memcmp' from incompatible
scalar storage order [-Wscalar-storage-order]
   53 |   same = memcmp (msg1, msg2, sizeof (t_s12));
  |^~~~
sso-14.c:46:7: warning: variable 'same' set but not used
[-Wunused-but-set-variable]
   46 |   int same;

[Bug c/118836] sso warning dependend on -fno-builtin

2025-02-12 Thread george.thopas at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118836

--- Comment #2 from George Thopas  ---
(In reply to Andrew Pinski from comment #1)
> This is by design; without -fno-builtin, memcmp, memset, etc. become normal
> functions and they have unknown behaviors.

The only solution to get rid of the warning is to explicit cast each argument
every where it's called. This makes for far worse code as you lose the
validation that the argument are pointers

I really do not want to disable the sso warning globally either as it's an
umbrella for a set of warning.  I do not want disable sso punning errors for
example which point to real problems.

Pragma's are also of no help as you can't disable the warning on a function
level, so you would have to put pragma's around each call 

While it may be as designed, there is at least an inconsistency here.  And it
still is not clear how any of these type warnings bring anything to the table
for void pointers.  

Can you suggest any path forward ?

Thanks