Skip to content

Commit

Permalink
[ConstantFold] Fix result type when folding powi.f16 (#98681)
Browse files Browse the repository at this point in the history
Fixes #98665.
  • Loading branch information
dtcxzyw committed Jul 15, 2024
1 parent 662c6fc commit 34bfed6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
37 changes: 19 additions & 18 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2754,27 +2754,28 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
((Mask & fcPosInf) && Op1V.isPosInfinity());
return ConstantInt::get(Ty, Result);
}
case Intrinsic::powi: {
int Exp = static_cast<int>(Op2C->getSExtValue());
switch (Ty->getTypeID()) {
case Type::HalfTyID:
case Type::FloatTyID: {
APFloat Res(std::pow(Op1V.convertToFloat(), Exp));

This comment has been minimized.

Copy link
@dtcxzyw

dtcxzyw Jul 15, 2024

Author Member

See https://en.cppreference.com/w/cpp/numeric/math/pow

C++98 added overloads where exp has type int on top of C pow(), and the return type of std::pow(float, int) was float. However, the additional overloads introduced in C++11 specify that std::pow(float, int) should return double. LWG issue 550 was raised to target this conflict, and the resolution is to removed the extra int exp overloads.

if (Ty->isHalfTy()) {
bool Unused;
Res.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
&Unused);
}
return ConstantFP::get(Ty->getContext(), Res);
}
case Type::DoubleTyID:
return ConstantFP::get(Ty, std::pow(Op1V.convertToDouble(), Exp));
default:
return nullptr;
}
}
default:
break;
}

if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;
if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy())
return ConstantFP::get(
Ty->getContext(),
APFloat((float)std::pow((float)Op1V.convertToDouble(),
(int)Op2C->getZExtValue())));
if (IntrinsicID == Intrinsic::powi && Ty->isFloatTy())
return ConstantFP::get(
Ty->getContext(),
APFloat((float)std::pow((float)Op1V.convertToDouble(),
(int)Op2C->getZExtValue())));
if (IntrinsicID == Intrinsic::powi && Ty->isDoubleTy())
return ConstantFP::get(
Ty->getContext(),
APFloat((double)std::pow(Op1V.convertToDouble(),
(int)Op2C->getZExtValue())));
}
return nullptr;
}
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/Transforms/EarlyCSE/math-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,14 @@ define double @i_powi() {
ret double %res
}

; Make sure that the type is correct after constant folding

define half @pr98665() {
; CHECK-LABEL: @pr98665(
; CHECK-NEXT: ret half 0xH3C00
;
%x = call half @llvm.powi.f16.i32(half 0xH3C00, i32 1)
ret half %x
}

attributes #0 = { nofree nounwind willreturn }

0 comments on commit 34bfed6

Please sign in to comment.