https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
--- Comment #93 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- I tried a bit more with lto and discovered that -flto -O2 removes all the code from test() although it is marked noinline, noclone To work around that, I added an asm statement initializing all these mem-refs, now the test case looks like that: cat t.cc #include <cstddef> //namespace std { enum class byte: unsigned char {}; }; struct t { int x; //std::byte kk[1]; unsigned char k; } __attribute__((may_alias)); t t1; t t2; t *t3; t *t4; void __attribute__((noinline, noclone)) test() { t1 = t2; *t4 = *t3; } int main() { asm("":"=m"(t1), "=m"(t2), "=m"(t3), "=m"(t4)); test(); } This prevents -flto -O2 from removing the mem-refs. But I discovered that the asm output arguments don't use the alias-set zero: g++ -flto -O2 -fdump-rtl-final t.cc has this rtl from the asm stmt: (insn:TI 5 2 6 2 (parallel [ (set (mem/c:DI (symbol_ref:DI ("t1") [flags 0x2] <var_decl 0x7f0d3d106ab0 t1>) [2 t1+0 S8 A64]) (asm_operands:DI ("") ("=m") 0 [] [] [] t.cc:23)) (set (mem/c:DI (symbol_ref:DI ("t2") [flags 0x2] <var_decl 0x7f0d3d106b40 t2>) [2 t2+0 S8 A64]) (asm_operands:DI ("") ("=m") 1 [] [] [] t.cc:23)) (set (mem/f/c:DI (symbol_ref:DI ("t3") [flags 0x2] <var_decl 0x7f0d3d106bd0 t3>) [1 t3+0 S8 A64]) (asm_operands:DI ("") ("=m") 2 [] [] [] t.cc:23)) (set (mem/f/c:DI (symbol_ref:DI ("t4") [flags 0x2] <var_decl 0x7f0d3d106c60 t4>) [1 t4+0 S8 A64]) (asm_operands:DI ("") ("=m") 3 [] [] [] t.cc:23)) (clobber (reg:CCFP 18 fpsr)) (clobber (reg:CC 17 flags)) ]) "t.cc":23 -1 (expr_list:REG_UNUSED (reg:CCFP 18 fpsr) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))) Again alias set 2 for t1, and t2. This is identical also for non-lto build.