From 80029561822fe4f010f72940527c4ee9ff8dbf56 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 17 Jul 2020 08:49:29 +0200 Subject: [PATCH] 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. --- 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.30.2