aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-02-13 16:41:00 +0100
committerGitHub <noreply@github.com>2024-02-13 16:41:00 +0100
commit25b9ed6e4964344e3710359bec4c831e5a8448b9 (patch)
tree8f6b5a69ba66cb94cf556333b1d057fd21c2288a
parent89c1bf1230e011f2f0e43554c278205fa1819de5 (diff)
downloadllvm-25b9ed6e4964344e3710359bec4c831e5a8448b9.zip
llvm-25b9ed6e4964344e3710359bec4c831e5a8448b9.tar.gz
llvm-25b9ed6e4964344e3710359bec4c831e5a8448b9.tar.bz2
[DAGCombine] Fix multi-use miscompile in load combine (#81586)
The load combine replaces a number of original loads with one new loads and also replaces the output chains of the original loads with the output chain of the new load. This is incorrect if the original load is retained (due to multi-use), as it may get incorrectly reordered. Fix this by using makeEquivalentMemoryOrdering() instead, which will create a TokenFactor with both chains. Fixes https://github.com/llvm/llvm-project/issues/80911.
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp2
-rw-r--r--llvm/test/CodeGen/X86/load-combine.ll3
2 files changed, 2 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index d3cd9b1..52011e5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9252,7 +9252,7 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
// Transfer chain users from old loads to the new load.
for (LoadSDNode *L : Loads)
- DAG.ReplaceAllUsesOfValueWith(SDValue(L, 1), SDValue(NewLoad.getNode(), 1));
+ DAG.makeEquivalentMemoryOrdering(L, NewLoad);
if (!NeedsBswap)
return NewLoad;
diff --git a/llvm/test/CodeGen/X86/load-combine.ll b/llvm/test/CodeGen/X86/load-combine.ll
index 7e4e11f..b5f3e78 100644
--- a/llvm/test/CodeGen/X86/load-combine.ll
+++ b/llvm/test/CodeGen/X86/load-combine.ll
@@ -1283,7 +1283,6 @@ define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {
ret i32 %tmp8
}
-; FIXME: This is a miscompile.
define i32 @pr80911_vector_load_multiuse(ptr %ptr, ptr %clobber) nounwind {
; CHECK-LABEL: pr80911_vector_load_multiuse:
; CHECK: # %bb.0:
@@ -1299,9 +1298,9 @@ define i32 @pr80911_vector_load_multiuse(ptr %ptr, ptr %clobber) nounwind {
;
; CHECK64-LABEL: pr80911_vector_load_multiuse:
; CHECK64: # %bb.0:
+; CHECK64-NEXT: movl (%rdi), %ecx
; CHECK64-NEXT: movzwl (%rdi), %eax
; CHECK64-NEXT: movl $0, (%rsi)
-; CHECK64-NEXT: movl (%rdi), %ecx
; CHECK64-NEXT: movl %ecx, (%rdi)
; CHECK64-NEXT: retq
%load = load <4 x i8>, ptr %ptr, align 16