[llvm] r174555 - Signficantly generalize our ability to constant fold floating point intrinsics, including ones on half types.

Aaron Ballman aaron at aaronballman.com
Wed Feb 6 15:42:31 PST 2013


On Wed, Feb 6, 2013 at 5:43 PM, Owen Anderson <resistor at mac.com> wrote:
> Author: resistor
> Date: Wed Feb  6 16:43:31 2013
> New Revision: 174555
>
> URL: http://llvm.org/viewvc/llvm-project?rev=174555&view=rev
> Log:
> Signficantly generalize our ability to constant fold floating point intrinsics, including ones on half types.
>
> Added:
>     llvm/trunk/test/Transforms/ConstProp/half.ll
> Modified:
>     llvm/trunk/lib/Analysis/ConstantFolding.cpp
>
> Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=174555&r1=174554&r2=174555&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
> +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Feb  6 16:43:31 2013
> @@ -289,6 +289,10 @@ static bool ReadDataFromGlobal(Constant
>        C = FoldBitCast(C, Type::getInt32Ty(C->getContext()), TD);
>        return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, TD);
>      }
> +    if (CFP->getType()->isHalfTy()){
> +      C = FoldBitCast(C, Type::getInt16Ty(C->getContext()), TD);
> +      return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, TD);
> +    }
>      return false;
>    }
>
> @@ -381,7 +385,9 @@ static Constant *FoldReinterpretLoadFrom
>      // that address spaces don't matter here since we're not going to result in
>      // an actual new load.
>      Type *MapTy;
> -    if (LoadTy->isFloatTy())
> +    if (LoadTy->isHalfTy())
> +      MapTy = Type::getInt16PtrTy(C->getContext());
> +    else if (LoadTy->isFloatTy())
>        MapTy = Type::getInt32PtrTy(C->getContext());
>      else if (LoadTy->isDoubleTy())
>        MapTy = Type::getInt64PtrTy(C->getContext());
> @@ -1089,6 +1095,13 @@ Constant *llvm::ConstantFoldLoadThroughG
>  bool
>  llvm::canConstantFoldCallTo(const Function *F) {
>    switch (F->getIntrinsicID()) {
> +  case Intrinsic::fabs:
> +  case Intrinsic::log:
> +  case Intrinsic::log2:
> +  case Intrinsic::log10:
> +  case Intrinsic::exp:
> +  case Intrinsic::exp2:
> +  case Intrinsic::floor:
>    case Intrinsic::sqrt:
>    case Intrinsic::pow:
>    case Intrinsic::powi:
> @@ -1156,11 +1169,17 @@ static Constant *ConstantFoldFP(double (
>      return 0;
>    }
>
> +  if (Ty->isHalfTy()) {
> +    APFloat APF(V);
> +    bool unused;
> +    APF.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &unused);
> +    return ConstantFP::get(Ty->getContext(), APF);
> +  }
>    if (Ty->isFloatTy())
>      return ConstantFP::get(Ty->getContext(), APFloat((float)V));
>    if (Ty->isDoubleTy())
>      return ConstantFP::get(Ty->getContext(), APFloat(V));
> -  llvm_unreachable("Can only constant fold float/double");
> +  llvm_unreachable("Can only constant fold half/float/double");
>  }
>
>  static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
> @@ -1172,11 +1191,17 @@ static Constant *ConstantFoldBinaryFP(do
>      return 0;
>    }
>
> +  if (Ty->isHalfTy()) {
> +    APFloat APF(V);
> +    bool unused;
> +    APF.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &unused);
> +    return ConstantFP::get(Ty->getContext(), APF);
> +  }
>    if (Ty->isFloatTy())
>      return ConstantFP::get(Ty->getContext(), APFloat((float)V));
>    if (Ty->isDoubleTy())
>      return ConstantFP::get(Ty->getContext(), APFloat(V));
> -  llvm_unreachable("Can only constant fold float/double");
> +  llvm_unreachable("Can only constant fold half/float/double");
>  }
>
>  /// ConstantFoldConvertToInt - Attempt to an SSE floating point to integer
> @@ -1228,7 +1253,7 @@ llvm::ConstantFoldCall(Function *F, Arra
>        if (!TLI)
>          return 0;
>
> -      if (!Ty->isFloatTy() && !Ty->isDoubleTy())
> +      if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
>          return 0;
>
>        /// We only fold functions with finite arguments. Folding NaN and inf is
> @@ -1241,8 +1266,36 @@ llvm::ConstantFoldCall(Function *F, Arra
>        /// the host native double versions.  Float versions are not called
>        /// directly but for all these it is true (float)(f((double)arg)) ==
>        /// f(arg).  Long double not supported yet.
> -      double V = Ty->isFloatTy() ? (double)Op->getValueAPF().convertToFloat() :
> -                                     Op->getValueAPF().convertToDouble();
> +      double V;
> +      if (Ty->isFloatTy())
> +        V = Op->getValueAPF().convertToFloat();
> +      else if (Ty->isDoubleTy())
> +        V = Op->getValueAPF().convertToDouble();
> +      else {
> +        bool unused;
> +        APFloat APF = Op->getValueAPF();
> +        APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &unused);
> +        V = APF.convertToDouble();
> +      }
> +
> +      switch (F->getIntrinsicID()) {
> +        default: break;
> +        case Intrinsic::fabs:
> +          return ConstantFoldFP(fabs, V, Ty);
> +        case Intrinsic::log2:
> +          return ConstantFoldFP(log2, V, Ty);
> +        case Intrinsic::log:
> +          return ConstantFoldFP(log, V, Ty);
> +        case Intrinsic::log10:
> +          return ConstantFoldFP(log10, V, Ty);
> +        case Intrinsic::exp:
> +          return ConstantFoldFP(exp, V, Ty);
> +        case Intrinsic::exp2:
> +          return ConstantFoldFP(exp2, V, Ty);
> +        case Intrinsic::floor:
> +          return ConstantFoldFP(floor, V, Ty);
> +      }
> +

Unfortunately, this breaks the MSVC build because it doesn't have log2
or exp2 defined in the standard libraries.

~Aaron



More information about the llvm-commits mailing list