Skip to content

Question about GetFoldedArithOpResultHandleFlags() #100059

@BruceForstall

Description

@BruceForstall

#70452 introduced GetFoldedArithOpResultHandleFlags() that loses specific handle types and seems to associate incorrect handle types with arithmetic operations on handles. This problem is seen during OptRepeat compilations with shared constant CSE.

Consider:

This tree defines V134 tmp133 as a base constant for shared constant CSE:

STMT00003 ( 0x007[--] ... ??? )
N009 ( 41, 42) [000008] -ACXG-------                        *  CALL      void   <unknown method> $VN.Void
N006 ( 19, 20) [002663] DAC--------- arg1 setup             +--*  STORE_LCL_VAR ref    V122 tmp121      d:2 $VN.Void
N005 ( 19, 20) [000003] -AC---------                        |  \--*  CALL help ref    CORINFO_HELP_NEWSFAST $1c0
N004 (  3,  9) [002869] -A---------- arg0 in r0             |     \--*  COMMA     int    $140
N002 (  2,  8) [002867] DA----------                        |        +--*  STORE_LCL_VAR int    V134 tmp133      d:2 $VN.Void
N001 (  2,  8) [000002] H-----------                        |        |  \--*  CNS_INT(h) int    -0x5275842C class <unknown class> $140
N003 (  1,  1) [002868] ------------                        |        \--*  LCL_VAR   int    V134 tmp133      u:2 $140
N007 (  1,  1) [002664] ------------ arg1 in r1             +--*  LCL_VAR   ref    V122 tmp121      u:2 (last use) $1c0
N008 (  2,  8) [000009] H----------- gctx in r0             \--*  CNS_INT(h) int    -0x52758314 method <unknown method> $141

This tree defines V38 tmp37 as an offset from V134 tmp133:

STMT00118 ( 0x00C[E-] ... ??? )
N008 ( 22, 26) [000628] DACXG-------                        *  STORE_LCL_VAR byref  V38 tmp37        d:2 $1c2
N007 ( 22, 26) [000015] --CXG-------                        \--*  COMMA     int    $242
N003 ( 19, 22) [000014] H-CXG-------                           +--*  CALL help int    CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS $241
N001 (  2,  8) [000012] ------------ arg0 in r0                |  +--*  CNS_INT   int    -0x4BFB5600 $4f
N002 (  1,  2) [000013] ------------ arg1 in r1                |  \--*  CNS_INT   int    1 $50
N006 (  3,  4) [002872] -------N----                           \--*  ADD       int    $142
N004 (  1,  1) [002870] ------------                              +--*  LCL_VAR   int    V134 tmp133      u:2 $140
N005 (  1,  2) [002871] ------------                              \--*  CNS_INT   int    492 $51

Node [000624] uses V38 tmp37. Note in particular the IND is NOT invariant:

STMT00149 ( INL10 @ 0x000[E-] ... ??? ) <- INL03 @ 0x051[E-] <- INLRT @ 0x00C[E-]
N005 (  7,  7) [000729] ----GO------                        *  JTRUE     void   $VN.Void
N004 (  5,  5) [000728] J---GO-N--S-                        \--*  EQ        int    <l:$261, c:$262>
N002 (  3,  2) [000726] n---GO------                           +--*  IND       int    <l:$286, c:$93>
N001 (  1,  1) [000624] ------------                           |  \--*  LCL_VAR   byref  V38 tmp37        u:2 $142
N003 (  1,  2) [000727] ------------                           \--*  CNS_INT   int    11 $52

After VN-based fold of [000624]:

STMT00149 ( INL10 @ 0x000[E-] ... ??? ) <- INL03 @ 0x051[E-] <- INLRT @ 0x00C[E-]
N005 (  7,  7) [000729] ----GO------                        *  JTRUE     void   $VN.Void
N004 (  5,  5) [000728] J---GO-N--S-                        \--*  EQ        int    <l:$261, c:$262>
N002 (  3,  2) [000726] #---GO------                           +--*  IND       int    <l:$286, c:$93>
               [003090] H-----------                           |  \--*  CNS_INT(h) int    -0x52758240 const ptr $142
N003 (  1,  2) [000727] ------------                           \--*  CNS_INT   int    11 $52

Note in particular that the replacement has const ptr handle type, and because of that, the IND is marked invariant (# flag). The computed constant starts as GTF_ICON_CLASS_HDL, the handle type of the constant assigned to V134 tmp133. With shared constant CSE, we add 492 to get the actual value, which originally was:

N004 (  2,  8) CSE #01 (use)[000010] H-----------                           \--*  CNS_INT(h) int    -0x52758240 static Fseq[<unknown field>] $142

Then GetFoldedArithOpResultHandleFlags maps GTF_ICON_CLASS_HDL to GTF_ICON_CONST_PTR.

Of course, this is wrong. But also, because it is "constant" and the IND marked invariant, that means the IND can later be CSE'd, incorrectly.

Question: wouldn't it be safer, in the presence of shared constant CSE, to always fold handle types to (mutable) GTF_ICON_GLOBAL_PTR? Or lose the handle-ness of them entirely?

For instance, what does it mean for unary op neg/not/bswap16/bswap on a handle constant? How can the result be a handle? And what does it mean to add some arbitrary number N to a class handle? Are there cases where it makes sense?

@jakobbotsch @AndyAyersMS @EgorBo @SingleAccretion

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions