[GCC] PR target/86487: fix the way 'uses_hard_regs_p' handles paradoxical

subregs

gcc/ChangeLog:
2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>

	PR target/86487
	* lra-constraints.c(uses_hard_regs_p): Fix handling of
	paradoxical SUBREGS.

gcc/testsuite/ChangeLog:
2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>

	PR target/86487
	* gcc.target/arm/pr86487.c: New.

From-SVN: r269039
This commit is contained in:
Andre Vieira 2019-02-20 14:11:43 +00:00 committed by Andre Vieira
parent c9ea5b639b
commit 145d4e1a4e
4 changed files with 34 additions and 3 deletions

View file

@ -1,3 +1,9 @@
2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
PR target/86487
* lra-constraints.c(uses_hard_regs_p): Fix handling of
paradoxical SUBREGS.
2019-02-20 Li Jia He <helijia@linux.ibm.com>
PR target/88100

View file

@ -1770,14 +1770,24 @@ uses_hard_regs_p (rtx x, HARD_REG_SET set)
return false;
code = GET_CODE (x);
mode = GET_MODE (x);
if (code == SUBREG)
{
/* For all SUBREGs we want to check whether the full multi-register
overlaps the set. For normal SUBREGs this means 'get_hard_regno' of
the inner register, for paradoxical SUBREGs this means the
'get_hard_regno' of the full SUBREG and for complete SUBREGs either is
fine. Use the wider mode for all cases. */
rtx subreg = SUBREG_REG (x);
mode = wider_subreg_mode (x);
x = SUBREG_REG (x);
code = GET_CODE (x);
if (mode == GET_MODE (subreg))
{
x = subreg;
code = GET_CODE (x);
}
}
if (REG_P (x))
if (REG_P (x) || SUBREG_P (x))
{
x_hard_regno = get_hard_regno (x, true);
return (x_hard_regno >= 0

View file

@ -1,3 +1,8 @@
2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
PR target/86487
* gcc.target/arm/pr86487.c: New.
2019-02-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84536

View file

@ -0,0 +1,10 @@
/* { dg-skip-if "" { *-*-* } { "-march=armv[0-6]*" "-mthumb" } { "" } } */
/* { dg-require-effective-target arm_neon_hw } */
/* { dg-options "-O1 -mbig-endian" } */
/* { dg-add-options arm_neon } */
int a, b, c, d;
long long fn1(long long p2) { return p2 == 0 ? -1 : -1 % p2; }
void fn2(long long p1, short p2, long p3) {
b = fn1((d || 6) & a);
c = b | p3;
}