-
Notifications
You must be signed in to change notification settings - Fork 13.6k
add power function to APInt #122788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add power function to APInt #122788
Conversation
@llvm/pr-subscribers-llvm-adt @llvm/pr-subscribers-llvm-support Author: Iman Hosseini (ImanHosseini) ChangesI am trying to calculate power function for APFloat, APInt to constant fold vector reductions: #122450 Full diff: https://github.com/llvm/llvm-project/pull/122788.diff 3 Files Affected:
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index bf80fa5a06580b..236469d43678fe 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1531,6 +1531,26 @@ inline APFloat abs(APFloat X) {
return X;
}
+/// Returns X^N for N >= 0.
+inline APFloat pow(const APFloat &X, const int &N) {
+ assert(N >= 0 && "negative exponents not supported.");
+ if (N == 0) {
+ return APFloat::getOne(X.getSemantics());
+ }
+ APFloat Acc = X;
+ int64_t RemainingExponent = N;
+ while (RemainingExponent > 1) {
+ if (RemainingExponent % 2 == 0) {
+ Acc = Acc * Acc;
+ RemainingExponent /= 2;
+ } else {
+ Acc = Acc * X;
+ RemainingExponent--;
+ }
+ }
+ return Acc;
+};
+
/// Returns the negated value of the argument.
inline APFloat neg(APFloat X) {
X.changeSign();
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 225390f1af60b3..e93f1759875688 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -2263,6 +2263,9 @@ APInt mulhs(const APInt &C1, const APInt &C2);
/// Returns the high N bits of the multiplication result.
APInt mulhu(const APInt &C1, const APInt &C2);
+/// Compute X^N for N>0.
+APInt pow(const APInt &X, const int &N);
+
/// Compute GCD of two unsigned APInt values.
///
/// This function returns the greatest common divisor of the two APInt values
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index ea8295f95c751a..d95c1bc8e7194e 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -3108,3 +3108,22 @@ APInt APIntOps::mulhu(const APInt &C1, const APInt &C2) {
APInt C2Ext = C2.zext(FullWidth);
return (C1Ext * C2Ext).extractBits(C1.getBitWidth(), C1.getBitWidth());
}
+
+APInt APIntOps::pow(const APInt &X, const int &N) {
+ assert(N >= 0 && "negative exponents not supported.");
+ if (N == 0) {
+ return APInt(X.getBitWidth(), 1);
+ }
+ APInt Acc = X;
+ int64_t RemainingExponent = N;
+ while (RemainingExponent > 1) {
+ if (RemainingExponent % 2 == 0) {
+ Acc = Acc * Acc;
+ RemainingExponent /= 2;
+ } else {
+ Acc = Acc * X;
+ RemainingExponent--;
+ }
+ }
+ return Acc;
+};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add unit tests?
Added unit tests. Removed APFloat change- this change is now only for APInt. |
APInt V_27 = APInt::getZero(32) + 27; | ||
EXPECT_EQ(ThreeTo3, V_27); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test getMaxValue, getMaxSignedValue, getMinSignedValue cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added tests for getSignedMaxValue
and getMaxValue
. I don't know what you mean by testing getMinSignedValue
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean APInt::getSignedMinValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right check?
// Test that SignedMinValue^3 == 0
TEST(APIntTest, PowerSignedMinValueTo3) {
APInt SignedMinValue = APInt::getSignedMinValue(32);
APInt MinTo3 = APIntOps::pow(SignedMinValue, 3);
EXPECT_TRUE(MinTo3.isZero());
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM % nit
Co-authored-by: Jakub Kuderski <[email protected]>
✅ With the latest revision this PR passed the C/C++ code formatter. |
Remove erroneous extra semicolon in: #122788 Co-authored-by: ImanHosseini <[email protected]>
Remove erroneous extra semicolon in: llvm/llvm-project#122788 Co-authored-by: ImanHosseini <[email protected]>
I am trying to calculate power function for APFloat, APInt to constant fold vector reductions: #122450
I need this utility to fold N
mul
s into power.