http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54200
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-03-29 15:36:15 UTC --- This patch regressed code quality on find_vma function in Linux kernel on s390x: struct rb_node { unsigned long __rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } __attribute__ ((aligned (sizeof (long)))); struct rb_root { struct rb_node *rb_node; }; struct vm_area_struct { unsigned long vm_start; unsigned long vm_end; struct vm_area_struct *vm_next, *vm_prev; struct rb_node vm_rb; }; struct mm_struct { struct vm_area_struct *mmap; struct rb_root mm_rb; struct vm_area_struct *mmap_cache; }; struct vm_area_struct * find_vma (struct mm_struct *mm, unsigned long addr) { struct vm_area_struct *vma = ((void *) 0); static _Bool __attribute__ ((__section__ (".data.unlikely"))) __warned; int __ret_warn_once = !!(!mm); if (__builtin_expect (!!(__ret_warn_once), 0)) { int __ret_warn_on = !!(!__warned); if (__builtin_expect (!!(__ret_warn_on), 0)) asm volatile ("": :"i" (1920), "i" (((1 << 0) | ((9) << 8))), "i" (64)); if (__builtin_expect (!!(__ret_warn_on), 0)) __warned = 1; } if (__builtin_expect (!!(__ret_warn_once), 0)) return ((void *) 0); vma = mm->mmap_cache; if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) { struct rb_node *rb_node; rb_node = mm->mm_rb.rb_node; vma = ((void *) 0); while (rb_node) { struct vm_area_struct *vma_tmp; const typeof (((struct vm_area_struct *)0)->vm_rb) *__mptr = rb_node; vma_tmp = (struct vm_area_struct *) ((char *) __mptr - __builtin_offsetof (struct vm_area_struct, vm_rb)); if (vma_tmp->vm_end > addr) { vma = vma_tmp; if (vma_tmp->vm_start <= addr) break; rb_node = rb_node->rb_left; } else rb_node = rb_node->rb_right; } if (vma) mm->mmap_cache = vma; } return vma; } with: -fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -O2 -m64 -mbackchain -msoft-float -march=z9-109 -mpacked-stack -mstack-size=16384 -fno-strength-reduce -fno-stack-protector -fomit-frame-pointer -fno-inline-functions-called-once -fconserve-stack The difference in *.optimized is just: - # vma_5 = PHI <0B(18), vma_2(15), vma_20(6), vma_2(16), 0B(7)> - return vma_5; + # _5 = PHI <0B(18), vma_2(15), vma_20(6), vma_2(16), 0B(7)> + return _5; but later on CSE2 decides to use REG_EQUAL somewhere for some reason, and we end up reading mm->mmap_cache twice, first into a register to do the comparisons of it, and then when we know it is the value we actually want to return, we just forget we have it in a pseudo and read it again from memory.