[PATCH] D128591: Transforms: refactor pow(x, n) expansion where n is a constant integer value

Paul Osmialowski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 6 12:12:46 PDT 2022


pawosm01 added inline comments.


================
Comment at: llvm/test/Transforms/InstCombine/pow-4.ll:140
+; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.pow.f64(double [[X:%.*]], double 1.650000e+01)
+; CHECK-NEXT:    ret double [[TMP1]]
 ;
----------------
RKSimon wrote:
> I guess we need to decide whether we want to retain this variety of cases somehow? I assume we can perform this as powi(x, 16) * sqrt(x) ?
Something like this?:
```
   const APFloat *ExpoF;
   if (match(Expo, m_APFloat(ExpoF)) && !ExpoF->isExactlyValue(0.5) &&
       !ExpoF->isExactlyValue(-0.5)) {
+    // This transformation applies to integer or integer+0.5 exponents only.
+    // For integer+0.5, we create a sqrt(Base) call.
+    APFloat ExpoA(abs(*ExpoF));
+    Value *Sqrt = nullptr;
+    if (AllowApprox && !ExpoA.isInteger()) {
+      APFloat Expo2 = ExpoA;
+      // To check if ExpoA is an integer + 0.5, we add it to itself. If there
+      // is no floating point exception and the result is an integer, then
+      // ExpoA == integer + 0.5
+      if (Expo2.add(ExpoA, APFloat::rmNearestTiesToEven) != APFloat::opOK)
+        return nullptr;
+
+      if (!Expo2.isInteger())
+        return nullptr;
+
+      Sqrt = getSqrtCall(Base, Pow->getCalledFunction()->getAttributes(),
+                         Pow->doesNotAccessMemory(), M, B, TLI);
+      if (!Sqrt)
+        return nullptr;
+    }
+
     APSInt IntExpo(TLI->getIntSize(), /*isUnsigned=*/false);
+    // pow(x, n) -> powi(x, n) if n is a constant signed integer value
     if (ExpoF->isInteger() &&
         ExpoF->convertToInteger(IntExpo, APFloat::rmTowardZero, &Ignored) ==
             APFloat::opOK) {
-      return copyFlags(
+      Value *PowI = copyFlags(
           *Pow,
           createPowWithIntegerExponent(
               Base, ConstantInt::get(B.getIntNTy(TLI->getIntSize()), IntExpo),
               M, B));
+
+      if (PowI && Sqrt)
+        return B.CreateFMul(PowI, Sqrt);
+
+      return PowI;
     }
   }
```
Sadly, this leads to infinite loop of self-contradicting optimizations:
```
FAIL: LLVM :: Transforms/InstCombine/pow_fp_int.ll (10150 of 45161)
******************** TEST 'LLVM :: Transforms/InstCombine/pow_fp_int.ll' FAILED ********************
Script:
--
: 'RUN: at line 1';   /dsg_space/projectscratch_dsg_space/pawosm01/upstream/llvm-project.git/build-shared-debug/bin/opt -mtriple unknown -passes=instcombine -S < /dsg_space/projectscratch_dsg_space/pawosm01/upstream/llvm-project.git/llvm/test/Transforms/InstCombine/pow_fp_int.ll | /dsg_space/projectscratch_dsg_space/pawosm01/upstream/llvm-project.git/build-shared-debug/bin/FileCheck /dsg_space/projectscratch_dsg_space/pawosm01/upstream/llvm-project.git/llvm/test/Transforms/InstCombine/pow_fp_int.ll
--
Exit Code: 2

Command Output (stderr):
--
LLVM ERROR: Instruction Combining seems stuck in an infinite loop after 100 iterations.
```



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128591/new/

https://reviews.llvm.org/D128591



More information about the llvm-commits mailing list