https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Uroš Bizjak from comment #1)
> (In reply to Andrew Pinski from comment #0)
> > Take:
> > ```
> > int g(void); int h(void); int t(void);
> > int f(int a, int b)
> > {
> >   int c = a - b;
> >   if(c == 0)
> >     return g();
> >   if (c > 0)
> >     return h();
> >   return t();
> > }
> > ```
> > This is reduced from bzip2 in spec 2006, though I am not so sure any more.
> > On x86_64 GCC produces:
> > ```
> >         subl    %esi, %edi
> >         testl   %edi, %edi
> >         je      .L5
> >         jle     .L3
> >         jmp     h()
> > .L3:
> >         jmp     t()
> > .L5:
> >         jmp     g()
> > ```
> > But GCC should produce (likes clang/LLVM does):
> > ```
> >         cmpl    %esi, %edi
> >         je      .L5
> >         jle     .L3
> >         jmp     h()
> > .L3:
> >         jmp     t()
> > .L5:
> >         jmp     g()
> > ```
> > 
> > Note a similar thing happens with aarch64 target too.
> 
> These two assemblies are not equal as demonstrated by the following test:
> 
> --cut here--
> #include <stdio.h>
> 
> _Bool
> __attribute__((noinline))
> foo (int a, int b)
> {
>   _Bool r;
>   int tmp;
> 
>   asm ("subl %3, %0; testl %0, %0"
>        : "=r"(tmp), "=@cc" "le"(r)
>        : "0"(a), "r"(b));
>   return r;
> }
> 
> _Bool
> __attribute__((noinline))
> bar (int a, int b)
> {
>   _Bool r;
> 
>   asm ("cmpl %2, %1"
>        : "=@cc" "le"(r)
>        : "r"(a), "r"(b));
>   return r;
> }
> 
> int
> main ()
> {
>   int a, b;
>   _Bool ra, rb;
> 
>   a = 0x80000000, b = 0x40000000;
>   ra = foo (a, b);
>   rb = bar (a, b);
> 
>   printf ("%i %i\n", ra, rb);
>   return 0;
> }
> --cut here--
> 
> $ ./a.out 
> 0 1
> 
> The difference is in handling of overflow flag.

Right but 0x80000000 - 0x40000000 is undefined for signed integers ...
If this was unsigned subtraction then I would say it is they are different.
Note maybe RTL level is not the best place for this optimization as subtraction
already lost if it is undefined on overflow or not ...

Reply via email to