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

LICM does not detect defs from virtual method calls #7003

Closed
LouisJenkinsCS opened this issue Aug 12, 2017 · 10 comments
Closed

LICM does not detect defs from virtual method calls #7003

LouisJenkinsCS opened this issue Aug 12, 2017 · 10 comments

Comments

@LouisJenkinsCS
Copy link
Member

Summary of Problem

Loop Invariant Code Motion (LICM) seems to cause some sort of 'undefined behavior' in that it causes some things to be compiled away entirely. Like how the tuple variable seems to be given undefined/uninitialized values. Furthermore, how the entire loop gets optimized away if we do not add that extra 'writeln' (of which is not needed with the --no-loop-invariant-code-motion flag).

As well, this is another opportunity to bring another issue that @e-kayrakli had made in my place, #6542 , which can also be reproduced here by calling fn() without capturing it in the the tuples (a,b) will produce a segfault (with and without --no-loop-invariant-code-motion flag).

The amount of time I've spent double, triple, and quadruple checking my data structure thinking that I corrupted my data structure or something was exhausting.

Steps to Reproduce

Source Code:

TIO (Online Compiler)

With --no-loop-invariant-code-motion

TIO (Online Compiler)

class D {
  proc fn() : (bool, int) {
    halt("Should not be called...");
  }
}

class C : D {
  proc fn() : (bool, int) {
    return (false, 1);
  }
}

var c : D = new C();

var (a, b) = (true, 0);
for 1 .. 5 {
  // This shows that the value, if printed prior to usage, seems to cause an issue
  if b != 0 then writeln("a: ", a, ", b: ", b);
  (a, b) = c.fn();
}
// Note: If this line is removed, the loop itself will not run (optimized away?)
writeln("Needed so it will not be compiled away on TIO...");

Output:

a: true, b: 180388626485
a: true, b: 180388626485
a: true, b: 180388626485
a: true, b: 180388626485
Needed so it will not be compiled away on TIO...

Output (With '--no-loop-invariant-code-motion'):

a: false, b: 1
a: false, b: 1
a: false, b: 1
a: false, b: 1
Needed so it will not be compiled away on TIO...
@LouisJenkinsCS
Copy link
Member Author

@ben-albrecht

Here is the issue and MWE you wanted me to make.

@ronawho

Ben said you'd be interested in this.

@LouisJenkinsCS
Copy link
Member Author

LouisJenkinsCS commented Aug 12, 2017

@e-kayrakli

I think I came across this bug before as well, it was when I reported that 'Dynamic Dispatch was causing undefined behavior' for my FIFO queue, and you said that dynamic dispatch was just exposing some race condition. Code used the exact same pattern here (code is snapshot of almost 2 months ago). I spent days trying to figure out what was wrong, at least now I know its a bug.

@ben-albrecht
Copy link
Member

ben-albrecht commented Aug 14, 2017

For context on why this considered a "gating issue":

fn() is a simplified remove() from the Collections Module.

@ronawho
Copy link
Contributor

ronawho commented Aug 17, 2017

I think I have a good lead on the issue here. I'm going to be away for the next 2 weeks, but I think I can get a fix in for the release.

@ben-albrecht could add a .future test for this bug and link to it in the issue description?

@ronawho ronawho added this to the 1.16.0 milestone Sep 12, 2017
@ronawho ronawho changed the title LICM introduces undefined behavior for tuple variables declared outside of loop. LICM does not detect defs from virtual method calls Sep 14, 2017
ronawho added a commit to ronawho/chapel that referenced this issue Sep 14, 2017
Add test to show licm bug related to virtual methods. Code is from
chapel-lang#7003
ronawho added a commit to ronawho/chapel that referenced this issue Sep 14, 2017
`astutil.cpp:isDefAndOrUse()` doesn't currently handle virtual methods, so we
weren't detecting a def of a variable through a virtual method call. Workaround
this limitation by checking for virtual methods defs in licm.

Note that the correct solution here is to update isDefAndOrUse, but that led to
regressions that I don't have time to look into yet.

Closes chapel-lang#7003
ronawho added a commit that referenced this issue Sep 14, 2017
Fix licm bug with dynamic dispatch

[reviewed by @benharsh]

`astutil.cpp:isDefAndOrUse()` doesn't currently handle virtual methods, so we
weren't detecting a def of a variable through a virtual method call. Workaround
this limitation by checking for virtual methods defs in licm.

Note that the correct solution here is to update isDefAndOrUse, but that led to
regressions that I don't have time to look into yet.

Closes #7003
@ronawho
Copy link
Contributor

ronawho commented Sep 14, 2017

@ben-albrecht and/or @LouisJenkinsCS #7315 should resolve this. Can you confirm that this resolves the issue you were running into and if so remove the bug-note in Collection.chpl

@LouisJenkinsCS
Copy link
Member Author

I'll make it a priority to get around to testing it myself (rerunning all tests without --no-loop-invariant-code-motion) and removing any trace of those bug notes tonight. I'll update here when I do.

@LouisJenkinsCS
Copy link
Member Author

All tests succeed, I'll make a new PR soon.

@ronawho
Copy link
Contributor

ronawho commented Sep 14, 2017

Cool! Thanks for checking

@LouisJenkinsCS
Copy link
Member Author

@ronawho

I spoke too soon. I went back and made a few minor changes to the unit tests (refactored as originally it was written to 'step around' the whole LICM bug), and now I get this:

A while loop with a constant condition

I'll make a PR soon, and @ mention you on it.

@LouisJenkinsCS
Copy link
Member Author

Posting this here:

#7322 (comment)

Its link to my comment in case not notified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants