[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
This commit is contained in:
Kyrylo Tkachov 2018-03-08 15:50:25 +00:00 committed by Kyrylo Tkachov
parent 24545562ca
commit c8574943c1
4 changed files with 47 additions and 1 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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;
}