https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61298
--- Comment #4 from baoshan <pangbw at gmail dot com> --- (In reply to Peter Bergner from comment #3) >> I can say that unsigned_reg_p() probably doesn't catch every case >> where we're doing an unsigned compare and force it to use non > signed compare. Since you have a subreg, have you looked at > how SUBREG_PROMOTED_UNSIGNED_P is set? Is that supposed to be > set for your case? Yes, SUBREG_PROMOTED_UNSIGNED_P is supposed to be set for this case, it has been set originally, but the setting is lost while doing mode converting in function convert_modes():expr.c, do you think the following code is good enough to fix this issue? rtx convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int unsignedp) { rtx temp; /* If FROM is a SUBREG that indicates that we have already done at least the required extension, strip it. */ if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x) && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode) && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp) { x = gen_lowpart (mode, SUBREG_REG (x)); if(GET_CODE (x) == SUBREG) { SUBREG_PROMOTED_VAR_P (x) = 1; SUBREG_PROMOTED_UNSIGNED_SET (x, unsignedp); } } . . .