Author: lattner Date: Tue Dec 11 01:49:37 2007 New Revision: 44856 URL: http://llvm.org/viewvc/llvm-project?rev=44856&view=rev Log: Teach VMCore to constant fold shufflevectors with constant operands. This allows us to compile:
#include <emmintrin.h> typedef __m128i VSInt16; typedef short vSInt16 __attribute__ ((__vector_size__ (16))); VSInt16 t3() { return (VSInt16)((vSInt16)_mm_set1_epi16(6518)); } into: _t3: movaps LCPI1_0, %xmm0 ret instead of: _t3: movl $6518, %eax movd %eax, %xmm0 pextrw $0, %xmm0, %eax xorps %xmm0, %xmm0 pinsrw $0, %eax, %xmm0 punpcklwd %xmm0, %xmm0 pshufd $0, %xmm0, %xmm0 ret Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=44856&r1=44855&r2=44856&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Dec 11 01:49:37 2007 @@ -396,11 +396,54 @@ return 0; } +/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef +/// return the specified element value. Otherwise return null. +static Constant *GetVectorElement(const Constant *C, unsigned EltNo) { + if (const ConstantVector *CV = dyn_cast<ConstantVector>(C)) + return const_cast<Constant*>(CV->getOperand(EltNo)); + + const Type *EltTy = cast<VectorType>(C->getType())->getElementType(); + if (isa<ConstantAggregateZero>(C)) + return Constant::getNullValue(EltTy); + if (isa<UndefValue>(C)) + return UndefValue::get(EltTy); + return 0; +} + Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, const Constant *V2, const Constant *Mask) { - // TODO: - return 0; + // Undefined shuffle mask -> undefined value. + if (isa<UndefValue>(Mask)) return UndefValue::get(V1->getType()); + + unsigned NumElts = cast<VectorType>(V1->getType())->getNumElements(); + const Type *EltTy = cast<VectorType>(V1->getType())->getElementType(); + + // Loop over the shuffle mask, evaluating each element. + SmallVector<Constant*, 32> Result; + for (unsigned i = 0; i != NumElts; ++i) { + Constant *InElt = GetVectorElement(Mask, i); + if (InElt == 0) return 0; + + if (isa<UndefValue>(InElt)) + InElt = UndefValue::get(EltTy); + else if (ConstantInt *CI = dyn_cast<ConstantInt>(InElt)) { + unsigned Elt = CI->getZExtValue(); + if (Elt >= NumElts*2) + InElt = UndefValue::get(EltTy); + else if (Elt >= NumElts) + InElt = GetVectorElement(V2, Elt-NumElts); + else + InElt = GetVectorElement(V1, Elt); + if (InElt == 0) return 0; + } else { + // Unknown value. + return 0; + } + Result.push_back(InElt); + } + + return ConstantVector::get(&Result[0], Result.size()); } /// EvalVectorOp - Given two vector constants and a function pointer, apply the _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits