[llvm] [SimplifyLibCalls] Simplify cabs libcall if real or imaginary part of input is zero (PR #97976)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 03:55:31 PDT 2024


================
@@ -1958,25 +1959,53 @@ static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B,
 
 // cabs(z) -> sqrt((creal(z)*creal(z)) + (cimag(z)*cimag(z)))
 Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) {
-  if (!CI->isFast())
-    return nullptr;
-
-  // Propagate fast-math flags from the existing call to new instructions.
-  IRBuilderBase::FastMathFlagGuard Guard(B);
-  B.setFastMathFlags(CI->getFastMathFlags());
-
   Value *Real, *Imag;
+
   if (CI->arg_size() == 1) {
+
+    if (!CI->isFast())
+      return nullptr;
+
     Value *Op = CI->getArgOperand(0);
     assert(Op->getType()->isArrayTy() && "Unexpected signature for cabs!");
+
     Real = B.CreateExtractValue(Op, 0, "real");
     Imag = B.CreateExtractValue(Op, 1, "imag");
+
   } else {
     assert(CI->arg_size() == 2 && "Unexpected signature for cabs!");
+
     Real = CI->getArgOperand(0);
     Imag = CI->getArgOperand(1);
+
+    // if real or imaginary part is zero, simplify to abs(cimag(z))
+    // or abs(creal(z))
+    Value *AbsOp = nullptr;
+    if (ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
+      if (ConstReal->isZero())
+        AbsOp = Imag;
+
+    } else if (ConstantFP *ConstImag = dyn_cast<ConstantFP>(Imag)) {
+      if (ConstImag->isZero())
+        AbsOp = Real;
+    }
+
+    if (AbsOp) {
+      IRBuilderBase::FastMathFlagGuard Guard(B);
+      B.setFastMathFlags(CI->getFastMathFlags());
+
+      return copyFlags(
----------------
arsenm wrote:

You can always write out fpext float -0.0 to fp128 and run that through instsimplify to see how it's printed 

https://github.com/llvm/llvm-project/pull/97976


More information about the llvm-commits mailing list