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