diff mbox

[rs6000] Fix ICE for vec_ld and vec_st of array when compiled with g++

Message ID 91EC9DA4-2497-46BC-960D-0C20C050B244@linux.vnet.ibm.com
State New
Headers show

Commit Message

Bill Schmidt June 3, 2016, 4:41 p.m. UTC
Hi,

When changing vec_ld and vec_st to be expanded during parsing, I
missed a subtle case that happens only for C++.  If the base address
argument has an array type, this doesn’t get converted to a pointer.
For our purposes, we need the pointer, and it’s safe to make that
conversion, so this patch performs that adjustment.  I’ve added a
test to the C++ torture bucket to verify this now works.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions.  Is this ok for trunk, and eventual backport to the 6 branch?

Thanks,
Bill


[gcc]

2016-06-03  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* rs6000-c.c (c/c-tree.h): Add #include.
	(altivec_resolve_overloaded_builtin): Handle ARRAY_TYPE arguments
	in C++ when found in the base position of vec_ld or vec_st.

[gcc/testsuite]

2016-06-03  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* g++.dg/torture/ppc-ldst-array.C: New.

Comments

Segher Boessenkool June 3, 2016, 6:17 p.m. UTC | #1
On Fri, Jun 03, 2016 at 11:41:26AM -0500, Bill Schmidt wrote:
> When changing vec_ld and vec_st to be expanded during parsing, I
> missed a subtle case that happens only for C++.  If the base address
> argument has an array type, this doesn’t get converted to a pointer.
> For our purposes, we need the pointer, and it’s safe to make that
> conversion, so this patch performs that adjustment.  I’ve added a
> test to the C++ torture bucket to verify this now works.
> 
> Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> regressions.  Is this ok for trunk, and eventual backport to the 6 branch?

Okay.  A few questions about the testcase...


> +++ b/gcc/testsuite/g++.dg/torture/ppc-ldst-array.C
> @@ -0,0 +1,18 @@
> +/* { dg-do compile { target { powerpc64*-*-* } } } */
> +/* { dg-skip-if "do not override mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
> +/* { dg-options "-O0 -mcpu=power8" } */

It's torture, do you need to force -O0?  And the skip isn't necessary I think?


Segher
Bill Schmidt June 3, 2016, 6:21 p.m. UTC | #2
You’re right, I don’t need the -O0.  I’d like to leave the dg-skip-if in place because I’m worried about older processors not defining altivec, etc.

Thanks!

Bill

> On Jun 3, 2016, at 1:17 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> 
> On Fri, Jun 03, 2016 at 11:41:26AM -0500, Bill Schmidt wrote:
>> When changing vec_ld and vec_st to be expanded during parsing, I
>> missed a subtle case that happens only for C++.  If the base address
>> argument has an array type, this doesn’t get converted to a pointer.
>> For our purposes, we need the pointer, and it’s safe to make that
>> conversion, so this patch performs that adjustment.  I’ve added a
>> test to the C++ torture bucket to verify this now works.
>> 
>> Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
>> regressions.  Is this ok for trunk, and eventual backport to the 6 branch?
> 
> Okay.  A few questions about the testcase...
> 
> 
>> +++ b/gcc/testsuite/g++.dg/torture/ppc-ldst-array.C
>> @@ -0,0 +1,18 @@
>> +/* { dg-do compile { target { powerpc64*-*-* } } } */
>> +/* { dg-skip-if "do not override mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
>> +/* { dg-options "-O0 -mcpu=power8" } */
> 
> It's torture, do you need to force -O0?  And the skip isn't necessary I think?
> 
> 
> Segher
>
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 79ac115..9e479a9 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -30,6 +30,7 @@ 
 #include "stor-layout.h"
 #include "c-family/c-pragma.h"
 #include "langhooks.h"
+#include "c/c-tree.h"
 
 
 
@@ -5203,6 +5204,14 @@  assignment for unaligned loads and stores");
 	    arg0 = build1 (NOP_EXPR, sizetype, arg0);
 
 	  tree arg1_type = TREE_TYPE (arg1);
+	  if (TREE_CODE (arg1_type) == ARRAY_TYPE)
+	    {
+	      arg1_type = TYPE_POINTER_TO (TREE_TYPE (arg1_type));
+	      tree const0 = build_int_cstu (sizetype, 0);
+	      tree arg1_elt0 = build_array_ref (loc, arg1, const0);
+	      arg1 = build1 (ADDR_EXPR, arg1_type, arg1_elt0);
+	    }
+
 	  tree addr = fold_build2_loc (loc, POINTER_PLUS_EXPR, arg1_type,
 				       arg1, arg0);
 	  tree aligned = fold_build2_loc (loc, BIT_AND_EXPR, arg1_type, addr,
@@ -5256,6 +5265,14 @@  assignment for unaligned loads and stores");
 	    arg1 = build1 (NOP_EXPR, sizetype, arg1);
 
 	  tree arg2_type = TREE_TYPE (arg2);
+	  if (TREE_CODE (arg2_type) == ARRAY_TYPE)
+	    {
+	      arg2_type = TYPE_POINTER_TO (TREE_TYPE (arg2_type));
+	      tree const0 = build_int_cstu (sizetype, 0);
+	      tree arg2_elt0 = build_array_ref (loc, arg2, const0);
+	      arg2 = build1 (ADDR_EXPR, arg2_type, arg2_elt0);
+	    }
+
 	  tree addr = fold_build2_loc (loc, POINTER_PLUS_EXPR, arg2_type,
 				       arg2, arg1);
 	  tree aligned = fold_build2_loc (loc, BIT_AND_EXPR, arg2_type, addr,
diff --git a/gcc/testsuite/g++.dg/torture/ppc-ldst-array.C b/gcc/testsuite/g++.dg/torture/ppc-ldst-array.C
new file mode 100644
index 0000000..9f7da6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/ppc-ldst-array.C
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc64*-*-* } } } */
+/* { dg-skip-if "do not override mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-O0 -mcpu=power8" } */
+
+/* When compiled with C++, this code was breaking because of different
+   tree representations of arrays between C and C++.  */
+
+#include <altivec.h>
+
+extern vector float vf;
+
+void foo ()
+{
+  float __attribute__((aligned (16))) x[4];
+  float __attribute__((aligned (16))) y[4];
+  vf = vec_ld (0, x);
+  vec_st (vf, 0, y);
+}