diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e7d4c4b88191b..5bed32db528d6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2783,7 +2783,7 @@ void SelectionDAGISel::UpdateChains( /// be used as the input node chain for the generated nodes. static SDValue HandleMergeInputChains(const SmallVectorImpl &ChainNodesMatched, - SelectionDAG *CurDAG) { + SDValue InputGlue, SelectionDAG *CurDAG) { SmallPtrSet Visited; SmallVector Worklist; @@ -2826,8 +2826,16 @@ HandleMergeInputChains(const SmallVectorImpl &ChainNodesMatched, // node that is both the predecessor and successor of the // to-be-merged nodes. Fail. Visited.clear(); - for (SDValue V : InputChains) + for (SDValue V : InputChains) { + // If we need to create a TokenFactor, and any of the input chain nodes will + // also be glued to the output, we cannot merge the chains. The TokenFactor + // would prevent the glue from being honored. + if (InputChains.size() != 1 && + V->getValueType(V->getNumValues() - 1) == MVT::Glue && + InputGlue.getNode() == V.getNode()) + return SDValue(); Worklist.push_back(V.getNode()); + } for (auto *N : ChainNodesMatched) if (SDNode::hasPredecessorHelper(N, Visited, Worklist, Max, true)) @@ -3989,7 +3997,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, } // Merge the input chains if they are not intra-pattern references. - InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG); + InputChain = HandleMergeInputChains(ChainNodesMatched, InputGlue, CurDAG); if (!InputChain.getNode()) break; // Failed to merge. @@ -4033,7 +4041,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, break; // Merge the input chains if they are not intra-pattern references. - InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG); + InputChain = HandleMergeInputChains(ChainNodesMatched, InputGlue, CurDAG); if (!InputChain.getNode()) break; // Failed to merge. diff --git a/llvm/test/CodeGen/X86/pr63790.ll b/llvm/test/CodeGen/X86/pr63790.ll new file mode 100644 index 0000000000000..e4e7a3c536d07 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr63790.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -mtriple=x86_64 | FileCheck %s + +define void @f(ptr %0, i64 %1) { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %BB +; CHECK-NEXT: subq $40, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: andl $1, %esi +; CHECK-NEXT: movaps (%rdi), %xmm0 +; CHECK-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; CHECK-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movl $42, %edi +; CHECK-NEXT: callq *16(%rsp,%rsi,8) +; CHECK-NEXT: movaps (%rsp), %xmm0 # 16-byte Reload +; CHECK-NEXT: movaps %xmm0, (%rax) +; CHECK-NEXT: addq $40, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +BB: + %fps = load <2 x ptr>, ptr %0 + %fp = extractelement <2 x ptr> %fps, i64 %1 + %p = call ptr %fp(i32 42) + store <2 x ptr> %fps, ptr %p + ret void +}