Skip to content

[RyuJIT] The "reuse flags" optimization handles compares incorrectly #9059

Closed
@mikedn

Description

@mikedn

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 trouble
  • x LE 0 - equivalent to x EQ 0. Morph does this transform already.
  • x GT 0 - equivalent to x NE 0. Morph handles this too.
  • x GE 0 - always true; like LT, this should be removed but it's not worth the trouble.

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions