[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #26 from Richard Biener --- (In reply to Segher Boessenkool from comment #25) > At expand time, the assignment is > > > ;; c_ = c; > > (insn 35 34 36 (set (reg/f:DI 140) > (unspec:DI [ > (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) > (reg:DI 2 2) > ] UNSPEC_TOCREL)) "proc_ptr_51.f90":26:0 -1 > (expr_list:REG_EQUAL (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) > (nil))) > > (insn 36 35 37 (set (reg/f:DI 141) > (unspec:DI [ > (symbol_ref:DI ("__f_MOD_c") [flags 0x3] 0x3fff7 > 86a7d00 c>) > (reg:DI 2 2) > ] UNSPEC_TOCREL)) "proc_ptr_51.f90":26:0 -1 > (expr_list:REG_EQUAL (symbol_ref:DI ("__f_MOD_c") [flags 0x3] > cl 0x3fff786a7d00 c>) > (nil))) > > (insn 37 36 0 (set (mem/f/c:DI (reg/f:DI 140) [13 c_+0 S8 A64]) > (reg/f:DI 141)) "proc_ptr_51.f90":26:0 -1 > (nil)) > > > while the use is (immediately after that!) > > > ;; rhs.2 = c_.5_12 (); [return slot optimization] > > (insn 38 37 39 (set (reg:DI 142) > (plus:DI (reg/f:DI 112 virtual-stack-vars) > (const_int 48 [0x30]))) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (insn 39 38 40 (set (reg/f:DI 143) > (mem/u/c:DI (unspec:DI [ > (symbol_ref/u:DI ("*.LC1") [flags 0x2]) > (reg:DI 2 2) > ] UNSPEC_TOCREL) [21 S8 A8])) "proc_ptr_51.f90":35:0 -1 > (expr_list:REG_EQUAL (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] > ) > (nil))) > > (insn 40 39 41 (set (reg/f:DI 144) > (mem/f/c:DI (reg/f:DI 143) [13 c_+0 S8 A64])) "proc_ptr_51.f90":35:0 > -1 > (nil)) > > (insn 41 40 42 (set (reg:DI 3 3) > (reg:DI 142)) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (insn 42 41 43 (set (reg:DI 145) > (mem:DI (reg/f:DI 144) [0 S8 A8])) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (insn 43 42 44 (set (reg:DI 97 ctr) > (reg:DI 145)) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (insn 44 43 45 (set (reg:DI 11 11) > (mem:DI (plus:DI (reg/f:DI 144) > (const_int 16 [0x10])) [0 S8 A8])) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (call_insn 45 44 46 (parallel [ > (call (mem:SI (reg:DI 97 ctr) [0 *c_.5_12 S4 A8]) > (const_int 64 [0x40])) > (use (mem:DI (plus:DI (reg/f:DI 144) > (const_int 8 [0x8])) [0 S8 A8])) > (set (reg:DI 2 2) > (unspec:DI [ > (const_int 40 [0x28]) > ] UNSPEC_TOCSLOT)) > (clobber (reg:DI 96 lr)) > ]) "proc_ptr_51.f90":35:0 -1 > (expr_list:REG_CALL_DECL (nil) > (nil)) > (expr_list (use (reg:DI 11 11)) > (expr_list:DI (use (reg:DI 3 3)) > (nil > > (insn 46 45 47 (set (reg:DI 146) > (plus:DI (reg/f:DI 112 virtual-stack-vars) > (const_int 48 [0x30]))) "proc_ptr_51.f90":35:0 -1 > (nil)) > > (insn 47 46 0 (set (reg:TI 127 [ rhs.2 ]) > (mem:TI (reg:DI 146) [7 S16 A64])) "proc_ptr_51.f90":35:0 -1 > (nil)) > > > > so it is wrong (if this is wrong!) at expand already. > > > In gimple this was: > > c_ = c; > c_.5_12 = c_; > rhs.2 = c_.5_12 (); [return slot optimization] OK, so this is really static fnptrtype c_ = dumped in a weird way and then a load from the global var. Not sure why this isn't optimized on GIMPLE (to a direct call)... Note the type we're basing the indirect call ABI on is struct __class_f_S_p (*) (void) _12; not sure if that's correct. To me it seems the function returns a pointer, not an aggregate. That may be very well the (frontend) issue? For the C testcase typedef void (*fnptr)(void); void bar(void); fnptr g; fnptr foo() { g = bar; return g; } we happily optimize the load, even when I make the types mismatching. The odd thing is that for the Fortran example even the tree oracle claims the store doesn't alias the load... Because they are different variables! Dumping with -uid shows c_D.3918 = cD.3925; c_.5_12 = c_D.3933; rhs.2D.4008 = c_.5_12 (); that's probably not intended either... c_D.3933 is never initialized anywhere in the testcase.
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #25 from Segher Boessenkool --- At expand time, the assignment is ;; c_ = c; (insn 35 34 36 (set (reg/f:DI 140) (unspec:DI [ (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (reg:DI 2 2) ] UNSPEC_TOCREL)) "proc_ptr_51.f90":26:0 -1 (expr_list:REG_EQUAL (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (nil))) (insn 36 35 37 (set (reg/f:DI 141) (unspec:DI [ (symbol_ref:DI ("__f_MOD_c") [flags 0x3] ) (reg:DI 2 2) ] UNSPEC_TOCREL)) "proc_ptr_51.f90":26:0 -1 (expr_list:REG_EQUAL (symbol_ref:DI ("__f_MOD_c") [flags 0x3] ) (nil))) (insn 37 36 0 (set (mem/f/c:DI (reg/f:DI 140) [13 c_+0 S8 A64]) (reg/f:DI 141)) "proc_ptr_51.f90":26:0 -1 (nil)) while the use is (immediately after that!) ;; rhs.2 = c_.5_12 (); [return slot optimization] (insn 38 37 39 (set (reg:DI 142) (plus:DI (reg/f:DI 112 virtual-stack-vars) (const_int 48 [0x30]))) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 39 38 40 (set (reg/f:DI 143) (mem/u/c:DI (unspec:DI [ (symbol_ref/u:DI ("*.LC1") [flags 0x2]) (reg:DI 2 2) ] UNSPEC_TOCREL) [21 S8 A8])) "proc_ptr_51.f90":35:0 -1 (expr_list:REG_EQUAL (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) (nil))) (insn 40 39 41 (set (reg/f:DI 144) (mem/f/c:DI (reg/f:DI 143) [13 c_+0 S8 A64])) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 41 40 42 (set (reg:DI 3 3) (reg:DI 142)) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 42 41 43 (set (reg:DI 145) (mem:DI (reg/f:DI 144) [0 S8 A8])) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 43 42 44 (set (reg:DI 97 ctr) (reg:DI 145)) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 44 43 45 (set (reg:DI 11 11) (mem:DI (plus:DI (reg/f:DI 144) (const_int 16 [0x10])) [0 S8 A8])) "proc_ptr_51.f90":35:0 -1 (nil)) (call_insn 45 44 46 (parallel [ (call (mem:SI (reg:DI 97 ctr) [0 *c_.5_12 S4 A8]) (const_int 64 [0x40])) (use (mem:DI (plus:DI (reg/f:DI 144) (const_int 8 [0x8])) [0 S8 A8])) (set (reg:DI 2 2) (unspec:DI [ (const_int 40 [0x28]) ] UNSPEC_TOCSLOT)) (clobber (reg:DI 96 lr)) ]) "proc_ptr_51.f90":35:0 -1 (expr_list:REG_CALL_DECL (nil) (nil)) (expr_list (use (reg:DI 11 11)) (expr_list:DI (use (reg:DI 3 3)) (nil (insn 46 45 47 (set (reg:DI 146) (plus:DI (reg/f:DI 112 virtual-stack-vars) (const_int 48 [0x30]))) "proc_ptr_51.f90":35:0 -1 (nil)) (insn 47 46 0 (set (reg:TI 127 [ rhs.2 ]) (mem:TI (reg:DI 146) [7 S16 A64])) "proc_ptr_51.f90":35:0 -1 (nil)) so it is wrong (if this is wrong!) at expand already. In gimple this was: c_ = c; c_.5_12 = c_; rhs.2 = c_.5_12 (); [return slot optimization]
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #24 from Segher Boessenkool --- Is that disallowed? Is there any way to prevent that from happening, in general?
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #23 from rguenther at suse dot de --- On July 6, 2019 12:18:47 AM GMT+02:00, "pthaugen at linux dot ibm.com" wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 > >Pat Haugen changed: > > What|Removed |Added > > CC||pthaugen at linux dot ibm.com, > ||rguenth at gcc dot gnu.org > >--- Comment #22 from Pat Haugen --- >So the problem appears to be alias.c:true_dependence() telling >sched-deps.c:sched_analyze_2() that the following two instructions' >memory >references don't alias. > >Breakpoint 11, sched_analyze_2 (deps=0x7fffdbf8, x=0x759a1a40, >insn=0x757f16c0) >at /home/pthaugen/src/gcc/temp/gcc/gcc/sched-deps.c:2671 >2671if (true_dependence (pending_mem->element (), >VOIDmode, >t) >(gdb) pr pending->insn() >(insn 37 36 38 4 (set (mem/f/c:DI (unspec:DI [ >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) >(reg:DI 2 2) >] UNSPEC_TOCREL) [8 c_+0 S8 A64]) >(reg/f:DI 141)) "proc_ptr_51.f90":28:0 609 {*movdi_internal64} > (expr_list:REG_DEAD (reg/f:DI 141) >(nil))) > >(gdb) pr insn >(insn 39 38 40 4 (set (reg/f:DI 143 [ c_ ]) >(mem/f/c:DI (reg/f:DI 142) [8 c_+0 S8 A64])) "proc_ptr_51.f90":37:0 609 >{*movdi_internal64} > (expr_list:REG_DEAD (reg/f:DI 142) > (expr_list:REG_EQUAL (mem/f/c:DI (symbol_ref:DI ("__f_MOD_c_") [flags >0xc0] ) [8 c_+0 S8 A64]) >(nil > >Which then lets the scheduler move the load above the store. Since they >really >are referring to the same location, we load up garbage (null) and >branch to it. > >Including some additional detail from a couple various spots in the >debug >chain. Hoping someone with more alias.c knowledge can chime in. > > >Breakpoint 13, true_dependence_1 (mem=0x759a4878, >mem_mode=E_VOIDmode, >mem_addr=0x0, x=0x759a8e08, >x_addr=0x0, mem_canonicalized=false) at >/home/pthaugen/src/gcc/temp/gcc/gcc/alias.c:2902 >2902{ >(gdb) pr mem >(mem/f/c:DI (unspec:DI [ >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) >(reg:DI 2 2) >] UNSPEC_TOCREL) [8 c_+0 S8 A64]) >(gdb) pr x >(mem/f/c:DI (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] 0x77f70990 >c_>) [8 c_+0 S8 A64]) > >... > >(gdb) pr x_addr >(symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] c_>) >(gdb) pr true_mem_addr >(unspec:DI [ >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) >(reg:DI 2 2) >] UNSPEC_TOCREL) >(gdb) pr mem_base >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) > >2958 if (! base_alias_check (x_addr, base, true_mem_addr, >mem_base, >(gdb) p base_alias_check (x_addr, base, true_mem_addr, mem_base, >GET_MODE (x), >mem_mode) >$18 = 0 > >(gdb) s >base_alias_check (x=0x75992990, x_base=0x75992990, >y=0x759a4890, >y_base=0x75990ac8, >x_mode=E_DImode, y_mode=E_DImode) at >/home/pthaugen/src/gcc/temp/gcc/gcc/alias.c:2174 >2174 if (x_base == 0) >(gdb) pr x >(symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] c_>) >(gdb) pr x_base >(symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] c_>) >(gdb) pr y >(unspec:DI [ >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) >(reg:DI 2 2) >] UNSPEC_TOCREL) >(gdb) pr y_base >(symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) > >2221return compare_base_symbol_refs (x_base, y_base) != 0; >(gdb) p compare_base_symbol_refs (x_base, y_base) >$19 = 0 > >2136 if (!x_node->definition) >(gdb) n >2137return 0; We seem to access the same decl (see MEM_EXPR) once via section anchor and once not. We seem to be confused about this in this very place?
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 Pat Haugen changed: What|Removed |Added CC||pthaugen at linux dot ibm.com, ||rguenth at gcc dot gnu.org --- Comment #22 from Pat Haugen --- So the problem appears to be alias.c:true_dependence() telling sched-deps.c:sched_analyze_2() that the following two instructions' memory references don't alias. Breakpoint 11, sched_analyze_2 (deps=0x7fffdbf8, x=0x759a1a40, insn=0x757f16c0) at /home/pthaugen/src/gcc/temp/gcc/gcc/sched-deps.c:2671 2671if (true_dependence (pending_mem->element (), VOIDmode, t) (gdb) pr pending->insn() (insn 37 36 38 4 (set (mem/f/c:DI (unspec:DI [ (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (reg:DI 2 2) ] UNSPEC_TOCREL) [8 c_+0 S8 A64]) (reg/f:DI 141)) "proc_ptr_51.f90":28:0 609 {*movdi_internal64} (expr_list:REG_DEAD (reg/f:DI 141) (nil))) (gdb) pr insn (insn 39 38 40 4 (set (reg/f:DI 143 [ c_ ]) (mem/f/c:DI (reg/f:DI 142) [8 c_+0 S8 A64])) "proc_ptr_51.f90":37:0 609 {*movdi_internal64} (expr_list:REG_DEAD (reg/f:DI 142) (expr_list:REG_EQUAL (mem/f/c:DI (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) [8 c_+0 S8 A64]) (nil Which then lets the scheduler move the load above the store. Since they really are referring to the same location, we load up garbage (null) and branch to it. Including some additional detail from a couple various spots in the debug chain. Hoping someone with more alias.c knowledge can chime in. Breakpoint 13, true_dependence_1 (mem=0x759a4878, mem_mode=E_VOIDmode, mem_addr=0x0, x=0x759a8e08, x_addr=0x0, mem_canonicalized=false) at /home/pthaugen/src/gcc/temp/gcc/gcc/alias.c:2902 2902{ (gdb) pr mem (mem/f/c:DI (unspec:DI [ (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (reg:DI 2 2) ] UNSPEC_TOCREL) [8 c_+0 S8 A64]) (gdb) pr x (mem/f/c:DI (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) [8 c_+0 S8 A64]) ... (gdb) pr x_addr (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) (gdb) pr true_mem_addr (unspec:DI [ (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (reg:DI 2 2) ] UNSPEC_TOCREL) (gdb) pr mem_base (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) 2958 if (! base_alias_check (x_addr, base, true_mem_addr, mem_base, (gdb) p base_alias_check (x_addr, base, true_mem_addr, mem_base, GET_MODE (x), mem_mode) $18 = 0 (gdb) s base_alias_check (x=0x75992990, x_base=0x75992990, y=0x759a4890, y_base=0x75990ac8, x_mode=E_DImode, y_mode=E_DImode) at /home/pthaugen/src/gcc/temp/gcc/gcc/alias.c:2174 2174 if (x_base == 0) (gdb) pr x (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) (gdb) pr x_base (symbol_ref:DI ("__f_MOD_c_") [flags 0xc0] ) (gdb) pr y (unspec:DI [ (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) (reg:DI 2 2) ] UNSPEC_TOCREL) (gdb) pr y_base (symbol_ref:DI ("*.LANCHOR1") [flags 0x182]) 2221return compare_base_symbol_refs (x_base, y_base) != 0; (gdb) p compare_base_symbol_refs (x_base, y_base) $19 = 0 2136 if (!x_node->definition) (gdb) n 2137return 0;
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #21 from Paul Thomas --- (In reply to pthaugen from comment #20) > (In reply to Segher Boessenkool from comment #17) > > sched2 swaps the two insns (37 and 40 for me -- use -dp to see the numbers > > in your .s file, use -da if you want lots of dumps, -dap together). > > > > So why did sched2 decide it can swap these? They are in the same aliasing > > set, so it shouldn't do this. Hrm. > > I'm looking into this... Hi there, Have you made any progress? Anyway, thanks for anything that you can do. Regards Paul
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 pthaugen at gcc dot gnu.org changed: What|Removed |Added CC||pthaugen at gcc dot gnu.org --- Comment #20 from pthaugen at gcc dot gnu.org --- (In reply to Segher Boessenkool from comment #17) > sched2 swaps the two insns (37 and 40 for me -- use -dp to see the numbers > in your .s file, use -da if you want lots of dumps, -dap together). > > So why did sched2 decide it can swap these? They are in the same aliasing > set, so it shouldn't do this. Hrm. I'm looking into this...
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 Michael Meissner changed: What|Removed |Added CC||meissner at gcc dot gnu.org --- Comment #19 from Michael Meissner --- Power8 fusion is meant to transform: ADDIS tmp,2,foo@toc@ha LD reg,foo@toc@l(tmp) into: ADDIS reg,2,foo@toc@ha LD reg,foo@toc@l(reg) I.e. instead of using a random register for the upper 16-bits, it uses the same register that is being loaded. I haven't looked into detail at why this is failing.
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #18 from Segher Boessenkool --- -mno-power8-fusion seems to fix this. Can you confirm?
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #17 from Segher Boessenkool --- sched2 swaps the two insns (37 and 40 for me -- use -dp to see the numbers in your .s file, use -da if you want lots of dumps, -dap together). So why did sched2 decide it can swap these? They are in the same aliasing set, so it shouldn't do this. Hrm.
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 Thomas Koenig changed: What|Removed |Added Priority|P4 |P3 --- Comment #16 from Thomas Koenig --- I'm also trying to create a C test case, but that is a bit complex :-) Resetting priority, BTW.
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 --- Comment #15 from paul.richard.thomas at gmail dot com --- Hi Thomas, I had come to the conclusion that the optimizer is screwing up somehow and was going to suggest testing -fno-inline. Your splitting the files was definitely the smoking gun. It's weird, is it not, that it should be target specific? Who is the guru that we should be appealing to? Thanks for working on this. Paul On Sun, 23 Jun 2019 at 20:49, tkoenig at gcc dot gnu.org wrote: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 > > Thomas Koenig changed: > >What|Removed |Added > > Component|fortran |rtl-optimization > > --- Comment #14 from Thomas Koenig --- > So, the code of actually calling the procedure seems to be correct. > (It loads the address of the procedure pointer, then loads > the address from there, and branches). > > What appears to be wrong is that the subroutine fs, which assigns > the address of c to the procedure pointer, is never executed. > > Data point: -fno-inline restores the correct behavior. > > In the .optimized dump, the relevant lines are > > MEM[(struct s &)_7].i = 99; > c_ = c; > c_.5_12 = c_; > rhs.2 = c_.5_12 (); > > and it seems tat the statement > > c_ = c; > > is somehow eliminated later. > > Ouch, yes, I think I see this now (after some debugging). > > This > > # proc_ptr_51.f90:35: res => c_() > addis 10,2,.LC1@toc@ha # tmp142,, > ld 10,.LC1@toc@l(10) # tmp142,, tmp142 > > loads the contents of LC1 (where the procedure > pointer resides) into r10. > > This > > # proc_ptr_51.f90:26:c_ => c ! This used to ICE > addis 9,2,__f_MOD_c@toc@ha # tmp141,, > # proc_ptr_51.f90:30: end module f > li 8,99 # tmp139, > # proc_ptr_51.f90:26:c_ => c ! This used to ICE > addi 9,9,__f_MOD_c@toc@l # tmp141, tmp141, > > puts the address of __f_MOD_c into r9 (and loads another > value in the meantime). > > Next lines are > > # proc_ptr_51.f90:33: allocate (tgt, source = s(99)) > addis 7,2,.LANCHOR0+8@toc@ha # tmp178,,, > addi 30,30,32# tmp172, tmp171, > # proc_ptr_51.f90:30: end module f > stw 8,0(3) # MEM[(struct s &)_7].i, tmp139 > > These lines are unrelated. > > # proc_ptr_51.f90:35: res => c_() > ld 12,0(10) # c_, c_ > > This loads the contents of the procedure poitner into r12. > > # proc_ptr_51.f90:26:c_ => c ! This used to ICE > addis 10,2,.LANCHOR1@toc@ha # tmp179,, > # proc_ptr_51.f90:33: allocate (tgt, source = s(99)) > std 30,.LANCHOR0+8@toc@l(7) # tgt._vptr, tmp172 > # proc_ptr_51.f90:26:c_ => c ! This used to ICE > std 9,.LANCHOR1@toc@l(10)# c_, tmp141 > > This (if I am not mistaken) stores the contents of r9 into the > procedure pointer, but it is too late, because this > > # proc_ptr_51.f90:35: res => c_() > mtctr 12 #, > > jumps to the NULL pointer. > > Interesting question: Why is the store done too late? The tree > dumps look OK; the problem also does not occur if the > call to fs is replaced by a simple pointer assignment. > > So, I am going to guess and say this is probably an RTL problem. > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug rtl-optimization/90813] [10 regression] gfortran.dg/proc_ptr_51.f90 fails (SIGSEGV) after 272084
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813 Thomas Koenig changed: What|Removed |Added Component|fortran |rtl-optimization --- Comment #14 from Thomas Koenig --- So, the code of actually calling the procedure seems to be correct. (It loads the address of the procedure pointer, then loads the address from there, and branches). What appears to be wrong is that the subroutine fs, which assigns the address of c to the procedure pointer, is never executed. Data point: -fno-inline restores the correct behavior. In the .optimized dump, the relevant lines are MEM[(struct s &)_7].i = 99; c_ = c; c_.5_12 = c_; rhs.2 = c_.5_12 (); and it seems tat the statement c_ = c; is somehow eliminated later. Ouch, yes, I think I see this now (after some debugging). This # proc_ptr_51.f90:35: res => c_() addis 10,2,.LC1@toc@ha # tmp142,, ld 10,.LC1@toc@l(10) # tmp142,, tmp142 loads the contents of LC1 (where the procedure pointer resides) into r10. This # proc_ptr_51.f90:26:c_ => c ! This used to ICE addis 9,2,__f_MOD_c@toc@ha # tmp141,, # proc_ptr_51.f90:30: end module f li 8,99 # tmp139, # proc_ptr_51.f90:26:c_ => c ! This used to ICE addi 9,9,__f_MOD_c@toc@l # tmp141, tmp141, puts the address of __f_MOD_c into r9 (and loads another value in the meantime). Next lines are # proc_ptr_51.f90:33: allocate (tgt, source = s(99)) addis 7,2,.LANCHOR0+8@toc@ha # tmp178,,, addi 30,30,32# tmp172, tmp171, # proc_ptr_51.f90:30: end module f stw 8,0(3) # MEM[(struct s &)_7].i, tmp139 These lines are unrelated. # proc_ptr_51.f90:35: res => c_() ld 12,0(10) # c_, c_ This loads the contents of the procedure poitner into r12. # proc_ptr_51.f90:26:c_ => c ! This used to ICE addis 10,2,.LANCHOR1@toc@ha # tmp179,, # proc_ptr_51.f90:33: allocate (tgt, source = s(99)) std 30,.LANCHOR0+8@toc@l(7) # tgt._vptr, tmp172 # proc_ptr_51.f90:26:c_ => c ! This used to ICE std 9,.LANCHOR1@toc@l(10)# c_, tmp141 This (if I am not mistaken) stores the contents of r9 into the procedure pointer, but it is too late, because this # proc_ptr_51.f90:35: res => c_() mtctr 12 #, jumps to the NULL pointer. Interesting question: Why is the store done too late? The tree dumps look OK; the problem also does not occur if the call to fs is replaced by a simple pointer assignment. So, I am going to guess and say this is probably an RTL problem.