[Committed] Fix PR96127

Message ID 20200717082706.14734-1-krebbel@linux.ibm.com
State New
Headers show
Series
  • [Committed] Fix PR96127
Related show

Commit Message

Jonathan Wakely via Gcc-patches July 17, 2020, 8:27 a.m.
In s390_expand_insv the movstrict patterns are always generated with a
CC clobber although only movstricthi actually needs one.  The patch
invokes the expanders instead of constructing the pattern by hand.

Bootstrapped and regression tested on s390x.

Committed to mainline

gcc/ChangeLog:

	PR target/96127
	* config/s390/s390.c (s390_expand_insv): Invoke the movstrict
	expanders to generate the pattern.
	* config/s390/s390.md ("*movstricthi", "*movstrictqi"): Remove the
	'*' to have callable expanders.

gcc/testsuite/ChangeLog:

	PR target/96127
	* gcc.target/s390/pr96127.c: New test.
---
 gcc/config/s390/s390.c                  | 15 ++++++++-----
 gcc/config/s390/s390.md                 |  4 ++--
 gcc/testsuite/gcc.target/s390/pr96127.c | 29 +++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/pr96127.c

-- 
2.17.1

Patch

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index bd49a897c76..22ac5e43121 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6436,11 +6436,16 @@  s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
       /* Emit a strict_low_part pattern if possible.  */
       if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
 	{
-	  op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest));
-	  op = gen_rtx_SET (op, gen_lowpart (smode, src));
-	  clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
-	  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
-	  return true;
+	  rtx low_dest = gen_lowpart (smode, dest);
+	  rtx low_src = gen_lowpart (smode, src);
+
+	  switch (smode)
+	    {
+	    case E_QImode: emit_insn (gen_movstrictqi (low_dest, low_src)); return true;
+	    case E_HImode: emit_insn (gen_movstricthi (low_dest, low_src)); return true;
+	    case E_SImode: emit_insn (gen_movstrictsi (low_dest, low_src)); return true;
+	    default: break;
+	    }
 	}
 
       /* ??? There are more powerful versions of ICM that are not
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index cd1c0634b71..4c3e5400a2b 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -2413,7 +2413,7 @@ 
 ; movstrictqi instruction pattern(s).
 ;
 
-(define_insn "*movstrictqi"
+(define_insn "movstrictqi"
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
                          (match_operand:QI 1 "memory_operand" "R,T"))]
   ""
@@ -2428,7 +2428,7 @@ 
 ; movstricthi instruction pattern(s).
 ;
 
-(define_insn "*movstricthi"
+(define_insn "movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
                          (match_operand:HI 1 "memory_operand" "Q,S"))
    (clobber (reg:CC CC_REGNUM))]
diff --git a/gcc/testsuite/gcc.target/s390/pr96127.c b/gcc/testsuite/gcc.target/s390/pr96127.c
new file mode 100644
index 00000000000..213ed147175
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr96127.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-loop-im --param=sccvn-max-alias-queries-per-access=0 -w" } */
+
+int a8;
+
+void
+c1 (int oz, int dk, int ub)
+{
+  int *hd = 0;
+  long int *th = &dk;
+
+  while (ub < 1)
+    {
+      oz || dk;
+      ++ub;
+    }
+
+  while (oz < 2)
+    {
+      long int *lq = &oz;
+
+      (*hd < (*lq = *th)) < oz;
+
+      if (oz == 0)
+        *th = a8 = oz;
+
+      *lq = 0;
+    }
+}