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