aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2019-08-05 03:32:38 +0000
committerKito Cheng <kito@gcc.gnu.org>2019-08-05 03:32:38 +0000
commit860edc46624a23e678934a907d8fccb2fad0dcb5 (patch)
treee7ddfc15b2e2736505adf431856280ffb2f2c38d /gcc
parent89c78fb2e1d862f4efbc22583eeb852bf173a0ad (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/riscv/riscv.c28
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c37
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;
+}