diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2013-01-06 19:00:15 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2013-01-06 19:00:15 +0000 |
| commit | 3fb03e23a42b064877497bb9c045b99693d14c95 (patch) | |
| tree | e5b58cc9e654d7d2e31f5e196f400833acc291bf /llvm | |
| parent | 4077efc146a70d2d934200f0aaa3eae9ce388926 (diff) | |
| download | bcm5719-llvm-3fb03e23a42b064877497bb9c045b99693d14c95.tar.gz bcm5719-llvm-3fb03e23a42b064877497bb9c045b99693d14c95.zip | |
Fix for PR14739. It's not safe to fold a load into a call across a store. Thanks to Nick Lewycky for the initial patch.
llvm-svn: 171665
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 5 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/fold-call.ll | 25 |
2 files changed, 26 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index c1eaa0e654c..935f9bd715f 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -420,6 +420,11 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) { if (!Chain.getNumOperands()) return false; + // Since we are not checking for AA here, conservatively abort if the chain + // writes to memory. It's not safe to move the callee (a load) across a store. + if (isa<MemSDNode>(Chain.getNode()) && + cast<MemSDNode>(Chain.getNode())->writeMem()) + return false; if (Chain.getOperand(0).getNode() == Callee.getNode()) return true; if (Chain.getOperand(0).getOpcode() == ISD::TokenFactor && diff --git a/llvm/test/CodeGen/X86/fold-call.ll b/llvm/test/CodeGen/X86/fold-call.ll index 603e9ad66ca..35327faa648 100644 --- a/llvm/test/CodeGen/X86/fold-call.ll +++ b/llvm/test/CodeGen/X86/fold-call.ll @@ -1,10 +1,27 @@ -; RUN: llc < %s -march=x86 | not grep mov -; RUN: llc < %s -march=x86-64 | not grep mov +; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -march=x86-64 | FileCheck %s -declare void @bar() +; CHECK: test1 +; CHECK-NOT: mov -define void @foo(i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, void()* %arg) nounwind { +declare void @bar() +define void @test1(i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, void()* %arg) nounwind { call void @bar() call void %arg() ret void } + +; PR14739 +; CHECK: test2 +; CHECK: mov{{.*}} $0, ([[REGISTER:%[a-z]+]]) +; CHECK-NOT: jmp{{.*}} *([[REGISTER]]) + +%struct.X = type { void ()* } +define void @test2(%struct.X* nocapture %x) { +entry: + %f = getelementptr inbounds %struct.X* %x, i64 0, i32 0 + %0 = load void ()** %f + store void ()* null, void ()** %f + tail call void %0() + ret void +} |

