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.

Reply via email to