public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable?
@ 2023-03-07 17:07 hbucher at gmail dot com
  2023-03-07 17:17 ` [Bug middle-end/109057] " hbucher at gmail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: hbucher at gmail dot com @ 2023-03-07 17:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109057
           Summary: Does GCC interpret assembly when deciding to optimize
                    away a variable?
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hbucher at gmail dot com
  Target Milestone: ---

I'm trying to figure out why GCC optimizes away a uint8_value that is passed
into assembly, basically discarding it. This is in context of Google
benchmarks. 

#include <stdint.h>
inline void DoNotOptimize( uint8_t value) {
  asm volatile("" : : "r,m"(value) : "memory");
}
static const uint8_t LUT[8] = {1,5,3,0,2,7,1,2};
void func1(uint8_t val) {
    DoNotOptimize(LUT[val]); 
}

In this case Gcc generates

func1(unsigned char):
        movzbl  %dil, %edi
        ret

More importantly, the entire static array LUT was optimized away from the
object file. 

https://godbolt.org/z/Tab5T84dM

Is this the correct behavior in your understanding?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
@ 2023-03-07 17:17 ` hbucher at gmail dot com
  2023-03-07 17:22 ` pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: hbucher at gmail dot com @ 2023-03-07 17:17 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Henry <hbucher at gmail dot com> ---
Two caveats: 

1. If you add something like `xor %0,%0` inside the assembly text, LUT is not
optimized

inline void DoNotOptimize( uint8_t value) {
  asm volatile("xor %0,%0" : : "r,m"(value) : "memory");
}
void func2(uint8_t val) {
    DoNotOptimize(LUT[val]); 
}

Produces

func2(unsigned char):
        movzbl  %dil, %edi
        xor LUT(%rdi),LUT(%rdi)
        ret
LUT:
        .string "\001\005\003"
        .ascii  "\002\007\001\002"

https://godbolt.org/z/Mn5asGWe4

2. If you make value a uint32_t instead of a uint8_t, LUT is not optimized

#include <stdint.h>
static const uint8_t LUT[8] = {1,5,3,0,2,7,1,2};

inline void DoNotOptimize( uint32_t value) {
  asm volatile("" : : "r,m"(value) : "memory");
}
void func2(uint8_t val) {
    DoNotOptimize(LUT[val]); 
}

Produces 

func2(unsigned char):
        movzbl  %dil, %edi
        movzbl  LUT(%rdi), %eax
        ret
LUT:
        .string "\001\005\003"
        .ascii  "\002\007\001\002"

https://godbolt.org/z/rTfExvEbb

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
  2023-03-07 17:17 ` [Bug middle-end/109057] " hbucher at gmail dot com
@ 2023-03-07 17:22 ` pinskia at gcc dot gnu.org
  2023-03-07 17:27 ` jakub at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-03-07 17:22 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>basically discarding it

No it is not. you just don't notice it there because goldbolt is hiding things
because it thinks it is unused.

If you use:
  asm volatile("#%0" : : "rm"(value) : "memory");

You get:
#LUT(%rdi)

Which is exactly what you expect.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
  2023-03-07 17:17 ` [Bug middle-end/109057] " hbucher at gmail dot com
  2023-03-07 17:22 ` pinskia at gcc dot gnu.org
@ 2023-03-07 17:27 ` jakub at gcc dot gnu.org
  2023-03-07 17:28 ` hbucher at gmail dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-07 17:27 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Yeah, you've told GCC you want it either in a register or in memory.  GCC
choose memory LUT(%rdi).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (2 preceding siblings ...)
  2023-03-07 17:27 ` jakub at gcc dot gnu.org
@ 2023-03-07 17:28 ` hbucher at gmail dot com
  2023-03-07 17:29 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: hbucher at gmail dot com @ 2023-03-07 17:28 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Henry <hbucher at gmail dot com> ---
Yes it is optimized away.

Note that even in this case the entire static array is optimized away from the
object file.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (3 preceding siblings ...)
  2023-03-07 17:28 ` hbucher at gmail dot com
@ 2023-03-07 17:29 ` jakub at gcc dot gnu.org
  2023-03-07 17:31 ` hbucher at gmail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-07 17:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #2)
> No it is not. you just don't notice it there because goldbolt is hiding
> things because it thinks it is unused.

This actually isn't godbolt hiding anything (which it does sometimes), but
because
nothing is printed in the asm nothing needs to be printed into the assembly
output.
It still acts as a black box to the compiler.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (4 preceding siblings ...)
  2023-03-07 17:29 ` jakub at gcc dot gnu.org
@ 2023-03-07 17:31 ` hbucher at gmail dot com
  2023-03-07 17:32 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: hbucher at gmail dot com @ 2023-03-07 17:31 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Henry <hbucher at gmail dot com> ---
Still, why is it then if you change the type to uint32_t the behavior changes? 

And why the entire static array is cut out from the object file?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (5 preceding siblings ...)
  2023-03-07 17:31 ` hbucher at gmail dot com
@ 2023-03-07 17:32 ` jakub at gcc dot gnu.org
  2023-03-07 17:32 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-07 17:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I certainly can't reproduce the LUT array not being emitted, tried GCC 11, 12
and trunk,
C and C++ (all -O2).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (6 preceding siblings ...)
  2023-03-07 17:32 ` jakub at gcc dot gnu.org
@ 2023-03-07 17:32 ` pinskia at gcc dot gnu.org
  2023-03-07 17:38 ` hbucher at gmail dot com
  2023-03-07 17:44 ` jakub at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-03-07 17:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #5)
> (In reply to Andrew Pinski from comment #2)
> > No it is not. you just don't notice it there because goldbolt is hiding
> > things because it thinks it is unused.
> 
> This actually isn't godbolt hiding anything (which it does sometimes), but
> because
> nothing is printed in the asm nothing needs to be printed into the assembly
> output.
> It still acts as a black box to the compiler.
Kinda.

>More importantly, the entire static array LUT was optimized away from the object file. 
the asm code still has LUT array (godbolt does hide unused lables by default).
Using the original code we do get:

        .type   LUT, @object
        .size   LUT, 8
LUT:
        .string "\001\005\003"
        .ascii  "\002\007\001\002"

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (7 preceding siblings ...)
  2023-03-07 17:32 ` pinskia at gcc dot gnu.org
@ 2023-03-07 17:38 ` hbucher at gmail dot com
  2023-03-07 17:44 ` jakub at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: hbucher at gmail dot com @ 2023-03-07 17:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Henry <hbucher at gmail dot com> ---
Just to make it clear, I'm not saying this is a bug on GCC. 

Im just trying to understand what is happening since this is affecting some of
our benchmarks. Then we can counter with some wit. 

Perhaps there is an alternate venue for this type of clarification? I tried
Reddit but no dice. The GCC IRC channel perhaps?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug middle-end/109057] Does GCC interpret assembly when deciding to optimize away a variable?
  2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
                   ` (8 preceding siblings ...)
  2023-03-07 17:38 ` hbucher at gmail dot com
@ 2023-03-07 17:44 ` jakub at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-07 17:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Henry from comment #9)
> Just to make it clear, I'm not saying this is a bug on GCC. 
> 
> Im just trying to understand what is happening since this is affecting some
> of our benchmarks. Then we can counter with some wit. 
> 
> Perhaps there is an alternate venue for this type of clarification? I tried
> Reddit but no dice. The GCC IRC channel perhaps?

If you use
inline void DoNotOptimize( unsigned int value) {
  asm volatile("" : : "r,m"(value) : "memory");
}
static const unsigned char LUT[8] = {1,5,3,0,2,7,1,2};
void func1(unsigned int val) {
    DoNotOptimize(LUT[val]); 
}
then obviously it can't choose the "m" variant for value, because value is
32-bit,
while LUT(%rdi) is 8-bit.  So it can choose only "r" variant and therefore it
needs
to emit an instruction that computes that (zero extends the value).
If you change LUT array to be const unsigned int LUT[8], then "m" variant can
be selected (and is in my testing).

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-03-07 17:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-07 17:07 [Bug c++/109057] New: Does GCC interpret assembly when deciding to optimize away a variable? hbucher at gmail dot com
2023-03-07 17:17 ` [Bug middle-end/109057] " hbucher at gmail dot com
2023-03-07 17:22 ` pinskia at gcc dot gnu.org
2023-03-07 17:27 ` jakub at gcc dot gnu.org
2023-03-07 17:28 ` hbucher at gmail dot com
2023-03-07 17:29 ` jakub at gcc dot gnu.org
2023-03-07 17:31 ` hbucher at gmail dot com
2023-03-07 17:32 ` jakub at gcc dot gnu.org
2023-03-07 17:32 ` pinskia at gcc dot gnu.org
2023-03-07 17:38 ` hbucher at gmail dot com
2023-03-07 17:44 ` jakub at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).