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

Initialize gtUseNum before use #57256

Merged
merged 5 commits into from
Aug 17, 2021
Merged

Conversation

kunalspathak
Copy link
Member

gtUseNum remained uninitialized until the use.

Fixes: #56953

@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 Aug 12, 2021
@kunalspathak
Copy link
Member Author

@dotnet/jit-contrib

@ghost
Copy link

ghost commented Aug 12, 2021

Hello @kunalspathak!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

Do note that I've been instructed to only help merge pull requests of this repository that have been opened for at least 10 minutes, a condition that will be fulfilled in about 4 minutes. No worries though, I will be back when the time is right! 😉

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@kunalspathak
Copy link
Member Author

linux arm failure is related to #55441

@kunalspathak
Copy link
Member Author

I am seeing a new issue on OSX/arm64 that was discovered by the test I added.

Assert failure(PID 92709 [0x00016a25], Thread: 75045132 [0x479190c]): Assertion failed 'false && "it's not expected to be hit at the moment, but can be allowed."' in 'System.Runtime.CompilerServices.CastHelpers:ChkCastClassSpecial(long,System.Object):System.Object' during 'Do value numbering' (IL size 100)

Copy link
Contributor

@briansull briansull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks Good

@kunalspathak
Copy link
Member Author

@briansull - We hit this code when we do multiple iterations of optimization.

assert(false && "it's not expected to be hit at the moment, but can be allowed.");
// tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);

As seen below, in 1st iteration, we CSE the [000081]

***** BB01
STMT00021 (IL 0x007...  ???)
N004 (  6, 14)              [000095] -A--G---R---              *  ASG       ref    $c3
N003 (  1,  1)              [000094] D------N----              +--*  LCL_VAR   ref    V05 tmp2         d:1 $c3
N002 (  6, 14)              [000082] #---G-------              \--*  IND       ref    $c3
N001 (  3, 12) CSE #01 (def)[000081] H-----------                 \--*  CNS_INT(h) long   0xD9673020 [ICON_STR_HDL] $2c0

...
...

Considering CSE #01 {K_000001A1D9673000} [def=100.000000, use=50.000000, cost=  3      ]
CSE Expression : 
N001 (  3, 12) CSE #01 (def)[000081] H-----------              *  CNS_INT(h) long   0xD9673020 [ICON_STR_HDL] $2c0

Aggressive CSE Promotion (250.000000 >= 200.000000)
cseRefCnt=250.000000, aggressiveRefCnt=200.000000, moderateRefCnt=100.000000
defCnt=100.000000, useCnt=50.000000, cost=3, size=12
def_cost=1, use_cost=1, extra_no_cost=22, extra_yes_cost=0
CSE cost savings check (172.000000 >= 150.000000) passes

Promoting CSE:

lvaGrabTemp returning 6 (V06 rat0) (a long lifetime temp) called for CSE - aggressive.
CSE #01 is single-def, so associated CSE temp V06 will be in SSA
New refCnts for V06: refCnt =  2, refCntWtd = 2   
New refCnts for V06: refCnt =  3, refCntWtd = 2.50

We have shared Const CSE's and selected $2c0 with a value of 0x000001A1D9673020 as the base.

CSE #01 def at [000081] replaced in BB01 with def of V06
optValnumCSE morphed tree:
N008 ( 13, 19)              [000095] -A--G---R---              *  ASG       ref    $c3
N007 (  1,  1)              [000094] D------N----              +--*  LCL_VAR   ref    V05 tmp2         d:1 $c3
N006 ( 13, 19)              [000082] #A--G-------              \--*  IND       ref    $c3
N005 ( 10, 17)              [000131] -A----------                 \--*  COMMA     long   $2c0
N003 (  7, 15)              [000129] -A------R---                    +--*  ASG       long   $VN.Void
N002 (  3,  2)              [000128] D------N----                    |  +--*  LCL_VAR   long   V06 cse0         d:1 $2c0
N001 (  3, 12)              [000081] H-----------                    |  \--*  CNS_INT(h) long   0xD9673020 [ICON_STR_HDL] $2c0
N004 (  3,  2)              [000130] ------------                    \--*  LCL_VAR   long   V06 cse0         u:1 $2c0

During 2nd iteration (because COMPlus_JitOptRepeat=ChkCastClassSpecial), we try to value number the COMMA node but then hit the assert:

***** BB01, STMT00021(before)
N008 ( 13, 19) [000095] -A--G---R---              *  ASG       ref   
N007 (  1,  1) [000094] D------N----              +--*  LCL_VAR   ref    V05 tmp2         d:1
N006 ( 13, 19) [000082] #A--G-------              \--*  IND       ref   
N005 ( 10, 17) [000131] -A----------                 \--*  COMMA     long  
N003 (  7, 15) [000129] -A------R---                    +--*  ASG       long  
N002 (  3,  2) [000128] D------N----                    |  +--*  LCL_VAR   long   V06 cse0         d:1
N001 (  3, 12) [000081] H-----------                    |  \--*  CNS_INT(h) long   0xD9673020 [ICON_STR_HDL]
N004 (  3,  2) [000130] ------------                    \--*  LCL_VAR   long   V06 cse0         u:1

The assert message says that it is fine to have different operator, but wanted to check with you what should be the desired behavior?

@briansull
Copy link
Contributor

briansull commented Aug 12, 2021

@kunalspathak - That assert was added by EgorBo on Mar 22 with PR #50000

https://github.com/dotnet/runtime/pull/50000/files#r598977718

We have replaced the CNS_INT with the COMMA tree introduced during CSE.

@kunalspathak
Copy link
Member Author

Thanks @briansull . @EgorBo - any thoughts?

@EgorBo
Copy link
Member

EgorBo commented Aug 13, 2021

@kunalspathak I think it should be safe to change this line

if (addr->IsCnsIntOrI())

to be

f (addr->gtEffectiveVal()->IsCnsIntOrI())

or maybe even here

GenTree* addr = tree->AsIndir()->Addr();
🤔

@briansull
Copy link
Contributor

@kunalspathak I think it should be safe to change this line
to be
f (addr->gtEffectiveVal()->IsCnsIntOrI())

The gtEffectiveVal call will just pull out the CSE LclVar that gets assigned to be the constant.
Then IsCnsIntOrI will still be false.

@EgorBo
Copy link
Member

EgorBo commented Aug 13, 2021

@kunalspathak I think it should be safe to change this line
to be
f (addr->gtEffectiveVal()->IsCnsIntOrI())

The gtEffectiveVal call will just pull out the CSE LclVar that gets assigned to be the constant.
Then IsCnsIntOrI will still be false.

Ah, indeed, then it's ->gtCommaAssignVal()

@EgorBo
Copy link
Member

EgorBo commented Aug 13, 2021

As the assert states: it can be just removed - there should not be a case where GT_IND has GTF_IND_NONNULL but the address was changed to something that can be null...

@briansull
Copy link
Contributor

briansull commented Aug 13, 2021

You could assert that there is no exception set on the gtEffectiveVal, (which requires a new call to unpack)
and/or check to see if the gtEffectiveVal ValueNumber is still a constant.

@kunalspathak
Copy link
Member Author

You could assert that there is no exception set on the gtEffectiveVal, (which requires a new call to unpack)
and/or check to see if the gtEffectiveVal ValueNumber is still a constant.

Did I get it correct?

assert(addr->gtEffectiveVal()->IsCnsIntOrI() || addr->gtEffectiveVal()->gtVNPair.GetLiberal() == ValueNumStore::VNForEmptyExcSet());

@briansull
Copy link
Contributor

addr->gtEffectiveVal()->gtVNPair.GetLiberal()

No, an unpack operation is necessary, you can't do it without introducing new DEBUG only variables.
Example:

            // Unpack, Norm,Exc for 'rhsVNPair'
            ValueNum vnRhsLibNorm;
            vnStore->VNUnpackExc(rhsVNPair.GetLiberal(), &vnRhsLibNorm, &vnExcSet);

Also the changes for this PR doesn't include any changes to ValueNumber.cpp
So I am not seeing your code changes (other than in the comment above)

@kunalspathak
Copy link
Member Author

Also the changes for this PR doesn't include any changes to ValueNumber.cpp

Right, I wanted to make sure that I get it right. So what you are recommending is:

#ifdef DEBUG

                            ValueNum effectiveVnExcSet;
                            ValueNum effectiveValueNum;
                            vnStore->VNUnpackExc(addr->gtEffectiveVal()->gtVNPair.GetLiberal(), &effectiveValueNum,
                                                 &effectiveVnExcSet);
                            assert(addr->gtEffectiveVal()->IsCnsIntOrI() ||
                                   effectiveVnExcSet == ValueNumStore::VNForEmptyExcSet());

#endif
                            tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);

@SingleAccretion
Copy link
Contributor

No, an unpack operation is necessary

Hmm, I though you could also use the VNHasExc helper method in such situations. Is that not true?

@EgorBo
Copy link
Member

EgorBo commented Aug 16, 2021

Also the changes for this PR doesn't include any changes to ValueNumber.cpp
So I am not seeing your code changes (other than in the comment above)

From my understanding that assert can be hit in Main when you enable CSE for constants (string literal handle in this case).

So my suggestion is to rewrite it like this: https://www.diffchecker.com/n2HaLLdk

@kunalspathak
Copy link
Member Author

I have opened #57515 and disabled the test for Arm64 for now.

@kunalspathak
Copy link
Member Author

The failure is related to #57452.

@kunalspathak
Copy link
Member Author

Failures are unrelated.

@kunalspathak kunalspathak merged commit 53d3281 into dotnet:main Aug 17, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Sep 16, 2021
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

operand->gtUseNum == -1 during 'Generate code'
6 participants