Hi Nathan!

Thanks for looking into this.  When I reported this,
<http://news.gmane.org/find-root.php?message_id=%3C87fv3is74z.fsf%40schwinge.name%3E>,
quite a lot of testcases had been failing -- with recent GCC trunk, the
number is smaller (because of other middle end/optimization changes, I
suppose).  Yet, the problem still can be observed; grep for "%retval" in
g++.log.

On Thu, 8 Oct 2015 13:33:55 -0400, Nathan Sidwell <nat...@acm.org> wrote:
> I've committed this to trunk.  The C++ ABI now returns a pointer to the 
> passed-in artificial arg that points to the return area.  consequently 
> return-in-mem and type_mode(return_type) == VOIDmode are  not tautologies.

>       * config/nvptx/nvptx.c (nvptx_declare_function_name): Functions
>       may return pointer as well as in memory.
>       (nvptx_output_return): Likewise.

Hmm, but what I now see happening is that now there is incorrect
"%out_retval" usage (but it's not part of the function prototypes), for
example:

    $ build-gcc/gcc/xg++ -Bbuild-gcc/gcc/ 
source-gcc/gcc/testsuite/g++.dg/ipa/ipa-icf-6.C -std=gnu++98 -O3 -o 
ipa-icf-6.exe -S

Diff before/after your change:

    $ diff -U4 O/ipa-icf-6.exe ipa-icf-6.exe
    --- O/ipa-icf-6.exe 2015-10-06 18:30:21.581187448 +0200
    +++ ipa-icf-6.exe   2015-10-09 07:49:23.894893180 +0200
    @@ -10,8 +10,9 @@
     .visible .func _Z5test21A(.param.u64 %in_ar1, .param.u64 %in_ar2)
     {
        .reg.u64 %ar2;
        .reg.u64 %ar1;
    +   .reg.u64 %retval;
        .reg.u64 %hr10;
        .reg.u64 %r25;
        .reg.u64 %r26;
        .reg.u64 %r27;
    @@ -28,8 +29,9 @@
        }
     $L2:
                st.u64  [%r25+8], %r25;
                mov.u64 %retval, %r25;
    +   st.param.u64    [%out_retval], %retval;
        ret;
        }
     // BEGIN FUNCTION DECL: _ZL7test_mePF1AS_E
     .func _ZL7test_mePF1AS_E(.param.u64 %in_ar1);
    @@ -78,8 +80,9 @@
     .visible .func _Z5test11A(.param.u64 %in_ar1, .param.u64 %in_ar2)
     {
        .reg.u64 %ar2;
        .reg.u64 %ar1;
    +   .reg.u64 %retval;
        .reg.u64 %hr10;
        .reg.u64 %r25;
        .reg.u64 %r26;
        .reg.u64 %r27;
    @@ -96,8 +99,9 @@
        }
     $L6:
                st.u64  [%r25+8], %r25;
                mov.u64 %retval, %r25;
    +   st.param.u64    [%out_retval], %retval;
        ret;
        }
     // BEGIN GLOBAL FUNCTION DECL: main
     .visible .func (.param.u32 %out_retval)main(.param.u32 %argc, .param.u64 
%argv);

(I have not yet made an attempt at trying to understand the problem.)


For reference:

> Index: gcc/config/nvptx/nvptx.c
> ===================================================================
> --- gcc/config/nvptx/nvptx.c  (revision 228617)
> +++ gcc/config/nvptx/nvptx.c  (working copy)
> @@ -531,13 +531,8 @@ nvptx_declare_function_name (FILE *file,
>    nvptx_write_function_decl (s, name, decl);
>    fprintf (file, "%s", s.str().c_str());
>  
> -  bool return_in_mem = false;
> -  if (TYPE_MODE (result_type) != VOIDmode)
> -    {
> -      machine_mode mode = TYPE_MODE (result_type);
> -      if (!RETURN_IN_REG_P (mode))
> -     return_in_mem = true;
> -    }
> +  bool return_in_mem = (TYPE_MODE (result_type) != VOIDmode
> +                     && !RETURN_IN_REG_P (TYPE_MODE (result_type)));
>  
>    fprintf (file, "\n{\n");
>  
> @@ -547,9 +542,13 @@ nvptx_declare_function_name (FILE *file,
>                      false, return_in_mem);
>    if (return_in_mem)
>      fprintf (file, "\t.reg.u%d %%ar1;\n", GET_MODE_BITSIZE (Pmode));
> -  else if (TYPE_MODE (result_type) != VOIDmode)
> +
> +  /* C++11 ABI causes us to return a reference to the passed in
> +     pointer for return_in_mem.  */
> +  if (cfun->machine->ret_reg_mode != VOIDmode)
>      {
> -      machine_mode mode = arg_promotion (TYPE_MODE (result_type));
> +      machine_mode mode = arg_promotion
> +     ((machine_mode)cfun->machine->ret_reg_mode);
>        fprintf (file, "\t.reg%s %%retval;\n",
>              nvptx_ptx_type_from_mode (mode, false));
>      }
> @@ -635,17 +634,13 @@ nvptx_declare_function_name (FILE *file,
>  const char *
>  nvptx_output_return (void)
>  {
> -  tree fntype = TREE_TYPE (current_function_decl);
> -  tree result_type = TREE_TYPE (fntype);
> -  if (TYPE_MODE (result_type) != VOIDmode)
> +  machine_mode mode = (machine_mode)cfun->machine->ret_reg_mode;
> +
> +  if (mode != VOIDmode)
>      {
> -      machine_mode mode = TYPE_MODE (result_type);
> -      if (RETURN_IN_REG_P (mode))
> -     {
> -       mode = arg_promotion (mode);
> -       fprintf (asm_out_file, "\tst.param%s\t[%%out_retval], %%retval;\n",
> -                nvptx_ptx_type_from_mode (mode, false));
> -     }
> +      mode = arg_promotion (mode);
> +      fprintf (asm_out_file, "\tst.param%s\t[%%out_retval], %%retval;\n",
> +            nvptx_ptx_type_from_mode (mode, false));
>      }
>  
>    return "ret;";
> Index: gcc/config/nvptx/nvptx.h
> ===================================================================
> --- gcc/config/nvptx/nvptx.h  (revision 228617)
> +++ gcc/config/nvptx/nvptx.h  (working copy)
> @@ -228,7 +228,7 @@ struct GTY(()) machine_function
>    bool has_call_with_varargs;
>    bool has_call_with_sc;
>    HOST_WIDE_INT outgoing_stdarg_size;
> -  int ret_reg_mode;
> +  int ret_reg_mode; /* machine_mode not defined yet. */
>    int punning_buffer_size;
>  };
>  #endif


Grüße,
 Thomas

Attachment: signature.asc
Description: PGP signature

Reply via email to