if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
if (CFP->getType()->isFloatTy()) {
- SmallVector<float, 16> Elts;
+ SmallVector<uint32_t, 16> Elts;
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(CFP->getValueAPF().convertToFloat());
+ Elts.push_back(
+ CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
else
break;
if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
+ return ConstantDataArray::getFP(C->getContext(), Elts);
} else if (CFP->getType()->isDoubleTy()) {
- SmallVector<double, 16> Elts;
+ SmallVector<uint64_t, 16> Elts;
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(CFP->getValueAPF().convertToDouble());
+ Elts.push_back(
+ CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
else
break;
if (Elts.size() == V.size())
- return ConstantDataArray::get(C->getContext(), Elts);
+ return ConstantDataArray::getFP(C->getContext(), Elts);
}
}
}
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
if (CFP->getType()->isFloatTy()) {
- SmallVector<float, 16> Elts;
+ SmallVector<uint32_t, 16> Elts;
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(CFP->getValueAPF().convertToFloat());
+ Elts.push_back(
+ CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
else
break;
if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
+ return ConstantDataVector::getFP(C->getContext(), Elts);
} else if (CFP->getType()->isDoubleTy()) {
- SmallVector<double, 16> Elts;
+ SmallVector<uint64_t, 16> Elts;
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
- Elts.push_back(CFP->getValueAPF().convertToDouble());
+ Elts.push_back(
+ CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
else
break;
if (Elts.size() == V.size())
- return ConstantDataVector::get(C->getContext(), Elts);
+ return ConstantDataVector::getFP(C->getContext(), Elts);
}
}
}
Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
bool OnlyIfReduced) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
- bool AnyChange = Ty != getType();
- for (unsigned i = 0; i != Ops.size(); ++i)
- AnyChange |= Ops[i] != getOperand(i);
- if (!AnyChange) // No operands changed, return self.
+ // If no operands changed return self.
+ if (Ty == getType() && std::equal(Ops.begin(), Ops.end(), op_begin()))
return const_cast<ConstantExpr*>(this);
Type *OnlyIfReducedTy = OnlyIfReduced ? Ty : nullptr;
return FC; // Fold a few common cases.
// Get the result type of the getelementptr!
- Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs);
+ Type *Ty = GetElementPtrInst::getIndexedType(
+ cast<PointerType>(C->getType()->getScalarType())->getElementType(), Idxs);
assert(Ty && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace();
Type *ReqTy = Ty->getPointerTo(AS);
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<double> Elts) {
Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
+}
+
+/// getFP() constructors - Return a constant with array type with an element
+/// count and element type of float with precision matching the number of
+/// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+/// double for 64bits) Note that this can return a ConstantAggregateZero
+/// object.
+Constant *ConstantDataArray::getFP(LLVMContext &Context,
+ ArrayRef<uint16_t> Elts) {
+ Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 2), Ty);
+}
+Constant *ConstantDataArray::getFP(LLVMContext &Context,
+ ArrayRef<uint32_t> Elts) {
+ Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 4), Ty);
+}
+Constant *ConstantDataArray::getFP(LLVMContext &Context,
+ ArrayRef<uint64_t> Elts) {
+ Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
}
/// getString - This method constructs a CDS and initializes it with a text
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<double> Elts) {
Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
const char *Data = reinterpret_cast<const char *>(Elts.data());
- return getImpl(StringRef(const_cast<char *>(Data), Elts.size()*8), Ty);
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
+}
+
+/// getFP() constructors - Return a constant with vector type with an element
+/// count and element type of float with the precision matching the number of
+/// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+/// double for 64bits) Note that this can return a ConstantAggregateZero
+/// object.
+Constant *ConstantDataVector::getFP(LLVMContext &Context,
+ ArrayRef<uint16_t> Elts) {
+ Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 2), Ty);
+}
+Constant *ConstantDataVector::getFP(LLVMContext &Context,
+ ArrayRef<uint32_t> Elts) {
+ Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 4), Ty);
+}
+Constant *ConstantDataVector::getFP(LLVMContext &Context,
+ ArrayRef<uint64_t> Elts) {
+ Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
+ const char *Data = reinterpret_cast<const char *>(Elts.data());
+ return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
}
Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
if (CFP->getType()->isFloatTy()) {
- SmallVector<float, 16> Elts(NumElts, CFP->getValueAPF().convertToFloat());
- return get(V->getContext(), Elts);
+ SmallVector<uint32_t, 16> Elts(
+ NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ return getFP(V->getContext(), Elts);
}
if (CFP->getType()->isDoubleTy()) {
- SmallVector<double, 16> Elts(NumElts,
- CFP->getValueAPF().convertToDouble());
- return get(V->getContext(), Elts);
+ SmallVector<uint64_t, 16> Elts(
+ NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
+ return getFP(V->getContext(), Elts);
}
}
return ConstantVector::getSplat(NumElts, V);
default:
llvm_unreachable("Accessor can only be used when element is float/double!");
case Type::FloatTyID: {
- const float *FloatPrt = reinterpret_cast<const float *>(EltPtr);
- return APFloat(*const_cast<float *>(FloatPrt));
- }
+ auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
+ return APFloat(APFloat::IEEEsingle, APInt(32, EltVal));
+ }
case Type::DoubleTyID: {
- const double *DoublePtr = reinterpret_cast<const double *>(EltPtr);
- return APFloat(*const_cast<double *>(DoublePtr));
- }
+ auto EltVal = *reinterpret_cast<const uint64_t *>(EltPtr);
+ return APFloat(APFloat::IEEEdouble, APInt(64, EltVal));
+ }
}
}
}
Instruction *ConstantExpr::getAsInstruction() {
- SmallVector<Value*,4> ValueOperands;
- for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
- ValueOperands.push_back(cast<Value>(I));
-
+ SmallVector<Value *, 4> ValueOperands(op_begin(), op_end());
ArrayRef<Value*> Ops(ValueOperands);
switch (getOpcode()) {
case Instruction::ShuffleVector:
return new ShuffleVectorInst(Ops[0], Ops[1], Ops[2]);
- case Instruction::GetElementPtr:
- if (cast<GEPOperator>(this)->isInBounds())
- return GetElementPtrInst::CreateInBounds(Ops[0], Ops.slice(1));
- else
- return GetElementPtrInst::Create(Ops[0], Ops.slice(1));
-
+ case Instruction::GetElementPtr: {
+ const auto *GO = cast<GEPOperator>(this);
+ if (GO->isInBounds())
+ return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(),
+ Ops[0], Ops.slice(1));
+ return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
+ Ops.slice(1));
+ }
case Instruction::ICmp:
case Instruction::FCmp:
return CmpInst::Create((Instruction::OtherOps)getOpcode(),