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

--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, to sum up, in #c9 we are (or want to do) in Fortran roughly what in C we
would do with:
void foo (double aa, double bb, void *c_aptr, void *c_bptr, double **aptr,
double **bptr, _Bool _aa, _Bool _bb, _Bool _c_aptr, _Bool _c_bptr)
{
  if (!_c_aptr | !_c_bptr)
    __builtin_abort ();
}
void bar (double aa, double bb, void *c_aptr, void *c_bptr, double **aptr,
double **bptr, unsigned char _aa, unsigned char _bb, unsigned char _c_aptr,
unsigned char _c_bptr)
{
  if (!_c_aptr | !_c_bptr)
    __builtin_abort ();
}
int
main ()
{
  double *aptr, *bptr;
  foo (0.0, 0.0, 0, 0, &aptr, &bptr, 1, 1, 1, 1);
  bar (0.0, 0.0, 0, 0, &aptr, &bptr, 1, 1, 1, 1);
  return 0;
}
and that works just fine in C, even at -O0.
Looking at expand dump of foo vs. test_dummy_opt_val_callee_2
I don't see any relevant differences in the arg passing:
-;; _1 = ~_c_aptr_4(D);
+;; _1 = ~_c_aptr_6(D);

-(insn 17 16 18 (set (reg:QI 124)
+(insn 17 16 18 (set (reg:QI 126)
         (mem/c:QI (plus:DI (reg/f:DI 111 virtual-incoming-args)
-                (const_int 64 [0x40])) [4 _c_aptr+0 S1 A64])) "pr92305.c":3:7
-1
+                (const_int 64 [0x40])) [4 _c_aptr+0 S1 A64]))
"pr92305.f90":14:0 -1
      (nil))
...
-;; _2 = ~_c_bptr_5(D);
+;; _3 = ~_c_bptr_7(D);

-(insn 20 19 21 (set (reg:QI 126)
+(insn 22 21 23 (set (reg:QI 129)
         (mem/c:QI (plus:DI (reg/f:DI 111 virtual-incoming-args)
-                (const_int 72 [0x48])) [4 _c_bptr+0 S1 A64])) "pr92305.c":3:18
-1
+                (const_int 72 [0x48])) [4 _c_bptr+0 S1 A64]))
"pr92305.f90":14:0 -1
      (nil))

In the caller, in Fortran I see:
    (expr_list (use (reg:DI 2 2))
        (expr_list:DF (use (reg:DF 33 1))
            (expr_list:DF (use (reg:DF 34 2))
                (expr_list:DI (use (reg:DI 5 5))
                    (expr_list:DI (use (reg:DI 6 6))
                        (expr_list:DI (use (reg:DI 7 7))
                            (expr_list:DI (use (reg:DI 8 8))
                                (expr_list:QI (use (reg:DI 9 9))
                                    (expr_list:QI (use (reg:DI 10 10))
                                        (expr_list:QI (use (mem:DI (reg/f:DI
114 virtual-outgoing-args) [0  S1 A64]))
                                            (expr_list:QI (use (mem:DI (plus:DI
(reg/f:DI 114 virtual-outgoing-args)
                                                            (const_int 8
[0x8])) [0  S1 A64]))
                                                (nil)))))))))))))
and both DImode slot at virtual-outgoing-args and at +8 are initialized with
full DImode store of 1 in there, while in C:
    (expr_list (use (reg:DI 2 2))
        (expr_list:DF (use (reg:DF 33 1))
            (expr_list:DF (use (reg:DF 34 2))
                (expr_list:DI (use (reg:DI 5 5))
                    (expr_list:DI (use (reg:DI 6 6))
                        (expr_list:DI (use (reg:DI 7 7))
                            (expr_list:DI (use (reg:DI 8 8))
                                (expr_list:QI (use (reg:DI 9 9))
                                    (expr_list:QI (use (reg:DI 10 10))
                                        (expr_list:QI (use (mem:DI (plus:DI
(reg/f:DI 114 virtual-outgoing-args)
                                                        (const_int 64 [0x40]))
[0  S1 A64]))
                                            (expr_list:QI (use (mem:DI (plus:DI
(reg/f:DI 114 virtual-outgoing-args)
                                                            (const_int 72
[0x48])) [0  S1 A64]))
                                                (nil)))))))))))))
and again, the +64 and +72 slots are initialized to full DImode values of 1.

Reply via email to