[llvm] [ValueTracking] Implement `computeKnownFPClass` for `llvm.vector.reduce.{fmin,fmax,fmaximum,fminimum}` (PR #88408)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 14 11:59:37 PDT 2024


================
@@ -0,0 +1,105 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt < %s -S -passes=instcombine | FileCheck %s
+
+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:    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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+define i1 @vector_reduce_maximum_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
+; CHECK-LABEL: define i1 @vector_reduce_maximum_signbit_fail_maybe_nan
+; 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 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]]
+;
+  %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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+
+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:    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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+define i1 @vector_reduce_minimum_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
+; CHECK-LABEL: define i1 @vector_reduce_minimum_signbit_fail_maybe_nan
+; 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 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]]
+;
+  %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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+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:    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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+define i1 @vector_reduce_max_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
+; CHECK-LABEL: define i1 @vector_reduce_max_signbit_fail_maybe_nan
+; 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 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]]
+;
+  %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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+
+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:    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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
+define i1 @vector_reduce_min_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
+; CHECK-LABEL: define i1 @vector_reduce_min_signbit_fail_maybe_nan
+; 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 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]]
+;
+  %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)
+  %cmp = fcmp oge double %op, 0.0
+  ret i1 %cmp
+}
+
----------------
arsenm wrote:

Should test the case where the nnan flag on the call itself allows preserving the signbit 

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


More information about the llvm-commits mailing list