https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90813

--- Comment #26 from Richard Biener <rguenth at gcc dot gnu.org> ---
(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]  <function_decl
> 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] 
> <function_de
> 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] 
> <var_decl 0x3fff7aa40990 c_>)
>         (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_ = &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 (*<T5e3>) (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.

Reply via email to