mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Avoid conversion to float when creating ConstantDataArray/ConstantDataVector.
Patch by Raoux, Thomas F! llvm-svn: 229864
This commit is contained in:
parent
c0850fa665
commit
75192238cd
@ -676,6 +676,15 @@ public:
|
|||||||
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
|
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
|
||||||
static Constant *get(LLVMContext &Context, ArrayRef<double> 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
|
/// getString - This method constructs a CDS and initializes it with a text
|
||||||
/// string. The default behavior (AddNull==true) causes a null terminator to
|
/// 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
|
/// 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<float> Elts);
|
||||||
static Constant *get(LLVMContext &Context, ArrayRef<double> 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
|
/// getSplat - Return a ConstantVector with the specified constant in each
|
||||||
/// element. The specified constant has to be a of a compatible type (i8/i16/
|
/// 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.
|
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
|
||||||
|
@ -911,23 +911,25 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
|
|||||||
|
|
||||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
|
||||||
if (CFP->getType()->isFloatTy()) {
|
if (CFP->getType()->isFloatTy()) {
|
||||||
SmallVector<float, 16> Elts;
|
SmallVector<uint32_t, 16> Elts;
|
||||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
||||||
Elts.push_back(CFP->getValueAPF().convertToFloat());
|
Elts.push_back(
|
||||||
|
CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
if (Elts.size() == V.size())
|
if (Elts.size() == V.size())
|
||||||
return ConstantDataArray::get(C->getContext(), Elts);
|
return ConstantDataArray::getFP(C->getContext(), Elts);
|
||||||
} else if (CFP->getType()->isDoubleTy()) {
|
} else if (CFP->getType()->isDoubleTy()) {
|
||||||
SmallVector<double, 16> Elts;
|
SmallVector<uint64_t, 16> Elts;
|
||||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
||||||
Elts.push_back(CFP->getValueAPF().convertToDouble());
|
Elts.push_back(
|
||||||
|
CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
if (Elts.size() == V.size())
|
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 (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
|
||||||
if (CFP->getType()->isFloatTy()) {
|
if (CFP->getType()->isFloatTy()) {
|
||||||
SmallVector<float, 16> Elts;
|
SmallVector<uint32_t, 16> Elts;
|
||||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
||||||
Elts.push_back(CFP->getValueAPF().convertToFloat());
|
Elts.push_back(
|
||||||
|
CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
if (Elts.size() == V.size())
|
if (Elts.size() == V.size())
|
||||||
return ConstantDataVector::get(C->getContext(), Elts);
|
return ConstantDataVector::getFP(C->getContext(), Elts);
|
||||||
} else if (CFP->getType()->isDoubleTy()) {
|
} else if (CFP->getType()->isDoubleTy()) {
|
||||||
SmallVector<double, 16> Elts;
|
SmallVector<uint64_t, 16> Elts;
|
||||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
|
||||||
Elts.push_back(CFP->getValueAPF().convertToDouble());
|
Elts.push_back(
|
||||||
|
CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
if (Elts.size() == V.size())
|
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) {
|
Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef<double> Elts) {
|
||||||
Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
|
Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
|
||||||
const char *Data = reinterpret_cast<const char *>(Elts.data());
|
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
|
/// 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) {
|
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<double> Elts) {
|
||||||
Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
|
Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
|
||||||
const char *Data = reinterpret_cast<const char *>(Elts.data());
|
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) {
|
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 (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
|
||||||
if (CFP->getType()->isFloatTy()) {
|
if (CFP->getType()->isFloatTy()) {
|
||||||
SmallVector<float, 16> Elts(NumElts, CFP->getValueAPF().convertToFloat());
|
SmallVector<uint32_t, 16> Elts(
|
||||||
return get(V->getContext(), Elts);
|
NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
|
return getFP(V->getContext(), Elts);
|
||||||
}
|
}
|
||||||
if (CFP->getType()->isDoubleTy()) {
|
if (CFP->getType()->isDoubleTy()) {
|
||||||
SmallVector<double, 16> Elts(NumElts,
|
SmallVector<uint64_t, 16> Elts(
|
||||||
CFP->getValueAPF().convertToDouble());
|
NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue());
|
||||||
return get(V->getContext(), Elts);
|
return getFP(V->getContext(), Elts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ConstantVector::getSplat(NumElts, V);
|
return ConstantVector::getSplat(NumElts, V);
|
||||||
|
12
test/Transforms/ConstProp/InsertElement.ll
Normal file
12
test/Transforms/ConstProp/InsertElement.ll
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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]
|
; 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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user