diff options
author | Shunsuke Watanabe <watanabe.shu-06@fujitsu.com> | 2025-07-09 13:43:54 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-09 13:43:54 +0900 |
commit | c9900015a9a0bc2ccadae5e24b63ddbfe4d508fd (patch) | |
tree | 716230bb2154fb0dd6c16759a8b23add6f76ebc2 /flang/lib/Frontend | |
parent | bccd34f32342e0f299d528ffbb70c825eee983d5 (diff) | |
download | llvm-c9900015a9a0bc2ccadae5e24b63ddbfe4d508fd.zip llvm-c9900015a9a0bc2ccadae5e24b63ddbfe4d508fd.tar.gz llvm-c9900015a9a0bc2ccadae5e24b63ddbfe4d508fd.tar.bz2 |
[flang] Add -fcomplex-arithmetic= option and select complex division algorithm (#146641)
This patch adds an option to select the method for computing complex
number division. It uses `LoweringOptions` to determine whether to lower
complex division to a runtime function call or to MLIR's `complex.div`,
and `CodeGenOptions` to select the computation algorithm for
`complex.div`. The available option values and their corresponding
algorithms are as follows:
- `full`: Lower to a runtime function call. (Default behavior)
- `improved`: Lower to `complex.div` and expand to Smith's algorithm.
- `basic`: Lower to `complex.div` and expand to the algebraic algorithm.
See also the discussion in the following discourse post:
https://discourse.llvm.org/t/optimization-of-complex-number-division/83468
---------
Co-authored-by: Tarun Prabhu <tarunprabhu@gmail.com>
Diffstat (limited to 'flang/lib/Frontend')
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 21 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 2 |
2 files changed, 23 insertions, 0 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index e5c6b1d..5455efd 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -485,6 +485,21 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, } parseDoConcurrentMapping(opts, args, diags); + + if (const llvm::opt::Arg *arg = + args.getLastArg(clang::driver::options::OPT_complex_range_EQ)) { + llvm::StringRef argValue = llvm::StringRef(arg->getValue()); + if (argValue == "full") { + opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Full); + } else if (argValue == "improved") { + opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Improved); + } else if (argValue == "basic") { + opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Basic); + } else { + diags.Report(clang::diag::err_drv_invalid_value) + << arg->getAsString(args) << arg->getValue(); + } + } } /// Parses all target input arguments and populates the target @@ -1812,4 +1827,10 @@ void CompilerInvocation::setLoweringOptions() { .setNoSignedZeros(langOptions.NoSignedZeros) .setAssociativeMath(langOptions.AssociativeMath) .setReciprocalMath(langOptions.ReciprocalMath); + + if (codegenOpts.getComplexRange() == + CodeGenOptions::ComplexRangeKind::CX_Improved || + codegenOpts.getComplexRange() == + CodeGenOptions::ComplexRangeKind::CX_Basic) + loweringOpts.setComplexDivisionToRuntime(false); } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index bf15def..b5f4f94 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -750,6 +750,8 @@ void CodeGenAction::generateLLVMIR() { if (ci.getInvocation().getLoweringOpts().getIntegerWrapAround()) config.NSWOnLoopVarInc = false; + config.ComplexRange = opts.getComplexRange(); + // Create the pass pipeline fir::createMLIRToLLVMPassPipeline(pm, config, getCurrentFile()); (void)mlir::applyPassManagerCLOptions(pm); |