llvm.org GIT mirror llvm / 1e60881
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 Dale Johannesen 10 years ago
4 changed file(s) with 35 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
19521952 /// that value are zero, and the corresponding bits in the SplatUndef mask
19531953 /// are set. The SplatBitSize value is set to the splat element size in
19541954 /// bits. HasAnyUndefs is set to true if any bits in the vector are
1955 /// undefined.
1955 /// undefined. isBigEndian describes the endianness of the target.
19561956 bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
19571957 unsigned &SplatBitSize, bool &HasAnyUndefs,
1958 unsigned MinSplatBits = 0);
1958 unsigned MinSplatBits = 0, bool isBigEndian = false);
19591959
19601960 static inline bool classof(const BuildVectorSDNode *) { return true; }
19611961 static inline bool classof(const SDNode *N) {
59155915 APInt &SplatUndef,
59165916 unsigned &SplatBitSize,
59175917 bool &HasAnyUndefs,
5918 unsigned MinSplatBits) {
5918 unsigned MinSplatBits,
5919 bool isBigEndian) {
59195920 EVT VT = getValueType(0);
59205921 assert(VT.isVector() && "Expected a vector type");
59215922 unsigned sz = VT.getSizeInBits();
59325933 unsigned int nOps = getNumOperands();
59335934 assert(nOps > 0 && "isConstantSplat has 0-size build vector");
59345935 unsigned EltBitSize = VT.getVectorElementType().getSizeInBits();
5935 for (unsigned i = 0; i < nOps; ++i) {
5936
5937 for (unsigned j = 0; j < nOps; ++j) {
5938 unsigned i = isBigEndian ? nOps-1-j : j;
59365939 SDValue OpVal = getOperand(i);
5937 unsigned BitPos = i * EltBitSize;
5940 unsigned BitPos = j * EltBitSize;
59385941
59395942 if (OpVal.getOpcode() == ISD::UNDEF)
5940 SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos +EltBitSize);
5943 SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos + EltBitSize);
59415944 else if (ConstantSDNode *CN = dyn_cast(OpVal))
59425945 SplatValue |= (APInt(CN->getAPIntValue()).zextOrTrunc(EltBitSize).
59435946 zextOrTrunc(sz) << BitPos);
636636 unsigned BitSize;
637637 bool HasAnyUndefs;
638638
639 if (BV->isConstantSplat(APVal, APUndef, BitSize, HasAnyUndefs, 32))
639 if (BV->isConstantSplat(APVal, APUndef, BitSize, HasAnyUndefs, 32, true))
640640 if (ConstantFPSDNode *CFP = dyn_cast(N->getOperand(0)))
641641 return CFP->getValueAPF().isNegZero();
642642
36713671 unsigned SplatBitSize;
36723672 bool HasAnyUndefs;
36733673 if (! BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
3674 HasAnyUndefs) || SplatBitSize > 32)
3674 HasAnyUndefs, 0, true) || SplatBitSize > 32)
36753675 return SDValue();
36763676
36773677 unsigned SplatBits = APSplatBits.getZExtValue();
0 ; RUN: llc < %s -march=ppc32 -mtriple=powerpc-apple-darwin -mcpu=g5 | FileCheck %s
1 ; Formerly incorrectly inserted vsldoi (endian confusion)
2
3 @baz = common global <16 x i8> zeroinitializer ; <<16 x i8>*> [#uses=1]
4
5 define void @foo(<16 x i8> %x) nounwind ssp {
6 entry:
7 ; CHECK: _foo:
8 ; CHECK-NOT: vsldoi
9 %x_addr = alloca <16 x i8> ; <<16 x i8>*> [#uses=2]
10 %temp = alloca <16 x i8> ; <<16 x i8>*> [#uses=2]
11 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
12 store <16 x i8> %x, <16 x i8>* %x_addr
13 store <16 x i8> , <16 x i8>* %temp, align 16
14 %0 = load <16 x i8>* %x_addr, align 16 ; <<16 x i8>> [#uses=1]
15 %1 = load <16 x i8>* %temp, align 16 ; <<16 x i8>> [#uses=1]
16 %tmp = add <16 x i8> %0, %1 ; <<16 x i8>> [#uses=1]
17 store <16 x i8> %tmp, <16 x i8>* @baz, align 16
18 br label %return
19
20 return: ; preds = %entry
21 ret void
22 ; CHECK: blr
23 }