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
This commit is contained in:
Chris Lattner 2006-03-31 06:02:07 +00:00
parent 2a8fd4aa18
commit 4468c22458
2 changed files with 29 additions and 9 deletions

View File

@ -1368,6 +1368,35 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
return Val; return Val;
} }
break; 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(); return SDOperand();

View File

@ -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. Instcombine llvm.ppc.altivec.vperm with an immediate into a shuffle operation.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//