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 | |
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
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 29 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/unal-altivec.ll | 6 |
2 files changed, 34 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()) && diff --git a/llvm/test/CodeGen/PowerPC/unal-altivec.ll b/llvm/test/CodeGen/PowerPC/unal-altivec.ll index f89f299e142..dec93ebf769 100644 --- a/llvm/test/CodeGen/PowerPC/unal-altivec.ll +++ b/llvm/test/CodeGen/PowerPC/unal-altivec.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mcpu=g5 | FileCheck %s +; RUN: llc < %s -mcpu=g5 | FileCheck %s -check-prefix=CHECK-PC target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -38,6 +39,11 @@ vector.body: ; preds = %vector.body, %vecto ; CHECK: vaddfp {{[0-9]+}}, [[R1]], [[CNST]] ; CHECK: blr +; CHECK-PC: @foo +; CHECK-PC: lvsl +; CHECK-PC-NOT: lvsl +; CHECK-PC: blr + for.end: ; preds = %vector.body ret void } |