[PATCH] D126190: [InstCombine] Add combine for fcmp sqrt(x),C --> fcmp x,C*C

Bradley Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 24 05:24:31 PDT 2022


bsmith updated this revision to Diff 431649.
bsmith added a comment.

- Rebase.
- Move fast math flag requirements from fcmp to sqrt.
- Don't require 'fast' flag on sqrt, only 'nnan && (reassoc || afn)'


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126190

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/fcmp.ll


Index: llvm/test/Transforms/InstCombine/fcmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fcmp.ll
+++ llvm/test/Transforms/InstCombine/fcmp.ll
@@ -3,6 +3,7 @@
 
 declare half @llvm.fabs.f16(half)
 declare double @llvm.fabs.f64(double)
+declare double @llvm.sqrt.f64(double)
 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
 declare double @llvm.copysign.f64(double, double)
 declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>)
@@ -1210,3 +1211,60 @@
   %cmp = fcmp ninf une float %a, %fneg
   ret i1 %cmp
 }
+
+; fcmp sqrt(X),C --> fcmp X,C*C - when using afn flag
+define i1 @fcmp_fsqrt_test1(double %v) {
+; CHECK-LABEL: @fcmp_fsqrt_test1(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[V:%.*]], 4.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sqrt = call nnan afn double @llvm.sqrt.f64(double %v)
+  %cmp = fcmp ogt double %sqrt, 2.000000e+00
+  ret i1 %cmp
+}
+
+; fcmp sqrt(X),C --> fcmp X,C*C - when using reassoc flag
+define i1 @fcmp_fsqrt_test2(double %v) {
+; CHECK-LABEL: @fcmp_fsqrt_test2(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[V:%.*]], 4.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sqrt = call nnan reassoc double @llvm.sqrt.f64(double %v)
+  %cmp = fcmp ogt double %sqrt, 2.000000e+00
+  ret i1 %cmp
+}
+
+; fcmp sqrt(X),C --> fcmp X,C*C - fcmp flags are preserved
+define i1 @fcmp_fsqrt_test3(double %v) {
+; CHECK-LABEL: @fcmp_fsqrt_test3(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt double [[V:%.*]], 4.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sqrt = call nnan reassoc double @llvm.sqrt.f64(double %v)
+  %cmp = fcmp fast ogt double %sqrt, 2.000000e+00
+  ret i1 %cmp
+}
+
+; ensure we preserve sqrts when compared against negative numbers.
+define i1 @fcmp_fsqrt_test4(double %v) {
+; CHECK-LABEL: @fcmp_fsqrt_test4(
+; CHECK-NEXT:    [[SQRT:%.*]] = call nnan afn double @llvm.sqrt.f64(double [[V:%.*]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[SQRT]], -2.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sqrt = call nnan afn double @llvm.sqrt.f64(double %v)
+  %cmp = fcmp ogt double %sqrt, -2.000000e+00
+  ret i1 %cmp
+}
+
+; ensure we maintain sqrts when preserving NaNs.
+define i1 @fcmp_fsqrt_test5(double %v) {
+; CHECK-LABEL: @fcmp_fsqrt_test5(
+; CHECK-NEXT:    [[SQRT:%.*]] = call reassoc double @llvm.sqrt.f64(double [[V:%.*]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[SQRT]], 2.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sqrt = call reassoc double @llvm.sqrt.f64(double %v)
+  %cmp = fcmp ogt double %sqrt, 2.000000e+00
+  ret i1 %cmp
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6775,6 +6775,19 @@
     }
   }
 
+  if (match(Op0, m_Sqrt(m_Value(X)))) {
+    // fcmp sqrt(x),C -> fcmp x,C*C
+    const APFloat *CF;
+    Instruction *Sqrt = cast<Instruction>(Op0);
+    if (match(Op1, m_APFloat(CF)) && !CF->isNegative() && Sqrt->hasNoNaNs() &&
+        (Sqrt->hasAllowReassoc() || Sqrt->hasApproxFunc())) {
+      Constant *C = ConstantFP::get(X->getType(), *CF);
+      Instruction *FCmp = new FCmpInst(Pred, X, ConstantExpr::getFMul(C, C));
+      FCmp->setFastMathFlags(I.getFastMathFlags());
+      return FCmp;
+    }
+  }
+
   if (match(Op0, m_FPExt(m_Value(X)))) {
     // fcmp (fpext X), (fpext Y) -> fcmp X, Y
     if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D126190.431649.patch
Type: text/x-patch
Size: 3586 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220524/c01699ac/attachment.bin>


More information about the llvm-commits mailing list