Adjust isConstantSplat to allow for big-endian targets.

PPC is such a target; make it work.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@87060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2009-11-13 01:45:18 +00:00
parent 0418c102dd
commit 1e608819aa
4 changed files with 35 additions and 8 deletions

View File

@ -1953,10 +1953,10 @@ public:
/// that value are zero, and the corresponding bits in the SplatUndef mask
/// are set. The SplatBitSize value is set to the splat element size in
/// bits. HasAnyUndefs is set to true if any bits in the vector are
/// undefined.
/// undefined. isBigEndian describes the endianness of the target.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
unsigned &SplatBitSize, bool &HasAnyUndefs,
unsigned MinSplatBits = 0);
unsigned MinSplatBits = 0, bool isBigEndian = false);
static inline bool classof(const BuildVectorSDNode *) { return true; }
static inline bool classof(const SDNode *N) {

View File

@ -5916,7 +5916,8 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
APInt &SplatUndef,
unsigned &SplatBitSize,
bool &HasAnyUndefs,
unsigned MinSplatBits) {
unsigned MinSplatBits,
bool isBigEndian) {
EVT VT = getValueType(0);
assert(VT.isVector() && "Expected a vector type");
unsigned sz = VT.getSizeInBits();
@ -5933,12 +5934,14 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
unsigned int nOps = getNumOperands();
assert(nOps > 0 && "isConstantSplat has 0-size build vector");
unsigned EltBitSize = VT.getVectorElementType().getSizeInBits();
for (unsigned i = 0; i < nOps; ++i) {
for (unsigned j = 0; j < nOps; ++j) {
unsigned i = isBigEndian ? nOps-1-j : j;
SDValue OpVal = getOperand(i);
unsigned BitPos = i * EltBitSize;
unsigned BitPos = j * EltBitSize;
if (OpVal.getOpcode() == ISD::UNDEF)
SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos +EltBitSize);
SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos + EltBitSize);
else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal))
SplatValue |= (APInt(CN->getAPIntValue()).zextOrTrunc(EltBitSize).
zextOrTrunc(sz) << BitPos);

View File

@ -637,7 +637,7 @@ bool PPC::isAllNegativeZeroVector(SDNode *N) {
unsigned BitSize;
bool HasAnyUndefs;
if (BV->isConstantSplat(APVal, APUndef, BitSize, HasAnyUndefs, 32))
if (BV->isConstantSplat(APVal, APUndef, BitSize, HasAnyUndefs, 32, true))
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)))
return CFP->getValueAPF().isNegZero();
@ -3672,7 +3672,7 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
unsigned SplatBitSize;
bool HasAnyUndefs;
if (! BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
HasAnyUndefs) || SplatBitSize > 32)
HasAnyUndefs, 0, true) || SplatBitSize > 32)
return SDValue();
unsigned SplatBits = APSplatBits.getZExtValue();

View File

@ -0,0 +1,24 @@
; RUN: llc < %s -march=ppc32 -mtriple=powerpc-apple-darwin -mcpu=g5 | FileCheck %s
; Formerly incorrectly inserted vsldoi (endian confusion)
@baz = common global <16 x i8> zeroinitializer ; <<16 x i8>*> [#uses=1]
define void @foo(<16 x i8> %x) nounwind ssp {
entry:
; CHECK: _foo:
; CHECK-NOT: vsldoi
%x_addr = alloca <16 x i8> ; <<16 x i8>*> [#uses=2]
%temp = alloca <16 x i8> ; <<16 x i8>*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store <16 x i8> %x, <16 x i8>* %x_addr
store <16 x i8> <i8 0, i8 0, i8 0, i8 14, i8 0, i8 0, i8 0, i8 14, i8 0, i8 0, i8 0, i8 14, i8 0, i8 0, i8 0, i8 14>, <16 x i8>* %temp, align 16
%0 = load <16 x i8>* %x_addr, align 16 ; <<16 x i8>> [#uses=1]
%1 = load <16 x i8>* %temp, align 16 ; <<16 x i8>> [#uses=1]
%tmp = add <16 x i8> %0, %1 ; <<16 x i8>> [#uses=1]
store <16 x i8> %tmp, <16 x i8>* @baz, align 16
br label %return
return: ; preds = %entry
ret void
; CHECK: blr
}