Runtime: JIT fails to constant fold multiplies, and/or merge shifts

Created on 17 Oct 2020  路  2Comments  路  Source: dotnet/runtime

```C#
[MethodImpl(MethodImplOptions.NoInlining)]
static int Y(int x) => x * 2 * 2;

```asm
; Assembly listing for method X:Y(int):int
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
;  V00 arg0         [V00,T00] (  3,  3   )     int  ->  rcx
;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]   "OutgoingArgSpace"
;
; Lcl frame size = 0

G_M5754_IG01:              ;; offset=0000H
                                                ;; bbWeight=1    PerfScore 0.00
G_M5754_IG02:              ;; offset=0000H
       8D0409               lea      eax, [rcx+rcx]
       03C0                 add      eax, eax
                                                ;; bbWeight=1    PerfScore 0.75
G_M5754_IG03:              ;; offset=0005H
       C3                   ret
                                                ;; bbWeight=1    PerfScore 1.00

; Total bytes of code 6, prolog size 0, PerfScore 2.35, instruction count 3 (MethodHash=7c40e985) for method X:Y(int):int

Should be simple enough to handle this in morph. Or we could re-associate better.

category:cq
theme:expression-opts
skill-level:intermediate
cost:medium

area-CodeGen-coreclr up-for-grabs

Most helpful comment

Right, inlining will break trees and we don't have anything today that will patch them back up. This causes lots of issues. See #6973 or #4655.

I've tried a couple of approaches to fixing this but haven't settled on one that I think is workable.

All 2 comments

even GT_ADD has issues 馃檪

int val1() => 1;
int val2() => 2;

int Test(int x) => x + val1() + val2();

asm for Test:

       FFC2                 inc      edx
       8BC2                 mov      eax, edx
       83C002               add      eax, 2
       C3                   ret     

because after inlining, in Morph we have two statements (I expected a single one):

fgMorphTree BB01, STMT00002 (before)
               [000008] -AC---------              *  ASG       int   
               [000007] D------N----              +--*  LCL_VAR   int    V03 tmp1         
               [000004] --C---------              \--*  ADD       int   
               [000000] ------------                 +--*  LCL_VAR   int    V01 arg1         
               [000013] ------------                 \--*  CNS_INT   int    1

fgMorphTree BB01, STMT00003 (before)
               [000012] --C---------              *  RETURN    int   
               [000011] --C---------              \--*  ADD       int   
               [000009] ------------                 +--*  LCL_VAR   int    V03 tmp1         
               [000015] ------------                 \--*  CNS_INT   int    2

Right, inlining will break trees and we don't have anything today that will patch them back up. This causes lots of issues. See #6973 or #4655.

I've tried a couple of approaches to fixing this but haven't settled on one that I think is workable.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

btecu picture btecu  路  3Comments

sahithreddyk picture sahithreddyk  路  3Comments

nalywa picture nalywa  路  3Comments

jkotas picture jkotas  路  3Comments

bencz picture bencz  路  3Comments