[PATCH] D55073: [SelectionDAG] Split very large token factors for loads into 64k chunks

Amara Emerson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 29 13:07:44 PST 2018


aemerson created this revision.
aemerson added reviewers: craig.topper, spatel, eli.friedman.

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


Repository:
  rL LLVM

https://reviews.llvm.org/D55073

Files:
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp


Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1032,8 +1032,25 @@
   }
 
   // Otherwise, we have to make a token factor node.
-  SDValue Root = DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other,
-                             PendingLoads);
+  // If we have >= 2^16 loads then split across multiple token factors as
+  // there's a 64k limit on the number of SDNode operands.
+  SDValue Root;
+  size_t Limit = (1 << 16) - 1;
+  if (PendingLoads.size() <= Limit) {
+    Root =
+        DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, PendingLoads);
+  } else {
+    SmallVector<SDValue, 4> TokenFactors;
+    for (unsigned i = 0; i < PendingLoads.size(); i += Limit) {
+      auto LoadSlice = ArrayRef<SDValue>(PendingLoads)
+                           .slice(i, std::min(Limit, PendingLoads.size() - i));
+      assert(LoadSlice.size() <= Limit && "Too many loads in slice");
+      TokenFactors.emplace_back(
+          DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, LoadSlice));
+    }
+    Root =
+        DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, TokenFactors);
+  }
   PendingLoads.clear();
   DAG.setRoot(Root);
   return Root;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55073.175944.patch
Type: text/x-patch
Size: 1362 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181129/d689cb52/attachment.bin>


More information about the llvm-commits mailing list