------- Comment #4 from rguenth at gcc dot gnu dot org 2010-02-15 13:16 ------- It also fails with -O1 and -O2 -fno-strict-aliasing and with -O2 -fno-inline.
Assembler differences for -O2 vs. -O2 with my patch (which effectively makes us see more must-aliases, thus "accept" slightly invalid strict-aliasing violating code): --- ref2.s.good 2010-02-15 13:47:03.000000000 +0100 +++ ref2.s.bad 2010-02-15 13:46:34.000000000 +0100 @@ -90,15 +90,16 @@ .cfi_startproc subq $40, %rsp .cfi_def_cfa_offset 48 - leaq 28(%rsp), %rsi + leaq 28(%rsp), %rdx movl $1, 28(%rsp) movq $_ZNK3Inc1fERi, (%rsp) movq $0, 8(%rsp) leaq 16(%rsp), %rdi - movq %rsi, 16(%rsp) + movq %rdx, 16(%rsp) movb %al, 16(%rsp) movl $_ZNK3Inc1fERi, %eax testb $1, %al + movq 16(%rsp), %rsi je .L10 movq _ZNK3Inc1fERi-1(%rsi), %rax .L10: that's _Z6test02v. You can see the aliasing byte-store to 16(%rsp) and the probably seemingly redundant load from 16(%rsp) that we maybe remove with strict-aliasing on. The tree code for the above is at .optimize time: <bb 2>: counter = 1; D.29754 = {}; __bound_args#0 = D.29754; D.25693._M_f.__pmf.__pfn = f; D.25693._M_f.__pmf.__delta = 0; D.25693._M_bound_args.D.25507.D.25257.D.25050._M_head_impl._M_data = &counter; this.24_34 = (struct Inc *) &D.25693._M_bound_args.D.25507; *this.24_34 = __bound_args#0; D.29831_51 = D.25693._M_bound_args.D.25507.D.25257.D.25050._M_head_impl._M_data; iftmp.27_55 = D.25693._M_f.__pmf.__pfn; D.29837_56 = (long int) iftmp.27_55; D.29838_57 = D.29837_56 & 1; if (D.29838_57 != 0) goto <bb 3>; else goto <bb 4>; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43075