[Bug target/86014] [AArch64] missed LDP optimization

2018-08-02 Thread jcw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86014

--- Comment #2 from jcw at gcc dot gnu.org ---
Author: jcw
Date: Thu Aug  2 10:39:23 2018
New Revision: 263249

URL: https://gcc.gnu.org/viewcvs?rev=263249&root=gcc&view=rev
Log:
gcc/
2018-08-02  Jackson Woodruff  

PR target/86014
* config/aarch64/aarch64.c (aarch64_operands_adjust_ok_for_ldpstp):
No longer check last store for clobber of address register.


gcc/testsuite
2018-08-02  Jackson Woodruff  

PR target/86014
* gcc.target/aarch64/ldp_stp_13.c: New test.



Added:
trunk/gcc/testsuite/gcc.target/aarch64/ldp_stp_13.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/config/aarch64/aarch64.c
trunk/gcc/testsuite/ChangeLog

[Bug target/86014] [AArch64] missed LDP optimization

2018-08-02 Thread jcw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86014

jcw at gcc dot gnu.org changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||jcw at gcc dot gnu.org
 Resolution|--- |FIXED

--- Comment #3 from jcw at gcc dot gnu.org ---
Fixed by r263249.

[Bug target/82214] New: [AArch64] Incorrect checking of LDP/STP offsets in aarch64_print_operand

2017-09-14 Thread jcw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82214

Bug ID: 82214
   Summary: [AArch64] Incorrect checking of LDP/STP offsets in
aarch64_print_operand
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: jcw at gcc dot gnu.org
  Target Milestone: ---

Hi,

Currently, aarch64_print_operand calls aarch64_print_operand_address
(indirectly) when used on a memory address.

For LDP/STP memory operands, the behavior is incorrect.
`aarch64_print_operand_address` checks `aarch64_classify_address` to see
whether the passed address is valid and to determine some classification
information.

However, aarch64_print_operand does not have enough information to distinguish
between a LDP/STP operand and a LDR/STR operand. This means that in the call
the aarch64_classify_address, the address is treated as a (differently sized)
LDR/STR operand. In some cases, the LDP/STP operand is not within the range for
LDR/STR and results in an ICE.

An example of this case is with a negative offset for a 8 byte wide mode (such
as a double). The offset for LDR/STR can be 12 bits unsigned adjusted, or 9
bits signed unadjusted, and the 7 bits signed adjusted of LDP/STP has a wider
range than either of those in this case.

I suggest that we add another format type to aarch64_print_operand for LDP/STP
addresses that does the correct checking for LDP/STP memory addresses.

Note that if this patch has gone in:
https://gcc.gnu.org/ml/gcc-patches/2017-09/msg00873.html

Then it can be updated to not disallow negative offsets for double and long int
modes by changing (in aarch64_gen_adjusted_ldpstp):


/* The base offset is optimally half way between the two stp/ldp offsets. 
*/
   if (msize <= 4) 
 base_off = (off_val_1 + off_val_3) / 2;
   else
 /* However, due to issues with negative LDP/STP offset generation for
larger modes, for DF and DI modes (and any vector modes that have
since been added) we must not use negative addresses smaller than
9 signed unadjusted bits can store.  This provides the most range
in this case.  */
 base_off = off_val_1;

   /* Adjust the base so that it is aligned with the addresses but still
  optimal.  */
   if (base_off % msize != off_val_1 % msize)
 /* Fix the offset, bearing in mind we want to make it bigger not
smaller.  */
 base_off += (((base_off % msize) - (off_val_1 % msize)) + msize) % msize;
   else if (msize <= 4) 
 /* The negative range of LDP/STP is one larger than the positive range. 
*/
 base_off += msize;
to
   /* The base offset is optimally half way between the two stp/ldp offsets. 
*/
   base_off = (off_val_1 + off_val_3) / 2;

   /* Adjust the base so that it is aligned with the addresses but still
  optimal.  */
   if (base_off % msize != off_val_1 % msize)
 /* Fix the offset, bearing in mind we want to make it bigger not
smaller.  */
 base_off += (((base_off % msize) - (off_val_1 % msize)) + msize) % msize;
   else 
 /* The negative range of LDP/STP is one larger than the positive range. 
*/
 base_off += msize;


I expect this to fix test case `gcc.target/aarch64/ldp_stp_11.c`


To reproduce:

The bug is hidden on current trunk as we don't generate negative offset LDP/STP
instructions on AArch64. If the above patch is installed, it is again hidden by
the extra checks.

To reproduce, make sure my patch is installed, remove the checks from the code
as I indicated above. Then testcase `gcc.target/aarch64/ldp_stp_11` should ICE.

Jackson.