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]

fix reduction with min/max


While looking at ia64 output for the recently added tests, I noticed
that we weren't emitting the code for MIN.  And that was because we
finished the reduction with MIN<val, 0>, which rightly got folded to
just plain 0.

For integer code, we could pick a min/max value from the type, but
I suspect that this would often result in unnecessary constant
loads.  I chose to just use the init_val that the user provided.

Something that ought to be looked at is that we're generating an
unnecessary operation here.  Something like

	t = { init_val, ... init_val };
	loop {
	  t = min<loop_val, t>
	}
	u = reduce_min<t>
	u = min<u, init_val>

I'm not planning to look at that; at present I'm content that the 
code isn't actively wrong.

Tested on ia64-linux.


r~


        * tree-vect-transform.c (get_initial_def_for_reduction): Use correct
        type for DEF and INIT_VAL.  Pretend MIN/MAX need epilogue adjustment.

        * gcc.dg/vect/vect-reduc-1.c: Adjust test to properly validate MIN.
        * gcc.dg/vect/vect-reduc-1char.c: Likewise.
        * gcc.dg/vect/vect-reduc-1short.c: Likewise.
        * gcc.dg/vect/vect-reduc-2.c: Likewise.
        * gcc.dg/vect/vect-reduc-2char.c: Likewise.
        * gcc.dg/vect/vect-reduc-2short.c: Likewise.

Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.32
diff -u -p -d -r2.32 tree-vect-transform.c
--- tree-vect-transform.c	28 Jun 2005 05:15:11 -0000	2.32
+++ tree-vect-transform.c	28 Jun 2005 07:26:46 -0000
@@ -727,8 +727,11 @@ get_initial_def_for_reduction (tree stmt
   switch (code)
   {
   case PLUS_EXPR:
-    def = INTEGRAL_TYPE_P (type) ? integer_zero_node :
-                                   build_real (type, dconst0);
+    if (INTEGRAL_TYPE_P (type))
+      def = build_int_cst (type, 0);
+    else
+      def = build_real (type, dconst0);
+
 #ifdef ADJUST_IN_EPILOG
     /* All the 'nunits' elements are set to 0. The final result will be
        adjusted by 'init_val' at the loop epilog.  */
@@ -746,7 +749,7 @@ get_initial_def_for_reduction (tree stmt
   case MAX_EXPR:
     def = init_val;
     nelements = nunits;
-    need_epilog_adjust = false;
+    need_epilog_adjust = true;
     break;
 
   default:
@@ -754,9 +757,7 @@ get_initial_def_for_reduction (tree stmt
   }
 
   for (i = nelements - 1; i >= 0; --i)
-    {
-      t = tree_cons (NULL_TREE, def, t);
-    }
+    t = tree_cons (NULL_TREE, def, t);
 
   if (nelements == nunits - 1)
     {
@@ -771,11 +772,15 @@ get_initial_def_for_reduction (tree stmt
   else
     vec = build_constructor (vectype, t);
     
-  if (need_epilog_adjust)
-    *scalar_def = init_val;
-  else
-    *scalar_def = INTEGRAL_TYPE_P (type) ? integer_zero_node
-                                           : build_real (type, dconst0);
+  if (!need_epilog_adjust)
+    {
+      if (INTEGRAL_TYPE_P (type))
+	init_val = build_int_cst (type, 0);
+      else
+	init_val = build_real (type, dconst0);
+    }
+  *scalar_def = init_val;
+
   return vect_init_vector (stmt, vec);
 }
 
Index: testsuite/gcc.dg/vect/vect-reduc-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-1.c,v
retrieving revision 1.5
diff -u -p -d -r1.5 vect-reduc-1.c
--- testsuite/gcc.dg/vect/vect-reduc-1.c	21 Jun 2005 09:01:58 -0000	1.5
+++ testsuite/gcc.dg/vect/vect-reduc-1.c	28 Jun 2005 07:27:01 -0000
@@ -8,14 +8,14 @@
 
 /* Test vectorization of reduction of unsigned-int.  */
 
-int main1 (unsigned int x, unsigned int max_result)
+void main1 (unsigned int x, unsigned int max_result, unsigned int min_result)
 {
   int i;
-  unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
-  unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  unsigned int ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  unsigned int uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   unsigned int udiff = 2;
   unsigned int umax = x;
-  unsigned int umin = 10;
+  unsigned int umin = x;
 
   /* Summation.  */
   for (i = 0; i < N; i++) {
@@ -37,18 +37,17 @@ int main1 (unsigned int x, unsigned int 
     abort ();
   if (umax != max_result)
     abort ();
-  if (umin != 0)
+  if (umin != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
+  return 0;
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail i?86-*-* x86_64-*-* } } } */
Index: testsuite/gcc.dg/vect/vect-reduc-1char.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-1char.c,v
retrieving revision 1.1
diff -u -p -d -r1.1 vect-reduc-1char.c
--- testsuite/gcc.dg/vect/vect-reduc-1char.c	21 Jun 2005 09:01:59 -0000	1.1
+++ testsuite/gcc.dg/vect/vect-reduc-1char.c	28 Jun 2005 07:27:01 -0000
@@ -6,14 +6,15 @@
 #define N 16
 #define DIFF 242
 
-int main1 (unsigned char x, unsigned char max_result)
+void
+main1 (unsigned char x, unsigned char max_result, unsigned char min_result)
 {
   int i;
-  unsigned char ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
-  unsigned char uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  unsigned char ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   unsigned char udiff = 2;
   unsigned char umax = x;
-  unsigned char umin = 10;
+  unsigned char umin = x;
 
   for (i = 0; i < N; i++) {
     udiff += (unsigned char)(ub[i] - uc[i]);
@@ -32,18 +33,16 @@ int main1 (unsigned char x, unsigned cha
     abort ();
   if (umax != max_result)
     abort ();
-  if (umin != 0)
+  if (umin != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
   return 0;
 }
 
Index: testsuite/gcc.dg/vect/vect-reduc-1short.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-1short.c,v
retrieving revision 1.2
diff -u -p -d -r1.2 vect-reduc-1short.c
--- testsuite/gcc.dg/vect/vect-reduc-1short.c	28 Jun 2005 06:16:57 -0000	1.2
+++ testsuite/gcc.dg/vect/vect-reduc-1short.c	28 Jun 2005 07:27:01 -0000
@@ -6,14 +6,15 @@
 #define N 16
 #define DIFF 242
 
-int main1 (unsigned short x, unsigned short max_result)
+void
+main1 (unsigned short x, unsigned short max_result, unsigned short min_result)
 {
   int i;
-  unsigned short ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
-  unsigned short uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  unsigned short ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  unsigned short uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   unsigned short  udiff = 2;
   unsigned short umax = x;
-  unsigned short umin = 10;
+  unsigned short umin = x;
 
   for (i = 0; i < N; i++) {
     udiff += (unsigned short)(ub[i] - uc[i]);
@@ -32,18 +33,16 @@ int main1 (unsigned short x, unsigned sh
     abort ();
   if (umax != max_result)
     abort ();
-  if (umin != 0)
+  if (umin != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
   return 0;
 }
 
Index: testsuite/gcc.dg/vect/vect-reduc-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-2.c,v
retrieving revision 1.5
diff -u -p -d -r1.5 vect-reduc-2.c
--- testsuite/gcc.dg/vect/vect-reduc-2.c	21 Jun 2005 09:01:59 -0000	1.5
+++ testsuite/gcc.dg/vect/vect-reduc-2.c	28 Jun 2005 07:27:01 -0000
@@ -8,14 +8,14 @@
 
 /* Test vectorization of reduction of signed-int.  */
 
-int main1 (int x, int max_result)
+void main1 (int x, int max_result, int min_result)
 {
   int i;
-  int b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
-  int c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  int b[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   int diff = 0;
   int max = x;
-  int min = 10;
+  int min = x;
 
   for (i = 0; i < N; i++) {
     diff += (b[i] - c[i]);
@@ -34,18 +34,16 @@ int main1 (int x, int max_result)
     abort ();
   if (max != max_result)
     abort ();
-  if (min != 0)
+  if (min != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
   return 0;
 }
 
Index: testsuite/gcc.dg/vect/vect-reduc-2char.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-2char.c,v
retrieving revision 1.2
diff -u -p -d -r1.2 vect-reduc-2char.c
--- testsuite/gcc.dg/vect/vect-reduc-2char.c	28 Jun 2005 06:16:57 -0000	1.2
+++ testsuite/gcc.dg/vect/vect-reduc-2char.c	28 Jun 2005 07:27:01 -0000
@@ -6,17 +6,17 @@
 #define N 16
 #define DIFF 121
 
-int main1 (char x, char max_result)
+void main1 (signed char x, signed char max_result, signed char min_result)
 {
   int i;
-  char b[N] = {0,2,3,6,8,10,12,14,16,18,20,22,24,26,28,30};
-  char c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  signed char b[N] = {1,2,3,6,8,10,12,14,16,18,20,22,24,26,28,30};
+  signed char c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   signed char diff = 2;
-  char max = x;
-  char min = 10;
+  signed char max = x;
+  signed char min = x;
 
   for (i = 0; i < N; i++) {
-    diff += (b[i] - c[i]);
+    diff += (signed char)(b[i] - c[i]);
   }
 
   for (i = 0; i < N; i++) {
@@ -32,19 +32,17 @@ int main1 (char x, char max_result)
     abort ();
   if (max != max_result)
     abort ();
-  if (min != 0)
+  if (min != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
-  return 0 ;
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
+  return 0;
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
Index: testsuite/gcc.dg/vect/vect-reduc-2short.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-reduc-2short.c,v
retrieving revision 1.1
diff -u -p -d -r1.1 vect-reduc-2short.c
--- testsuite/gcc.dg/vect/vect-reduc-2short.c	21 Jun 2005 09:01:59 -0000	1.1
+++ testsuite/gcc.dg/vect/vect-reduc-2short.c	28 Jun 2005 07:27:01 -0000
@@ -1,23 +1,22 @@
 /* { dg-require-effective-target vect_int } */
 
 #include <stdarg.h>
-#include <stdio.h>
 #include "tree-vect.h"
 
 #define N 16
 #define DIFF 242
 
-int main1 (short x, short max_result)
+void main1 (short x, short max_result, short min_result)
 {
   int i;
-  short b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
-  short c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  short b[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   short diff = 2;
   short max = x;
-  short min = 10;
+  short min = x;
 
   for (i = 0; i < N; i++) {
-    diff += (b[i] - c[i]);
+    diff += (short)(b[i] - c[i]);
   }
   for (i = 0; i < N; i++) {
     max = max < c[i] ? c[i] : max;
@@ -32,18 +31,16 @@ int main1 (short x, short max_result)
     abort ();
   if (max != max_result)
     abort ();
-  if (min != 0)
+  if (min != min_result)
     abort ();
-
-  return 0;
 }
 
 int main (void)
 { 
   check_vect ();
   
-  main1 (100, 100);
-  main1 (0, 15);
+  main1 (100, 100, 1);
+  main1 (0, 15, 0);
   return 0;
 }
 


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