Patchwork [ARM] Fix handling of function arguments with excess alignment

login
register
mail settings
Submitter Richard Earnshaw
Date Aug. 8, 2013, 1:38 p.m.
Message ID <52039F53.3080008@arm.com>
Download mbox | patch
Permalink /patch/265732/
State New
Headers show

Comments

Richard Earnshaw - Aug. 8, 2013, 1:38 p.m.
PR target/56979 is a bug where a parameter to a function has an
alignment that is larger than its natural alignment.  In this case this
causes the mid-end to generate a mode for the argument that is
incompatible with the registers that are assigned for it.  We then end
up creating invalid RTL and subsequently abort when the pattern cannot
emit assembly code.

The fix is to decompose the assignment when this would happen in the
same way that we handle other block mode arguments and handle each piece
in turn.

	PR target/56979
	* arm.c (aapcs_vfp_allocate): Decompose the argument if the
	suggested mode for the assignment isn't compatible with the
	registers required.

Committed to trunk.

R.
Richard Earnshaw - Aug. 21, 2013, 4:25 p.m.
On 08/08/13 14:38, Richard Earnshaw wrote:
> PR target/56979 is a bug where a parameter to a function has an
> alignment that is larger than its natural alignment.  In this case this
> causes the mid-end to generate a mode for the argument that is
> incompatible with the registers that are assigned for it.  We then end
> up creating invalid RTL and subsequently abort when the pattern cannot
> emit assembly code.
> 
> The fix is to decompose the assignment when this would happen in the
> same way that we handle other block mode arguments and handle each piece
> in turn.
> 
> 	PR target/56979
> 	* arm.c (aapcs_vfp_allocate): Decompose the argument if the
> 	suggested mode for the assignment isn't compatible with the
> 	registers required.
> 
> Committed to trunk.
> 

And back-ported to the 4.7 and 4.8 branches.

Patch

--- arm.c	(revision 201547)
+++ arm.c	(local)
@@ -4544,7 +4544,9 @@  aapcs_vfp_allocate (CUMULATIVE_ARGS *pcu
     if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask)
       {
 	pcum->aapcs_vfp_reg_alloc = mask << regno;
-	if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
+	if (mode == BLKmode
+	    || (mode == TImode && !TARGET_NEON)
+	    || ! arm_hard_regno_mode_ok (FIRST_VFP_REGNUM + regno, mode))
 	  {
 	    int i;
 	    int rcount = pcum->aapcs_vfp_rcount;