[llvm] [SelectionDAGISel] Don't merge input chains if it would put a token factor in the way of a glue. (PR #167805)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 13 07:34:26 PST 2025
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/167805
>From 712fd9fb4449a32fe598cdfb95fd97eba6908de7 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 12 Nov 2025 17:04:12 -0800
Subject: [PATCH 1/3] [SelectionDAGISel] Don't merge input chains if it would
put a token factor in the way of a glue.
In the new test, we're trying to fold a load and a X86ISD::CALL.
The call has a CopyToReg glued to it. The load and the call have
different input chains so they need to be merged. This results in
a TokenFactor that gets put between the CopyToReg and the final CALLm
instruction. The DAG scheduler can't handle that.
The load here was created by legalization of the extract_element
using a stack temporary store and load. A normal IR load would
be chained into call sequence by SelectionDAGBuilder. This would usually
have the load chained in before the CopyToReg. The store/load created by
legalization don't get chained into the rest of the DAG.
Fixes #63790
---
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 16 ++++++++++++----
llvm/test/CodeGen/X86/pr63790.ll | 10 ++++++++++
2 files changed, 22 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/pr63790.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e78dfb12505c7..9aac0ff3cd8a7 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(SmallVectorImpl<SDNode*> &ChainNodesMatched,
- SelectionDAG *CurDAG) {
+ SDValue InputGlue, SelectionDAG *CurDAG) {
SmallPtrSet<const SDNode *, 16> Visited;
SmallVector<const SDNode *, 8> Worklist;
@@ -2826,8 +2826,16 @@ HandleMergeInputChains(SmallVectorImpl<SDNode*> &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 chains 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..608d3ff41d164
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr63790.ll
@@ -0,0 +1,10 @@
+; RUN: llc < %s -mtriple=x86_64 | FileCheck %s
+
+define void @f(ptr %0, i64 %1) {
+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
+}
>From 2caeb4a745443ac760d1338a64958d671660ee0f Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 12 Nov 2025 17:51:29 -0800
Subject: [PATCH 2/3] fixup! clang-format
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 9aac0ff3cd8a7..efc49941e14db 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2782,7 +2782,7 @@ void SelectionDAGISel::UpdateChains(
/// induce cycles in the DAG) and if so, creating a TokenFactor node. that will
/// be used as the input node chain for the generated nodes.
static SDValue
-HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
+HandleMergeInputChains(SmallVectorImpl<SDNode *> &ChainNodesMatched,
SDValue InputGlue, SelectionDAG *CurDAG) {
SmallPtrSet<const SDNode *, 16> Visited;
@@ -2831,7 +2831,7 @@ HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
// 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 &&
+ V->getValueType(V->getNumValues() - 1) == MVT::Glue &&
InputGlue.getNode() == V.getNode())
return SDValue();
Worklist.push_back(V.getNode());
>From 1c7edce021f41bdb996ba693649a6b03e4d1695c Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 13 Nov 2025 07:34:06 -0800
Subject: [PATCH 3/3] fixup! Add CHECK lines
---
llvm/test/CodeGen/X86/pr63790.ll | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/llvm/test/CodeGen/X86/pr63790.ll b/llvm/test/CodeGen/X86/pr63790.ll
index 608d3ff41d164..e4e7a3c536d07 100644
--- a/llvm/test/CodeGen/X86/pr63790.ll
+++ b/llvm/test/CodeGen/X86/pr63790.ll
@@ -1,6 +1,22 @@
+; 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
More information about the llvm-commits
mailing list