summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-02-22 05:18:04 +0000
committerChris Lattner <sabre@nondot.org>2008-02-22 05:18:04 +0000
commitab8bfc28c8c1bdbc070301ce7c92cf7ba94e2451 (patch)
tree2514b0e24d8c7fe4f0c8cccd37630b9a3343c77b
parente665095da163cc6be8bc0dffd32edfd9548045e0 (diff)
downloadbcm5719-llvm-ab8bfc28c8c1bdbc070301ce7c92cf7ba94e2451.tar.gz
bcm5719-llvm-ab8bfc28c8c1bdbc070301ce7c92cf7ba94e2451.zip
copy mmx values from/to memory with GPRs on x86-32
instead of with mmx registers. This horribleness is apparently done by gcc to avoid having to insert emms in places that really should have it. This is the second half of rdar://5741668. llvm-svn: 47474
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp26
-rw-r--r--llvm/test/CodeGen/X86/mmx-copy-gprs.ll5
2 files changed, 28 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 96a58c11ef7..a2e0036e38d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -5897,7 +5897,31 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
St->isVolatile(), St->getAlignment());
}
- // TODO: 2 32-bit copies.
+ // Otherwise, lower to two 32-bit copies.
+ SDOperand LoAddr = Ld->getBasePtr();
+ SDOperand HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
+ DAG.getConstant(MVT::i32, 4));
+
+ SDOperand LoLd = DAG.getLoad(MVT::i32, Ld->getChain(), LoAddr,
+ Ld->getSrcValue(), Ld->getSrcValueOffset(),
+ Ld->isVolatile(), Ld->getAlignment());
+ SDOperand HiLd = DAG.getLoad(MVT::i32, Ld->getChain(), HiAddr,
+ Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
+ Ld->isVolatile(),
+ MinAlign(Ld->getAlignment(), 4));
+
+ LoAddr = St->getBasePtr();
+ HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
+ DAG.getConstant(MVT::i32, 4));
+
+ SDOperand LoSt = DAG.getStore(LoLd.getValue(1), LoLd, LoAddr,
+ St->getSrcValue(), St->getSrcValueOffset(),
+ St->isVolatile(), St->getAlignment());
+ SDOperand HiSt = DAG.getStore(HiLd.getValue(1), HiLd, HiAddr,
+ St->getSrcValue(), St->getSrcValueOffset()+4,
+ St->isVolatile(),
+ MinAlign(St->getAlignment(), 4));
+ return DAG.getNode(ISD::TokenFactor, MVT::Other, LoSt, HiSt);
}
return SDOperand();
}
diff --git a/llvm/test/CodeGen/X86/mmx-copy-gprs.ll b/llvm/test/CodeGen/X86/mmx-copy-gprs.ll
index 8cf36e05a83..da17a04a466 100644
--- a/llvm/test/CodeGen/X86/mmx-copy-gprs.ll
+++ b/llvm/test/CodeGen/X86/mmx-copy-gprs.ll
@@ -1,4 +1,5 @@
; RUN: llvm-as < %s | llc -march=x86-64 | grep {movq.*(%rsi), %rax}
+; RUN: llvm-as < %s | llc -march=x86 | grep {movl.*4(%eax),}
; This test should use GPRs to copy the mmx value, not MMX regs. Using mmx regs,
; increases the places that need to use emms.
@@ -6,9 +7,9 @@
; rdar://5741668
target triple = "x86_64-apple-darwin8"
-define i32 @foo(<1 x i64>* %x, <1 x i64>* %y) nounwind {
+define void @foo(<1 x i64>* %x, <1 x i64>* %y) nounwind {
entry:
%tmp1 = load <1 x i64>* %y, align 8 ; <<1 x i64>> [#uses=1]
store <1 x i64> %tmp1, <1 x i64>* %x, align 8
- ret i32 undef
+ ret void
}
OpenPOWER on IntegriCloud