diff --git a/flang/include/flang/Lower/ConvertExpr.h b/flang/include/flang/Lower/ConvertExpr.h --- a/flang/include/flang/Lower/ConvertExpr.h +++ b/flang/include/flang/Lower/ConvertExpr.h @@ -232,10 +232,6 @@ builder.getUnitAttr()}; } -/// Generate max(\p value, 0) where \p value is a scalar integer. -mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc, - mlir::Value value); - } // namespace Fortran::lower #endif // FORTRAN_LOWER_CONVERTEXPR_H diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -542,6 +542,10 @@ /// Unwrap integer constant from an mlir::Value. llvm::Optional getIntIfConstant(mlir::Value value); +/// Generate max(\p value, 0) where \p value is a scalar integer. +mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value value); + } // namespace fir::factory #endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -839,7 +839,7 @@ mlir::Value rawLen = fir::getBase(genval(*lengthExpr)); // F2018 7.4.4.2 point 5. funcPtrResultLength = - Fortran::lower::genMaxWithZero(builder, getLoc(), rawLen); + fir::factory::genMaxWithZero(builder, getLoc(), rawLen); } } if (!funcPtrResultLength) @@ -2223,7 +2223,7 @@ type->characterTypeSpec().length().GetExplicit()) { mlir::Value len = fir::getBase(genval(*lenExpr)); // F2018 7.4.4.2 point 5. - len = Fortran::lower::genMaxWithZero(builder, getLoc(), len); + len = fir::factory::genMaxWithZero(builder, getLoc(), len); symMap.addSymbol(*arg, replaceScalarCharacterLength(gen(*expr), len)); continue; @@ -7588,15 +7588,3 @@ esp.resetBindings(); esp.incrementCounter(); } - -mlir::Value Fortran::lower::genMaxWithZero(fir::FirOpBuilder &builder, - mlir::Location loc, - mlir::Value value) { - mlir::Value zero = builder.createIntegerConstant(loc, value.getType(), 0); - if (mlir::Operation *definingOp = value.getDefiningOp()) - if (auto cst = mlir::dyn_cast(definingOp)) - if (auto intAttr = cst.getValue().dyn_cast()) - return intAttr.getInt() < 0 ? zero : value; - return Fortran::lower::genMax(builder, loc, - llvm::SmallVector{value, zero}); -} diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -1090,7 +1090,7 @@ auto diff = builder.create(loc, idxTy, ub, lb); mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); auto rawExtent = builder.create(loc, idxTy, diff, one); - return Fortran::lower::genMaxWithZero(builder, loc, rawExtent); + return fir::factory::genMaxWithZero(builder, loc, rawExtent); } /// Lower explicit lower bounds into \p result. Does nothing if this is not an @@ -1145,7 +1145,7 @@ mlir::Value ub = builder.createConvert( loc, idxTy, genScalarValue(converter, loc, expr, symMap, stmtCtx)); if (lowerBounds.empty()) - result.emplace_back(Fortran::lower::genMaxWithZero(builder, loc, ub)); + result.emplace_back(fir::factory::genMaxWithZero(builder, loc, ub)); else result.emplace_back( computeExtent(builder, loc, lowerBounds[spec.index()], ub)); @@ -1173,7 +1173,7 @@ if (llvm::Optional lenExpr = box.getCharLenExpr()) // If the length expression is negative, the length is zero. See F2018 // 7.4.4.2 point 5. - return Fortran::lower::genMaxWithZero( + return fir::factory::genMaxWithZero( builder, loc, genScalarValue(converter, loc, *lenExpr, symMap, stmtCtx)); return mlir::Value{}; @@ -1338,7 +1338,7 @@ Fortran::lower::SomeExpr highEx{*high}; mlir::Value ub = genValue(highEx); ub = builder.createConvert(loc, idxTy, ub); - shapes.emplace_back(genMaxWithZero(builder, loc, ub)); + shapes.emplace_back(fir::factory::genMaxWithZero(builder, loc, ub)); } else if (spec->ubound().isColon()) { assert(box && "assumed bounds require a descriptor"); mlir::Value dim = @@ -1409,7 +1409,7 @@ mlir::Value rawLen = genValue(*charLen); // If the length expression is negative, the length is zero. See // F2018 7.4.4.2 point 5. - return genMaxWithZero(builder, loc, rawLen); + return fir::factory::genMaxWithZero(builder, loc, rawLen); }; ba.match( diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -1216,3 +1216,17 @@ return intAttr.getInt(); return {}; } + +mlir::Value fir::factory::genMaxWithZero(fir::FirOpBuilder &builder, + mlir::Location loc, + mlir::Value value) { + mlir::Value zero = builder.createIntegerConstant(loc, value.getType(), 0); + if (mlir::Operation *definingOp = value.getDefiningOp()) + if (auto cst = mlir::dyn_cast(definingOp)) + if (auto intAttr = cst.getValue().dyn_cast()) + return intAttr.getInt() > 0 ? value : zero; + mlir::Value valueIsGreater = builder.create( + loc, mlir::arith::CmpIPredicate::sgt, value, zero); + return builder.create(loc, valueIsGreater, value, + zero); +}