forked from OSchip/llvm-project
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 llvm-svn: 44856
This commit is contained in:
parent
6a6b3fb62b
commit
8e6a8f984c
|
@ -396,11 +396,54 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue