https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116085
--- Comment #6 from Jeffrey A. Law <law at gcc dot gnu.org> --- So I think Philipp's code would work if it transformed the resulting min/max into a minu/maxu. And I think there's some room for improvement here. The core bug is that we're sign-extending the non-constant operand. If that operand has a negative value in SImode, then it's going to have a negative value in DImode. If the original code was smax, we must change it to umax to preserve semantics of the comparison (the constant operand always have a positive value). Similarly for smin->umin. Philipp's code appears to a 4->3 combination. We're combining the zero extension of the nonconstant operand, loading the constant operand into a register, a min/max and sign extension of result into sign extension of the nonconstant operand, loading the constant operand into a register and the min/max. A define_split would be better for this scenario. It's also the case that if we know the nonconstant operand is a sign promoted subreg, then we can eliminate the sign extension step in the new RTL. In that case it's a 4->2 combination. And fun tidbit. ext-dce removes an extension in this code before combine and as a result the faulty pattern doesn't trigger and makes this instance of the bug go latent!