Skip to content

Commit

Permalink
PPC: Combine duplicate (offset) lvsl Altivec intrinsics
Browse files Browse the repository at this point in the history
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182708 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Hal Finkel committed May 25, 2013
1 parent 81349a7 commit 5a0e604
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
29 changes: 28 additions & 1 deletion lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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()) &&
Expand Down
6 changes: 6 additions & 0 deletions test/CodeGen/PowerPC/unal-altivec.ll
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit 5a0e604

Please sign in to comment.