aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.ibm.com>2020-07-17 08:49:29 +0200
committerAndreas Krebbel <krebbel@linux.ibm.com>2020-07-17 09:26:49 +0200
commit80029561822fe4f010f72940527c4ee9ff8dbf56 (patch)
tree00c6cb16c5cab3cae1cdb2514b7e6bcdb03b7359
parent0757d3660c1c5a63d1e8fbc1350c3ba0bcbf9fdb (diff)
downloadgcc-80029561822fe4f010f72940527c4ee9ff8dbf56.zip
gcc-80029561822fe4f010f72940527c4ee9ff8dbf56.tar.gz
gcc-80029561822fe4f010f72940527c4ee9ff8dbf56.tar.bz2
Fix PR96127
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.
-rw-r--r--gcc/config/s390/s390.c15
-rw-r--r--gcc/config/s390/s390.md4
-rw-r--r--gcc/testsuite/gcc.target/s390/pr96127.c29
3 files changed, 41 insertions, 7 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index bd49a89..22ac5e4 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 cd1c063..4c3e540 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 0000000..213ed14
--- /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;
+ }
+}