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
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;
+ }
+}
--
2.17.1