summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-04-02 05:30:25 +0000
committerChris Lattner <sabre@nondot.org>2006-04-02 05:30:25 +0000
commitf42d0aeda16357403fff5729676fab2cb50008c7 (patch)
tree40285de09dc7d93b43f5f8e37ab74bc6aead0320 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parent80fdc1eb6bf93a454585c2f6fe7fb54f81cff8bd (diff)
downloadbcm5719-llvm-f42d0aeda16357403fff5729676fab2cb50008c7.tar.gz
bcm5719-llvm-f42d0aeda16357403fff5729676fab2cb50008c7.zip
Turn altivec lvx/stvx intrinsics into loads and stores. This allows the
elimination of one load from this: int AreSecondAndThirdElementsBothNegative( vector float *in ) { #define QNaN 0x7FC00000 const vector unsigned int testData = (vector unsigned int)( QNaN, 0, 0, QNaN ); vector float test = vec_ld( 0, (float*) &testData ); return ! vec_any_ge( test, *in ); } Now generating: _AreSecondAndThirdElementsBothNegative: mfspr r2, 256 oris r4, r2, 49152 mtspr 256, r4 li r4, lo16(LCPI1_0) lis r5, ha16(LCPI1_0) addi r6, r1, -16 lvx v0, r5, r4 stvx v0, 0, r6 lvx v1, 0, r3 vcmpgefp. v0, v0, v1 mfcr r3, 2 rlwinm r3, r3, 27, 31, 31 xori r3, r3, 1 cntlzw r3, r3 srwi r3, r3, 5 mtspr 256, r2 blr llvm-svn: 27352
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index c5c2a5e3c57..3697b2a5148 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -5437,6 +5437,28 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
} else {
switch (II->getIntrinsicID()) {
default: break;
+ case Intrinsic::ppc_altivec_lvx:
+ case Intrinsic::ppc_altivec_lvxl:
+ // Turn lvx -> load if the pointer is known aligned.
+ if (GetKnownAlignment(II->getOperand(1), TD) >= 16) {
+ Instruction *Ptr = new CastInst(II->getOperand(1),
+ PointerType::get(II->getType()), "tmp");
+ InsertNewInstBefore(Ptr, CI);
+ return new LoadInst(Ptr);
+ }
+ break;
+ case Intrinsic::ppc_altivec_stvx:
+ case Intrinsic::ppc_altivec_stvxl:
+ // Turn stvx -> store if the pointer is known aligned.
+ if (GetKnownAlignment(II->getOperand(2), TD) >= 16) {
+ const Type *OpTy = II->getOperand(1)->getType();
+ Instruction *Ptr = new CastInst(II->getOperand(2),
+ PointerType::get(OpTy), "tmp");
+ InsertNewInstBefore(Ptr, CI);
+ return new StoreInst(II->getOperand(1), Ptr);
+ }
+ break;
+
case Intrinsic::stackrestore: {
// If the save is right next to the restore, remove the restore. This can
// happen when variable allocas are DCE'd.
OpenPOWER on IntegriCloud