RISC-V: Promote type correctly for libcalls
authorKito Cheng <kito.cheng@sifive.com>
Mon, 5 Aug 2019 03:32:38 +0000 (03:32 +0000)
committerKito Cheng <kito@gcc.gnu.org>
Mon, 5 Aug 2019 03:32:38 +0000 (03:32 +0000)
 - 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

gcc/ChangeLog
gcc/config/riscv/riscv.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c [new file with mode: 0644]

index 4235f73f16f771d8451732692b52332e458a85c7..2de2e652357bcfb15e16a29d953e7fb60fc8c72c 100644 (file)
@@ -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
index e274f1bd10feffcafa56c4d136004f7787261ce7..431e90a89572fa1edeee2548b2abc0e7c37c8766 100644 (file)
@@ -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
index 8f58e185efed7565af94d5425c602316a0bde298..8fe569ac17686681d244585783ac98471dc35c2f 100644 (file)
@@ -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 (file)
index 0000000..bdbcbc0
--- /dev/null
@@ -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;
+}