Avoid conversion to float when creating ConstantDataArray/ConstantDataVector.

Patch by Raoux, Thomas F!

llvm-svn: 229864
This commit is contained in:
Rafael Espindola 2015-02-19 16:08:20 +00:00
parent 354aa51587
commit 8c97e19124
4 changed files with 111 additions and 19 deletions

View File

@ -676,6 +676,15 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
/// 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.
static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
/// getString - This method constructs a CDS and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
/// be placed at the end of the array (increasing the length of the string by
@ -728,6 +737,15 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
/// 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.
static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
/// getSplat - Return a ConstantVector with the specified constant in each
/// element. The specified constant has to be a of a compatible type (i8/i16/
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.

View File

@ -911,23 +911,25 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
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);
}
}
}
@ -1097,23 +1099,25 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
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);
}
}
}
@ -2544,7 +2548,31 @@ Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<float> Elts) {
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
@ -2597,7 +2625,31 @@ Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<float> Elts) {
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) {
@ -2623,13 +2675,14 @@ 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);

View File

@ -0,0 +1,12 @@
; RUN: opt < %s -constprop -S | FileCheck %s
define i32 @test1() {
%A = bitcast i32 2139171423 to float
%B = insertelement <1 x float> undef, float %A, i32 0
%C = extractelement <1 x float> %B, i32 0
%D = bitcast float %C to i32
ret i32 %D
; CHECK: @test1
; CHECK: ret i32 2139171423
}

View File

@ -65,3 +65,12 @@ define [3 x %struct] @undef-test3() {
; CHECK: ret [3 x %struct] [%struct undef, %struct { i32 0, [4 x i8] undef }, %struct undef]
}
define i32 @test-float-Nan() {
%A = bitcast i32 2139171423 to float
%B = insertvalue [1 x float] undef, float %A, 0
%C = extractvalue [1 x float] %B, 0
%D = bitcast float %C to i32
ret i32 %D
; CHECK: @test-float-Nan
; CHECK: ret i32 2139171423
}