http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54200
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> 2013-04-02 07:56:26 UTC --- On Fri, 29 Mar 2013, jakub at gcc dot gnu.org wrote: > > 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. Surely not a bug with the patch but a bug in CSE. What the patch can change is how pseudos are coalesced. A "fix" may be in the coalescing code, not restrict coalescing to SSA names with the same underlying decl (with the cost issue of a bigger conflict map).