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

            Bug ID: 87690
           Summary: [RISCV][ABI] GCC fails to sign-extend floats passed in
                    the lp64 ABI
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: asb at lowrisc dot org
  Target Milestone: ---

The RISC-V PSABI documentation specifies the following for the base/integer
calling convention:
1) When passed in registers, scalars narrower than XLEN bits are widened
according to the sign of their type up to 32 bits, then sign-extended to XLEN
bits.
2) Floating-point reals are passed the same way as integers of the same size
3) For aggregates, bits unused due to padding, and bits past the end of an
aggregate whose size in bits is not divisible by XLEN, are undefined.

i.e. when XLEN=64, floats should be sign-extended when passed in GPRs.

In the following example, the top 54 bits in the GPR for char_struct and the
top 32 bits in the GPR for float_struct are undefined. Therefore, the compiler
should insert an explicit sign extension in both cases.

$ cat foo.c
struct float_struct { float v; };
struct char_struct { char v; };

struct float_struct callee(float, char);

struct float_struct caller(struct float_struct fs, struct char_struct cs) {
  return callee(fs.v, cs.v);
}

It does for the char, but not for the float. This is not compliant with the
specified ABI:
./riscv32-unknown-elf-gcc -march=rv64i -mabi=lp64 -S -o - foo.c -O2
        .file   "foo.c"
        .option nopic
        .text
        .align  2
        .globl  caller
        .type   caller, @function
caller:
        andi    a1,a1,0xff
        tail    callee
        .size   caller, .-caller
        .ident  "GCC: (GNU) 9.0.0 20180922 (experimental)"

Note: this is a compiler build from one month ago. I can't see any commits
since then that fix this, and unfortunately I seem unable to build
gas+newlib+gcc in a combined tree currently which I usually do for a rapid
build in order to verify a bug (Error: non-constant .uleb128 is not supported).

Reply via email to