public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] S/390: Simplify vector conditionals
@ 2015-12-15  9:53 Robin Dapp
  2015-12-17  9:51 ` Robin Dapp
  2015-12-18  9:55 ` Andreas Krebbel
  0 siblings, 2 replies; 4+ messages in thread
From: Robin Dapp @ 2015-12-15  9:53 UTC (permalink / raw)
  To: gcc-patches; +Cc: krebbel

[-- Attachment #1: Type: text/plain, Size: 739 bytes --]

Hi,

the attached patch simplifies vector conditional statements like
v < 0 ? -1 : 0 into v >> 31. The code is largely based on the x86
implementation of this feature by Jakub Jelinek. In future, (and if
useful for more backends) it could make sense to implement this directly
at tree-level.

Bootstrapped and regression-tested on s390.

Regards
 Robin

gcc/ChangeLog:

2015-12-15  Robin Dapp  <rdapp@linux.vnet.ibm.com>

        * config/s390/s390.c (s390_expand_vcond): Convert vector
        conditional into shift.
        * config/s390/vector.md: Change operand predicate.

gcc/testsuite/ChangeLog:

2015-12-15  Robin Dapp  <rdapp@linux.vnet.ibm.com>

        * gcc.target/s390/vcond-shift.c: New test to check vcond
	simplification.

[-- Attachment #2: gcc-vcond-shift.diff --]
[-- Type: text/x-patch, Size: 6427 bytes --]

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 67639bc..a72c9e1 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6108,19 +6108,60 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
   machine_mode result_mode;
   rtx result_target;
 
+  machine_mode target_mode = GET_MODE (target);
+  machine_mode cmp_mode = GET_MODE (cmp_op1);
+  rtx op = (cond == LT) ? els : then;
+
+  /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
+     and x < 0 ? 1 : 0 into (unsigned) x >> 31.  Likewise
+     for short and byte (x >> 15 and x >> 7 respectively).  */
+  if ((cond == LT || cond == GE)
+      && target_mode == cmp_mode
+      && cmp_op2 == CONST0_RTX (cmp_mode)
+      && op == CONST0_RTX (target_mode)
+      && s390_vector_mode_supported_p (target_mode)
+      && GET_MODE_CLASS (target_mode) == MODE_VECTOR_INT)
+    {
+      rtx negop = (cond == LT) ? then : els;
+
+      int shift = GET_MODE_BITSIZE (GET_MODE_INNER (target_mode)) - 1;
+
+      /* if x < 0 ? 1 : 0 or if x >= 0 ? 0 : 1 */
+      if (negop == CONST1_RTX (target_mode))
+	{
+	  rtx res = expand_simple_binop (cmp_mode, LSHIFTRT, cmp_op1,
+					 GEN_INT (shift), target,
+					 1, OPTAB_DIRECT);
+	  if (res != target)
+	    emit_move_insn (target, res);
+	  return;
+	}
+
+      /* if x < 0 ? -1 : 0 or if x >= 0 ? 0 : -1 */
+      else if (constm1_operand (negop, target_mode))
+	{
+	  rtx res = expand_simple_binop (cmp_mode, ASHIFTRT, cmp_op1,
+					 GEN_INT (shift), target,
+					 0, OPTAB_DIRECT);
+	  if (res != target)
+	    emit_move_insn (target, res);
+	  return;
+	}
+    }
+
   /* We always use an integral type vector to hold the comparison
      result.  */
-  result_mode = GET_MODE (cmp_op1) == V2DFmode ? V2DImode : GET_MODE (cmp_op1);
+  result_mode = cmp_mode == V2DFmode ? V2DImode : cmp_mode;
   result_target = gen_reg_rtx (result_mode);
 
-  /* Alternatively this could be done by reload by lowering the cmp*
-     predicates.  But it appears to be better for scheduling etc. to
-     have that in early.  */
+  /* We allow vector immediates as comparison operands that
+     can be handled by the optimization above but not by the
+     following code.  Hence, force them into registers here.  */
   if (!REG_P (cmp_op1))
-    cmp_op1 = force_reg (GET_MODE (target), cmp_op1);
+    cmp_op1 = force_reg (target_mode, cmp_op1);
 
   if (!REG_P (cmp_op2))
-    cmp_op2 = force_reg (GET_MODE (target), cmp_op2);
+    cmp_op2 = force_reg (target_mode, cmp_op2);
 
   s390_expand_vec_compare (result_target, cond,
 			   cmp_op1, cmp_op2);
@@ -6130,7 +6171,7 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
   if (constm1_operand (then, GET_MODE (then))
       && const0_operand (els, GET_MODE (els)))
     {
-      emit_move_insn (target, gen_rtx_SUBREG (GET_MODE (target),
+      emit_move_insn (target, gen_rtx_SUBREG (target_mode,
 					      result_target, 0));
       return;
     }
@@ -6139,10 +6180,10 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
   /* This gets triggered e.g.
      with gcc.c-torture/compile/pr53410-1.c */
   if (!REG_P (then))
-    then = force_reg (GET_MODE (target), then);
+    then = force_reg (target_mode, then);
 
   if (!REG_P (els))
-    els = force_reg (GET_MODE (target), els);
+    els = force_reg (target_mode, els);
 
   tmp = gen_rtx_fmt_ee (EQ, VOIDmode,
 			result_target,
@@ -6150,9 +6191,9 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
 
   /* We compared the result against zero above so we have to swap then
      and els here.  */
-  tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (target), tmp, els, then);
+  tmp = gen_rtx_IF_THEN_ELSE (target_mode, tmp, els, then);
 
-  gcc_assert (GET_MODE (target) == GET_MODE (then));
+  gcc_assert (target_mode == GET_MODE (then));
   emit_insn (gen_rtx_SET (target, tmp));
 }
 
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index c9f5890..f6a85c8 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -403,7 +403,7 @@
 	(if_then_else:V_HW
 	 (match_operator 3 "comparison_operator"
 			 [(match_operand:V_HW2 4 "register_operand" "")
-			  (match_operand:V_HW2 5 "register_operand" "")])
+			  (match_operand:V_HW2 5 "nonmemory_operand" "")])
 	 (match_operand:V_HW 1 "nonmemory_operand" "")
 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
@@ -418,7 +418,7 @@
 	(if_then_else:V_HW
 	 (match_operator 3 "comparison_operator"
 			 [(match_operand:V_HW2 4 "register_operand" "")
-			  (match_operand:V_HW2 5 "register_operand" "")])
+			  (match_operand:V_HW2 5 "nonmemory_operand" "")])
 	 (match_operand:V_HW 1 "nonmemory_operand" "")
 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
diff --git a/gcc/testsuite/gcc.target/s390/vcond-shift.c b/gcc/testsuite/gcc.target/s390/vcond-shift.c
new file mode 100644
index 0000000..f58bd1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vcond-shift.c
@@ -0,0 +1,61 @@
+/* Check if conditional vector instructions are simplified
+   into shift operations.  */
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -march=z13 -mzarch" } */
+
+/* { dg-final { scan-assembler "vesraf\t%v.?,%v.?,31" } } */
+/* { dg-final { scan-assembler "vesrah\t%v.?,%v.?,15" } } */
+/* { dg-final { scan-assembler "vesrab\t%v.?,%v.?,7" } } */
+/* { dg-final { scan-assembler-not "vzero\t*" } } */
+/* { dg-final { scan-assembler "vesrlf\t%v.?,%v.?,31" } } */
+/* { dg-final { scan-assembler "vesrlh\t%v.?,%v.?,15" } } */
+/* { dg-final { scan-assembler "vesrlb\t%v.?,%v.?,7" } } */
+
+#define SZ 4
+#define SZ2 8
+#define SZ3 16
+
+void foo(int *w)
+{
+  int i;
+  /* Should expand to (w + (w < 0 ? 1 : 0)) >> 1
+     which in turn should get simplified to (w + (w >> 31)) >> 1.  */
+  for (i = 0; i < SZ; i++)
+    w[i] = w[i] / 2;
+}
+
+void foo2(short *w)
+{
+  int i;
+  for (i = 0; i < SZ2; i++)
+    w[i] = w[i] / 2;
+}
+
+
+void foo3(signed char *w)
+{
+  int i;
+  for (i = 0; i < SZ3; i++)
+    w[i] = w[i] / 2;
+}
+
+int baz(int *x)
+{
+  int i;
+  for (i = 0; i < SZ; i++)
+    x[i] = x[i] < 0 ? -1 : 0;
+}
+
+int baf(short *x)
+{
+  int i;
+  for (i = 0; i < SZ2; i++)
+    x[i] = x[i] >= 0 ? 0 : 1;
+}
+
+int bal(signed char *x)
+{
+  int i;
+  for (i = 0; i < SZ3; i++)
+    x[i] = x[i] >= 0 ? 0 : -1;
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] S/390: Simplify vector conditionals
  2015-12-15  9:53 [Patch] S/390: Simplify vector conditionals Robin Dapp
@ 2015-12-17  9:51 ` Robin Dapp
  2015-12-18  9:55   ` Andreas Krebbel
  2015-12-18  9:55 ` Andreas Krebbel
  1 sibling, 1 reply; 4+ messages in thread
From: Robin Dapp @ 2015-12-17  9:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andreas Krebbel

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

Hi,

the attached patch renames the constm1_operand predicate to
all_ones_operand and introduces a check for int mode.
It should be applied on top of the last patch ([Patch] S/390: Simplify
vector conditionals).

Regtested on s390.

Regards
 Robin

gcc/ChangeLog:

2015-12-15 Robin Dapp <rdapp@linux.vnet.ibm.com>

	* config/s390/predicates.md: Change and rename
	constm1_operand to all_ones_operand
	* config/s390/s390.c (s390_expand_vcond): Use all_ones_operand
	* config/s390/vector.md: Likewise

[-- Attachment #2: gcc-constm1_operand.diff --]
[-- Type: text/x-patch, Size: 3983 bytes --]

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 5c462c4..02a1e4e 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -29,9 +29,10 @@
   (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
-;; Return true if OP an all ones operand (int/float/vector).
-(define_predicate "constm1_operand"
-  (and (match_code "const_int,const_wide_int,const_double,const_vector")
+;; Return true if OP an all ones operand (int/vector).
+(define_predicate "all_ones_operand"
+  (and (match_code "const_int, const_wide_int, const_vector")
+       (match_test "INTEGRAL_MODE_P (GET_MODE (op))")
        (match_test "op == CONSTM1_RTX (mode)")))
 
 ;; Return true if OP is a 4 bit mask operand
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 529b884..d58c243 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6169,7 +6169,7 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
 	}
 
       /* if x < 0 ? -1 : 0 or if x >= 0 ? 0 : -1 */
-      else if (constm1_operand (negop, target_mode))
+      else if (all_ones_operand (negop, target_mode))
 	{
 	  rtx res = expand_simple_binop (cmp_mode, ASHIFTRT, cmp_op1,
 					 GEN_INT (shift), target,
@@ -6199,7 +6199,7 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
 
   /* If the results are supposed to be either -1 or 0 we are done
      since this is what our compare instructions generate anyway.  */
-  if (constm1_operand (then, GET_MODE (then))
+  if (all_ones_operand (then, GET_MODE (then))
       && const0_operand (els, GET_MODE (els)))
     {
       emit_move_insn (target, gen_rtx_SUBREG (target_mode,
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index f6a85c8..cd9407a 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -1107,7 +1107,7 @@
 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
 	     (match_operand:V 4 "const0_operand" ""))
 	 (match_operand:V 1 "const0_operand" "")
-	 (match_operand:V 2 "constm1_operand" "")))]
+	 (match_operand:V 2 "all_ones_operand" "")))]
   "TARGET_VX"
   [(set (match_dup 0) (match_dup 3))]
 {
@@ -1120,7 +1120,7 @@
 	(if_then_else:V
 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
 	     (match_operand:V 4 "const0_operand" ""))
-	 (match_operand:V 1 "constm1_operand" "")
+	 (match_operand:V 1 "all_ones_operand" "")
 	 (match_operand:V 2 "const0_operand" "")))]
   "TARGET_VX"
   [(set (match_dup 0) (not:V (match_dup 3)))]
@@ -1134,7 +1134,7 @@
 	(if_then_else:V
 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
 	     (match_operand:V 4 "const0_operand" ""))
-	 (match_operand:V 1 "constm1_operand" "")
+	 (match_operand:V 1 "all_ones_operand" "")
 	 (match_operand:V 2 "const0_operand" "")))]
   "TARGET_VX"
   [(set (match_dup 0) (match_dup 3))]
@@ -1149,7 +1149,7 @@
 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
 	     (match_operand:V 4 "const0_operand" ""))
 	 (match_operand:V 1 "const0_operand" "")
-	 (match_operand:V 2 "constm1_operand" "")))]
+	 (match_operand:V 2 "all_ones_operand" "")))]
   "TARGET_VX"
   [(set (match_dup 0) (not:V (match_dup 3)))]
 {
@@ -1185,7 +1185,7 @@
   [(set (match_operand:V 0 "register_operand" "=v")
 	(if_then_else:V
 	 (eq (match_operand:<tointvec> 3 "register_operand" "v")
-	     (match_operand:<tointvec> 4 "constm1_operand" ""))
+	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
 	 (match_operand:V 1 "register_operand" "v")
 	 (match_operand:V 2 "register_operand" "v")))]
   "TARGET_VX"
@@ -1197,7 +1197,7 @@
   [(set (match_operand:V 0 "register_operand" "=v")
 	(if_then_else:V
 	 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
-	     (match_operand:<tointvec> 4 "constm1_operand" ""))
+	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
 	 (match_operand:V 1 "register_operand" "v")
 	 (match_operand:V 2 "register_operand" "v")))]
   "TARGET_VX"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] S/390: Simplify vector conditionals
  2015-12-17  9:51 ` Robin Dapp
@ 2015-12-18  9:55   ` Andreas Krebbel
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas Krebbel @ 2015-12-18  9:55 UTC (permalink / raw)
  To: Robin Dapp, gcc-patches

On 12/17/2015 10:51 AM, Robin Dapp wrote:

> 2015-12-15 Robin Dapp <rdapp@linux.vnet.ibm.com>
> 
> 	* config/s390/predicates.md: Change and rename
> 	constm1_operand to all_ones_operand
> 	* config/s390/s390.c (s390_expand_vcond): Use all_ones_operand
> 	* config/s390/vector.md: Likewise

Applied. Thanks!

-Andreas-


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] S/390: Simplify vector conditionals
  2015-12-15  9:53 [Patch] S/390: Simplify vector conditionals Robin Dapp
  2015-12-17  9:51 ` Robin Dapp
@ 2015-12-18  9:55 ` Andreas Krebbel
  1 sibling, 0 replies; 4+ messages in thread
From: Andreas Krebbel @ 2015-12-18  9:55 UTC (permalink / raw)
  To: Robin Dapp, gcc-patches

On 12/15/2015 10:53 AM, Robin Dapp wrote:
> gcc/ChangeLog:
> 
> 2015-12-15  Robin Dapp  <rdapp@linux.vnet.ibm.com>
> 
>         * config/s390/s390.c (s390_expand_vcond): Convert vector
>         conditional into shift.
>         * config/s390/vector.md: Change operand predicate.
> 
> gcc/testsuite/ChangeLog:
> 
> 2015-12-15  Robin Dapp  <rdapp@linux.vnet.ibm.com>
> 
>         * gcc.target/s390/vcond-shift.c: New test to check vcond
> 	simplification.

Applied. Thanks!

-Andreas-


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-12-18  9:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-15  9:53 [Patch] S/390: Simplify vector conditionals Robin Dapp
2015-12-17  9:51 ` Robin Dapp
2015-12-18  9:55   ` Andreas Krebbel
2015-12-18  9:55 ` Andreas Krebbel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).