diff options
author | Chris Lattner <sabre@nondot.org> | 2006-04-02 05:30:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-04-02 05:30:25 +0000 |
commit | f42d0aeda16357403fff5729676fab2cb50008c7 (patch) | |
tree | 40285de09dc7d93b43f5f8e37ab74bc6aead0320 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp | |
parent | 80fdc1eb6bf93a454585c2f6fe7fb54f81cff8bd (diff) | |
download | bcm5719-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.cpp | 22 |
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. |