This is an archive of the discontinued LLVM Phabricator instance.

[SelectionDAG] Split very large token factors for loads into 64k chunks
ClosedPublic

Authored by aemerson on Nov 29 2018, 1:07 PM.

Details

Summary

There's a 64k limit on the number of SDNode operands, and some very large functions with 64k or more loads can cause crashes due to this limit being hit when a TokenFactor with this many operands is created. To fix this, create sub-tokenfactors if we've exceeded the limit. No test case as it requires a very large function, however, the test is just this:

define void @foo() {                                                                                                                                                                                                                                                                                                          
  %r1 = load i8, i8* undef                                                                                                                                                                                                                                                                                                    
  %r2 = load i8, i8* undef                                                                                                                                                                                                                                                                                                    
  %r3 = load i8, i8* undef
  ... etc etc 2^16 times
  call void @llvm.trap()                                                                                                                                                                                                                                                                                                      
  unreachable

rdar://45196621

Diff Detail

Repository
rL LLVM

Event Timeline

aemerson created this revision.Nov 29 2018, 1:07 PM
efriedma added inline comments.
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
1052 ↗(On Diff #175944)

Instead of making a tree of TokenFactors, could you make a list? It seems a little simpler (less code, and you don't have to worry about the length of TokenFactors itself).

I'm a little worried that other code dealing with TokenFactors might end up violating the limit if we're very close... any idea if there's other code that could be affected, like DAGCombine? Do we have an assertion somewhere that will reliably catch this issue?

aemerson marked an inline comment as done.Nov 29 2018, 2:52 PM
aemerson added inline comments.
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
1052 ↗(On Diff #175944)

Could you clarify what you mean by list?

efriedma added inline comments.Nov 29 2018, 3:01 PM
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
1052 ↗(On Diff #175944)

I mean, each TokenFactor should only have one TokenFactor operand. So the algorithm would be something like this: remove "Limit" loads from end of PendingLoads, make a TokenFactor, and append the resulting TokenFactor to PendingLoads. Repeat as necessary.

Does this fix PR7250 and PR37000 ? Those test cases look usable.

aemerson marked an inline comment as done and an inline comment as not done.Nov 30 2018, 1:22 PM

Does this fix PR7250 and PR37000 ? Those test cases look usable.

PR7250 asserts in a different place, for the number of result values of a node. This issue is very similar, but instead exceeds the number of operands.

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
1052 ↗(On Diff #175944)

Ok, I could do that. As for the other places, since SDAG will CSE nodes we should be able to catch this case in getNode() somewhere and assert.

aemerson updated this revision to Diff 176189.Nov 30 2018, 1:31 PM

Changed the approach to replace values in PendingLoads in place. Also added an assert in SelectionDAG::createOperands() to check if we can store the requested number of operands.

efriedma accepted this revision.Dec 4 2018, 3:54 PM

LGTM

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
9027 ↗(On Diff #176189)

Maybe this would be more readable using std::numeric_limits? Your choice.

This revision is now accepted and ready to land.Dec 4 2018, 3:54 PM
aemerson marked an inline comment as done.Dec 4 2018, 4:33 PM
aemerson added inline comments.
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
9027 ↗(On Diff #176189)

Sure.

This revision was automatically updated to reflect the committed changes.