[llvm] [ConstantFolding] Fold `vector.fmax` and `vector.fmin` (PR #143904)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 12 07:14:34 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nikolay Panchenko (npanchen)

<details>
<summary>Changes</summary>

The changeset adds folding of `vector.fmax` and `vector.fmin` intrinsics
by invoking `maxnum` and `minnum` respectively.

---
Full diff: https://github.com/llvm/llvm-project/pull/143904.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/ConstantFolding.cpp (+25) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll (+16) 


``````````diff
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 139a0b81e299b..788ad93627cf3 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1635,6 +1635,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case Intrinsic::vector_reduce_smax:
   case Intrinsic::vector_reduce_umin:
   case Intrinsic::vector_reduce_umax:
+  case Intrinsic::vector_reduce_fmin:
+  case Intrinsic::vector_reduce_fmax:
   case Intrinsic::vector_extract:
   case Intrinsic::vector_insert:
   case Intrinsic::vector_interleave2:
@@ -2021,6 +2023,27 @@ Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {
   if (!isa<ConstantVector>(Op) && !isa<ConstantDataVector>(Op))
     return nullptr;
 
+  // Try to fold floating point reductions
+  if (auto *EltC = dyn_cast<ConstantFP>(Op->getAggregateElement(0U))) {
+    APFloat Res(EltC->getValueAPF());
+    for (unsigned I = 1, E = VT->getNumElements(); I != E; ++I) {
+      if (!(EltC = dyn_cast<ConstantFP>(Op->getAggregateElement(I))))
+        return nullptr;
+
+      switch (IID) {
+      case Intrinsic::vector_reduce_fmin:
+        Res = minnum(Res, EltC->getValueAPF());
+        break;
+      case Intrinsic::vector_reduce_fmax:
+        Res = maxnum(Res, EltC->getValueAPF());
+        break;
+      default:
+        return nullptr;
+      }
+    }
+    return ConstantFP::get(VT->getElementType(), Res);
+  }
+
   auto *EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(0U));
   if (!EltC)
     return nullptr;
@@ -2826,6 +2849,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
   case Intrinsic::vector_reduce_smax:
   case Intrinsic::vector_reduce_umin:
   case Intrinsic::vector_reduce_umax:
+  case Intrinsic::vector_reduce_fmin:
+  case Intrinsic::vector_reduce_fmax:
     if (Constant *C = constantFoldVectorReduce(IntrinsicID, Operands[0]))
       return C;
     break;
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
index 9dbe3d4e50ee1..641cb77f30b82 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
@@ -66,3 +66,19 @@ define {<vscale x 4 x i32>, <vscale x 4 x i32>} @fold_scalable_vector_deinterlea
   %1 = call {<vscale x 4 x i32>, <vscale x 4 x i32>} @llvm.vector.deinterleave2.v4i32.v8i32(<vscale x 8 x i32> zeroinitializer)
   ret {<vscale x 4 x i32>, <vscale x 4 x i32>} %1
 }
+
+define float @fold_vector_fmin() {
+; CHECK-LABEL: define float @fold_vector_fmin() {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %1 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)
+  ret float %1
+}
+
+define float @fold_vector_fmax() {
+; CHECK-LABEL: define float @fold_vector_fmax() {
+; CHECK-NEXT:    ret float 4.000000e+00
+;
+  %1 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)
+  ret float %1
+}

``````````

</details>


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


More information about the llvm-commits mailing list