Patchwork [1/n] Fix PR50444, handle unaligned VIEW_CONVERT_EXPRs during expansion

login
register
mail settings
Submitter Richard Guenther
Date Jan. 23, 2012, 12:04 p.m.
Message ID <alpine.LNX.2.00.1201231301410.4999@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/137350/
State New
Headers show

Comments

Richard Guenther - Jan. 23, 2012, 12:04 p.m.
The VIEW_CONVERT_EXPR expansion path fails to handle the case where
we promote alignment for !STRICT_ALIGNMENT targets but for modes
that are supposed to be handled by movmisalign.

This is exposed in gcc.dg/torture/pr45678-2.c on i?86 when
you apply the candidate patch for PR50444 in comment #15.

I'm now bootstrapping and regtesting this as a prerequesite.

Richard.

2012-01-23  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50444
	* expr.c (expand_expr_real_1): Properly expand VIEW_CONVERT_EXPR
	to an aligned mode from unaligned memory using movmisalign.
Richard Guenther - Jan. 23, 2012, 3:05 p.m.
On Mon, 23 Jan 2012, Richard Guenther wrote:

> 
> The VIEW_CONVERT_EXPR expansion path fails to handle the case where
> we promote alignment for !STRICT_ALIGNMENT targets but for modes
> that are supposed to be handled by movmisalign.
> 
> This is exposed in gcc.dg/torture/pr45678-2.c on i?86 when
> you apply the candidate patch for PR50444 in comment #15.
> 
> I'm now bootstrapping and regtesting this as a prerequesite.

Actually I discovered that Jakub fixed this on the 4.4 and 4.5
branches but left 4.6 unfixed ... thus I'm re-testing

2012-01-23  Richard Guenther  <rguenther@suse.de>

	Forward-port to trunk
	2010-09-21  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/45678
	* expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: If
	op0 isn't sufficiently aligned and there is movmisalignM
	insn for mode, use it to load op0 into a temporary register.

Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 183423)
--- gcc/expr.c	(working copy)
*************** expand_expr_real_1 (tree exp, rtx target
*** 10044,10053 ****
--- 10044,10075 ----
  	 results.  */
        if (MEM_P (op0))
  	{
+ 	  enum insn_code icode;
+ 
  	  op0 = copy_rtx (op0);
  
  	  if (TYPE_ALIGN_OK (type))
  	    set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+ 	  else if (mode != BLKmode
+ 		   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
+ 		   /* If the target does have special handling for unaligned
+ 		      loads of mode then use them.  */
+ 		   && ((icode = optab_handler (movmisalign_optab, mode))
+ 		       != CODE_FOR_nothing))
+ 	    {
+ 	      rtx reg, insn;
+ 
+ 	      op0 = adjust_address (op0, mode, 0);
+ 	      /* We've already validated the memory, and we're creating a
+ 		 new pseudo destination.  The predicates really can't
+ 		 fail.  */
+ 	      reg = gen_reg_rtx (mode);
+ 
+ 	      /* Nor can the insn generator.  */
+ 	      insn = GEN_FCN (icode) (reg, op0);
+ 	      emit_insn (insn);
+ 	      return reg;
+ 	    }
  	  else if (STRICT_ALIGNMENT
  		   && mode != BLKmode
  		   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))

Patch

Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 183423)
+++ gcc/expr.c	(working copy)
@@ -10044,10 +10044,24 @@  expand_expr_real_1 (tree exp, rtx target
 	 results.  */
       if (MEM_P (op0))
 	{
+	  enum insn_code icode;
+
 	  op0 = copy_rtx (op0);
 
 	  if (TYPE_ALIGN_OK (type))
 	    set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+	  else if (mode != BLKmode
+		   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
+		   && ((icode = optab_handler (movmisalign_optab, mode))
+		       != CODE_FOR_nothing))
+	    {
+	      struct expand_operand ops[2];
+	      PUT_MODE (op0, mode);
+	      create_output_operand (&ops[0], NULL_RTX, mode);
+	      create_fixed_operand (&ops[1], op0);
+	      expand_insn (icode, 2, ops);
+	      return ops[0].value;
+	    }
 	  else if (STRICT_ALIGNMENT
 		   && mode != BLKmode
 		   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))