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

--- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> ---
(gdb) p debug(x1)
(set (reg:DI 444)
    (plus:DI (reg:DI 444)
        (const_int -32 [0xffffffffffffffe0])))

Looking at the generated code, I see:

switch (GET_CODE (x4))  → (reg:DI 444)
    case REG:
      operands[1] = x4;  → (reg:DI 444)
      x6 = XEXP (x3, 1); → (const_int -32 [0xffffffffffffffe0])
      operands[2] = x6;
      switch (GET_CODE (operands[1]))
        case REG:
          switch (GET_MODE (operands[0]))  → E_DImode
            case E_DImode:
              if (pnum_clobbers != NULL
                  && register_operand (operands[0], E_DImode)
                  && GET_MODE (x3) == E_DImode
                  && register_operand (operands[1], E_DImode)
                  && nonmemory_operand (operands[2], E_DImode))
                {
                  *pnum_clobbers = 2;
                  return 29; /* adddi3 */
                }
              break;

Thus, we have three times the E_DImode – but 'pnum_clobbers' == NULL
as it is called via:

recog.c:
  2768          icode = recog_memoized (insn);
→ rtl.h:
  273         INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
→ insn-recog.c
  recog (rtx x1 ATTRIBUTE_UNUSED,
        rtx_insn *insn ATTRIBUTE_UNUSED,
        int *pnum_clobbers ATTRIBUTE_UNUSED)

There 0 (for a nullptr) is passed → pnum_clobbers == NULL.


In gcn.md, the code for 'adddi3' is:

; Having this as an insn_and_split allows us to keep together DImode adds
; through some RTL optimisation passes, and means the CC reg we set isn't
; dependent on the constraint alternative (which doesn't seem to work well).

; If v_addc_u32 is used to add with carry, a 32-bit literal constant cannot be
; used as an operand due to the read of VCC, so we restrict constants to the
; inlinable range for that alternative.

(define_insn_and_split "adddi3"
  [(set (match_operand:DI 0 "register_operand"           "=Sg, v")
        (plus:DI (match_operand:DI 1 "register_operand"  " Sg, v")
                 (match_operand:DI 2 "nonmemory_operand" "SgB,vA")))
   (clobber (match_scratch:BI 3                          "=cs, X"))
   (clobber (match_scratch:DI 4                          "= X,cV"))]


I am not 100% sure, I understand where the 'pnum_clobbers != NULL' comes from,
but I think from:
  acceptance_ptr->u.full.u.num_clobbers = XVECLEN (pattern, 0) - i;
in genrecog.c's remove_clobbers.

In any case, the define_insn_and_split does have two clobber ...

Reply via email to