diff options
author | Andreas Krebbel <krebbel@linux.ibm.com> | 2020-07-17 08:49:29 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.ibm.com> | 2020-07-17 09:26:49 +0200 |
commit | 80029561822fe4f010f72940527c4ee9ff8dbf56 (patch) | |
tree | 00c6cb16c5cab3cae1cdb2514b7e6bcdb03b7359 | |
parent | 0757d3660c1c5a63d1e8fbc1350c3ba0bcbf9fdb (diff) | |
download | gcc-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.c | 15 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/pr96127.c | 29 |
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; + } +} |