Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8736,12 +8736,6 @@ static mlir::Value genExtremumResult(mlir::Location loc,
fir::FirOpBuilder &builder,
mlir::Value left, mlir::Value right) {
mlir::Type type = left.getType();
mlir::arith::CmpIPredicate integerPredicate =
type.isUnsignedInteger() ? isMax ? mlir::arith::CmpIPredicate::ugt
: mlir::arith::CmpIPredicate::ult
: isMax ? mlir::arith::CmpIPredicate::sgt
: mlir::arith::CmpIPredicate::slt;
mlir::Value pred;
if (fir::isa_real(type)) {
switch (builder.getFPMaxminBehavior()) {
case Fortran::common::FPMaxminBehavior::Portable:
Expand Down Expand Up @@ -8782,26 +8776,41 @@ static mlir::Value genExtremumResult(mlir::Location loc,

llvm_unreachable("unsupported FPMaxminBehavior");
} else if (fir::isa_integer(type)) {
mlir::Value cmpLeft = left;
mlir::Value cmpRight = right;
// It is probably okay to use signed index.maxs/mins, but
// maybe the caller needs to specify signedness.
// There are currently no callers that pass values of index
// type, so just emit a TODO.
if (mlir::isa<mlir::IndexType>(type))
TODO(loc, "extremum for index type");

if (type.isUnsignedInteger()) {
// arith.maxui/minui operands must have singless type.
mlir::Type signlessType = mlir::IntegerType::get(
builder.getContext(), type.getIntOrFloatBitWidth(),
mlir::IntegerType::SignednessSemantics::Signless);
cmpLeft = builder.createConvert(loc, signlessType, left);
cmpRight = builder.createConvert(loc, signlessType, right);
left = builder.createConvert(loc, signlessType, left);
right = builder.createConvert(loc, signlessType, right);

mlir::Value result;
if constexpr (isMax)
result = mlir::arith::MaxUIOp::create(builder, loc, left, right);
else
result = mlir::arith::MinUIOp::create(builder, loc, left, right);

return builder.createConvert(loc, type, result);
} else {
if constexpr (isMax)
return mlir::arith::MaxSIOp::create(builder, loc, left, right);
else
return mlir::arith::MinSIOp::create(builder, loc, left, right);
}
pred = mlir::arith::CmpIOp::create(builder, loc, integerPredicate, cmpLeft,
cmpRight);
} else if (fir::isa_char(type) || fir::isa_char(fir::unwrapRefType(type))) {
// TODO: ! character min and max is tricky because the result
// length is the length of the longest argument!
// So we may need a temp.
TODO(loc, "intrinsic: min and max for CHARACTER");
}
assert(pred && "pred must be defined");

return mlir::arith::SelectOp::create(builder, loc, pred, left, right);
llvm_unreachable("unsupported extremum");
}

// UNLINK
Expand Down
44 changes: 5 additions & 39 deletions flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ class MinMaxvalAsElementalConverter
this->checkReductions(currentValue);
llvm::SmallVector<mlir::Value> result;
fir::FirOpBuilder &builder = this->builder;
builder.setFPMaxminBehavior(fpMaxminBehavior);
mlir::Location loc = this->loc;
hlfir::Entity elementValue =
hlfir::loadElementAt(loc, builder, array, oneBasedIndices);
Expand Down Expand Up @@ -893,45 +894,10 @@ class MinMaxvalAsElementalConverter
assert(!useIsFirst() &&
"unordered max/min reduction must not use first predicate");

if (mlir::isa<fir::CharacterType>(this->getSourceElementType()))
TODO(loc, "max/minval with CHARACTER type");

if (auto intType =
mlir::dyn_cast<mlir::IntegerType>(this->getSourceElementType())) {
if (intType.isUnsigned())
TODO(loc, "max/minval with UNSIGNED type");

if constexpr (isMax)
return mlir::arith::MaxSIOp::create(builder, loc, elementValue,
currentMinMax);
else
return mlir::arith::MinSIOp::create(builder, loc, elementValue,
currentMinMax);
}

if (fpMaxminBehavior == Fortran::common::FPMaxminBehavior::Extremum) {
if constexpr (isMax)
return mlir::arith::MaximumFOp::create(builder, loc, elementValue,
currentMinMax);
else
return mlir::arith::MinimumFOp::create(builder, loc, elementValue,
currentMinMax);
}

if (fpMaxminBehavior == Fortran::common::FPMaxminBehavior::ExtremeNum ||
(fpMaxminBehavior == Fortran::common::FPMaxminBehavior::Portable &&
mlir::arith::bitEnumContainsAll(
this->getFastMath(), mlir::arith::FastMathFlags::nnan |
mlir::arith::FastMathFlags::nsz))) {
if constexpr (isMax)
return mlir::arith::MaxNumFOp::create(builder, loc, elementValue,
currentMinMax);
else
return mlir::arith::MinNumFOp::create(builder, loc, elementValue,
currentMinMax);
}

llvm_unreachable("unhandled unordered max/min reduction");
if constexpr (isMax)
return fir::genMax(builder, loc, {elementValue, currentMinMax});
else
return fir::genMin(builder, loc, {elementValue, currentMinMax});
}

std::size_t getNumReductions() const { return useIsFirst() ? 2 : 1; }
Expand Down
3 changes: 1 addition & 2 deletions flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ subroutine test_as_strided_elemental(lb, ub, stride)
! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_15:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.maxsi %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_6]], %[[VAL_16]] : i64
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i64) -> index
! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_18]] : (index) -> !fir.shape<1>
Expand Down
12 changes: 4 additions & 8 deletions flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ subroutine test_implied_do(n)
! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_11:.*]] = arith.divsi %[[VAL_9]], %[[VAL_10]] : i64
! CHECK: %[[VAL_12:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.maxsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_15:.*]] = arith.muli %[[VAL_4]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_3]], %[[VAL_15]] : i64
! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index
Expand Down Expand Up @@ -191,8 +190,7 @@ subroutine test_strided_implied_do(lb, ub, stride)
! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_15:.*]] = arith.divsi %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_17:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_16]] : i64
! CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_15]], %[[VAL_16]] : i64
! CHECK: %[[VAL_18:.*]] = arith.maxsi %[[VAL_15]], %[[VAL_16]] : i64
! CHECK: %[[VAL_19:.*]] = arith.muli %[[VAL_8]], %[[VAL_18]] : i64
! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_7]], %[[VAL_19]] : i64
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index
Expand Down Expand Up @@ -253,8 +251,7 @@ subroutine test_nested_implied_do(n, m)
! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_15:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_16:.*]] = arith.maxsi %[[VAL_13]], %[[VAL_14]] : i64
! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_6]], %[[VAL_16]] : i64
! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_19:.*]] = arith.constant 1 : i64
Expand All @@ -264,8 +261,7 @@ subroutine test_nested_implied_do(n, m)
! CHECK: %[[VAL_23:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_24:.*]] = arith.divsi %[[VAL_22]], %[[VAL_23]] : i64
! CHECK: %[[VAL_25:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_26:.*]] = arith.cmpi sgt, %[[VAL_24]], %[[VAL_25]] : i64
! CHECK: %[[VAL_27:.*]] = arith.select %[[VAL_26]], %[[VAL_24]], %[[VAL_25]] : i64
! CHECK: %[[VAL_27:.*]] = arith.maxsi %[[VAL_24]], %[[VAL_25]] : i64
! CHECK: %[[VAL_28:.*]] = arith.muli %[[VAL_17]], %[[VAL_27]] : i64
! CHECK: %[[VAL_29:.*]] = arith.addi %[[VAL_5]], %[[VAL_28]] : i64
! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
Expand Down
3 changes: 1 addition & 2 deletions flang/test/Lower/HLFIR/binary-ops.f90
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ subroutine extremum(c, n, l)
! CHECK: hlfir.declare {{.*}}c"}
! CHECK: %[[VAL_11:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_12:.*]] = fir.load %{{.*}} : !fir.ref<i64>
! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: arith.maxsi %[[VAL_11]], %[[VAL_12]] : i64

subroutine cmp_int(l, x, y)
logical :: l
Expand Down
Loading