[flang-commits] [flang] [Flang] RFC: Allow extended argument types in min0/max0 intrinsics (PR #162551)
Carlos Seo via flang-commits
flang-commits at lists.llvm.org
Wed Oct 8 14:19:33 PDT 2025
https://github.com/ceseo created https://github.com/llvm/llvm-project/pull/162551
Change the behavior of min0/max0 when they are called with non-default integer kinds by preserving the argument kinds instead of converting to default integer.
Fixes #132646
>From afbaba0417d9cab55d0771873d9a942316f0b778 Mon Sep 17 00:00:00 2001
From: Carlos Seo <carlos.seo at linaro.org>
Date: Wed, 8 Oct 2025 18:14:58 -0300
Subject: [PATCH] [Flang] RFC: Allow extended argument types in min0/max0
intrinsics
Change the behavior of min0/max0 when they are called with
non-default integer kinds by preserving the argument kinds
instead of converting to default integer.
Fixes #132646
---
flang/docs/Extensions.md | 3 +++
flang/lib/Evaluate/intrinsics.cpp | 6 ++++++
flang/test/Evaluate/folding04.f90 | 13 +++++++------
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 420b7517922b7..3fef0ab742287 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -287,6 +287,9 @@ end
* Specific intrinsics AMAX0, AMAX1, AMIN0, AMIN1, DMAX1, DMIN1, MAX0, MAX1,
MIN0, and MIN1 accept more argument types than specified. They are replaced by
the related generics followed by conversions to the specified result types.
+ For MAX0 and MIN0, the result type matches the argument types rather than
+ being converted to default INTEGER, preserving the kind of the arguments.
+ For example, `MAX0(1_8, 2_8)` returns `INTEGER(8)`, not `INTEGER(4)`.
* When a scalar CHARACTER actual argument of the same kind is known to
have a length shorter than the associated dummy argument, it is extended
on the right with blanks, similar to assignment.
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index fe679da4ff98b..46375ed0e08f6 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -3654,6 +3654,12 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
.GetTypeAndShape())
.type()};
DynamicType newType{GetReturnType(*specIter->second, defaults_)};
+ // For MAX0/MIN0, preserve the generic type rather than forcing
+ // to default integer. This allows, for example, MAX0(1_8,2_8) to
+ // return INTEGER(8) instead of INTEGER(4).
+ if (genericType.category() == newType.category()) {
+ newType = genericType;
+ }
if (genericType.category() == newType.category() ||
((genericType.category() == TypeCategory::Integer ||
genericType.category() == TypeCategory::Real) &&
diff --git a/flang/test/Evaluate/folding04.f90 b/flang/test/Evaluate/folding04.f90
index 027db20f608b2..390197eb9cfdd 100644
--- a/flang/test/Evaluate/folding04.f90
+++ b/flang/test/Evaluate/folding04.f90
@@ -79,15 +79,16 @@ module parentheses
module specific_extremums
! f18 accepts all type kinds for the arguments of specific extremum intrinsics
! instead of of only default kind (or double precision for DMAX1 and DMIN1).
- ! This extensions is implemented by using the related generic intrinsic and
- ! converting the result.
+ ! This extension is implemented by using the related generic intrinsic.
+ ! For MAX0/MIN0, the result type matches the argument types (preserving kind).
+ ! For AMAX0/AMIN0/MAX1/MIN1, the result is converted to the specified type.
! The tests below are cases where an implementation that converts the arguments to the
! standard required types instead would give different results than the implementation
- ! specified for f18 (converting the result).
+ ! specified for f18.
integer(8), parameter :: max_i32_8 = 2_8**31-1
- integer, parameter :: expected_min0 = int(min(max_i32_8, 2_8*max_i32_8), 4)
- !WARN: portability: Argument types do not match specific intrinsic 'min0' requirements; using 'min' generic instead and converting the result to INTEGER(4) if needed [-Wuse-generic-intrinsic-when-specific-doesnt-match]
- integer, parameter :: result_min0 = min0(max_i32_8, 2_8*max_i32_8)
+ integer(8), parameter :: expected_min0 = min(max_i32_8, 2_8*max_i32_8)
+ !WARN: portability: Argument types do not match specific intrinsic 'min0' requirements; using 'min' generic instead and converting the result to INTEGER(8) if needed [-Wuse-generic-intrinsic-when-specific-doesnt-match]
+ integer(8), parameter :: result_min0 = min0(max_i32_8, 2_8*max_i32_8)
! result_min0 would be -2 if arguments were converted to default integer.
logical, parameter :: test_min0 = expected_min0 .EQ. result_min0
More information about the flang-commits
mailing list