diff mbox

[PR67766] reorder return value copying from PARALLELs and CONCATs (was: Re: [PR64164] drop copyrename, integrate into expand)

Message ID orsi5k7gde.fsf_-_@livre.home
State New
Headers show

Commit Message

Alexandre Oliva Oct. 9, 2015, 5:36 a.m. UTC
This fixes fallout from the PR64164 expander revamp.  On alpha, PARALLEL
hard return values may be modeless, and this confuses the code that
wants to copy the pseudo/s in the returned value to the return hard
regs.

It used to work because PARALLELs and CONCATs used to lead to DECL_RTL
with the same mode, but now we try harder to create a pseudo or MEM with
a reasonable mode.

The solution was as simple as moving down the code that handled mode
differences, so that PARALLELs and CONCATs are handled as they should.
Since AFAICT they don't ever have to deal with mode promotion anyway, we
should be fine with this simple change, that Uroš kindly tested with an
alpha-linux-gnu regstrap.  I tested it myself on x86_64-linux-gnu and
i686-linux-gnu.

Ok to install?


[PR67766] reorder handling of parallels, concats and promoted values in return

From: Alexandre Oliva <aoliva@redhat.com>

for  gcc/ChangeLog

	PR middle-end/67766
	* function.c (expand_function_end): Move return value
	promotion past the handling of PARALLELs and CONCATs.
---
 gcc/function.c |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

Comments

Richard Biener Oct. 9, 2015, 9:36 a.m. UTC | #1
On Fri, Oct 9, 2015 at 7:36 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> This fixes fallout from the PR64164 expander revamp.  On alpha, PARALLEL
> hard return values may be modeless, and this confuses the code that
> wants to copy the pseudo/s in the returned value to the return hard
> regs.
>
> It used to work because PARALLELs and CONCATs used to lead to DECL_RTL
> with the same mode, but now we try harder to create a pseudo or MEM with
> a reasonable mode.
>
> The solution was as simple as moving down the code that handled mode
> differences, so that PARALLELs and CONCATs are handled as they should.
> Since AFAICT they don't ever have to deal with mode promotion anyway, we
> should be fine with this simple change, that Uroš kindly tested with an
> alpha-linux-gnu regstrap.  I tested it myself on x86_64-linux-gnu and
> i686-linux-gnu.
>
> Ok to install?

Ok.

Richard.

>
> [PR67766] reorder handling of parallels, concats and promoted values in return
>
> From: Alexandre Oliva <aoliva@redhat.com>
>
> for  gcc/ChangeLog
>
>         PR middle-end/67766
>         * function.c (expand_function_end): Move return value
>         promotion past the handling of PARALLELs and CONCATs.
> ---
>  gcc/function.c |   24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/function.c b/gcc/function.c
> index e76ba2b..d16d6d8 100644
> --- a/gcc/function.c
> +++ b/gcc/function.c
> @@ -5446,18 +5446,6 @@ expand_function_end (void)
>                               decl_rtl);
>               shift_return_value (GET_MODE (decl_rtl), true, real_decl_rtl);
>             }
> -         /* If a named return value dumped decl_return to memory, then
> -            we may need to re-do the PROMOTE_MODE signed/unsigned
> -            extension.  */
> -         else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
> -           {
> -             int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
> -             promote_function_mode (TREE_TYPE (decl_result),
> -                                    GET_MODE (decl_rtl), &unsignedp,
> -                                    TREE_TYPE (current_function_decl), 1);
> -
> -             convert_move (real_decl_rtl, decl_rtl, unsignedp);
> -           }
>           else if (GET_CODE (real_decl_rtl) == PARALLEL)
>             {
>               /* If expand_function_start has created a PARALLEL for decl_rtl,
> @@ -5488,6 +5476,18 @@ expand_function_end (void)
>               emit_move_insn (tmp, decl_rtl);
>               emit_move_insn (real_decl_rtl, tmp);
>             }
> +         /* If a named return value dumped decl_return to memory, then
> +            we may need to re-do the PROMOTE_MODE signed/unsigned
> +            extension.  */
> +         else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
> +           {
> +             int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
> +             promote_function_mode (TREE_TYPE (decl_result),
> +                                    GET_MODE (decl_rtl), &unsignedp,
> +                                    TREE_TYPE (current_function_decl), 1);
> +
> +             convert_move (real_decl_rtl, decl_rtl, unsignedp);
> +           }
>           else
>             emit_move_insn (real_decl_rtl, decl_rtl);
>         }
>
>
> --
> Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/   FSF Latin America board member
> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
diff mbox

Patch

diff --git a/gcc/function.c b/gcc/function.c
index e76ba2b..d16d6d8 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5446,18 +5446,6 @@  expand_function_end (void)
 			      decl_rtl);
 	      shift_return_value (GET_MODE (decl_rtl), true, real_decl_rtl);
 	    }
-	  /* If a named return value dumped decl_return to memory, then
-	     we may need to re-do the PROMOTE_MODE signed/unsigned
-	     extension.  */
-	  else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
-	    {
-	      int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
-	      promote_function_mode (TREE_TYPE (decl_result),
-				     GET_MODE (decl_rtl), &unsignedp,
-				     TREE_TYPE (current_function_decl), 1);
-
-	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
-	    }
 	  else if (GET_CODE (real_decl_rtl) == PARALLEL)
 	    {
 	      /* If expand_function_start has created a PARALLEL for decl_rtl,
@@ -5488,6 +5476,18 @@  expand_function_end (void)
 	      emit_move_insn (tmp, decl_rtl);
 	      emit_move_insn (real_decl_rtl, tmp);
 	    }
+	  /* If a named return value dumped decl_return to memory, then
+	     we may need to re-do the PROMOTE_MODE signed/unsigned
+	     extension.  */
+	  else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
+	    {
+	      int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
+	      promote_function_mode (TREE_TYPE (decl_result),
+				     GET_MODE (decl_rtl), &unsignedp,
+				     TREE_TYPE (current_function_decl), 1);
+
+	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
+	    }
 	  else
 	    emit_move_insn (real_decl_rtl, decl_rtl);
 	}