https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100051
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to huadong from comment #4)
> Hi, commit d1d01a6 has introduced a issue in gcc 12 on aarch64 platform.
>
This code violates aliasing rules and is undefined.
> 1、 demo code:
> #include <stdio.h>
> #include <stdint.h>
> #include <stdbool.h>
> #include <ctype.h>
>
> #define reg_write(addr, val) \
> (*(volatile uint32_t *)(uintptr_t)(addr) = (val))
>
>
> static inline void writeb(void *addr, unsigned int val)
> {
> reg_write((uintptr_t)addr & (~0x3), val);
> }
>
> static char c;
> static void str_test(char *str)
> {
> c = str[1];
> if (islower(c))
> writeb(&c, toupper(c));
> putchar(c);
> putchar('\n');
> }
>
>
> int main(int argc, char *argv[])
> {
> if (argc > 1)
> str_test(argv[1]);
> else
> str_test(argv[0]);
>
> return 0;
> }
>
> 2、compile command:aarch64-linux-musl-gcc -O2 -fdump-tree-fre demo.c
> dump gimple code:
> void str_test (char * str)
> {
> char _1;
> unsigned int _3;
> unsigned int _4;
> int _6;
> int _7;
> unsigned int _8;
> int _10;
> long unsigned int addr.3_18;
> long unsigned int _19;
> volatile uint32_t * _20;
>
> <bb 2> :
> _1 = MEM[(char *)str_13(D) + 1B];
> c = _1;
> _3 = (unsigned int) _1;
> _4 = _3 + 4294967199;
> if (_4 <= 25)
> goto <bb 3>; [INV]
> else
> goto <bb 4>; [INV]
>
> <bb 3> :
> _6 = (int) _1;
> _7 = toupper (_6);
> _8 = (unsigned int) _7;
> addr.3_18 = (long unsigned int) &c;
> _19 = addr.3_18 & 18446744073709551612;
> _20 = (volatile uint32_t *) _19;
> *_20 ={v} _8;
>
> <bb 4> :
> _10 = (int) _1;
> putchar (_10);
> putchar (10);
> return;
>
> }
>
> the character print by putchar should be uppercased _8, but it take original
> value _1.