diff options
author | Chris Lattner <sabre@nondot.org> | 2006-03-31 06:02:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-03-31 06:02:07 +0000 |
commit | 4468c224586ba0f75e17ed7520a39a30e8caf636 (patch) | |
tree | b6bde7bd8b014208da2812026e02eaea4689f658 /lib/Target | |
parent | 2a8fd4aa18219df4fa2f8c442ace4de2f84d9a23 (diff) | |
download | external_llvm-4468c224586ba0f75e17ed7520a39a30e8caf636.zip external_llvm-4468c224586ba0f75e17ed7520a39a30e8caf636.tar.gz external_llvm-4468c224586ba0f75e17ed7520a39a30e8caf636.tar.bz2 |
Implement an item from the readme, folding vcmp/vcmp. instructions with
identical instructions into a single instruction. For example, for:
void test(vector float *x, vector float *y, int *P) {
int v = vec_any_out(*x, *y);
*x = (vector float)vec_cmpb(*x, *y);
*P = v;
}
we now generate:
_test:
mfspr r2, 256
oris r6, r2, 49152
mtspr 256, r6
lvx v0, 0, r4
lvx v1, 0, r3
vcmpbfp. v0, v1, v0
mfcr r4, 2
stvx v0, 0, r3
rlwinm r3, r4, 27, 31, 31
xori r3, r3, 1
stw r3, 0(r5)
mtspr 256, r2
blr
instead of:
_test:
mfspr r2, 256
oris r6, r2, 57344
mtspr 256, r6
lvx v0, 0, r4
lvx v1, 0, r3
vcmpbfp. v2, v1, v0
mfcr r4, 2
*** vcmpbfp v0, v1, v0
rlwinm r4, r4, 27, 31, 31
stvx v0, 0, r3
xori r3, r4, 1
stw r3, 0(r5)
mtspr 256, r2
blr
Testcase here: CodeGen/PowerPC/vcmp-fold.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27290 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 29 | ||||
-rw-r--r-- | lib/Target/PowerPC/README_ALTIVEC.txt | 9 |
2 files changed, 29 insertions, 9 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index d5da69f..76fcde6 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1368,6 +1368,35 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N, return Val; } break; + case PPCISD::VCMP: { + // If a VCMPo node already exists with exactly the same operands as this + // node, use its result instead of this node (VCMPo computes both a CR6 and + // a normal output). + // + if (!N->getOperand(0).hasOneUse() && + !N->getOperand(1).hasOneUse() && + !N->getOperand(2).hasOneUse()) { + + // Scan all of the users of the LHS, looking for VCMPo's that match. + SDNode *VCMPoNode = 0; + + SDNode *LHSN = N->getOperand(0).Val; + for (SDNode::use_iterator UI = LHSN->use_begin(), E = LHSN->use_end(); + UI != E; ++UI) + if ((*UI)->getOpcode() == PPCISD::VCMPo && + (*UI)->getOperand(1) == N->getOperand(1) && + (*UI)->getOperand(2) == N->getOperand(2) && + (*UI)->getOperand(0) == N->getOperand(0)) { + VCMPoNode = *UI; + break; + } + + // If there are non-zero uses of the flag value, use the VCMPo node! + if (!VCMPoNode->hasNUsesOfValue(0, 1)) + return SDOperand(VCMPoNode, 0); + } + break; + } } return SDOperand(); diff --git a/lib/Target/PowerPC/README_ALTIVEC.txt b/lib/Target/PowerPC/README_ALTIVEC.txt index 7e013a1..a30b39d 100644 --- a/lib/Target/PowerPC/README_ALTIVEC.txt +++ b/lib/Target/PowerPC/README_ALTIVEC.txt @@ -131,15 +131,6 @@ This would fix two problems: //===----------------------------------------------------------------------===// -Two identical comparisons in predicate and nonpredicate form like this: - -a = vec_cmpb(x, y); -b = vec_any_out(x, y); - -Should turn into one "." compare instruction, not a dot and "nondot" form. - -//===----------------------------------------------------------------------===// - Instcombine llvm.ppc.altivec.vperm with an immediate into a shuffle operation. //===----------------------------------------------------------------------===// |