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 | 700843ec2c4cb4aa442377809c6ebb3ae3030c61 (patch) | |
tree | bf8225bf3559cfb593f53cb2c97e2a5e05e611f9 | |
parent | c6b4936a59234704b788532de36d860f14b45e82 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171665 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 5 | ||||
-rw-r--r-- | test/CodeGen/X86/fold-call.ll | 25 |
2 files changed, 26 insertions, 4 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index c1eaa0e654..935f9bd715 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/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/test/CodeGen/X86/fold-call.ll b/test/CodeGen/X86/fold-call.ll index 603e9ad66c..35327faa64 100644 --- a/test/CodeGen/X86/fold-call.ll +++ b/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 +} |