[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