mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
continue making the world safe for ConstantDataVector. At this point,
we should (theoretically optimize and codegen ConstantDataVector as well as ConstantVector. llvm-svn: 149116
This commit is contained in:
parent
f1e0eb546a
commit
466ff4b5f1
@ -6061,7 +6061,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
// constant pool entry to get its address.
|
||||
const Value *OpVal = OpInfo.CallOperandVal;
|
||||
if (isa<ConstantFP>(OpVal) || isa<ConstantInt>(OpVal) ||
|
||||
isa<ConstantVector>(OpVal)) {
|
||||
isa<ConstantVector>(OpVal) || isa<ConstantDataVector>(OpVal)) {
|
||||
OpInfo.CallOperand = DAG.getConstantPool(cast<Constant>(OpVal),
|
||||
TLI.getPointerTy());
|
||||
} else {
|
||||
|
@ -2174,7 +2174,7 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
||||
return Val;
|
||||
}
|
||||
|
||||
std::vector<Constant*> Elts;
|
||||
SmallVector<Constant*, 32> Elts;
|
||||
if (StructType *STy = dyn_cast<StructType>(Init->getType())) {
|
||||
// Break up the constant into its elements.
|
||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
||||
|
@ -623,14 +623,16 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
|
||||
case Intrinsic::ppc_altivec_vperm:
|
||||
// Turn vperm(V1,V2,mask) -> shuffle(V1,V2,mask) if mask is a constant.
|
||||
if (ConstantVector *Mask = dyn_cast<ConstantVector>(II->getArgOperand(2))) {
|
||||
assert(Mask->getNumOperands() == 16 && "Bad type for intrinsic!");
|
||||
if (Constant *Mask = dyn_cast<Constant>(II->getArgOperand(2))) {
|
||||
assert(Mask->getType()->getVectorNumElements() == 16 &&
|
||||
"Bad type for intrinsic!");
|
||||
|
||||
// Check that all of the elements are integer constants or undefs.
|
||||
bool AllEltsOk = true;
|
||||
for (unsigned i = 0; i != 16; ++i) {
|
||||
if (!isa<ConstantInt>(Mask->getOperand(i)) &&
|
||||
!isa<UndefValue>(Mask->getOperand(i))) {
|
||||
Constant *Elt = Mask->getAggregateElement(i);
|
||||
if (Elt == 0 ||
|
||||
!(isa<ConstantInt>(Elt) || isa<UndefValue>(Elt))) {
|
||||
AllEltsOk = false;
|
||||
break;
|
||||
}
|
||||
@ -649,9 +651,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
memset(ExtractedElts, 0, sizeof(ExtractedElts));
|
||||
|
||||
for (unsigned i = 0; i != 16; ++i) {
|
||||
if (isa<UndefValue>(Mask->getOperand(i)))
|
||||
if (isa<UndefValue>(Mask->getAggregateElement(i)))
|
||||
continue;
|
||||
unsigned Idx=cast<ConstantInt>(Mask->getOperand(i))->getZExtValue();
|
||||
unsigned Idx =
|
||||
cast<ConstantInt>(Mask->getAggregateElement(i))->getZExtValue();
|
||||
Idx &= 31; // Match the hardware behavior.
|
||||
|
||||
if (ExtractedElts[Idx] == 0) {
|
||||
|
@ -264,6 +264,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
||||
if (Op1F->isExactlyValue(1.0))
|
||||
return ReplaceInstUsesWith(I, Op0); // Eliminate 'fmul double %X, 1.0'
|
||||
} else if (Op1C->getType()->isVectorTy()) {
|
||||
// FIXME: Remove.
|
||||
if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1C)) {
|
||||
// As above, vector X*splat(1.0) -> X in all defined cases.
|
||||
if (Constant *Splat = Op1V->getSplatValue()) {
|
||||
@ -272,6 +273,14 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
||||
return ReplaceInstUsesWith(I, Op0);
|
||||
}
|
||||
}
|
||||
if (ConstantDataVector *Op1V = dyn_cast<ConstantDataVector>(Op1C)) {
|
||||
// As above, vector X*splat(1.0) -> X in all defined cases.
|
||||
if (Constant *Splat = Op1V->getSplatValue()) {
|
||||
if (ConstantFP *F = dyn_cast<ConstantFP>(Splat))
|
||||
if (F->isExactlyValue(1.0))
|
||||
return ReplaceInstUsesWith(I, Op0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to fold constant mul into select arguments.
|
||||
@ -688,28 +697,36 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
|
||||
}
|
||||
|
||||
// If it's a constant vector, flip any negative values positive.
|
||||
if (ConstantVector *RHSV = dyn_cast<ConstantVector>(Op1)) {
|
||||
unsigned VWidth = RHSV->getNumOperands();
|
||||
if (isa<ConstantVector>(Op1) || isa<ConstantDataVector>(Op1)) {
|
||||
Constant *C = cast<Constant>(Op1);
|
||||
unsigned VWidth = C->getType()->getVectorNumElements();
|
||||
|
||||
bool hasNegative = false;
|
||||
for (unsigned i = 0; !hasNegative && i != VWidth; ++i)
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(RHSV->getOperand(i)))
|
||||
bool hasMissing = false;
|
||||
for (unsigned i = 0; i != VWidth; ++i) {
|
||||
Constant *Elt = C->getAggregateElement(i);
|
||||
if (Elt == 0) {
|
||||
hasMissing = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elt))
|
||||
if (RHS->isNegative())
|
||||
hasNegative = true;
|
||||
}
|
||||
|
||||
if (hasNegative) {
|
||||
if (hasNegative && !hasMissing) {
|
||||
SmallVector<Constant *, 16> Elts(VWidth);
|
||||
for (unsigned i = 0; i != VWidth; ++i) {
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(RHSV->getOperand(i))) {
|
||||
Elts[i] = C->getAggregateElement(i);
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elts[i])) {
|
||||
if (RHS->isNegative())
|
||||
Elts[i] = cast<ConstantInt>(ConstantExpr::getNeg(RHS));
|
||||
else
|
||||
Elts[i] = RHS;
|
||||
}
|
||||
}
|
||||
|
||||
Constant *NewRHSV = ConstantVector::get(Elts);
|
||||
if (NewRHSV != RHSV) {
|
||||
if (NewRHSV != C) { // Don't loop on -MININT
|
||||
Worklist.AddValue(I.getOperand(1));
|
||||
I.setOperand(1, NewRHSV);
|
||||
return &I;
|
||||
|
@ -982,7 +982,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
|
||||
|
||||
if (NewUndefElts) {
|
||||
// Add additional discovered undefs.
|
||||
std::vector<Constant*> Elts;
|
||||
SmallVector<Constant*, 16> Elts;
|
||||
for (unsigned i = 0; i < VWidth; ++i) {
|
||||
if (UndefElts[i])
|
||||
Elts.push_back(UndefValue::get(Type::getInt32Ty(I->getContext())));
|
||||
|
@ -207,7 +207,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
|
||||
/// elements from either LHS or RHS, return the shuffle mask and true.
|
||||
/// Otherwise, return false.
|
||||
static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
|
||||
std::vector<Constant*> &Mask) {
|
||||
SmallVectorImpl<Constant*> &Mask) {
|
||||
assert(V->getType() == LHS->getType() && V->getType() == RHS->getType() &&
|
||||
"Invalid CollectSingleShuffleElements");
|
||||
unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
|
||||
@ -284,7 +284,7 @@ static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
|
||||
/// CollectShuffleElements - We are building a shuffle of V, using RHS as the
|
||||
/// RHS of the shuffle instruction, if it is not null. Return a shuffle mask
|
||||
/// that computes V and the LHS value of the shuffle.
|
||||
static Value *CollectShuffleElements(Value *V, std::vector<Constant*> &Mask,
|
||||
static Value *CollectShuffleElements(Value *V, SmallVectorImpl<Constant*> &Mask,
|
||||
Value *&RHS) {
|
||||
assert(V->getType()->isVectorTy() &&
|
||||
(RHS == 0 || V->getType() == RHS->getType()) &&
|
||||
@ -384,7 +384,7 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) {
|
||||
// If this insertelement isn't used by some other insertelement, turn it
|
||||
// (and any insertelements it points to), into one big shuffle.
|
||||
if (!IE.hasOneUse() || !isa<InsertElementInst>(IE.use_back())) {
|
||||
std::vector<Constant*> Mask;
|
||||
SmallVector<Constant*, 16> Mask;
|
||||
Value *RHS = 0;
|
||||
Value *LHS = CollectShuffleElements(&IE, Mask, RHS);
|
||||
if (RHS == 0) RHS = UndefValue::get(LHS->getType());
|
||||
@ -443,20 +443,21 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
|
||||
}
|
||||
|
||||
// Remap any references to RHS to use LHS.
|
||||
std::vector<Constant*> Elts;
|
||||
SmallVector<Constant*, 16> Elts;
|
||||
for (unsigned i = 0, e = LHSWidth; i != VWidth; ++i) {
|
||||
if (Mask[i] < 0)
|
||||
if (Mask[i] < 0) {
|
||||
Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext())));
|
||||
else {
|
||||
if ((Mask[i] >= (int)e && isa<UndefValue>(RHS)) ||
|
||||
(Mask[i] < (int)e && isa<UndefValue>(LHS))) {
|
||||
Mask[i] = -1; // Turn into undef.
|
||||
Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext())));
|
||||
} else {
|
||||
Mask[i] = Mask[i] % e; // Force to LHS.
|
||||
Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()),
|
||||
Mask[i]));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((Mask[i] >= (int)e && isa<UndefValue>(RHS)) ||
|
||||
(Mask[i] < (int)e && isa<UndefValue>(LHS))) {
|
||||
Mask[i] = -1; // Turn into undef.
|
||||
Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext())));
|
||||
} else {
|
||||
Mask[i] = Mask[i] % e; // Force to LHS.
|
||||
Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()),
|
||||
Mask[i]));
|
||||
}
|
||||
}
|
||||
SVI.setOperand(0, SVI.getOperand(1));
|
||||
|
@ -495,8 +495,10 @@ Value *InstCombiner::dyn_castNegVal(Value *V) const {
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(V))
|
||||
return ConstantExpr::getNeg(C);
|
||||
|
||||
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
|
||||
if (C->getType()->getElementType()->isIntegerTy())
|
||||
if (Constant *C = dyn_cast<Constant>(V))
|
||||
// FIXME: Remove ConstantVector
|
||||
if ((isa<ConstantVector>(C) || isa<ConstantDataVector>(C)) &&
|
||||
C->getType()->getVectorElementType()->isIntegerTy())
|
||||
return ConstantExpr::getNeg(C);
|
||||
|
||||
return 0;
|
||||
@ -514,8 +516,10 @@ Value *InstCombiner::dyn_castFNegVal(Value *V) const {
|
||||
if (ConstantFP *C = dyn_cast<ConstantFP>(V))
|
||||
return ConstantExpr::getFNeg(C);
|
||||
|
||||
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
|
||||
if (C->getType()->getElementType()->isFloatingPointTy())
|
||||
if (Constant *C = dyn_cast<Constant>(V))
|
||||
// FIXME: Remove ConstantVector
|
||||
if ((isa<ConstantVector>(C) || isa<ConstantDataVector>(C)) &&
|
||||
C->getType()->getVectorElementType()->isFloatingPointTy())
|
||||
return ConstantExpr::getFNeg(C);
|
||||
|
||||
return 0;
|
||||
|
@ -547,18 +547,17 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
|
||||
// If the cast operand is a constant vector, perform the cast by
|
||||
// operating on each element. In the cast of bitcasts, the element
|
||||
// count may be mismatched; don't attempt to handle that here.
|
||||
if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
|
||||
if (DestTy->isVectorTy() &&
|
||||
cast<VectorType>(DestTy)->getNumElements() ==
|
||||
CV->getType()->getNumElements()) {
|
||||
std::vector<Constant*> res;
|
||||
VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||
Type *DstEltTy = DestVecTy->getElementType();
|
||||
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
|
||||
res.push_back(ConstantExpr::getCast(opc,
|
||||
CV->getOperand(i), DstEltTy));
|
||||
return ConstantVector::get(res);
|
||||
}
|
||||
if ((isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) &&
|
||||
DestTy->isVectorTy() &&
|
||||
DestTy->getVectorNumElements() == V->getType()->getVectorNumElements()) {
|
||||
SmallVector<Constant*, 16> res;
|
||||
VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||
Type *DstEltTy = DestVecTy->getElementType();
|
||||
for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i)
|
||||
res.push_back(ConstantExpr::getCast(opc,
|
||||
V->getAggregateElement(i), DstEltTy));
|
||||
return ConstantVector::get(res);
|
||||
}
|
||||
|
||||
// We actually have to do a cast now. Perform the cast according to the
|
||||
// opcode specified.
|
||||
@ -694,7 +693,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
|
||||
if (Cond->isNullValue()) return V2;
|
||||
if (Cond->isAllOnesValue()) return V1;
|
||||
|
||||
// FIXME: CDV Condition.
|
||||
// FIXME: Remove ConstantVector
|
||||
// If the condition is a vector constant, fold the result elementwise.
|
||||
if (ConstantVector *CondV = dyn_cast<ConstantVector>(Cond)) {
|
||||
SmallVector<Constant*, 16> Result;
|
||||
@ -711,6 +710,20 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
|
||||
if (Result.size() == V1->getType()->getVectorNumElements())
|
||||
return ConstantVector::get(Result);
|
||||
}
|
||||
if (ConstantDataVector *CondV = dyn_cast<ConstantDataVector>(Cond)) {
|
||||
SmallVector<Constant*, 16> Result;
|
||||
for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){
|
||||
uint64_t Cond = CondV->getElementAsInteger(i);
|
||||
|
||||
Constant *Res = (Cond ? V2 : V1)->getAggregateElement(i);
|
||||
if (Res == 0) break;
|
||||
Result.push_back(Res);
|
||||
}
|
||||
|
||||
// If we were able to build the vector, return it.
|
||||
if (Result.size() == V1->getType()->getVectorNumElements())
|
||||
return ConstantVector::get(Result);
|
||||
}
|
||||
|
||||
|
||||
if (isa<UndefValue>(Cond)) {
|
||||
@ -738,22 +751,19 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
|
||||
Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
|
||||
Constant *Idx) {
|
||||
if (isa<UndefValue>(Val)) // ee(undef, x) -> undef
|
||||
return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
|
||||
return UndefValue::get(Val->getType()->getVectorElementType());
|
||||
if (Val->isNullValue()) // ee(zero, x) -> zero
|
||||
return Constant::getNullValue(
|
||||
cast<VectorType>(Val->getType())->getElementType());
|
||||
return Constant::getNullValue(Val->getType()->getVectorElementType());
|
||||
// ee({w,x,y,z}, undef) -> undef
|
||||
if (isa<UndefValue>(Idx))
|
||||
return UndefValue::get(Val->getType()->getVectorElementType());
|
||||
|
||||
if (ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
|
||||
if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
|
||||
uint64_t Index = CIdx->getZExtValue();
|
||||
if (Index >= CVal->getNumOperands())
|
||||
// ee({w,x,y,z}, wrong_value) -> undef
|
||||
return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
|
||||
return CVal->getOperand(CIdx->getZExtValue());
|
||||
} else if (isa<UndefValue>(Idx)) {
|
||||
// ee({w,x,y,z}, undef) -> undef
|
||||
return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
|
||||
}
|
||||
if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
|
||||
uint64_t Index = CIdx->getZExtValue();
|
||||
// ee({w,x,y,z}, wrong_value) -> undef
|
||||
if (Index >= Val->getType()->getVectorNumElements())
|
||||
return UndefValue::get(Val->getType()->getVectorElementType());
|
||||
return Val->getAggregateElement(Index);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -441,12 +441,12 @@ Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
|
||||
return C;
|
||||
}
|
||||
|
||||
ConstantInt* ConstantInt::get(IntegerType* Ty, uint64_t V,
|
||||
ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V,
|
||||
bool isSigned) {
|
||||
return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned));
|
||||
}
|
||||
|
||||
ConstantInt* ConstantInt::getSigned(IntegerType* Ty, int64_t V) {
|
||||
ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
|
||||
return get(Ty, V, true);
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
|
||||
return get(Ty, V, true);
|
||||
}
|
||||
|
||||
Constant *ConstantInt::get(Type* Ty, const APInt& V) {
|
||||
Constant *ConstantInt::get(Type *Ty, const APInt& V) {
|
||||
ConstantInt *C = get(Ty->getContext(), V);
|
||||
assert(C->getType() == Ty->getScalarType() &&
|
||||
"ConstantInt type doesn't match the type implied by its value!");
|
||||
@ -466,7 +466,7 @@ Constant *ConstantInt::get(Type* Ty, const APInt& V) {
|
||||
return C;
|
||||
}
|
||||
|
||||
ConstantInt* ConstantInt::get(IntegerType* Ty, StringRef Str,
|
||||
ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str,
|
||||
uint8_t radix) {
|
||||
return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix));
|
||||
}
|
||||
@ -496,7 +496,7 @@ void ConstantFP::anchor() { }
|
||||
/// get() - This returns a constant fp for the specified value in the
|
||||
/// specified type. This should only be used for simple constant values like
|
||||
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
|
||||
Constant *ConstantFP::get(Type* Ty, double V) {
|
||||
Constant *ConstantFP::get(Type *Ty, double V) {
|
||||
LLVMContext &Context = Ty->getContext();
|
||||
|
||||
APFloat FV(V);
|
||||
@ -513,7 +513,7 @@ Constant *ConstantFP::get(Type* Ty, double V) {
|
||||
}
|
||||
|
||||
|
||||
Constant *ConstantFP::get(Type* Ty, StringRef Str) {
|
||||
Constant *ConstantFP::get(Type *Ty, StringRef Str) {
|
||||
LLVMContext &Context = Ty->getContext();
|
||||
|
||||
APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str);
|
||||
|
@ -1932,10 +1932,8 @@ BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name,
|
||||
|
||||
// isConstantAllOnes - Helper function for several functions below
|
||||
static inline bool isConstantAllOnes(const Value *V) {
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
|
||||
return CI->isAllOnesValue();
|
||||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
|
||||
return CV->isAllOnesValue();
|
||||
if (const Constant *C = dyn_cast<Constant>(V))
|
||||
return C->isAllOnesValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user