This is an archive of the discontinued LLVM Phabricator instance.

[coroutines] Insert spills of PHI instructions correctly
ClosedPublic

Authored by GorNishanov on Apr 6 2017, 6:13 PM.

Details

Summary

Fix a bug where we were inserting a spill in between the PHIs in the beginning of the block.
Consider this fragment:

begin:
  %phi1 = phi i32 [ 0, %entry ], [ 2, %alt ]
  %phi2 = phi i32 [ 1, %entry ], [ 3, %alt ]
  %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
  switch i8 %sp1, label %suspend [i8 0, label %resume
                                  i8 1, label %cleanup]
resume:
  call i32 @print(i32 %phi1)

Unless we are spilling the argument or result of the invoke, we were always inserting the spill immediately following the instruction.
The fix adds a check that if the spilled instruction is a PHI Node, select an appropriate insert point with getFirstInsertionPt() that
skips all the PHI Nodes and EH pads.

Diff Detail

Repository
rL LLVM

Event Timeline

GorNishanov created this revision.Apr 6 2017, 6:13 PM
rnk accepted this revision.Apr 6 2017, 6:22 PM

lgtm

lib/Transforms/Coroutines/CoroFrame.cpp
441 ↗(On Diff #94469)

This will be a problem if this phi is in a catchswitch block created for MSVC EH. Is that something you worry about yet? You can make such a phi like this:

int x = 0;
try {
  may_throw();
  ++x;
  may_throw();
} catch (...) {
  use_int(x);
}

I'm not sure what you need to do to make this a coroutine as well, but maybe you can make a test case that way.

Anyway, this is totally something that doesn't need to be addressed in this change.

This revision is now accepted and ready to land.Apr 6 2017, 6:22 PM
This revision was automatically updated to reflect the committed changes.
GorNishanov added inline comments.Apr 7 2017, 7:30 AM
lib/Transforms/Coroutines/CoroFrame.cpp
441 ↗(On Diff #94469)

Thank you very much for review!

Good point about cathswitch. I'll have a fix for it in two commits. I will need to add eh aware edge splitting first.