Commit d0b51297 by Jackson Woodruff Committed by Kyrylo Tkachov

[AArch64] Improve LDP/STP generation that requires a base register

This patch generalizes the formation of LDP/STP that require a base register.

In AArch64, LDP/STP instructions have different sized immediate offsets than
normal LDR/STR instructions. This part of the backend attempts to spot groups
of four LDR/STR instructions that can be turned into LDP/STP instructions by
using a base register.

Previously, we would only accept address pairs that were ordered in ascending
or descending order, and only strictly sequential loads/stores. In fact, the
instructions that we generate from this should be able to consider any order
of loads or stores (provided that they can be re-ordered). They should also be
able to accept non-sequential loads and stores provided that the two pairs of
addresses are amenable to pairing. The current code is also overly restrictive
on the range of addresses that are accepted, as LDP/STP instructions may take
negative offsets as well as positive ones.

This patch improves that by allowing us to accept all orders of loads/stores
that are valid, and extending the range that the LDP/STP addresses can reach. 

2017-05-30  Jackson Woodruff  <jackson.woodruff@arm.com>

	* config/aarch64/aarch64.c (aarch64_host_wide_int_compare): New.
	(aarch64_ldrstr_offset_compare): New.
	(aarch64_operands_adjust_ok_for_ldpstp): Update to consider all
	load/store orderings.
	(aarch64_gen_adjusted_ldpstp): Likewise.

	* gcc.target/aarch64/simd/ldp_stp_9: New.
	* gcc.target/aarch64/simd/ldp_stp_10: New.
	* gcc.target/aarch64/simd/ldp_stp_11: New.
	* gcc.target/aarch64/simd/ldp_stp_12: New.

From-SVN: r260952
parent 2eb2847e
2017-05-30 Jackson Woodruff <jackson.woodruff@arm.com>
* config/aarch64/aarch64.c (aarch64_host_wide_int_compare): New.
(aarch64_ldrstr_offset_compare): New.
(aarch64_operands_adjust_ok_for_ldpstp): Update to consider all
load/store orderings.
(aarch64_gen_adjusted_ldpstp): Likewise.
2018-05-30 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.c (aarch64_ira_change_pseudo_allocno_class):
......
2017-05-30 Jackson Woodruff <jackson.woodruff@arm.com>
* gcc.target/aarch64/simd/ldp_stp_9: New.
* gcc.target/aarch64/simd/ldp_stp_10: New.
* gcc.target/aarch64/simd/ldp_stp_11: New.
* gcc.target/aarch64/simd/ldp_stp_12: New.
2018-05-30 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/tls1.adb, gnat.dg/tls1_pkg.ads: New testcase.
......
/* { dg-options "-O2" } */
int
load (int *arr)
{
return arr[527] << 1 + arr[400] << 1 + arr[401] << 1 + arr[528] << 1;
}
/* { dg-final { scan-assembler-times "ldp\tw\[0-9\]+, w\[0-9\]+, " 2 } } */
float
load_float (float *arr)
{
return arr[404] + arr[403] + arr[400] + arr[401];
}
/* { dg-final { scan-assembler-times "ldp\ts\[0-9\]+, s\[0-9\]+, " 2 } } */
long long
load_long (long long int *arr)
{
return arr[400] << 1 + arr[401] << 1 + arr[403] << 1 + arr[404] << 1;
}
/* { dg-final { scan-assembler-times "ldp\tx\[0-9\]+, x\[0-9\]+, " 2 } } */
double
load_double (double *arr)
{
return arr[200] + arr[201] + arr[263] + arr[264];
}
/* { dg-final { scan-assembler-times "ldp\td\[0-9\]+, d\[0-9\]+, " 2 } } */
/* { dg-options "-O2" } */
double
load_one (double *in)
{
return in[400] + in[401] + in[527] + in[528];
}
double
load_two (double *in)
{
return in[400] + in[401] + in[464] + in[465];
}
/* This is expected to fail due to PR 82214. */
/* { dg-final { scan-assembler-times "stp\td\[0-9\]+, d\[0-9\]+," 4 { xfail *-*-* } } } */
/* { dg-options "-O2" } */
void
store_offset (int *array, int x, int y)
{
array[1085] = x;
array[1084] = y;
array[1086] = y;
array[1087] = 5;
}
/* { dg-final { scan-assembler-times "stp\tw\[0-9\]+, w\[0-9\]+, " 2 } } */
/* { dg-options "-O2" } */
void
store (int *arr, int x, int y, int z)
{
arr[400] = x;
arr[401] = y;
arr[500] = z;
arr[501] = x;
}
/* { dg-final { scan-assembler-times "stp\tw\[0-9\]+, w\[0-9\]+, " 2 } } */
void
store_float (float *arr, float x, float y)
{
arr[404] = x;
arr[403] = y;
arr[400] = x;
arr[401] = y;
}
/* { dg-final { scan-assembler-times "stp\ts\[0-9\]+, s\[0-9\]+, " 2 } } */
void
store_long (long long int *arr, long long int x, long long int y)
{
arr[400] = x;
arr[401] = y;
arr[403] = y;
arr[404] = x;
}
/* { dg-final { scan-assembler-times "stp\tx\[0-9\]+, x\[0-9\]+, " 2 } } */
void
store_double (double *arr, double x, double y)
{
arr[200] = x;
arr[201] = y;
arr[263] = y;
arr[264] = x;
}
/* { dg-final { scan-assembler-times "stp\td\[0-9\]+, d\[0-9\]+, " 2 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment