diff mbox

[rs6000] Emit correct note for DWARF CFI information on LE prolog VSX stores

Message ID 1384659138.8213.175.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt Nov. 17, 2013, 3:32 a.m. UTC
Hi,

For VSX in little endian we currently split vector register stores into
a permute/store pair.  For prolog stores, this results in a
REG_FRAME_RELATED_EXPR note that doesn't have a simple register for its
RHS, which it needs to have.  This patch detects that situation and
ensures we produce the correct note.

This problem was breaking bootstrap when configured with
--with-cpu=power7, something we hadn't tried before.  With the patch we
now get past stage 1.  There is at least one wrong-code bug to track
down in stage 2, but modifying this note is clearly not involved with
that.

Otherwise bootstrapped and tested on powerpc64-unknown-linux-gnu with no
regressions on the big-endian side, also bootstrapped with
--with-cpu=power7.  Is this ok for trunk?

Thanks,
Bill


2011-11-16  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* config/rs6000/rs6000.c (rs6000_frame_related): Add split_reg
	parameter and use it in REG_FRAME_RELATED_EXPR note.
	(emit_frame_save): Call rs6000_frame_related with extra NULL_RTX
	parameter.
	(rs6000_emit_prologue): Likewise, but for little endian VSX
	stores, pass the source register of the store instead.

Comments

David Edelsohn Nov. 17, 2013, 12:55 p.m. UTC | #1
On Sat, Nov 16, 2013 at 10:32 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Hi,
>
> For VSX in little endian we currently split vector register stores into
> a permute/store pair.  For prolog stores, this results in a
> REG_FRAME_RELATED_EXPR note that doesn't have a simple register for its
> RHS, which it needs to have.  This patch detects that situation and
> ensures we produce the correct note.
>
> This problem was breaking bootstrap when configured with
> --with-cpu=power7, something we hadn't tried before.  With the patch we
> now get past stage 1.  There is at least one wrong-code bug to track
> down in stage 2, but modifying this note is clearly not involved with
> that.
>
> Otherwise bootstrapped and tested on powerpc64-unknown-linux-gnu with no
> regressions on the big-endian side, also bootstrapped with
> --with-cpu=power7.  Is this ok for trunk?
>
> Thanks,
> Bill
>
>
> 2011-11-16  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         * config/rs6000/rs6000.c (rs6000_frame_related): Add split_reg
>         parameter and use it in REG_FRAME_RELATED_EXPR note.
>         (emit_frame_save): Call rs6000_frame_related with extra NULL_RTX
>         parameter.
>         (rs6000_emit_prologue): Likewise, but for little endian VSX
>         stores, pass the source register of the store instead.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 204861)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -21439,7 +21439,7 @@  output_probe_stack_range (rtx reg1, rtx reg2)
 
 static rtx
 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
-		      rtx reg2, rtx rreg)
+		      rtx reg2, rtx rreg, rtx split_reg)
 {
   rtx real, temp;
 
@@ -21530,6 +21530,11 @@  rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE
 	  }
     }
 
+  /* If a store insn has been split into multiple insns, the
+     true source register is given by split_reg.  */
+  if (split_reg != NULL_RTX)
+    real = gen_rtx_SET (VOIDmode, SET_DEST (real), split_reg);
+
   RTX_FRAME_RELATED_P (insn) = 1;
   add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
 
@@ -21637,7 +21642,7 @@  emit_frame_save (rtx frame_reg, enum machine_mode
   reg = gen_rtx_REG (mode, regno);
   insn = emit_insn (gen_frame_store (reg, frame_reg, offset));
   return rs6000_frame_related (insn, frame_reg, frame_reg_to_sp,
-			       NULL_RTX, NULL_RTX);
+			       NULL_RTX, NULL_RTX, NULL_RTX);
 }
 
 /* Emit an offset memory reference suitable for a frame store, while
@@ -22217,7 +22222,7 @@  rs6000_emit_prologue (void)
 
       insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
       rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
-			    treg, GEN_INT (-info->total_size));
+			    treg, GEN_INT (-info->total_size), NULL_RTX);
       sp_off = frame_off = info->total_size;
     }
 
@@ -22302,7 +22307,7 @@  rs6000_emit_prologue (void)
 
 	  insn = emit_move_insn (mem, reg);
 	  rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
-				NULL_RTX, NULL_RTX);
+				NULL_RTX, NULL_RTX, NULL_RTX);
 	  END_USE (0);
 	}
     }
@@ -22358,7 +22363,7 @@  rs6000_emit_prologue (void)
 				     info->lr_save_offset,
 				     DFmode, sel);
       rs6000_frame_related (insn, ptr_reg, sp_off,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, NULL_RTX, NULL_RTX);
       if (lr)
 	END_USE (0);
     }
@@ -22437,7 +22442,7 @@  rs6000_emit_prologue (void)
 					 SAVRES_SAVE | SAVRES_GPR);
 
 	  rs6000_frame_related (insn, spe_save_area_ptr, sp_off - save_off,
-				NULL_RTX, NULL_RTX);
+				NULL_RTX, NULL_RTX, NULL_RTX);
 	}
 
       /* Move the static chain pointer back.  */
@@ -22487,7 +22492,7 @@  rs6000_emit_prologue (void)
 				     info->lr_save_offset + ptr_off,
 				     reg_mode, sel);
       rs6000_frame_related (insn, ptr_reg, sp_off - ptr_off,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, NULL_RTX, NULL_RTX);
       if (lr)
 	END_USE (0);
     }
@@ -22503,7 +22508,7 @@  rs6000_emit_prologue (void)
 			     info->gp_save_offset + frame_off + reg_size * i);
       insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
       rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, NULL_RTX, NULL_RTX);
     }
   else if (!WORLD_SAVE_P (info))
     {
@@ -22826,7 +22831,7 @@  rs6000_emit_prologue (void)
 				     info->altivec_save_offset + ptr_off,
 				     0, V4SImode, SAVRES_SAVE | SAVRES_VR);
       rs6000_frame_related (insn, scratch_reg, sp_off - ptr_off,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, NULL_RTX, NULL_RTX);
       if (REGNO (frame_reg_rtx) == REGNO (scratch_reg))
 	{
 	  /* The oddity mentioned above clobbered our frame reg.  */
@@ -22842,7 +22847,7 @@  rs6000_emit_prologue (void)
       for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
 	if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
 	  {
-	    rtx areg, savereg, mem;
+	    rtx areg, savereg, mem, split_reg;
 	    int offset;
 
 	    offset = (info->altivec_save_offset + frame_off
@@ -22860,8 +22865,18 @@  rs6000_emit_prologue (void)
 
 	    insn = emit_move_insn (mem, savereg);
 
+	    /* When we split a VSX store into two insns, we need to make
+	       sure the DWARF info knows which register we are storing.
+	       Pass it in to be used on the appropriate note.  */
+	    if (!BYTES_BIG_ENDIAN
+		&& GET_CODE (PATTERN (insn)) == SET
+		&& GET_CODE (SET_SRC (PATTERN (insn))) == VEC_SELECT)
+	      split_reg = savereg;
+	    else
+	      split_reg = NULL_RTX;
+
 	    rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
-				  areg, GEN_INT (offset));
+				  areg, GEN_INT (offset), split_reg);
 	  }
     }