From: Stefan Schulze Frielinghaus <[email protected]>

A difference in front ends is that in contrast to C the C++ FE does no
array-to-pointer conversion prior calling resolve_overloaded_builtin().
However, we depend on this for finding the proper overloaded builtin or
in case of direct expansion.  Therefore, do the conversion manually.

gcc/ChangeLog:

        * config/s390/s390-c.cc (s390_resolve_overloaded_builtin):
        Perform array-to-pointer conversion for C++.

gcc/testsuite/ChangeLog:

        * g++.target/s390/builtin-array-arg-1.C: New test.
        * gcc.target/s390/builtin-array-arg-1.c: New test.
---
 gcc/config/s390/s390-c.cc                     | 13 ++++++++
 .../g++.target/s390/builtin-array-arg-1.C     |  8 +++++
 .../gcc.target/s390/builtin-array-arg-1.c     | 33 +++++++++++++++++++
 3 files changed, 54 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/s390/builtin-array-arg-1.C
 create mode 100644 gcc/testsuite/gcc.target/s390/builtin-array-arg-1.c

diff --git a/gcc/config/s390/s390-c.cc b/gcc/config/s390/s390-c.cc
index a01c44c66ab..001bb2f4a0a 100644
--- a/gcc/config/s390/s390-c.cc
+++ b/gcc/config/s390/s390-c.cc
@@ -986,6 +986,19 @@ s390_resolve_overloaded_builtin (location_t loc, tree 
ob_fndecl,
     if ((*arglist)[i] == error_mark_node)
       return error_mark_node;
 
+  /* A difference in front ends is that in contrast to C the C++ FE does no
+     array-to-pointer conversion prior calling resolve_overloaded_builtin().
+     However, we depend on this for finding the proper overloaded builtin or in
+     case of direct expansion.  Therefore, do the conversion now.  */
+  if (c_dialect_cxx ())
+    for (i = 0; i < in_args_num; ++i)
+      {
+       tree t = (*arglist)[i];
+       if (TREE_CODE (t) == VIEW_CONVERT_EXPR
+           && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+         (*arglist)[i] = default_conversion (t);
+      }
+
   /* Overloaded builtins without any variants are directly expanded here.  */
   if (desc_start_for_overloaded_builtin[ob_fcode] ==
       S390_OVERLOADED_BUILTIN_VAR_MAX)
diff --git a/gcc/testsuite/g++.target/s390/builtin-array-arg-1.C 
b/gcc/testsuite/g++.target/s390/builtin-array-arg-1.C
new file mode 100644
index 00000000000..cbbcec79558
--- /dev/null
+++ b/gcc/testsuite/g++.target/s390/builtin-array-arg-1.C
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { scan-assembler-times 
{\tlarl\t(%r1),.LANCHOR0\n\tvllezf\t%v24,0\(\1\)\n\tbr\t%r14} 2 } } */
+/* { dg-final { scan-assembler-times 
{\tlarl\t(%r1),.LANCHOR0\n\tvl\t%v24,4\(\1\)\n\tbr\t%r14} 1 } } */
+
+/* Test C++ semantics w.r.t. array arguments.  */
+
+#include "../../gcc.target/s390/builtin-array-arg-1.c"
diff --git a/gcc/testsuite/gcc.target/s390/builtin-array-arg-1.c 
b/gcc/testsuite/gcc.target/s390/builtin-array-arg-1.c
new file mode 100644
index 00000000000..ee0e0742603
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/builtin-array-arg-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { scan-assembler-times 
{\tlarl\t(%r1),.LANCHOR0\n\tvllezf\t%v24,0\(\1\)\n\tbr\t%r14} 2 } } */
+/* { dg-final { scan-assembler-times 
{\tlarl\t(%r1),.LANCHOR0\n\tvl\t%v24,4\(\1\)\n\tbr\t%r14} 1 } } */
+
+/* Accept array arguments which are converted to pointers in the end.  */
+
+typedef unsigned int __attribute__ ((vector_size (16))) UV4SI;
+unsigned int a[42];
+
+/* Overloaded builtin.  */
+
+UV4SI
+test_vec_insert_and_zero (void)
+{
+  return __builtin_s390_vec_insert_and_zero (a);
+}
+
+/* Non-overloaded builtin.  */
+
+UV4SI
+test_vllezf (void)
+{
+  return __builtin_s390_vllezf (a);
+}
+
+/* Directly expanded overloaded builtin.  */
+
+UV4SI
+test_vec_xl (void)
+{
+  return __builtin_s390_vec_xl (4, a);
+}
-- 
2.52.0

Reply via email to