diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2018-03-08 15:50:25 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2018-03-08 15:50:25 +0000 |
commit | c8574943c1178b72c96c34eca2f2e684201260f4 (patch) | |
tree | 005276771a440d1d92a8b12943f3a1ea917fe037 /gcc | |
parent | 24545562ca5ece2615f8178ad6c6eb0be4fe6b3f (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr84748.c | 34 |
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; +} |