summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Constants.h18
-rw-r--r--llvm/lib/IR/Constants.cpp91
-rw-r--r--llvm/test/Transforms/ConstProp/InsertElement.ll12
-rw-r--r--llvm/test/Transforms/ConstProp/insertvalue.ll9
4 files changed, 111 insertions, 19 deletions
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 5f09fe1fb62..59be6531da3 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -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.
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 44052b22457..e87aa3d92ed 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -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);
diff --git a/llvm/test/Transforms/ConstProp/InsertElement.ll b/llvm/test/Transforms/ConstProp/InsertElement.ll
new file mode 100644
index 00000000000..d249c2eb1c5
--- /dev/null
+++ b/llvm/test/Transforms/ConstProp/InsertElement.ll
@@ -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
+}
+
diff --git a/llvm/test/Transforms/ConstProp/insertvalue.ll b/llvm/test/Transforms/ConstProp/insertvalue.ll
index 0d288b3841d..dce2b728b93 100644
--- a/llvm/test/Transforms/ConstProp/insertvalue.ll
+++ b/llvm/test/Transforms/ConstProp/insertvalue.ll
@@ -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
+}
OpenPOWER on IntegriCloud