This fixes a problem with vec_add/sub_u128 builtins.  The
s390_expand_builtin backend function is supposed to convert the
operand to TImode *AND* load it into a vector register.  The current
implementation did only the conversion and gave up then.

Will be applied to GCC 8 branch after a while.

gcc/ChangeLog:

2019-03-11  Andreas Krebbel  <kreb...@linux.ibm.com>

        * config/s390/s390.c (s390_expand_builtin): Do the copy_to_reg not
        only on the else branch.

gcc/testsuite/ChangeLog:

2019-03-11  Andreas Krebbel  <kreb...@linux.ibm.com>

        * gcc.target/s390/zvector/vec-addc-u128.c: New test.
---
 gcc/config/s390/s390.c                                | 14 ++++++++++----
 gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c | 10 ++++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index fce463f..b80d5e8 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -928,6 +928,8 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget 
ATTRIBUTE_UNUSED,
          continue;
        }
 
+      /* A memory operand is rejected by the memory_operand predicate.
+        Try making the address legal by copying it into a register.  */
       if (MEM_P (op[arity])
          && insn_op->predicate == memory_operand
          && (GET_MODE (XEXP (op[arity], 0)) == Pmode
@@ -951,10 +953,14 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget 
ATTRIBUTE_UNUSED,
        {
          op[arity] = tmp_rtx;
        }
-      else if (GET_MODE (op[arity]) == insn_op->mode
-              || GET_MODE (op[arity]) == VOIDmode
-              || (insn_op->predicate == address_operand
-                  && GET_MODE (op[arity]) == Pmode))
+
+      /* The predicate rejects the operand although the mode is fine.
+        Copy the operand to register.  */
+      if (!insn_op->predicate (op[arity], insn_op->mode)
+         && (GET_MODE (op[arity]) == insn_op->mode
+             || GET_MODE (op[arity]) == VOIDmode
+             || (insn_op->predicate == address_operand
+                 && GET_MODE (op[arity]) == Pmode)))
        {
          /* An address_operand usually has VOIDmode in the expander
             so we cannot use this.  */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c 
b/gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c
new file mode 100644
index 0000000..3ab0c71
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector 
-fno-asynchronous-unwind-tables" } */
+
+#include <vecintrin.h>
+
+vector unsigned char test(void)
+{
+   vector unsigned char a = { 0 };
+   return __builtin_s390_vec_addc_u128 (a, a);
+}
-- 
2.7.4

Reply via email to