[PATCH] D13994: [SimplifyLibCalls] Optimization for pow(x, n) where n is some constant
Mandeep Singh Grang via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 17 12:14:29 PST 2015
mgrang updated this revision to Diff 40421.
http://reviews.llvm.org/D13994
Files:
lib/Transforms/Utils/SimplifyLibCalls.cpp
Index: lib/Transforms/Utils/SimplifyLibCalls.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1061,6 +1061,46 @@
return Ret;
}
+static Value *getPow(Value *pow1, unsigned Exp, IRBuilder<> &B) {
+ // Pre-compute Addition Chains for each exponent upto 32
+ // Refer: http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
+
+ Value *AddChain[33];
+ AddChain[1] = pow1;
+ AddChain[2] = B.CreateFMul(pow1, pow1);
+ AddChain[3] = B.CreateFMul(AddChain[1], AddChain[2]);
+ AddChain[4] = B.CreateFMul(AddChain[2], AddChain[2]);
+ AddChain[5] = B.CreateFMul(AddChain[2], AddChain[3]);
+ AddChain[6] = B.CreateFMul(AddChain[3], AddChain[3]);
+ AddChain[7] = B.CreateFMul(AddChain[2], AddChain[5]);
+ AddChain[8] = B.CreateFMul(AddChain[4], AddChain[4]);
+ AddChain[9] = B.CreateFMul(AddChain[1], AddChain[8]);
+ AddChain[10] = B.CreateFMul(AddChain[5], AddChain[5]);
+ AddChain[11] = B.CreateFMul(AddChain[1], AddChain[10]);
+ AddChain[12] = B.CreateFMul(AddChain[6], AddChain[6]);
+ AddChain[13] = B.CreateFMul(AddChain[4], AddChain[9]);
+ AddChain[14] = B.CreateFMul(AddChain[7], AddChain[7]);
+ AddChain[15] = B.CreateFMul(AddChain[3], AddChain[12]);
+ AddChain[16] = B.CreateFMul(AddChain[8], AddChain[8]);
+ AddChain[17] = B.CreateFMul(AddChain[8], AddChain[9]);
+ AddChain[18] = B.CreateFMul(AddChain[2], AddChain[16]);
+ AddChain[19] = B.CreateFMul(AddChain[1], AddChain[18]);
+ AddChain[20] = B.CreateFMul(AddChain[10], AddChain[10]);
+ AddChain[21] = B.CreateFMul(AddChain[6], AddChain[15]);
+ AddChain[22] = B.CreateFMul(AddChain[11], AddChain[11]);
+ AddChain[23] = B.CreateFMul(AddChain[3], AddChain[20]);
+ AddChain[24] = B.CreateFMul(AddChain[12], AddChain[12]);
+ AddChain[25] = B.CreateFMul(AddChain[8], AddChain[17]);
+ AddChain[26] = B.CreateFMul(AddChain[13], AddChain[13]);
+ AddChain[27] = B.CreateFMul(AddChain[3], AddChain[24]);
+ AddChain[28] = B.CreateFMul(AddChain[14], AddChain[14]);
+ AddChain[29] = B.CreateFMul(AddChain[4], AddChain[25]);
+ AddChain[30] = B.CreateFMul(AddChain[15], AddChain[15]);
+ AddChain[31] = B.CreateFMul(AddChain[3], AddChain[28]);
+ AddChain[32] = B.CreateFMul(AddChain[16], AddChain[16]);
+ return AddChain[Exp];
+}
+
Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
Value *Ret = nullptr;
@@ -1154,6 +1194,27 @@
return B.CreateFMul(Op1, Op1, "pow2");
if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Op1, "powrecip");
+
+ // Only in fast-math mode, generate repeated fmul instead of generating
+ // pow(x, n).
+ if (canUseUnsafeFPMath(CI->getParent()->getParent())) {
+ APFloat V = abs(Op2C->getValueAPF());
+ // We limit to a max of 7 fmul(s). Thus max exponent is 32.
+ // This transformation applies to integer exponents only.
+ if (V.compare(APFloat(V.getSemantics(), 32.0)) ==
+ APFloat::cmpGreaterThan || !V.isInteger())
+ return nullptr;
+ // We cannot readily convert a non-double type (like float) to a double.
+ // So we first convert V to something which could be converted to double.
+ bool ignored;
+ V.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
+ Value *FMul = getPow(Op1, V.convertToDouble(), B);
+ // For negative exponents simply compute the reciprocal.
+ if (Op2C->isNegative())
+ FMul = B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), FMul);
+ return FMul;
+ }
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13994.40421.patch
Type: text/x-patch
Size: 3679 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151117/dafa4b45/attachment.bin>
More information about the llvm-commits
mailing list