Skip to content

SILCombine: fix a miscompile caused by dead-apply elimination #21803

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

Merged
merged 1 commit into from
Jan 14, 2019

Conversation

eeckstein
Copy link
Contributor

SILCombine ended up moving a strong_release past a dealloc_ref.

fixes https://bugs.swift.org/browse/SR-9627
rdar://problem/47153896

@eeckstein
Copy link
Contributor Author

@swift-ci test

@eeckstein eeckstein requested a review from gottesmm January 11, 2019 22:30
@eeckstein
Copy link
Contributor Author

@swift-ci benchmark

Copy link
Contributor

@gottesmm gottesmm left a comment

Choose a reason for hiding this comment

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

Looks overall good. Just needs more comments.

Did you figure out why we were actually moving this past the dealloc_ref? Was it b/c of the weird _effects thing? Maybe we should get rid of that?

// TODO: this is not required anymore when we have ownership SIL. But with
// the current SIL it can happen that the retain of a parameter is moved
// _after_ the apply.
// When we have ownerhip SIL we can just destroy the parameters at the apply
Copy link
Contributor

Choose a reason for hiding this comment

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

ownerhip => ownership

@@ -556,6 +563,12 @@ bool SILCombiner::eraseApply(FullApplySite FAS, const UserListTy &Users) {
} else {
if (!VLA.computeFrontier(Frontier, ValueLifetimeAnalysis::DontModifyCFG))
return false;
// As we are extending the lifetimes of owned parameters, we have to make
// sure that no dealloc_ref instructions are within this extended liferange.
// It could be that the dealloc_ref is deallocting a parameter and then
Copy link
Contributor

Choose a reason for hiding this comment

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

deallocting => deallocating

@@ -282,6 +282,9 @@ class ValueLifetimeAnalysis {
return LiveBlocks.count(BB) && BB != DefValue->getParent();
}

// Checks if there is a dealloc_ref inside the value's liferange.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we have been using the term "live range" instead of life range, no? Also this is an interface so it should be a doxygen comment (i.e. 3 slashes).

@@ -1369,6 +1369,37 @@ bool ValueLifetimeAnalysis::isWithinLifetime(SILInstruction *Inst) {
llvm_unreachable("Expected to find use of value in block!");
}

static bool blockContainsDeallocRef(SILBasicBlock *BB, SILInstruction *DefValue,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a comment here describing what you are doing? I would say something like:

Searches \p BB backwards from \p FrontierInst to the beginning of the list and returns true if we find a dealloc_ref /before/ we find the instruction that defines our target value.

Also, can you rename DefValue => ValueDefiningInst? Then it is really clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll keep DefValue, because it's consistent with ValueLifetimeAnalsis::DefValue

return false;
}

bool ValueLifetimeAnalysis::containsDeallocRef(const Frontier &Frontier) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this could use a comment as well. I know what you are doing here, but I had to read the code. I should be able to understand without reading the body basically what this is doing.

@eeckstein
Copy link
Contributor Author

I'm not sure why we are moving the retain. But with Ownership SIL we will not have the problem anymore, anyway

@swift-ci
Copy link
Contributor

Build comment file:

Performance: -Onone

TEST OLD NEW DELTA RATIO
Regression
DataAppendDataSmallToSmall 4100 4520 +10.2% 0.91x (?)
UTF8Decode_InitDecoding_ascii 757 816 +7.8% 0.93x (?)
How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac Pro
  Model Identifier: MacPro6,1
  Processor Name: 12-Core Intel Xeon E5
  Processor Speed: 2.7 GHz
  Number of Processors: 1
  Total Number of Cores: 12
  L2 Cache (per Core): 256 KB
  L3 Cache: 30 MB
  Memory: 64 GB
--------------

SILCombine ended up moving a strong_release past a dealloc_ref.
fixes https://bugs.swift.org/browse/SR-9627
rdar://problem/47153896
@eeckstein
Copy link
Contributor Author

@swift-ci smoke test

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

Successfully merging this pull request may close these issues.

3 participants