[llvm-commits] [llvm] r44856 - /llvm/trunk/lib/VMCore/ConstantFold.cpp
Chris Lattner
sabre at nondot.org
Mon Dec 10 23:49:41 PST 2007
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
More information about the llvm-commits
mailing list