Skip to content

[RyuJIT] Unsigned binary operation with overflow check #8783

@mikedn

Description

@mikedn

Remember #7439? I ran into that again but this time it's a real bug.

The importer does this: https://github.com/dotnet/coreclr/blob/a6045809b3720833459c9247aeb4aafe281d7841/src/jit/importer.cpp#L9374-L9396

Note that it selects the "castType" based on the signedness of the operation but it does not set the GTF_UNSIGNED flag on the cast.

So if it doesn't set the flag how come we zero extend int32 in the case of add.ovf.un? That's because CodeGen::genIntToIntCast does something weird: https://github.com/dotnet/coreclr/blob/a6045809b3720833459c9247aeb4aafe281d7841/src/jit/codegenxarch.cpp#L6490-L6497

It selects INS_movsxd if the source is signed. And if the destination is signed! That doesn't make sense, the sign of the destination is relevant only for overflow checks, it should have no impact on the kind of widening performed.

I was curious what the ARM64 codegen does and of course, it doesn't consider the destination sign and emits sxtw:

B9802C09          ldrsw   x9, [x0,#44]
93407D29          sxtw    x9, x9
F9400C2A          ldr     x10, [x1,#24]
AB0A0129          adds    x9, x9, x10
54000062          bhs     G_M55886_IG04

For the same code the x64 codegen produces mov, not movsxd.

So, if we want to keep the existing x64 behavior (zero extend add.ovf.un operands) we need to:

  • make the importer set GTF_UNSIGNED when needed (this will make ARM64 codegen generate the required code)
  • change x64 codegen to ignore the destination type when selecting INS_movsxd

Though after seeing this I'm more inclined to consider the current behavior to be a JIT bug and that sign extension should be performed. So:

  • change x64 codegen to ignore the destination type when selecting INS_movsxd

And either way we probably need to add tests for this. I only noticed this while looking at diffs in dotnet/coreclr#12676. All tests pass but the code isn't right.

Metadata

Metadata

Assignees

Labels

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

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions