Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT does not eliminate null check for "o ??= new()" #75987

Closed
tfenise opened this issue Sep 21, 2022 · 4 comments · Fixed by #76283
Closed

JIT does not eliminate null check for "o ??= new()" #75987

tfenise opened this issue Sep 21, 2022 · 4 comments · Fixed by #76283
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Milestone

Comments

@tfenise
Copy link
Contributor

tfenise commented Sep 21, 2022

Description

https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKGIGYACMhgYQYG8aHunHjykTFAwCy5ABQRgAKxhgMDCAEoOXHuoCWAMwbjJDAPwGAvAwB2MAO6KZcjOKUqNucwFcANu5UYAFlAjWFtYAoghgMAAOGBoQZg4A3GrcAL5JDGn0TAJCoqSStvKKKpzU6po6ehAMpkE2svIOTi5mHl4Mvv6BVgyh4VExcUqJpTypI9wZfNnEwiJ04hpmChrFaeW6GgwAPAwADE7Ve8NlPNob23vefgHm3b2R0bEJaWPqk1mCM6Io+fUKyqpxgwxskgA=

static void M1(object o) {
    if ((o ??= new object()) is null) throw new Exception();
}
    
static void M2(object o) {
    if ((o = new object()) is null) throw new Exception();
}

static void M3(int i) {
    if (i < 0) i = 0;
    if (i < 0) throw new Exception();
}
    
static void M4(object o) {
}

While the JIT can optimize M2(almost, but still curiously worse than M4) and M3 to a nop, it cannot optimize M1 similarly.

Found while discussing #75936.

Configuration

sharplab says "Core CLR 6.0.822.36306 on amd64".

I also tried 7.0.100-rc.1.22431.12 on amd64. The codegen for M1 was not really better.

Regression?

Probably not.

@tfenise tfenise added the tenet-performance Performance related issue label Sep 21, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Sep 21, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Sep 21, 2022
@ghost
Copy link

ghost commented Sep 21, 2022

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKGIGYACMhgYQYG8aHunHjykTFAwCy5ABQRgAKxhgMDCAEoOXHuoCWAMwbjJDAPwGAvAwB2MAO6KZcjOKUqNucwFcANu5UYAFlAjWFtYAoghgMAAOGBoQZg4A3GrcAL5JDGn0TAJCoqSStvKKKpzU6po6ehAMpkE2svIOTi5mHl4Mvv6BVgyh4VExcUqJpTypI9wZfNnEwiJ04hpmChrFaeW6GgwAPAwADE7Ve8NlPNob23vefgHm3b2R0bEJaWPqk1mCM6Io+fUKyqpxgwxskgA=

static void M1(object o) {
    if ((o ??= new object()) is null) throw new Exception();
}
    
static void M2(object o) {
    if ((o = new object()) is null) throw new Exception();
}

static void M3(int i) {
    if (i < 0) i = 0;
    if (i < 0) throw new Exception();
}
    
static void M4(object o) {
}

While the JIT can optimize M2(almost, but still curiously worse than M4) and M3 to a nop, it cannot optimize M1 similarly.

Found while discussing #75936.

Configuration

sharplab says "Core CLR 6.0.822.36306 on amd64".

I also tried 7.0.100-rc.1.22431.12 on amd64. The codegen for M1 was not really better.

Regression?

Probably not.

Author: tfenise
Assignees: -
Labels:

tenet-performance, area-CodeGen-coreclr

Milestone: -

@EgorBo
Copy link
Member

EgorBo commented Sep 21, 2022

Looks like Jump-Threading + PHI issue?

image

BB03 is never true because V02 is either come form V02 != 0 == true or it comes from BB02 where it's set to non-null
cc @AndyAyersMS to confirm

@EgorBo EgorBo added this to the Future milestone Sep 21, 2022
@EgorBo EgorBo removed the untriaged New issue has not been triaged by the area owner label Sep 21, 2022
@AndyAyersMS
Copy link
Member

Likely BB03 has some side effecting code; this currently blocks jump threading.

@AndyAyersMS
Copy link
Member

AndyAyersMS commented Sep 22, 2022

Likely BB03 has some side effecting code; this currently blocks jump threading.

No, you were right, this is the PHI case: #48115 (comment)

optRedundantRelop in BB03; jump tree is
N004 (  7,  6) [000012] -----------                         *  JTRUE     void   $VN.Void
N003 (  5,  4) [000011] J------N---                         \--*  NE        int    $101
N001 (  3,  2) [000009] -----------                            +--*  LCL_VAR   ref    V02 tmp1         u:2 (last use) $1c0
N002 (  1,  1) [000010] -----------                            \--*  CNS_INT   ref    null $VN.Null
 ... checking previous tree
N005 (  0,  0) [000038] -A------R--                         *  ASG       ref    $VN.Void
N004 (  0,  0) [000036] D------N---                         +--*  LCL_VAR   ref    V02 tmp1         d:2 $VN.Void
N003 (  0,  0) [000037] -----------                         \--*  PHI       ref    $1c0
N001 (  0,  0) [000040] ----------- pred BB02                  +--*  PHI_ARG   ref    V02 tmp1         u:3 $180
N002 (  0,  0) [000039] ----------- pred BB01                  \--*  PHI_ARG   ref    V02 tmp1         u:1 $80
 -- prev tree is a phi
Relop [000011] BB03 value unknown, trying inference

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Sep 28, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Sep 29, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Oct 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants