[llvm] r229864 - Avoid conversion to float when creating ConstantDataArray/ConstantDataVector.
NAKAMURA Takumi
geek4civic at gmail.com
Thu Feb 19 16:28:18 PST 2015
It fails with -m32 binary. Investigating.
2015-02-20 1:08 GMT+09:00 Rafael Espindola <rafael.espindola at gmail.com>:
> Author: rafael
> Date: Thu Feb 19 10:08:20 2015
> New Revision: 229864
>
> URL: http://llvm.org/viewvc/llvm-project?rev=229864&view=rev
> Log:
> Avoid conversion to float when creating ConstantDataArray/ConstantDataVector.
>
> Patch by Raoux, Thomas F!
>
> Added:
> llvm/trunk/test/Transforms/ConstProp/InsertElement.ll
> Modified:
> llvm/trunk/include/llvm/IR/Constants.h
> llvm/trunk/lib/IR/Constants.cpp
> llvm/trunk/test/Transforms/ConstProp/insertvalue.ll
>
> Modified: llvm/trunk/include/llvm/IR/Constants.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=229864&r1=229863&r2=229864&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Constants.h (original)
> +++ llvm/trunk/include/llvm/IR/Constants.h Thu Feb 19 10:08:20 2015
> @@ -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.
>
> Modified: llvm/trunk/lib/IR/Constants.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=229864&r1=229863&r2=229864&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/Constants.cpp (original)
> +++ llvm/trunk/lib/IR/Constants.cpp Thu Feb 19 10:08:20 2015
> @@ -911,23 +911,25 @@ Constant *ConstantArray::getImpl(ArrayTy
>
> 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(ArrayR
>
> 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(LLVMCon
> 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(LLVMCo
> 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(u
>
> 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);
>
> Added: llvm/trunk/test/Transforms/ConstProp/InsertElement.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/InsertElement.ll?rev=229864&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/ConstProp/InsertElement.ll (added)
> +++ llvm/trunk/test/Transforms/ConstProp/InsertElement.ll Thu Feb 19 10:08:20 2015
> @@ -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
> +}
> +
>
> Modified: llvm/trunk/test/Transforms/ConstProp/insertvalue.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/insertvalue.ll?rev=229864&r1=229863&r2=229864&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/ConstProp/insertvalue.ll (original)
> +++ llvm/trunk/test/Transforms/ConstProp/insertvalue.ll Thu Feb 19 10:08:20 2015
> @@ -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
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list