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.