Roslyn 不优化多个增量是否有原因?

Is there a reason why Roslyn does not optimize multiple increments?

我试图了解 Roslyn 如何优化以下代码段:

代码

public int F(int n) {
    ++n;       
    ++n;       
    ++n;       
    ++n;       

    return n;
}              

asm

C.F(Int32)
    L0000: inc edx
    L0002: inc edx
    L0004: inc edx
    L0006: inc edx
    L0008: mov eax, edx
    L000a: ret

问题

为什么 Roslyn 不像像 MSVC 这样的提前 C 编译器那样对其进行优化? 4 x INC 较慢(4 周期延迟与 1,即使假设移动消除,比吞吐量所需的多 4 微指令;https://agner.org/optimize/)。

C 它的“等价物”:

int
f(void *dummy_this, int n) {
        ++n;        
        ++n;        
        ++n;        
        ++n;        

        return n;
}

asm 来自 MSVC,或 GCC __attribute__((ms_abi)) 使用与 C# asm 相同的 Windows x64 调用约定:https://godbolt.org/z/sK6h7KKcn

f:
        lea     eax, [rdx+4]
        ret

编译器确实进行了优化。 n 是一个参数,所以不能修改。 JIT 编译器必须修改参数值的 copy

如果在递增之前将值分配给变量,Roslyn 编译器将消除递增。来自 this Sharplab.io snippet,此 C# 代码:

public int F(int i) {
    var n=i;
    ++n;       
    ++n;       
    ++n;       
    ++n;       

    return n;
} 

将翻译成

public int F(int i)
{
    return i + 1 + 1 + 1 + 1;
}

并最终编译成这段汇编代码:

C.F(Int32)
    L0000: lea eax, [edx+4]
    L0003: ret