dotnet / dotnet/runtime

JIT: Make cmov codegen the same for these equivalent IR sequences

Open
#124,785 2 comments 0 reactions 1 assignee Claimed by @BoyBaykiller View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

Consider these two equivalent functions (https://godbolt.org/z/6cWov3fhs):
```cs
private static CorFlags WithoutElse(Machine machine)
{
CorFlags result = CorFlags.ILOnly;

if (machine == Machine.I386)
{
result |= CorFlags.Requires32Bit;
}

return result;
}

private static CorFlags WithElse(Machine machine)
{
CorFlags result;
if (machine == Machine.I386)
{
result = CorFlags.ILOnly | CorFlags.Requires32Bit;
}
else
{
result = CorFlags.ILOnly;
}

return result;
}
```
And their IR after if conversion phase:
```
* STORE_LCL_VAR int V01 loc0 d:2 $VN.Void
\--* CNS_INT int 1 $41

* NOP void

* STORE_LCL_VAR int V01 loc0 d:3 $VN.Void
\--* SELECT int
+--* NE int $141
| +--* CAST int <- ushort <- int $140
| | \--* LCL_VAR int V00 arg0 u:1 (last use) $80
| \--* CNS_INT int 332 $44
+--* LCL_VAR int V01 loc0
\--* CNS_INT int 3 $45
```
```
* NOP void

* NOP void

* STORE_LCL_VAR int V01 loc0 d:3 $VN.Void
\--* SELECT int
+--* NE int $141
| +--* CAST int <- ushort <- int $140
| | \--* LCL_VAR int V00 arg0 u:1 (last use) $80
| \--* CNS_INT int 332 $44
+--* CNS_INT int 1 $41
\--* CNS_INT int 3 $45
```

The only difference is that for the (later) `WithElse` case, `CNS_INT int 1 $41` is substituted into the `SELECT`.
For some reason this causes `cmovne + mov` codegen instead of just `cmove`:
```asm
Program:WithoutElse(ushort):int (FullOpts):
mov eax, 1
movzx rcx, di
mov edx, 3
cmp ecx, 332
cmove eax, edx
ret

Program:WithElse(ushort):int (FullOpts):
movzx rax, di
mov ecx, 1
mov edx, 3
cmp eax, 332
mov eax, edx
cmovne eax, ecx
ret
```
---
With #124738, `WithoutElse` gets transformed into `WithElse` leading to unecessary regressions here.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.