S/390: Fix immediate vector operands for some builtins.
authorAndreas Krebbel <krebbel@linux.ibm.com>
Mon, 11 Mar 2019 13:30:35 +0000 (13:30 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 11 Mar 2019 13:30:35 +0000 (13:30 +0000)
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.

gcc/ChangeLog:

2019-03-11  Andreas Krebbel  <krebbel@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  <krebbel@linux.ibm.com>

* gcc.target/s390/zvector/vec-addc-u128.c: New test.

From-SVN: r269583

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/zvector/vec-addc-u128.c [new file with mode: 0644]

index d4bfbec..83f5a83 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-11  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * config/s390/s390.c (s390_expand_builtin): Do the copy_to_reg not
+       only on the else branch.
+
 2019-03-11  Martin Liska  <mliska@suse.cz>
 
        * gcov.c (output_intermediate_json_line): Print function
index fce463f..b80d5e8 100644 (file)
@@ -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.  */
index e8d393a..5d09166 100644 (file)
@@ -1,3 +1,7 @@
+2019-03-11  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * gcc.target/s390/zvector/vec-addc-u128.c: New test.
+
 2019-03-11  Eric Botcazou  <ebotcazou@adacore.com>
 
        * c-c++-common/unroll-6.c: New test.
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 (file)
index 0000000..3ab0c71
--- /dev/null
@@ -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);
+}