Fix PR96127
authorAndreas Krebbel <krebbel@linux.ibm.com>
Fri, 17 Jul 2020 06:49:29 +0000 (08:49 +0200)
committerAndreas Krebbel <krebbel@linux.ibm.com>
Fri, 17 Jul 2020 07:26:49 +0000 (09:26 +0200)
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.

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
gcc/config/s390/s390.md
gcc/testsuite/gcc.target/s390/pr96127.c [new file with mode: 0644]

index bd49a897c76f2969e14ff97aa36eca4ddfb22f5e..22ac5e431214e23139272589eb1a212341cda878 100644 (file)
@@ -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
index cd1c0634b7149669da354f5f763cf48b862c93f4..4c3e5400a2be4b02bca8d0a7e3f73f849266d3b0 100644 (file)
 ; 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"))]
   ""
 ; 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 (file)
index 0000000..213ed14
--- /dev/null
@@ -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;
+    }
+}