[flang-commits] [flang] [draft][flang] Query backend support for quad-precision compilation decision (PR #182230)

Shunsuke Watanabe via flang-commits flang-commits at lists.llvm.org
Wed Feb 18 23:23:50 PST 2026


https://github.com/s-watanabe314 created https://github.com/llvm/llvm-project/pull/182230

This is a draft related to the discussion [here](https://discourse.llvm.org/t/cross-compilation-of-real-kind-16/89161).

To determine quad-precision support for Flang at compile time, the frontend checks if the backend supports `fp128` for the target.
I'm considering checking this in three ways:

1. [`isTypeLegal`](https://github.com/llvm/llvm-project/blob/530c938485d7c4119e8df3f57e288f9f20a183cd/llvm/include/llvm/CodeGen/TargetLowering.h#L1103-L1105) is `true` for `fp128`.  
1. [`LegalizeAction`](https://github.com/llvm/llvm-project/blob/530c938485d7c4119e8df3f57e288f9f20a183cd/llvm/include/llvm/CodeGen/TargetLowering.h#L200-L201) for `FADD` instruction of `fp128` is `Legal` or `LibCall`.
1. [`LegalizeTypeAction`](https://github.com/llvm/llvm-project/blob/530c938485d7c4119e8df3f57e288f9f20a183cd/llvm/include/llvm/CodeGen/TargetLowering.h#L210-L211) for `fp128` is `TypeLegal`.

If these three conditions are used, whether `kind=16` can be compiled for each target is as follows.
For target specification, only `ArchType` is specified in `-target`, and `SubArch`, `Vendor`, `OS`, and `Environment` are not specified.

| target arch | flang support | `isTypeLegal` | `LegalizeAction` | `LegalizeTypeAction` | decision |
| --- | --- | --- | --- | --- | --- |
| aarch64 |  | true | LibCall | TypeLegal | OK |
| amdgcn |  | false | Legal | TypeSoftenFloat |  |
| arm | NYI (Not Yet Implemented) | false | Legal | TypeSoftenFloat |  |
| avr | NYI | false | Legal | TypeSoftenFloat |  |
| bpf | NYI | false | Legal | TypeSoftenFloat |  |
| hexagon | NYI | false | Legal | TypeSoftenFloat |  |
| lanai | NYI | false | Legal | TypeSoftenFloat |  |
| loongarch32 | NYI | false | Legal | TypeSoftenFloat |  |
| loongarch64 |  | false | Legal | TypeSoftenFloat |  |
| mips | NYI | false | Legal | TypeSoftenFloat |  |
| msp430 | NYI | false | Legal | TypeSoftenFloat |  |
| nvptx | NYI | false | Legal | TypeSoftenFloat |  |
| powerpc |  | false | Legal | TypeSoftenFloat |  |
| riscv32 | NYI | false | Legal | TypeSoftenFloat |  |
| riscv64 |  | false | Legal | TypeSoftenFloat |  |
| sparc |  | true | Custom | TypeLegal |  |
| spirv | NYI | false | Legal | TypeSoftenFloat |  |
| systemz | NYI | true | Legal | TypeLegal | OK |
| ve | NYI | true | Legal | TypeLegal | OK |
| wasm32 | NYI | false | Legal | TypeSoftenFloat |  |
| wasm64 | NYI | false | Legal | TypeSoftenFloat |  |
| x86_64 |  | true | LibCall | TypeLegal | OK |
| xcore | NYI | false | Legal | TypeSoftenFloat |  |
  
I have implemented the above logic in the Flang frontend (`flang/Tools/TargetSetup.h`).
The frontend checks the backend's support by creating an empty dummy LLVM IR function.
  
I would appreciate any feedback on the implementation method or the decision logic.


>From 35dc6ae68b02da85f5597da3ea0d8a78a0a9bc68 Mon Sep 17 00:00:00 2001
From: s-watanabe314 <watanabe.shu-06 at fujitsu.com>
Date: Thu, 12 Feb 2026 17:08:41 +0900
Subject: [PATCH] [flang] Query backend support for quad-precision compilation
 decision

---
 flang/include/flang/Tools/TargetSetup.h | 59 ++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 11 deletions(-)

diff --git a/flang/include/flang/Tools/TargetSetup.h b/flang/include/flang/Tools/TargetSetup.h
index 002e82aa72484..1e4c1884a362a 100644
--- a/flang/include/flang/Tools/TargetSetup.h
+++ b/flang/include/flang/Tools/TargetSetup.h
@@ -12,6 +12,10 @@
 #include "flang/Common/float128.h"
 #include "flang/Evaluate/target.h"
 #include "flang/Frontend/TargetOptions.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Target/TargetMachine.h"
 #include <cfloat>
 
@@ -58,17 +62,50 @@ namespace Fortran::tools {
     break;
   }
 
-  // Check for kind=16 support. See flang/runtime/Float128Math/math-entries.h.
-  // TODO: Take this from TargetInfo::getLongDoubleFormat for cross compilation.
-#ifdef FLANG_RUNTIME_F128_MATH_LIB
-  constexpr bool f128Support = true; // use libquadmath wrappers
-#elif HAS_LDBL128
-  constexpr bool f128Support = true; // use libm wrappers
-#else
-  constexpr bool f128Support = false;
-#endif
-
-  if constexpr (!f128Support) {
+  bool f128Support = false;
+  llvm::LLVMContext ctx;
+  std::unique_ptr<llvm::Module> dummyModule =
+      std::make_unique<llvm::Module>("quad-test", ctx);
+  dummyModule->setTargetTriple(targetMachine.getTargetTriple());
+  dummyModule->setDataLayout(targetMachine.createDataLayout());
+
+  llvm::FunctionType *dummyFTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), false);
+  llvm::Function *dummyF = llvm::Function::Create(dummyFTy,
+      llvm::GlobalValue::ExternalLinkage, "quad-test", dummyModule.get());
+
+  const llvm::TargetLowering *dummyTLI =
+      targetMachine.getSubtargetImpl(*dummyF)->getTargetLowering();
+
+  if (dummyTLI) {
+    llvm::EVT fp128EVT = llvm::EVT::getEVT(llvm::Type::getFP128Ty(ctx));
+
+    // Query for fp128 backend support. Based on this, determine whether
+    // compilation is possible on the frontend.
+    bool isLegal = dummyTLI->isTypeLegal(fp128EVT);
+
+    // We might also be able to determine fp128 backend support based on the
+    // LegalizeAction value. This is likely when the value is "Legal" or
+    // "LibCall". See
+    // https://llvm.org/doxygen/TargetLowering_8h_source.html#l00202.
+    llvm::TargetLowering::LegalizeAction LA =
+        dummyTLI->getOperationAction(llvm::ISD::FADD, fp128EVT);
+
+    // We might also be able to determine fp128 backend support based on the
+    // LegalizeTypeAction value. This is likely when the value is "TypeLegal".
+    // See https://llvm.org/doxygen/TargetLowering_8h_source.html#l00212.
+    llvm::TargetLowering::LegalizeTypeAction LTA =
+        dummyTLI->getTypeConversion(ctx, llvm::MVT::f128).first;
+
+    if (isLegal &&
+        (LA == llvm::TargetLowering::Legal ||
+            LA == llvm::TargetLowering::LibCall) &&
+        (LTA == llvm::TargetLowering::TypeLegal)) {
+      f128Support = true;
+    }
+  }
+
+  if (!f128Support) {
     targetCharacteristics.DisableType(Fortran::common::TypeCategory::Real, 16);
     targetCharacteristics.DisableType(
         Fortran::common::TypeCategory::Complex, 16);



More information about the flang-commits mailing list