Hi, Richard,

As you suggested, I added a default implementation of the target hook 
“zero_cal_used_regs (HARD_REG_SET)” as following in my latest patch


/* The default hook for TARGET_ZERO_CALL_USED_REGS.  */

void
default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
{
  gcc_assert (!hard_reg_set_empty_p (need_zeroed_hardregs));

  /* This array holds the zero rtx with the correponding machine mode.  */
  rtx zero_rtx[(int)MAX_MACHINE_MODE];
  for (int i = 0; i < (int) MAX_MACHINE_MODE; i++)
    zero_rtx[i] = NULL_RTX;

  expand_asm_memory_blockage ();

  for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
      {
        rtx reg, tmp;
        machine_mode mode = reg_raw_mode[regno];

        reg = gen_rtx_REG (mode, regno);

        /* update the data flow information.  */
        expand_asm_reg_clobber_blockage (reg);
        df_update_zeroed_reg_set (regno);

        if (zero_rtx[(int)mode] == NULL_RTX)
          {
            zero_rtx[(int)mode] = reg;
            tmp = gen_rtx_SET (reg, const0_rtx);
            emit_insn (tmp);
          }
        else
          emit_move_insn (reg, zero_rtx[(int)mode]);
      }
  return;
}

I tested this default implementation on aarch64 with a small testing case, 
-fzero-call-used-regs=all-gpr|used-gpr|used-gpr-arg|used-arg|used work well, 
however, 
-fzero-call-used-regs=all-arg or -fzero-call-used-regs=all have an internal 
compiler error as following:

t1.c:15:1: internal compiler error: in gen_highpart, at emit-rtl.c:1631
   15 | }
      | ^
0xcff58b gen_highpart(machine_mode, rtx_def*)
        ../../hjl-caller-saved-gcc/gcc/emit-rtl.c:1631
0x174b373 aarch64_split_128bit_move(rtx_def*, rtx_def*)
        ../../hjl-caller-saved-gcc/gcc/config/aarch64/aarch64.c:3390
0x1d8b087 gen_split_11(rtx_insn*, rtx_def**)
        ../../hjl-caller-saved-gcc/gcc/config/aarch64/aarch64.md:1394

As I studied today, I found the major issue for this bug is because the 
following statement:

        machine_mode mode = reg_raw_mode[regno];

“reg_raw_mode” returns E_TImode for aarch64 register V0 (which is a vector 
register on aarch64) , as a result, the zeroing insn for this register is:

(insn 112 111 113 7 (set (reg:TI 32 v0)
        (const_int 0 [0])) "t1.c":15:1 -1
     (nil))


However, looks like that the above RTL have to be splitted into two sub 
register moves on aarch64, and the splitting has some issue. 

So, I guess that on aarch64, zeroing vector registers might need other modes 
than the one returned by “reg_raw_mode”.  

My questions are:

1. Is there another available utility routine that returns the proper MODE for 
the hard registers that can be readily used to zero the hardr register?
2. If not, should I add one more target hook for this purpose? i.e 

/* Return the proper machine mode that can be used to zero this hard register 
specified by REGNO.  */
machine_mode zero-call-used-regs-mode (unsigned int REGNO)


Thanks.

Qing



Reply via email to