This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix BIT_FIELD_REF folding (PR middle-end/85195)


Hi!

On the following testcase because of the SCCVN limit we end up with a weird,
but valid, BIT_FIELD_REF - trying to extract V1TImode type out of a V1TImode
SSA_NAME, with 128 bits width and offset 0 (just SSA_NAME move would be
enough).  Not trying to address why we create it, rather fix how we handle
it.

The problem is that the BIT_FIELD_REF vector extraction is guarded with:
 (if (VECTOR_TYPE_P (TREE_TYPE (@0))
      && (types_match (type, TREE_TYPE (TREE_TYPE (@0)))
          || (VECTOR_TYPE_P (type)
              && types_match (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
and thus we must handle vector type as result, but assume incorrectly that
if count is 1, then we must be asking for an element and thus not vector
type.  For the first hunk we could do what we do in the second hunk, do
a VIEW_CONVERT_EXPR, but it seems cleaner to just fall through into the
count > 1 code which builds a CONSTRUCTOR.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-04-04  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/85195
	* match.pd (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2): If count == 1, only
	use elt value if type is not vector type, otherwise build CONSTRUCTOR.
	For n == const_k, use view_convert.

	* gcc.dg/pr85195.c: New test.

--- gcc/match.pd.jj	2018-03-28 21:15:00.000000000 +0200
+++ gcc/match.pd	2018-04-04 14:35:10.424127155 +0200
@@ -4648,7 +4648,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (if (multiple_p (idx, k, &elt) && multiple_p (n, k, &count))
        (if (CONSTRUCTOR_NELTS (ctor) == 0)
         { build_constructor (type, NULL); }
-	(if (count == 1)
+	(if (count == 1 && !VECTOR_TYPE_P (type))
 	 (if (elt < CONSTRUCTOR_NELTS (ctor))
 	  { CONSTRUCTOR_ELT (ctor, elt)->value; }
 	  { build_zero_cst (type); })
@@ -4668,7 +4668,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	(if (CONSTRUCTOR_NELTS (ctor) <= idx / const_k)
 	 { build_zero_cst (type); })
 	(if (n == const_k)
-	 { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; })
+	 (view_convert { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; }))
 	(BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; }
 		       @1 { bitsize_int ((idx % const_k) * width); })))))))))
 
--- gcc/testsuite/gcc.dg/pr85195.c.jj	2018-04-04 14:38:29.233235494 +0200
+++ gcc/testsuite/gcc.dg/pr85195.c	2018-04-04 14:38:14.696227566 +0200
@@ -0,0 +1,19 @@
+/* PR middle-end/85195 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-Wno-psabi -O -fno-tree-ccp --param=sccvn-max-scc-size=10" } */
+
+typedef __int128 V __attribute__ ((vector_size (16)));
+
+extern int bar (V);
+
+V v;
+int i;
+
+V
+foo (void)
+{
+  do
+    v *= bar (v & i);
+  while ((V){}[0]);
+  return v;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]