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

            Bug ID: 82106
           Summary: [RISCV] Misaligned loads generated when doubles are
                    split between stack and registers
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: asb at lowrisc dot org
  Target Milestone: ---

Created attachment 42127
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42127&action=edit
Simple program to reproduce this problem

When targeting RISC-V, GCC will allocate space on the stack for values which
are split between argument registers and the stack. If the type has alignment
larger than xlen, it is possible for misaligned loads to be generated. This can
be observed when passing a double in the attached example. The below is
generated using GCC r251714.

$ cat call.c

typedef long long int int64_t;
struct large_struct { int64_t h1; int64_t h2; };

void fun_float(float);
void fun_double(double);
void fun_int64(int64_t);

void callee(float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, 
    float fa6, float fa7, int a0, int a1, int a2, int a3, int a4, int a5, int 
    a6, double a7_s0, int64_t s1, float s2, struct large_struct s3) {
  fun_double(a7_s0);
  fun_int64(s1);
  fun_float(s2);
  fun_int64(s3.h1);
  fun_int64(s3.h2);
  return;
}

/riscv32-unknown-elf-gcc -v -c call.c -march=rv32ifd -mabi=ilp32d -O1
-fno-omit-frame-pointer -S -o -Using built-in specs.
COLLECT_GCC=./riscv32-unknown-elf-gcc
Target: riscv32-unknown-elf
Configured with: ../configure --target=riscv32-unknown-elf --enable-languages=c
--disable-shared --disable-threads --disable-multilib --disable-gdb
--disable-libssp --with-newlib --with-arch=rv32ima --with-abi=ilp32
--prefix=/home/asb/work/2017_09_05_gcc_build/combined/build/built
Thread model: single
gcc version 8.0.0 20170905 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-c' '-march=rv32ifd' '-mabi=ilp32d' '-O1'
'-fno-omit-frame-pointer' '-S' '-o' '-'

/home/asb/work/2017_09_05_gcc_build/combined/build/built/libexec/gcc/riscv32-unknown-elf/8.0.0/cc1
-quiet -v call.c -quiet -dumpbase call.c -march=rv32ifd -mabi=ilp32d
-auxbase-strip - -O1 -version -fno-omit-frame-pointer -o -
GNU C11 (GCC) version 8.0.0 20170905 (experimental) (riscv32-unknown-elf)
        compiled by GNU C version 7.1.1 20170630, GMP version 6.1.2, MPFR
version 3.1.5-p2, MPC version 1.0.3, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring nonexistent directory
"/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/../../../../riscv32-unknown-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:

/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/include

/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/include-fixed

/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/../../../../riscv32-unknown-elf/include
End of search list.
GNU C11 (GCC) version 8.0.0 20170905 (experimental) (riscv32-unknown-elf)
        compiled by GNU C version 7.1.1 20170630, GMP version 6.1.2, MPFR
version 3.1.5-p2, MPC version 1.0.3, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 82d1950b419a8e1b72499dc8b233dd66
        .file   "call.c"
        .option nopic
        .text
        .align  2
        .globl  callee
        .type   callee, @function
callee:
        add     sp,sp,-32
        sw      ra,12(sp)
        sw      s0,8(sp)
        sw      s1,4(sp)
        add     s0,sp,16
        sw      a7,12(s0)
        lw      s1,36(s0)
        fld     fa0,12(s0)
        call    fun_double
        lw      a0,24(s0)
        lw      a1,28(s0)
        call    fun_int64
        flw     fa0,32(s0)
        call    fun_float
        lw      a0,0(s1)
        lw      a1,4(s1)
        call    fun_int64
        lw      a0,8(s1)
        lw      a1,12(s1)
        call    fun_int64
        lw      ra,12(sp)
        lw      s0,8(sp)
        lw      s1,4(sp)
        add     sp,sp,32
        jr      ra
        .size   callee, .-callee
        .ident  "GCC: (GNU) 8.0.0 20170905 (experimental)"
COMPILER_PATH=/home/asb/work/2017_09_05_gcc_build/combined/build/built/libexec/gcc/riscv32-unknown-elf/8.0.0/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/libexec/gcc/riscv32-unknown-elf/8.0.0/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/libexec/gcc/riscv32-unknown-elf/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/../../../../riscv32-unknown-elf/bin/
LIBRARY_PATH=/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/:/home/asb/work/2017_09_05_gcc_build/combined/build/built/lib/gcc/riscv32-unknown-elf/8.0.0/../../../../riscv32-unknown-elf/lib/:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-c' '-march=rv32ifd' '-mabi=ilp32d' '-O1'
'-fno-omit-frame-pointer' '-S' '-o' '-'

`fld    fa0,12(s0)` is using a misaligned stack address. Although this should
work, the compiler should avoid generating misaligned accesses where possible
as they may be trigger an exception and an emulation routine.

Reply via email to