[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