aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2021-03-30 15:43:36 +0100
committerKyrylo Tkachov <kyrylo.tkachov@arm.com>2021-03-30 15:43:36 +0100
commit19199a6f2b0f4ce4b100856c78706d56a16b1956 (patch)
treef2d8b40b2c33cc40cd67c9bac772184ed94315b5 /gcc
parentf64b91568f3ac8f152c6c617b4fcc6b51da10ac4 (diff)
downloadgcc-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.md2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr99822.c41
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;
+ }
+}
+