summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/CodeGen/CodeGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/CodeGen/CodeGen.cpp')
-rw-r--r--flang/lib/Optimizer/CodeGen/CodeGen.cpp27
1 files changed, 20 insertions, 7 deletions
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index ecc04a6c9a2b..d879382555c3 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -33,6 +33,7 @@
#include "mlir/Conversion/ArithCommon/AttrToLLVMConverter.h"
#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
#include "mlir/Conversion/ComplexToLLVM/ComplexToLLVM.h"
+#include "mlir/Conversion/ComplexToROCDLLibraryCalls/ComplexToROCDLLibraryCalls.h"
#include "mlir/Conversion/ComplexToStandard/ComplexToStandard.h"
#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
@@ -1122,6 +1123,16 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
for (mlir::Value opnd : adaptor.getOperands())
size = rewriter.create<mlir::LLVM::MulOp>(
loc, ity, size, integerCast(loc, rewriter, ity, opnd));
+
+ // As the return value of malloc(0) is implementation defined, allocate one
+ // byte to ensure the allocation status being true. This behavior aligns to
+ // what the runtime has.
+ mlir::Value zero = genConstantIndex(loc, ity, rewriter, 0);
+ mlir::Value one = genConstantIndex(loc, ity, rewriter, 1);
+ mlir::Value cmp = rewriter.create<mlir::LLVM::ICmpOp>(
+ loc, mlir::LLVM::ICmpPredicate::sgt, size, zero);
+ size = rewriter.create<mlir::LLVM::SelectOp>(loc, cmp, size, one);
+
auto mallocTyWidth = lowerTy().getIndexTypeBitwidth();
auto mallocTy =
mlir::IntegerType::get(rewriter.getContext(), mallocTyWidth);
@@ -4145,22 +4156,24 @@ public:
// conversions that affect the ModuleOp, e.g. create new
// function operations in it. We have to run such conversions
// as passes here.
- mlir::OpPassManager mathConvertionPM("builtin.module");
+ mlir::OpPassManager mathConversionPM("builtin.module");
bool isAMDGCN = fir::getTargetTriple(mod).isAMDGCN();
// If compiling for AMD target some math operations must be lowered to AMD
// GPU library calls, the rest can be converted to LLVM intrinsics, which
// is handled in the mathToLLVM conversion. The lowering to libm calls is
// not needed since all math operations are handled this way.
- if (isAMDGCN)
- mathConvertionPM.addPass(mlir::createConvertMathToROCDL());
+ if (isAMDGCN) {
+ mathConversionPM.addPass(mlir::createConvertMathToROCDL());
+ mathConversionPM.addPass(mlir::createConvertComplexToROCDLLibraryCalls());
+ }
// Convert math::FPowI operations to inline implementation
// only if the exponent's width is greater than 32, otherwise,
// it will be lowered to LLVM intrinsic operation by a later conversion.
mlir::ConvertMathToFuncsOptions mathToFuncsOptions{};
mathToFuncsOptions.minWidthOfFPowIExponent = 33;
- mathConvertionPM.addPass(
+ mathConversionPM.addPass(
mlir::createConvertMathToFuncs(mathToFuncsOptions));
mlir::ConvertComplexToStandardPassOptions complexToStandardOptions{};
@@ -4173,15 +4186,15 @@ public:
complexToStandardOptions.complexRange =
mlir::complex::ComplexRangeFlags::improved;
}
- mathConvertionPM.addPass(
+ mathConversionPM.addPass(
mlir::createConvertComplexToStandardPass(complexToStandardOptions));
// Convert Math dialect operations into LLVM dialect operations.
// There is no way to prefer MathToLLVM patterns over MathToLibm
// patterns (applied below), so we have to run MathToLLVM conversion here.
- mathConvertionPM.addNestedPass<mlir::func::FuncOp>(
+ mathConversionPM.addNestedPass<mlir::func::FuncOp>(
mlir::createConvertMathToLLVMPass());
- if (mlir::failed(runPipeline(mathConvertionPM, mod)))
+ if (mlir::failed(runPipeline(mathConversionPM, mod)))
return signalPassFailure();
std::optional<mlir::DataLayout> dl =