aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2018-03-08 15:50:25 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2018-03-08 15:50:25 +0000
commitc8574943c1178b72c96c34eca2f2e684201260f4 (patch)
tree005276771a440d1d92a8b12943f3a1ea917fe037 /gcc
parent24545562ca5ece2615f8178ad6c6eb0be4fe6b3f (diff)
downloadgcc-c8574943c1178b72c96c34eca2f2e684201260f4.zip
gcc-c8574943c1178b72c96c34eca2f2e684201260f4.tar.gz
gcc-c8574943c1178b72c96c34eca2f2e684201260f4.tar.bz2
[AArch64] PR target/84748: Mark *compare_cstore<mode>_insn as clobbering CC reg
In this wrong-code PR the combine pass ends up moving a CC-using instruction past a *compare_cstore<mode>_insn insn_and_split. After reload the *compare_cstore<mode>_insn splitter ends up generating a SUBS instruction that clobbers the condition flags, and things go bad. The solution is simple, the *compare_cstore<mode>_insn pattern should specify that it clobbers the CC register so that combine (or any other pass) does not assume that it can move CC-using patterns across it. This patch does that and fixes the testcase. The testcase FAILs on GCC 8 only, but the buggy pattern is in GCC 6 onwards, so we should backport this as a latent bug fix after it's had some time to bake in trunk. Bootstrapped and tested on aarch64-none-linux-gnu. PR target/84748 * config/aarch64/aarch64.md (*compare_cstore<mode>_insn): Mark pattern as clobbering CC_REGNUM. * gcc.c-torture/execute/pr84748.c: New test. From-SVN: r258366
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.md3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr84748.c34
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d60c55..a467d7b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/84748
+ * config/aarch64/aarch64.md (*compare_cstore<mode>_insn): Mark pattern
+ as clobbering CC_REGNUM.
+
2018-03-08 Richard Biener <rguenther@suse.de>
PR middle-end/84552
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 5a2a930..5b879fa 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3242,7 +3242,8 @@
(define_insn_and_split "*compare_cstore<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
(EQL:GPI (match_operand:GPI 1 "register_operand" "r")
- (match_operand:GPI 2 "aarch64_imm24" "n")))]
+ (match_operand:GPI 2 "aarch64_imm24" "n")))
+ (clobber (reg:CC CC_REGNUM))]
"!aarch64_move_imm (INTVAL (operands[2]), <MODE>mode)
&& !aarch64_plus_operand (operands[2], <MODE>mode)
&& !reload_completed"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a5c31a..8b6d0e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/84748
+ * gcc.c-torture/execute/pr84748.c: New test.
+
2018-03-08 Richard Biener <rguenther@suse.de>
PR middle-end/84552
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr84748.c b/gcc/testsuite/gcc.c-torture/execute/pr84748.c
new file mode 100644
index 0000000..9572ab2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr84748.c
@@ -0,0 +1,34 @@
+/* { dg-require-effective-target int128 } */
+
+typedef unsigned __int128 u128;
+
+int a, c, d;
+u128 b;
+
+unsigned long long g0, g1;
+
+void
+store (unsigned long long a0, unsigned long long a1)
+{
+ g0 = a0;
+ g1 = a1;
+}
+
+void
+foo (void)
+{
+ b += a;
+ c = d != 84347;
+ b /= c;
+ u128 x = b;
+ store (x >> 0, x >> 64);
+}
+
+int
+main (void)
+{
+ foo ();
+ if (g0 != 0 || g1 != 0)
+ __builtin_abort ();
+ return 0;
+}