https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96865

Jeevitha <jeevitha at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jeevitha at gcc dot gnu.org

--- Comment #1 from Jeevitha <jeevitha at gcc dot gnu.org> ---
The issue was in the following RTL,
(insn 6 2 21 2 (parallel [
            (set (reg:SI 96 lr)
                (unspec:SI [
                        (symbol_ref:SI ("_GLOBAL_OFFSET_TABLE_") [flags 0x42])
                        (label_ref 0)
                    ] UNSPEC_TOCPTR))
            (code_label 0 0 0 2 (nil) [2 uses])
        ]) "test.c":6:6 798 {load_toc_v4_PIC_1b_normal}

The above RTL will generate the following assembly:

        bcl 20,31,$+8

There is no need for 'label_ref 0' and 'code_label' in the RTL instruction, as
the assembly does not require them. Is my understanding correct?

Currently, we are encountering an ICE due to the following reason: In the
'hash_rtx' function [cse.cc], handling for 'LABEL_REF' is present but not for
'code_label', causing it to not return a hash directly. Instead, it searches
for the format corresponding to '(code_label 0 0 0 4 (nil))', which is
"uuB00is". In the provided code snippet below, 'B' and 'u' do not have case
handling, leading to a 'gcc_unreachable'. This is the reason for the ICE
currently.


fmt = GET_RTX_FORMAT (code);  //code -> code_label
  for (; i >= 0; i--)
    {
      switch (fmt[i])
        {
        case 'e':
          /* If we are about to do the last recursive call
             needed at this level, change it into iteration.
             This function  is called enough to be worth it.  */
          if (i == 0)
            {
              x = XEXP (x, i);
              goto repeat;
            }

          hash += hash_rtx (XEXP (x, i), VOIDmode, do_not_record_p,
                            hash_arg_in_memory_p,
                            have_reg_qty, cb);
          break;

        case 'E':
          for (j = 0; j < XVECLEN (x, i); j++)
            hash += hash_rtx (XVECEXP (x, i, j), VOIDmode, do_not_record_p,
                              hash_arg_in_memory_p,
                              have_reg_qty, cb);
          break;

        case 's':
          hash += hash_rtx_string (XSTR (x, i));
          break;

        case 'i':
          hash += (unsigned int) XINT (x, i);
          break;

        case 'p':
          hash += constant_lower_bound (SUBREG_BYTE (x));
          break;

        case '0': case 't':
          /* Unused.  */
          break;

        default:
          gcc_unreachable ();
        }
    }

To address this, I've removed 'operand1' and adjusted the respective
'match_dup' to 'operand0' in the below pattern.

(define_insn "load_toc_v4_PIC_1b_normal"
  [(set (reg:SI LR_REGNO)
        (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
                    (label_ref (match_operand 1 "" ""))]
                UNSPEC_TOCPTR))
   (match_dup 1)]

After implementing the mentioned change, there were no ICEs or regressions. Is
this approach correct?

Reply via email to