https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109086
--- Comment #3 from liwei at loongson dot cn ---
Thank you for your quick reply!
The final call of the expand_simple_binop function returns part of the code as
follows (optabs.cc):
1671 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1672
1673 /* The second operand of a shift must always be extended. */
1674 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1675 no_extend && binoptab != ashl_optab);
1676
1677 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1678 unsignedp, OPTAB_DIRECT);
1679 if (temp)
1680 {
1681 if (mclass != MODE_INT
1682 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1683 {
1684 if (target == 0)
1685 target = gen_reg_rtx (mode);
1686 convert_move (target, temp, 0);
1687 return target;
1688 }
1689 else
1690 return gen_lowpart (mode, temp);
1691 }
In the above code, target = result, when promote xop0 and xop1 machine mode to
DI, then match adddi3 insn pattern and save the new rtx to temp, then because
the mclass equal MODE_INT (also equal true for TRULY_NOOP_TRUNCATION_MODES_P
function), the code enter else branch and return lowpart of temp which is
irrelevant with target (i.e. result).
Maybe the expand_binop function does not consider the case of dependency with
`target` when generating rtx for the case of promote MODE_INT mode, and maybe
theoretically it does not need to be considered, except that builtin_strcmp
happens to meet such cases, so I think it is enough to modify the processing
logic of builtin_strcmp (my humble opinion).