diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1801,8 +1801,22 @@ // Iterate through token factors. The TFs grows when new token factors are // encountered. for (unsigned i = 0; i < TFs.size(); ++i) { - SDNode *TF = TFs[i]; + // Limit number of nodes to inline, to avoid quadratic compile times. + // We have to add the outstanding tokenfactors to Ops, otherwise we might + // drop Ops from the resulting tokenfactor. + if (Ops.size() > 2048) { + // Expand first outstanding tokenfactor, to ensure we create a changed + // node. Otherwise, in some cases we might return an unchanged tokenfactor + // and we can get stuck in a cycle. + for (const SDValue &Op : TFs[i]->op_values()) + Ops.push_back(Op); + // Add remaining tokenfactors directly. + for (i++; i < TFs.size(); i++) + Ops.emplace_back(TFs[i], 0); + break; + } + SDNode *TF = TFs[i]; // Check each of the operands. for (const SDValue &Op : TF->op_values()) { switch (Op.getOpcode()) {