Hello!

The testcase in PR58792 [1], where a function returns its result in
multiple registers, triggered a very picky assert in mode-switching
code. The problem was, that x86_64 didn't mark correctly all of its
possible return registers, so code assumed that something went wrong
here.

The mode-switching code already handles __builtin_apply builtin, which
also generates multiple return registers. When a sequence of USEs is
detected, maybe_builtin_apply flag is raised to bypass the assert.
However, functions that pass their result in multiple registers also
generate multiple USEs, so the patch clarifies that __builtin_apply
situation actually applies to all multiple return register exits. The
patch clarifies this situation.

No functional changes (modulo converting a couple of variables to boolean type).

2013-10-19  Uros Bizjak  <ubiz...@gmail.com>

    * mode-switching.c (create_pre_exit): Rename maybe_builtin_apply
    to multi_reg_return.  Clarify that we are skipping USEs of multiple
    return registers.  Use bool type where appropriate.

Tested on x86_64-pc-linux-gnu and committed to mainline SVN.

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58792

Uros.
Index: mode-switching.c
===================================================================
--- mode-switching.c    (revision 203845)
+++ mode-switching.c    (working copy)
@@ -229,9 +229,9 @@ create_pre_exit (int n_entities, int *entity_map,
            int ret_start = REGNO (ret_reg);
            int nregs = hard_regno_nregs[ret_start][GET_MODE (ret_reg)];
            int ret_end = ret_start + nregs;
-           int short_block = 0;
-           int maybe_builtin_apply = 0;
-           int forced_late_switch = 0;
+           bool short_block = false;
+           bool multi_reg_return = false;
+           bool forced_late_switch = false;
            rtx before_return_copy;
 
            do
@@ -251,19 +251,20 @@ create_pre_exit (int n_entities, int *entity_map,
                       copy yet, the copy must have been deleted.  */
                    if (CALL_P (return_copy))
                      {
-                       short_block = 1;
+                       short_block = true;
                        break;
                      }
                    return_copy_pat = PATTERN (return_copy);
                    switch (GET_CODE (return_copy_pat))
                      {
                      case USE:
-                       /* Skip __builtin_apply pattern.  */
+                       /* Skip return values in multiple registers.
+                          __builtin_apply pattern is also handled here.  */
                        if (GET_CODE (XEXP (return_copy_pat, 0)) == REG
                            && (targetm.calls.function_value_regno_p
                                (REGNO (XEXP (return_copy_pat, 0)))))
                          {
-                           maybe_builtin_apply = 1;
+                           multi_reg_return = true;
                            last_insn = return_copy;
                            continue;
                          }
@@ -326,7 +327,7 @@ create_pre_exit (int n_entities, int *entity_map,
                           there are no return copy insns at all.  This
                           avoids an ice on that invalid function.  */
                        if (ret_start + nregs == ret_end)
-                         short_block = 1;
+                         short_block = true;
                        break;
                      }
                    if (!targetm.calls.function_value_regno_p (copy_start))
@@ -354,10 +355,10 @@ create_pre_exit (int n_entities, int *entity_map,
                           another mode than MODE_EXIT, even if it is
                           unrelated to the return value, so we want to put
                           the final mode switch after it.  */
-                       if (maybe_builtin_apply
+                       if (multi_reg_return
                            && targetm.calls.function_value_regno_p
                                (copy_start))
-                         forced_late_switch = 1;
+                         forced_late_switch = true;
 
                        /* For the SH4, floating point loads depend on fpscr,
                           thus we might need to put the final mode switch
@@ -367,7 +368,7 @@ create_pre_exit (int n_entities, int *entity_map,
                        if (copy_start >= ret_start
                            && copy_start + copy_num <= ret_end
                            && OBJECT_P (SET_SRC (return_copy_pat)))
-                         forced_late_switch = 1;
+                         forced_late_switch = true;
                        break;
                      }
                    if (copy_num == 0)
@@ -379,7 +380,7 @@ create_pre_exit (int n_entities, int *entity_map,
                    if (copy_start >= ret_start
                        && copy_start + copy_num <= ret_end)
                      nregs -= copy_num;
-                   else if (!maybe_builtin_apply
+                   else if (!multi_reg_return
                             || !targetm.calls.function_value_regno_p
                                 (copy_start))
                      break;
@@ -393,7 +394,7 @@ create_pre_exit (int n_entities, int *entity_map,
                   isolated use.  */
                if (return_copy == BB_HEAD (src_bb))
                  {
-                   short_block = 1;
+                   short_block = true;
                    break;
                  }
                last_insn = return_copy;

Reply via email to