https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117186
Richard Sandiford <rsandifo at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rsandifo at gcc dot gnu.org --- Comment #6 from Richard Sandiford <rsandifo at gcc dot gnu.org> --- This seems to go back to r0-29238 [https://gcc.gnu.org/pipermail/gcc-patches/2000-July/033786.html], for which the code now looks like: case COMPARE: /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */ if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT) || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU)) && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx) { rtx xop00 = XEXP (op0, 0); rtx xop10 = XEXP (op1, 0); if (REG_P (xop00) && REG_P (xop10) && REGNO (xop00) == REGNO (xop10) && GET_MODE (xop00) == mode && GET_MODE (xop10) == mode && GET_MODE_CLASS (mode) == MODE_CC) return xop00; } break; I think this PR shows why the optimisation isn't correct, at least not without information about how the COMPARE result is used. It implicitly assumes that the test of the COMPARE result will be of the same signedness as the GT/LT or GTU/LTU pair. In other words, the reason that the code needs to test for matching signedness (GT/LT or GTU/LTU) is also the reason why it can't do what it wants to do. (gt (compare (gt cc 0) (lt cc 0) 0) does simplify to: (gt cc 0) but: (gtu (compare (gt cc 0) (lt cc 0) 0) does not simplify to: (gtu cc 0)