diff options
author | Hal Finkel <hfinkel@anl.gov> | 2013-05-25 04:05:05 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2013-05-25 04:05:05 +0000 |
commit | bc2ee4c4e6e4ecb8acbc37144edd8957ce4722b1 (patch) | |
tree | c7c73b58a326d79dd28108db8734936e09b0238e /llvm/lib/Target/PowerPC/PPCISelLowering.cpp | |
parent | 8972aba19393b96c50507390ebaf4c3e5bb5c55b (diff) | |
download | bcm5719-llvm-bc2ee4c4e6e4ecb8acbc37144edd8957ce4722b1.tar.gz bcm5719-llvm-bc2ee4c4e6e4ecb8acbc37144edd8957ce4722b1.zip |
PPC: Combine duplicate (offset) lvsl Altivec intrinsics
The lvsl permutation control instruction is a function only of the alignment of
the pointer operand (relative to the 16-byte natural alignment of Altivec
vectors). As a result, multiple lvsl intrinsics where the operands differ by a
multiple of 16 can be combined.
llvm-svn: 182708
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 6c8af0c3689..f47376cc51b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -540,6 +540,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::BR_CC); setTargetDAGCombine(ISD::BSWAP); + setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); // Use reciprocal estimates. if (TM.Options.UnsafeFPMath) { @@ -6988,8 +6989,10 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, // cause the last vector in the sequence to be (re)loaded. Otherwise, // the next vector will be fetched as you might suspect was necessary. - // FIXME: We might be able to reuse the permutation generation from + // We might be able to reuse the permutation generation from // a different base address offset from this one by an aligned amount. + // The INTRINSIC_WO_CHAIN DAG combine will attempt to perform this + // optimization later. SDValue PermCntl = BuildIntrinsicOp(Intrinsic::ppc_altivec_lvsl, Ptr, DAG, dl, MVT::v16i8); @@ -7074,6 +7077,30 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, } } break; + case ISD::INTRINSIC_WO_CHAIN: + if (cast<ConstantSDNode>(N->getOperand(0))->getZExtValue() == + Intrinsic::ppc_altivec_lvsl && + N->getOperand(1)->getOpcode() == ISD::ADD) { + SDValue Add = N->getOperand(1); + + if (DAG.MaskedValueIsZero(Add->getOperand(1), + APInt::getAllOnesValue(4 /* 16 byte alignment */).zext( + Add.getValueType().getScalarType().getSizeInBits()))) { + SDNode *BasePtr = Add->getOperand(0).getNode(); + for (SDNode::use_iterator UI = BasePtr->use_begin(), + UE = BasePtr->use_end(); UI != UE; ++UI) { + if (UI->getOpcode() == ISD::INTRINSIC_WO_CHAIN && + cast<ConstantSDNode>(UI->getOperand(0))->getZExtValue() == + Intrinsic::ppc_altivec_lvsl) { + // We've found another LVSL, and this address if an aligned + // multiple of that one. The results will be the same, so use the + // one we've just found instead. + + return SDValue(*UI, 0); + } + } + } + } case ISD::BSWAP: // Turn BSWAP (LOAD) -> lhbrx/lwbrx. if (ISD::isNON_EXTLoad(N->getOperand(0).getNode()) && |