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 | d4058a59d4943b717f9a90682a91c0082d261e49 (patch) | |
| tree | ed7b5b00844199c08763de6d62167d9dddc2b3e1 | |
| parent | 5f0744d677ffa40335d26f177be4542a81c3e926 (diff) | |
| download | bcm5719-llvm-d4058a59d4943b717f9a90682a91c0082d261e49.tar.gz bcm5719-llvm-d4058a59d4943b717f9a90682a91c0082d261e49.zip | |
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
llvm-svn: 27290
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/README_ALTIVEC.txt | 9 | 
2 files changed, 29 insertions, 9 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index d5da69f5062..76fcde65b8d 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/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/llvm/lib/Target/PowerPC/README_ALTIVEC.txt b/llvm/lib/Target/PowerPC/README_ALTIVEC.txt index 7e013a1ccf3..a30b39ddded 100644 --- a/llvm/lib/Target/PowerPC/README_ALTIVEC.txt +++ b/llvm/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.  //===----------------------------------------------------------------------===// | 

