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 ...