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

--- Comment #27 from David Edelsohn <dje at gcc dot gnu.org> ---
GFORTRAN parse output describes the characters as follow

  symtree: 'char'        || symbol: 'char'         
    type spec : (UNKNOWN 0)
    attributes: (PROCEDURE INTRINSIC-PROC  FUNCTION ARRAY-OUTER-DEPENDENCY)
    result: char

  symtree: 'mychar'      || symbol: 'mychar'       
    type spec : (CHARACTER 1 1)
    attributes: (PROCEDURE INTERNAL-PROC  FUNCTION IMPLICIT-PURE CONTAINED)
    result: mychar
    Formal arglist: i

  CALL val (('B') ('B'))
  CALL val (('A') ('A'))
  CALL val (('A') (__char_1_i4[[((p:a) ((arg not-present)))]]))
  CALL val (('A') (mychar[[((65))]]))
  CALL val (('A') (mychar[[((p:a))]]))

258r.expand shows the shift of the function parameter:

(insn 114 113 115 11 (set (reg:SI 4 4)
        (ashift:SI (reg:SI 4 4)
            (const_int 24 [0x18]))) "value_9.f90":23:21 -1
     (nil))
(insn 115 114 116 11 (set (reg:SI 3 3)
        (reg:SI 185)) "value_9.f90":23:21 -1
     (nil))
(call_insn 116 115 117 11 (parallel [
            (call (mem:SI (symbol_ref:SI ("val.4[DS]") [flags 0x3] 
<function_decl 700e8d00 val>) [0 val S4 A8])
                (const_int 32 [0x20]))
            (use (const_int 0 [0]))
            (clobber (reg:SI 96 lr))
        ]) "value_9.f90":23:21 -1
     (expr_list:REG_EH_REGION (const_int 0 [0])
        (nil))
    (expr_list (use (reg:SI 2 2))
        (expr_list:SI (use (reg:SI 3 3))
            (expr_list:QI (use (reg:SI 4 4))
                (expr_list:SI (use (reg:SI 5 5))
                    (expr_list:SI (use (reg:SI 6 6))
                        (nil)))))))

The original tree is

  static void val (character(kind=1)[1:1] & restrict, character(kind=1)[1:1],
integer(kind=4), integer(kind=4));
  static integer(kind=4) a = 65;
  static character(kind=1) c[1:1] = "1";
  static character(kind=4) c4[1:1] = "\x00\x00\x004";

  val (&"B"[1]{lb: 1 sz: 1}, "B", 1, 1);
  val (&"A"[1]{lb: 1 sz: 1}, "A", 1, 1);
  {
    character(kind=1) char.6;

    char.6 = (character(kind=1)) a;
    val (&"A"[1]{lb: 1 sz: 1}, char.6, 1, 1);
  }
  {
    static integer(kind=4) C.2654 = 65;
    character(kind=1) str.7[1];

    mychar ((character(kind=1)[1:1] *) &str.7, 1, &C.2654);
    val (&"A"[1]{lb: 1 sz: 1}, str.7[0], 1, 1);
  }
  {
    character(kind=1) str.8[1];

    mychar ((character(kind=1)[1:1] *) &str.8, 1, &a);
    val (&"A"[1]{lb: 1 sz: 1}, str.8[0], 1, 1);
  }
  val (&"1"[1]{lb: 1 sz: 1}, c[1]{lb: 1 sz: 1}, 1, 1);
  val (&"1"[1]{lb: 1 sz: 1}, c[1]{lb: 1 sz: 1}, 1, 1);


The issue may not be endianness but assumptions about struct padding.  I don't
know exactly how GFORTRAN represents CHARACTER.  I can elicit the same behavior
in C if I embed a "char" in a struct like

struct mychar {
   char c1;
};

  struct mychar mc;

  mc.c1 = 'A';

On AIX, structs are left padded.  A char passed in a 32 bit register is

---------
|x|x|x|A|
---------

but a char passed by value in a struct is

---------
|A|x|x|x|
---------

If GFORTRAN assumes that a scalar value and a value in a struct are passed in
registers with the same padding, that is not a valid, general assumption.

Reply via email to