diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2021-03-30 15:43:36 +0100 |
---|---|---|
committer | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2021-03-30 15:43:36 +0100 |
commit | 19199a6f2b0f4ce4b100856c78706d56a16b1956 (patch) | |
tree | f2d8b40b2c33cc40cd67c9bac772184ed94315b5 /gcc | |
parent | f64b91568f3ac8f152c6c617b4fcc6b51da10ac4 (diff) | |
download | gcc-19199a6f2b0f4ce4b100856c78706d56a16b1956.zip gcc-19199a6f2b0f4ce4b100856c78706d56a16b1956.tar.gz gcc-19199a6f2b0f4ce4b100856c78706d56a16b1956.tar.bz2 |
aarch64: PR target/99822 Don't allow zero register in first operand of SUBS/ADDS-immediate
In this PR we end up generating an invalid instruction:
adds x1,xzr,#2
because the pattern accepts zero as an operand in the comparison, but the instruction doesn't.
Fix it by adjusting the predicate and constraints.
gcc/ChangeLog:
PR target/99822
* config/aarch64/aarch64.md (sub<mode>3_compare1_imm): Do not allow zero
in operand 1.
gcc/testsuite/ChangeLog:
PR target/99822
* gcc.c-torture/compile/pr99822.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr99822.c | 41 |
2 files changed, 42 insertions, 1 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index a398c3d..b139c08 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3034,7 +3034,7 @@ (define_insn "sub<mode>3_compare1_imm" [(set (reg:CC CC_REGNUM) (compare:CC - (match_operand:GPI 1 "aarch64_reg_or_zero" "rkZ,rkZ") + (match_operand:GPI 1 "register_operand" "rk,rk") (match_operand:GPI 2 "aarch64_plus_immediate" "I,J"))) (set (match_operand:GPI 0 "register_operand" "=r,r") (plus:GPI diff --git a/gcc/testsuite/gcc.c-torture/compile/pr99822.c b/gcc/testsuite/gcc.c-torture/compile/pr99822.c new file mode 100644 index 0000000..0660784 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr99822.c @@ -0,0 +1,41 @@ +/* PR target/99822 */ +/* { dg-do assemble } */ +/* { dg-require-effective-target int128 } */ + +int zt, bm, p5 = 1; + +void __attribute__ ((cold)) +l2 (unsigned long int hz) +{ + __int128 d9 = 0; + unsigned long int *mg = hz ? &hz : (unsigned long int *) &d9; + + while (d9 < 1) + { + bm = bm > d9; + bm = bm == (d9 = bm || hz); + + hz = 0x197000000; + d9 = hz * hz; + + while (p5 < 1) + { + bm = ((hz = 3) ? zt : 0) > 0x1001; + if (bm != 0) + { + __int128 *nd = (__int128 *) bm; + + *nd /= 3; + } + + *mg = 0x1001; + p5 -= *mg; + } + + for (zt = 0; zt >= 0; zt += 2) + d9 = 0; + + d9 += 2; + } +} + |