[llvm] 9eeae44 - [ValueTracking] Implement `computeKnownFPClass` for `llvm.vector.reduce.{fmin,fmax,fmaximum,fminimum}`

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 16 14:10:13 PDT 2024


Author: Noah Goldstein
Date: 2024-04-16T16:10:00-05:00
New Revision: 9eeae4421198b99eab3ae9a4ff678fda26bbda2a

URL: https://github.com/llvm/llvm-project/commit/9eeae4421198b99eab3ae9a4ff678fda26bbda2a
DIFF: https://github.com/llvm/llvm-project/commit/9eeae4421198b99eab3ae9a4ff678fda26bbda2a.diff

LOG: [ValueTracking] Implement `computeKnownFPClass` for `llvm.vector.reduce.{fmin,fmax,fmaximum,fminimum}`

Closes #88408

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll
    llvm/test/Transforms/InstSimplify/known-never-infinity.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e91dc07f31641b..ab2f43e1033fa1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5032,6 +5032,19 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
 
       break;
     }
+    case Intrinsic::vector_reduce_fmax:
+    case Intrinsic::vector_reduce_fmin:
+    case Intrinsic::vector_reduce_fmaximum:
+    case Intrinsic::vector_reduce_fminimum: {
+      // reduce min/max will choose an element from one of the vector elements,
+      // so we can infer and class information that is common to all elements.
+      Known = computeKnownFPClass(II->getArgOperand(0), II->getFastMathFlags(),
+                                  InterestedClasses, Depth + 1, Q);
+      // Can only propagate sign if output is never NaN.
+      if (!Known.isKnownNeverNaN())
+        Known.SignBit.reset();
+      break;
+    }
     case Intrinsic::trunc:
     case Intrinsic::floor:
     case Intrinsic::ceil:

diff  --git a/llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll b/llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll
index 2f3db14b2e1ac5..f46ea9db751ff4 100644
--- a/llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll
+++ b/llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll
@@ -4,10 +4,7 @@
 define i1 @vector_reduce_maximum_signbit(<4 x double> nofpclass(nan nzero) %x) {
 ; CHECK-LABEL: define i1 @vector_reduce_maximum_signbit
 ; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
-; CHECK-NEXT:    [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> [[X_ABS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
   %op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %x.abs)
@@ -33,10 +30,7 @@ define i1 @vector_reduce_maximum_signbit_fail_maybe_nan(<4 x double> nofpclass(n
 define i1 @vector_reduce_minimum_signbit(<4 x double> nofpclass(nan nzero) %x) {
 ; CHECK-LABEL: define i1 @vector_reduce_minimum_signbit
 ; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
-; CHECK-NEXT:    [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[X_ABS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
   %op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %x.abs)
@@ -61,10 +55,7 @@ define i1 @vector_reduce_minimum_signbit_fail_maybe_nan(<4 x double> nofpclass(n
 define i1 @vector_reduce_max_signbit(<4 x double> nofpclass(nan nzero) %x) {
 ; CHECK-LABEL: define i1 @vector_reduce_max_signbit
 ; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
-; CHECK-NEXT:    [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> [[X_ABS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
   %op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %x.abs)
@@ -90,10 +81,7 @@ define i1 @vector_reduce_max_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero
 define i1 @vector_reduce_min_signbit(<4 x double> nofpclass(nan nzero) %x) {
 ; CHECK-LABEL: define i1 @vector_reduce_min_signbit
 ; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
-; CHECK-NEXT:    [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[X_ABS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
   %op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %x.abs)
@@ -120,10 +108,7 @@ define i1 @vector_reduce_min_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero
 define i1 @vector_reduce_min_signbit_nnan_from_fmf(<4 x double> nofpclass(nzero) %x) {
 ; CHECK-LABEL: define i1 @vector_reduce_min_signbit_nnan_from_fmf
 ; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
-; CHECK-NEXT:    [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
-; CHECK-NEXT:    [[OP:%.*]] = call nnan double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[X_ABS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
   %op = call nnan double @llvm.vector.reduce.fmin.v4f64(<4 x double> %x.abs)

diff  --git a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
index 470b56a8ef2ae3..4d662c08b1a7a1 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
@@ -1112,10 +1112,7 @@ define float @fcmp_ult_neginf_implies_class_assert(float %arg) {
 define i1 @isKnownNeverInfinity_vector_reduce_maximum(<4 x double> %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_maximum
 ; CHECK-SAME: (<4 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> [[NINF_X]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
   %op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %ninf.x)
@@ -1140,10 +1137,7 @@ define i1 @isKnownNeverInfinity_vector_reduce_maximum_fail(<4 x double> %x) {
 define i1 @isKnownNeverInfinity_vector_reduce_minimum(<4 x double> %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_minimum
 ; CHECK-SAME: (<4 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[NINF_X]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
   %op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %ninf.x)
@@ -1168,10 +1162,7 @@ define i1 @isKnownNeverInfinity_vector_reduce_minimum_fail(<4 x double> %x) {
 define i1 @isKnownNeverInfinity_vector_reduce_fmax(<4 x double> %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmax
 ; CHECK-SAME: (<4 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> [[NINF_X]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
   %op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %ninf.x)
@@ -1196,10 +1187,7 @@ define i1 @isKnownNeverInfinity_vector_reduce_fmax_fail(<4 x double> %x) {
 define i1 @isKnownNeverInfinity_vector_reduce_fmin(<4 x double> %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmin
 ; CHECK-SAME: (<4 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[NINF_X:%.*]] = fadd ninf <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
-; CHECK-NEXT:    [[OP:%.*]] = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[NINF_X]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
   %op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %ninf.x)


        


More information about the llvm-commits mailing list