Closed
Description
dotnet/coreclr#14027 enabled all relops to reuse flags set by a previous ALU operation. This is incorrect for unsigned LT/LE/GT/GE relops:
static bool Test(uint x) => ((x - 42) < 0);
returns true
when x
is 42 but it should always return false
.
Generated code:
83C1D6 add ecx, -42
0F92C0 setb al ; checking CF here tells you that an overflow occurred
; not that the result is < 0, it never is
0FB6C0 movzx rax, al
Same for ARM64:
7100A800 subs w0, w0, dotnet/coreclr#42
9A9F27E0 cset x0, lo
For unsigned relops the optimization should be limited to EQ/NE. For others:
x LT 0
- always false; the entire relop should be removed together with the subsequent SETCC/JCC but it's a rare case so it's not worth the troublex LE 0
- equivalent tox EQ 0
. Morph does this transform already.x GT 0
- equivalent tox NE 0
. Morph handles this too.x GE 0
- always true; likeLT
, this should be removed but it's not worth the trouble.