diff options
author | Kito Cheng <kito.cheng@sifive.com> | 2019-08-05 03:32:38 +0000 |
---|---|---|
committer | Kito Cheng <kito@gcc.gnu.org> | 2019-08-05 03:32:38 +0000 |
commit | 860edc46624a23e678934a907d8fccb2fad0dcb5 (patch) | |
tree | e7ddfc15b2e2736505adf431856280ffb2f2c38d /gcc | |
parent | 89c78fb2e1d862f4efbc22583eeb852bf173a0ad (diff) | |
download | gcc-860edc46624a23e678934a907d8fccb2fad0dcb5.zip gcc-860edc46624a23e678934a907d8fccb2fad0dcb5.tar.gz gcc-860edc46624a23e678934a907d8fccb2fad0dcb5.tar.bz2 |
RISC-V: Promote type correctly for libcalls
- argument and return value for libcall won't promote at
default_promote_function_mode_always_promote, however we expect it
should sign-extend as normal function.
- Witout this patch, this test case will fail at -march=rv64i -mabi=lp64.
- The implementation of riscv_promote_function_mode is borrowed from MIPS.
gcc/ChangeLog
* config/riscv/riscv.c (riscv_promote_function_mode): New.
(TARGET_PROMOTE_FUNCTION_MODE): Use riscv_promote_function_mode.
gcc/testsuite/ChangeLog
* gcc.target/riscv/promote-type-for-libcall.c: New.
From-SVN: r274107
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c | 37 |
4 files changed, 73 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4235f73..2de2e65 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-05 Kito Cheng <kito.cheng@sifive.com> + + * config/riscv/riscv.c (riscv_promote_function_mode): New. + (TARGET_PROMOTE_FUNCTION_MODE): Use riscv_promote_function_mode. + 2019-08-05 Alan Modra <amodra@gmail.com> PR target/91349 diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index e274f1b..431e90a 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -4910,6 +4910,32 @@ riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align) return align; } +/* Implement TARGET_PROMOTE_FUNCTION_MODE. */ + +/* This function is equivalent to default_promote_function_mode_always_promote + except that it returns a promoted mode even if type is NULL_TREE. This is + needed by libcalls which have no type (only a mode) such as fixed conversion + routines that take a signed or unsigned char/short/int argument and convert + it to a fixed type. */ + +static machine_mode +riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return ATTRIBUTE_UNUSED) +{ + int unsignedp; + + if (type != NULL_TREE) + return promote_mode (type, mode, punsignedp); + + unsignedp = *punsignedp; + PROMOTE_MODE (mode, unsignedp, type); + *punsignedp = unsignedp; + return mode; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -4951,7 +4977,7 @@ riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align) #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start #undef TARGET_PROMOTE_FUNCTION_MODE -#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote +#define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f58e18..8fe569a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-05 Kito Cheng <kito.cheng@sifive.com> + + * gcc.target/riscv/promote-type-for-libcall.c: New. + 2019-08-02 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/90985 diff --git a/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c b/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c new file mode 100644 index 0000000..bdbcbc0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-options "-O1 -ftree-slp-vectorize -funroll-loops" } */ + +#include <stdio.h> +#include <stdlib.h> +#define N 4 +volatile float f[N]; +int x[N] __attribute__((aligned(8))); +int main() { + int i; + x[0] = -1; + x[1] = 2; + x[2] = -2; + x[3] = 2; + + for (i=0;i<N;++i){ + f[i] = x[i]; + } + + if (f[0] != -1.0f) { + abort(); + } + + if (f[1] != 2.0f) { + abort(); + } + + if (f[2] != -2.0f) { + abort(); + } + + if (f[3] != 2.0f) { + abort(); + } + + return 0; +} |