Skip to content

[flang] Modifications to ieee_support_halting #120747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 23, 2024
Merged

Conversation

vdonaldson
Copy link
Contributor

@vdonaldson vdonaldson commented Dec 20, 2024

The F23 standard requires that a call to intrinsic module procedure ieee_support_halting be foldable to a constant at compile time in some contexts. See for example F23 Clause 10.1.11 [Specification expression] list item (13), Clause 10.1.12 [Constant expression] list item (11), and references to specification and constant expressions elsewhere, such as constraints C1012, C853, and C704.

Some Arm processors allow a user to control processor behavior when an arithmetic exception is signaled, and some Arm processors do not have this capability. An Arm executable will run on either type of processor, so it is effectively unknown at compile time whether or not this support will be available at runtime. This in conflict with the standard requirement.

This patch addresses this conflict by implementing ieee_support_halting calls on Arm processors to check if this capability is present at runtime. A call to ieee_support_halting in a constant context, such as in the specification part of a program unit, will generate a compile time "cannot be computed as a constant value" error. The expectation is that such calls are unlikely to appear in production code.

Code generation for other processors will continue to generate a compile time constant result for ieee_support_halting calls.

@llvmbot
Copy link
Member

llvmbot commented Dec 20, 2024

@llvm/pr-subscribers-flang-fir-hlfir

@llvm/pr-subscribers-flang-semantics

Author: None (vdonaldson)

Changes

The F23 standard requires that a call to intrinsic module procedure ieee_support_halting be foldable to a constant at compile time in some contexts. See for example F23 Clause 10.1.11 [Specification expression] list item (13), Clause 1.1.12 [Constant expression] list item (11), and references to specification and constant expressions elsewhere, such as constraints C1012, C853, and C704.

Some Arm processors allow a user to control processor behavior when an arithmetic exception is signaled, and some Arm processors do not have this capability. An Arm executable will run on either type of processor, so it is effectively unknown at compile time whether or not this support will be available at runtime. This in conflict with the standard requirement.

This patch addresses this conflict by implementing ieee_support_halting calls on Arm processors to check if this capability is present at runtime. A call to ieee_support_halting in a constant context, such as in the specification part of a program unit, will generate a compile time "cannot be computed as a constant value" error. The expectation is that such calls are unlikely to appear in production code.

Code generation for other processors will continue to generate a compile time constant result for ieee_support_halting calls.


Full diff: https://github.com/llvm/llvm-project/pull/120747.diff

12 Files Affected:

  • (modified) flang/docs/Extensions.md (+12)
  • (modified) flang/include/flang/Evaluate/target.h (+19-4)
  • (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (+4-3)
  • (modified) flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h (+3)
  • (modified) flang/include/flang/Runtime/exceptions.h (+4)
  • (modified) flang/include/flang/Tools/TargetSetup.h (+7)
  • (modified) flang/lib/Evaluate/fold-logical.cpp (+5-2)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+26-10)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp (+8)
  • (modified) flang/runtime/exceptions.cpp (+17)
  • (modified) flang/test/Evaluate/fold-ieee.f90 (+7-3)
  • (modified) flang/test/Lower/Intrinsics/ieee_flag.f90 (+1-1)
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 626bf4399d6325..2d1c967a6068de 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -141,6 +141,18 @@ end
   This interpretation has usability advantages and is what six other
   Fortran compilers do, but is not conforming now that J3 approved an
   "interp" in June 2024 to the contrary.
+* Arm has processors that allow a user to control what happens when an
+  arithmetic exception is signaled, as well as processors that do not
+  have this capability. An Arm executable will run on either type of
+  processor, so it is effectively unknown at compile time whether or
+  not this support will be available at runtime. The standard requires
+  that a call to intrinsic module procedure `IEEE_SUPPORT_HALTING` with
+  a constant argument has a compile time constant result in `constant
+  expression` and `specification expression` contexts. In compilations
+  where this information is not known at compile time, f18 generates code
+  to determine the absence or presence of this capability at runtime.
+  A call to `IEEE_SUPPORT_HALTING` in contexts that the standard requires
+  to be constant will generate a compilation error.
 
 ## Extensions, deletions, and legacy features supported by default
 
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index 9d86000b2f8aa6..154561ce868eb1 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -36,6 +36,13 @@ class TargetCharacteristics {
   bool isBigEndian() const { return isBigEndian_; }
   void set_isBigEndian(bool isBig = true);
 
+  bool haltingSupportIsUnknownAtCompileTime() const {
+    return haltingSupportIsUnknownAtCompileTime_;
+  }
+  void set_haltingSupportIsUnknownAtCompileTime(bool yes = true) {
+    haltingSupportIsUnknownAtCompileTime_ = yes;
+  }
+
   bool areSubnormalsFlushedToZero() const {
     return areSubnormalsFlushedToZero_;
   }
@@ -50,6 +57,14 @@ class TargetCharacteristics {
   Rounding roundingMode() const { return roundingMode_; }
   void set_roundingMode(Rounding);
 
+  void set_ieeeFeature(IeeeFeature ieeeFeature, bool yes = true) {
+    if (yes) {
+      ieeeFeatures_.set(ieeeFeature);
+    } else {
+      ieeeFeatures_.reset(ieeeFeature);
+    }
+  }
+
   std::size_t procedurePointerByteSize() const {
     return procedurePointerByteSize_;
   }
@@ -112,6 +127,7 @@ class TargetCharacteristics {
   bool isBigEndian_{false};
   bool isPPC_{false};
   bool isOSWindows_{false};
+  bool haltingSupportIsUnknownAtCompileTime_{false};
   bool areSubnormalsFlushedToZero_{false};
   bool hasSubnormalFlushingControl_[maxKind + 1]{};
   Rounding roundingMode_{defaultRounding};
@@ -123,10 +139,9 @@ class TargetCharacteristics {
   std::string compilerOptionsString_;
   std::string compilerVersionString_;
   IeeeFeatures ieeeFeatures_{IeeeFeature::Denormal, IeeeFeature::Divide,
-      IeeeFeature::Flags, IeeeFeature::Halting, IeeeFeature::Inf,
-      IeeeFeature::Io, IeeeFeature::NaN, IeeeFeature::Rounding,
-      IeeeFeature::Sqrt, IeeeFeature::Standard, IeeeFeature::Subnormal,
-      IeeeFeature::UnderflowControl};
+      IeeeFeature::Flags, IeeeFeature::Inf, IeeeFeature::Io, IeeeFeature::NaN,
+      IeeeFeature::Rounding, IeeeFeature::Sqrt, IeeeFeature::Standard,
+      IeeeFeature::Subnormal, IeeeFeature::UnderflowControl};
 };
 
 } // namespace Fortran::evaluate
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 6899505eeb39d0..3d0516555f761b 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -296,9 +296,10 @@ struct IntrinsicLibrary {
   mlir::Value genIeeeSignalingCompare(mlir::Type resultType,
                                       llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeeeSignbit(mlir::Type, llvm::ArrayRef<mlir::Value>);
-  fir::ExtendedValue
-      genIeeeSupportFlagOrHalting(mlir::Type,
-                                  llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genIeeeSupportFlag(mlir::Type,
+                                        llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genIeeeSupportHalting(mlir::Type,
+                                           llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genIeeeSupportRounding(mlir::Type, llvm::ArrayRef<mlir::Value>);
   template <mlir::arith::CmpIPredicate pred>
   mlir::Value genIeeeTypeCompare(mlir::Type, llvm::ArrayRef<mlir::Value>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h b/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
index f2f83b46f20fde..f44e0c95ef6d4a 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
@@ -26,6 +26,9 @@ namespace fir::runtime {
 mlir::Value genMapExcept(fir::FirOpBuilder &builder, mlir::Location loc,
                          mlir::Value excepts);
 
+mlir::Value genSupportHalting(fir::FirOpBuilder &builder, mlir::Location loc,
+                              mlir::Value excepts);
+
 mlir::Value genGetUnderflowMode(fir::FirOpBuilder &builder, mlir::Location loc);
 void genSetUnderflowMode(fir::FirOpBuilder &builder, mlir::Location loc,
                          mlir::Value bit);
diff --git a/flang/include/flang/Runtime/exceptions.h b/flang/include/flang/Runtime/exceptions.h
index bd6c439b150ab9..483d0271bcab00 100644
--- a/flang/include/flang/Runtime/exceptions.h
+++ b/flang/include/flang/Runtime/exceptions.h
@@ -24,6 +24,10 @@ extern "C" {
 // This mapping is done at runtime to support cross compilation.
 std::uint32_t RTNAME(MapException)(std::uint32_t excepts);
 
+// Check if the processor has the ability to control whether to halt
+// or continue exeuction when a given exception is raised.
+bool RTNAME(SupportHalting)(uint32_t except);
+
 // Get and set the ieee underflow mode if supported; otherwise nops.
 bool RTNAME(GetUnderflowMode)(void);
 void RTNAME(SetUnderflowMode)(bool flag);
diff --git a/flang/include/flang/Tools/TargetSetup.h b/flang/include/flang/Tools/TargetSetup.h
index 1889140ddce75e..709c4bbe4b7b0b 100644
--- a/flang/include/flang/Tools/TargetSetup.h
+++ b/flang/include/flang/Tools/TargetSetup.h
@@ -34,6 +34,13 @@ namespace Fortran::tools {
     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
   }
+  if (targetTriple.isARM() || targetTriple.isAArch64()) {
+    targetCharacteristics.set_haltingSupportIsUnknownAtCompileTime();
+    targetCharacteristics.set_ieeeFeature(
+        evaluate::IeeeFeature::Halting, false);
+  } else {
+    targetCharacteristics.set_ieeeFeature(evaluate::IeeeFeature::Halting);
+  }
 
   // Figure out if we can support F128: see
   // flang/runtime/Float128Math/math-entries.h
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index 6c7758e99a4482..65f996ddc6dd1c 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -881,8 +881,11 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
     return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
         IeeeFeature::Flags)};
   } else if (name == "__builtin_ieee_support_halting") {
-    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
-        IeeeFeature::Halting)};
+    if (!context.targetCharacteristics()
+            .haltingSupportIsUnknownAtCompileTime()) {
+      return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+          IeeeFeature::Halting)};
+    }
   } else if (name == "__builtin_ieee_support_inf") {
     return Expr<T>{
         context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Inf)};
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index bbbacd25bca621..9a3777994a9df0 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -389,10 +389,10 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genIeeeSignalingCompare<mlir::arith::CmpFPredicate::UNE>},
     {"ieee_signbit", &I::genIeeeSignbit},
     {"ieee_support_flag",
-     &I::genIeeeSupportFlagOrHalting,
+     &I::genIeeeSupportFlag,
      {{{"flag", asValue}, {"x", asInquired, handleDynamicOptional}}},
      /*isElemental=*/false},
-    {"ieee_support_halting", &I::genIeeeSupportFlagOrHalting},
+    {"ieee_support_halting", &I::genIeeeSupportHalting},
     {"ieee_support_rounding", &I::genIeeeSupportRounding},
     {"ieee_unordered", &I::genIeeeUnordered},
     {"ieee_value", &I::genIeeeValue},
@@ -5259,14 +5259,14 @@ mlir::Value IntrinsicLibrary::genIeeeSignbit(mlir::Type resultType,
   return builder.createConvert(loc, resultType, sign);
 }
 
-// IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING
-fir::ExtendedValue IntrinsicLibrary::genIeeeSupportFlagOrHalting(
-    mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
-  // Check if a floating point exception or halting mode FLAG is supported.
-  // An IEEE_SUPPORT_FLAG flag is supported either for all type kinds or none.
-  // An optional kind argument X is therefore ignored.
-  // Standard flags are all supported.
-  // The nonstandard DENORM extension is not supported. (At least for now.)
+// IEEE_SUPPORT_FLAG
+fir::ExtendedValue
+IntrinsicLibrary::genIeeeSupportFlag(mlir::Type resultType,
+                                     llvm::ArrayRef<fir::ExtendedValue> args) {
+  // Check if a floating point exception flag is supported. A flag is
+  // supported either for all type kinds or none. An optional kind argument X
+  // is therefore ignored. Standard flags are all supported. The nonstandard
+  // DENORM extension is not supported, at least for now.
   assert(args.size() == 1 || args.size() == 2);
   auto [fieldRef, fieldTy] = getFieldRef(builder, loc, fir::getBase(args[0]));
   mlir::Value flag = builder.create<fir::LoadOp>(loc, fieldRef);
@@ -5283,6 +5283,22 @@ fir::ExtendedValue IntrinsicLibrary::genIeeeSupportFlagOrHalting(
           builder.createIntegerConstant(loc, fieldTy, 0)));
 }
 
+// IEEE_SUPPORT_HALTING
+fir::ExtendedValue IntrinsicLibrary::genIeeeSupportHalting(
+    mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
+  // Check if halting is supported for a floating point exception flag.
+  // Standard flags are all supported. The nonstandard DENORM extension is
+  // not supported, at least for now.
+  assert(args.size() == 1);
+  mlir::Type i32Ty = builder.getIntegerType(32);
+  auto [fieldRef, ignore] = getFieldRef(builder, loc, getBase(args[0]));
+  mlir::Value field = builder.create<fir::LoadOp>(loc, fieldRef);
+  return builder.createConvert(
+      loc, resultType,
+      fir::runtime::genSupportHalting(
+          builder, loc, {builder.create<fir::ConvertOp>(loc, i32Ty, field)}));
+}
+
 // IEEE_SUPPORT_ROUNDING
 mlir::Value
 IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
diff --git a/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp b/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
index 85f38424eabdc4..630281fdb593d7 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
@@ -21,6 +21,14 @@ mlir::Value fir::runtime::genMapExcept(fir::FirOpBuilder &builder,
   return builder.create<fir::CallOp>(loc, func, excepts).getResult(0);
 }
 
+mlir::Value fir::runtime::genSupportHalting(fir::FirOpBuilder &builder,
+                                            mlir::Location loc,
+                                            mlir::Value excepts) {
+  mlir::func::FuncOp func{
+      fir::runtime::getRuntimeFunc<mkRTKey(SupportHalting)>(loc, builder)};
+  return builder.create<fir::CallOp>(loc, func, excepts).getResult(0);
+}
+
 mlir::Value fir::runtime::genGetUnderflowMode(fir::FirOpBuilder &builder,
                                               mlir::Location loc) {
   mlir::func::FuncOp func{
diff --git a/flang/runtime/exceptions.cpp b/flang/runtime/exceptions.cpp
index 993c996c9ce75d..76f8d5168d7b69 100644
--- a/flang/runtime/exceptions.cpp
+++ b/flang/runtime/exceptions.cpp
@@ -81,6 +81,23 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
 // on some systems, e.g. Solaris, so omit object size comparison for now.
 // TODO: consider femode_t object size comparison once its more mature.
 
+// Check if the processor has the ability to control whether to halt or
+// continue execution when a given exception is raised.
+bool RTNAME(SupportHalting)(uint32_t except) {
+  except = RTNAME(MapException)(except);
+  int currentSet = fegetexcept(), flipSet, ok;
+  if (currentSet & except) {
+    ok = fedisableexcept(except);
+    flipSet = fegetexcept();
+    ok |= feenableexcept(except);
+  } else {
+    ok = feenableexcept(except);
+    flipSet = fegetexcept();
+    ok |= fedisableexcept(except);
+  }
+  return ok != -1 && currentSet != flipSet;
+}
+
 bool RTNAME(GetUnderflowMode)(void) {
 #if __x86_64__
   // The MXCSR Flush to Zero flag is the negation of the ieee_get_underflow_mode
diff --git a/flang/test/Evaluate/fold-ieee.f90 b/flang/test/Evaluate/fold-ieee.f90
index e70d558af1668e..99f8526fd23dbf 100644
--- a/flang/test/Evaluate/fold-ieee.f90
+++ b/flang/test/Evaluate/fold-ieee.f90
@@ -26,11 +26,13 @@ module m
   logical, parameter :: test_fl_ix_all = ieee_support_flag(ieee_inexact)
   logical, parameter :: test_fl_ix_4 = ieee_support_flag(ieee_inexact, 1.)
   logical, parameter :: test_fl_ix_8 = ieee_support_flag(ieee_inexact, 1.d0)
+#if __x86_64__
   logical, parameter :: test_halt_in = ieee_support_halting(ieee_invalid)
   logical, parameter :: test_halt_ov = ieee_support_halting(ieee_overflow)
   logical, parameter :: test_halt_d0 = ieee_support_halting(ieee_divide_by_zero)
   logical, parameter :: test_halt_un = ieee_support_halting(ieee_underflow)
   logical, parameter :: test_halt_ix = ieee_support_halting(ieee_inexact)
+#endif
   logical, parameter :: test_inf_all = ieee_support_inf()
   logical, parameter :: test_inf_4 = ieee_support_inf(1.)
   logical, parameter :: test_inf_8 = ieee_support_inf(1.d0)
@@ -58,7 +60,9 @@ module m
   logical, parameter :: test_sn_all = ieee_support_subnormal()
   logical, parameter :: test_sn_4 = ieee_support_subnormal(1.)
   logical, parameter :: test_sn_8 = ieee_support_subnormal(1.d0)
-! logical, parameter :: test_uc_all = .not. ieee_support_underflow_control()
-! logical, parameter :: test_uc_4 = ieee_support_underflow_control(1.)
-! logical, parameter :: test_uc_8 = ieee_support_underflow_control(1.d0)
+#if __x86_64__
+  logical, parameter :: test_uc_all = .not. ieee_support_underflow_control()
+  logical, parameter :: test_uc_4 = ieee_support_underflow_control(1.)
+  logical, parameter :: test_uc_8 = ieee_support_underflow_control(1.d0)
+#endif
 end
diff --git a/flang/test/Lower/Intrinsics/ieee_flag.f90 b/flang/test/Lower/Intrinsics/ieee_flag.f90
index 862cfbd8b28759..e4addc0d658dc4 100644
--- a/flang/test/Lower/Intrinsics/ieee_flag.f90
+++ b/flang/test/Lower/Intrinsics/ieee_flag.f90
@@ -271,7 +271,7 @@
   print*, 'Halting'
 
   ! CHECK:     %[[V_211:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
-  ! CHECK:     %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]], %true) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
+  ! CHECK:     %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]]
   print*, 'support invalid: ', ieee_support_halting(ieee_invalid)
 
   ! CHECK:     %[[V_222:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>

@llvmbot
Copy link
Member

llvmbot commented Dec 20, 2024

@llvm/pr-subscribers-flang-runtime

Author: None (vdonaldson)

Changes

The F23 standard requires that a call to intrinsic module procedure ieee_support_halting be foldable to a constant at compile time in some contexts. See for example F23 Clause 10.1.11 [Specification expression] list item (13), Clause 1.1.12 [Constant expression] list item (11), and references to specification and constant expressions elsewhere, such as constraints C1012, C853, and C704.

Some Arm processors allow a user to control processor behavior when an arithmetic exception is signaled, and some Arm processors do not have this capability. An Arm executable will run on either type of processor, so it is effectively unknown at compile time whether or not this support will be available at runtime. This in conflict with the standard requirement.

This patch addresses this conflict by implementing ieee_support_halting calls on Arm processors to check if this capability is present at runtime. A call to ieee_support_halting in a constant context, such as in the specification part of a program unit, will generate a compile time "cannot be computed as a constant value" error. The expectation is that such calls are unlikely to appear in production code.

Code generation for other processors will continue to generate a compile time constant result for ieee_support_halting calls.


Full diff: https://github.com/llvm/llvm-project/pull/120747.diff

12 Files Affected:

  • (modified) flang/docs/Extensions.md (+12)
  • (modified) flang/include/flang/Evaluate/target.h (+19-4)
  • (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (+4-3)
  • (modified) flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h (+3)
  • (modified) flang/include/flang/Runtime/exceptions.h (+4)
  • (modified) flang/include/flang/Tools/TargetSetup.h (+7)
  • (modified) flang/lib/Evaluate/fold-logical.cpp (+5-2)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+26-10)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp (+8)
  • (modified) flang/runtime/exceptions.cpp (+17)
  • (modified) flang/test/Evaluate/fold-ieee.f90 (+7-3)
  • (modified) flang/test/Lower/Intrinsics/ieee_flag.f90 (+1-1)
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 626bf4399d6325..2d1c967a6068de 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -141,6 +141,18 @@ end
   This interpretation has usability advantages and is what six other
   Fortran compilers do, but is not conforming now that J3 approved an
   "interp" in June 2024 to the contrary.
+* Arm has processors that allow a user to control what happens when an
+  arithmetic exception is signaled, as well as processors that do not
+  have this capability. An Arm executable will run on either type of
+  processor, so it is effectively unknown at compile time whether or
+  not this support will be available at runtime. The standard requires
+  that a call to intrinsic module procedure `IEEE_SUPPORT_HALTING` with
+  a constant argument has a compile time constant result in `constant
+  expression` and `specification expression` contexts. In compilations
+  where this information is not known at compile time, f18 generates code
+  to determine the absence or presence of this capability at runtime.
+  A call to `IEEE_SUPPORT_HALTING` in contexts that the standard requires
+  to be constant will generate a compilation error.
 
 ## Extensions, deletions, and legacy features supported by default
 
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index 9d86000b2f8aa6..154561ce868eb1 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -36,6 +36,13 @@ class TargetCharacteristics {
   bool isBigEndian() const { return isBigEndian_; }
   void set_isBigEndian(bool isBig = true);
 
+  bool haltingSupportIsUnknownAtCompileTime() const {
+    return haltingSupportIsUnknownAtCompileTime_;
+  }
+  void set_haltingSupportIsUnknownAtCompileTime(bool yes = true) {
+    haltingSupportIsUnknownAtCompileTime_ = yes;
+  }
+
   bool areSubnormalsFlushedToZero() const {
     return areSubnormalsFlushedToZero_;
   }
@@ -50,6 +57,14 @@ class TargetCharacteristics {
   Rounding roundingMode() const { return roundingMode_; }
   void set_roundingMode(Rounding);
 
+  void set_ieeeFeature(IeeeFeature ieeeFeature, bool yes = true) {
+    if (yes) {
+      ieeeFeatures_.set(ieeeFeature);
+    } else {
+      ieeeFeatures_.reset(ieeeFeature);
+    }
+  }
+
   std::size_t procedurePointerByteSize() const {
     return procedurePointerByteSize_;
   }
@@ -112,6 +127,7 @@ class TargetCharacteristics {
   bool isBigEndian_{false};
   bool isPPC_{false};
   bool isOSWindows_{false};
+  bool haltingSupportIsUnknownAtCompileTime_{false};
   bool areSubnormalsFlushedToZero_{false};
   bool hasSubnormalFlushingControl_[maxKind + 1]{};
   Rounding roundingMode_{defaultRounding};
@@ -123,10 +139,9 @@ class TargetCharacteristics {
   std::string compilerOptionsString_;
   std::string compilerVersionString_;
   IeeeFeatures ieeeFeatures_{IeeeFeature::Denormal, IeeeFeature::Divide,
-      IeeeFeature::Flags, IeeeFeature::Halting, IeeeFeature::Inf,
-      IeeeFeature::Io, IeeeFeature::NaN, IeeeFeature::Rounding,
-      IeeeFeature::Sqrt, IeeeFeature::Standard, IeeeFeature::Subnormal,
-      IeeeFeature::UnderflowControl};
+      IeeeFeature::Flags, IeeeFeature::Inf, IeeeFeature::Io, IeeeFeature::NaN,
+      IeeeFeature::Rounding, IeeeFeature::Sqrt, IeeeFeature::Standard,
+      IeeeFeature::Subnormal, IeeeFeature::UnderflowControl};
 };
 
 } // namespace Fortran::evaluate
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 6899505eeb39d0..3d0516555f761b 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -296,9 +296,10 @@ struct IntrinsicLibrary {
   mlir::Value genIeeeSignalingCompare(mlir::Type resultType,
                                       llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeeeSignbit(mlir::Type, llvm::ArrayRef<mlir::Value>);
-  fir::ExtendedValue
-      genIeeeSupportFlagOrHalting(mlir::Type,
-                                  llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genIeeeSupportFlag(mlir::Type,
+                                        llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genIeeeSupportHalting(mlir::Type,
+                                           llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genIeeeSupportRounding(mlir::Type, llvm::ArrayRef<mlir::Value>);
   template <mlir::arith::CmpIPredicate pred>
   mlir::Value genIeeeTypeCompare(mlir::Type, llvm::ArrayRef<mlir::Value>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h b/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
index f2f83b46f20fde..f44e0c95ef6d4a 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Exceptions.h
@@ -26,6 +26,9 @@ namespace fir::runtime {
 mlir::Value genMapExcept(fir::FirOpBuilder &builder, mlir::Location loc,
                          mlir::Value excepts);
 
+mlir::Value genSupportHalting(fir::FirOpBuilder &builder, mlir::Location loc,
+                              mlir::Value excepts);
+
 mlir::Value genGetUnderflowMode(fir::FirOpBuilder &builder, mlir::Location loc);
 void genSetUnderflowMode(fir::FirOpBuilder &builder, mlir::Location loc,
                          mlir::Value bit);
diff --git a/flang/include/flang/Runtime/exceptions.h b/flang/include/flang/Runtime/exceptions.h
index bd6c439b150ab9..483d0271bcab00 100644
--- a/flang/include/flang/Runtime/exceptions.h
+++ b/flang/include/flang/Runtime/exceptions.h
@@ -24,6 +24,10 @@ extern "C" {
 // This mapping is done at runtime to support cross compilation.
 std::uint32_t RTNAME(MapException)(std::uint32_t excepts);
 
+// Check if the processor has the ability to control whether to halt
+// or continue exeuction when a given exception is raised.
+bool RTNAME(SupportHalting)(uint32_t except);
+
 // Get and set the ieee underflow mode if supported; otherwise nops.
 bool RTNAME(GetUnderflowMode)(void);
 void RTNAME(SetUnderflowMode)(bool flag);
diff --git a/flang/include/flang/Tools/TargetSetup.h b/flang/include/flang/Tools/TargetSetup.h
index 1889140ddce75e..709c4bbe4b7b0b 100644
--- a/flang/include/flang/Tools/TargetSetup.h
+++ b/flang/include/flang/Tools/TargetSetup.h
@@ -34,6 +34,13 @@ namespace Fortran::tools {
     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
   }
+  if (targetTriple.isARM() || targetTriple.isAArch64()) {
+    targetCharacteristics.set_haltingSupportIsUnknownAtCompileTime();
+    targetCharacteristics.set_ieeeFeature(
+        evaluate::IeeeFeature::Halting, false);
+  } else {
+    targetCharacteristics.set_ieeeFeature(evaluate::IeeeFeature::Halting);
+  }
 
   // Figure out if we can support F128: see
   // flang/runtime/Float128Math/math-entries.h
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index 6c7758e99a4482..65f996ddc6dd1c 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -881,8 +881,11 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
     return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
         IeeeFeature::Flags)};
   } else if (name == "__builtin_ieee_support_halting") {
-    return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
-        IeeeFeature::Halting)};
+    if (!context.targetCharacteristics()
+            .haltingSupportIsUnknownAtCompileTime()) {
+      return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+          IeeeFeature::Halting)};
+    }
   } else if (name == "__builtin_ieee_support_inf") {
     return Expr<T>{
         context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Inf)};
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index bbbacd25bca621..9a3777994a9df0 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -389,10 +389,10 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genIeeeSignalingCompare<mlir::arith::CmpFPredicate::UNE>},
     {"ieee_signbit", &I::genIeeeSignbit},
     {"ieee_support_flag",
-     &I::genIeeeSupportFlagOrHalting,
+     &I::genIeeeSupportFlag,
      {{{"flag", asValue}, {"x", asInquired, handleDynamicOptional}}},
      /*isElemental=*/false},
-    {"ieee_support_halting", &I::genIeeeSupportFlagOrHalting},
+    {"ieee_support_halting", &I::genIeeeSupportHalting},
     {"ieee_support_rounding", &I::genIeeeSupportRounding},
     {"ieee_unordered", &I::genIeeeUnordered},
     {"ieee_value", &I::genIeeeValue},
@@ -5259,14 +5259,14 @@ mlir::Value IntrinsicLibrary::genIeeeSignbit(mlir::Type resultType,
   return builder.createConvert(loc, resultType, sign);
 }
 
-// IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING
-fir::ExtendedValue IntrinsicLibrary::genIeeeSupportFlagOrHalting(
-    mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
-  // Check if a floating point exception or halting mode FLAG is supported.
-  // An IEEE_SUPPORT_FLAG flag is supported either for all type kinds or none.
-  // An optional kind argument X is therefore ignored.
-  // Standard flags are all supported.
-  // The nonstandard DENORM extension is not supported. (At least for now.)
+// IEEE_SUPPORT_FLAG
+fir::ExtendedValue
+IntrinsicLibrary::genIeeeSupportFlag(mlir::Type resultType,
+                                     llvm::ArrayRef<fir::ExtendedValue> args) {
+  // Check if a floating point exception flag is supported. A flag is
+  // supported either for all type kinds or none. An optional kind argument X
+  // is therefore ignored. Standard flags are all supported. The nonstandard
+  // DENORM extension is not supported, at least for now.
   assert(args.size() == 1 || args.size() == 2);
   auto [fieldRef, fieldTy] = getFieldRef(builder, loc, fir::getBase(args[0]));
   mlir::Value flag = builder.create<fir::LoadOp>(loc, fieldRef);
@@ -5283,6 +5283,22 @@ fir::ExtendedValue IntrinsicLibrary::genIeeeSupportFlagOrHalting(
           builder.createIntegerConstant(loc, fieldTy, 0)));
 }
 
+// IEEE_SUPPORT_HALTING
+fir::ExtendedValue IntrinsicLibrary::genIeeeSupportHalting(
+    mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
+  // Check if halting is supported for a floating point exception flag.
+  // Standard flags are all supported. The nonstandard DENORM extension is
+  // not supported, at least for now.
+  assert(args.size() == 1);
+  mlir::Type i32Ty = builder.getIntegerType(32);
+  auto [fieldRef, ignore] = getFieldRef(builder, loc, getBase(args[0]));
+  mlir::Value field = builder.create<fir::LoadOp>(loc, fieldRef);
+  return builder.createConvert(
+      loc, resultType,
+      fir::runtime::genSupportHalting(
+          builder, loc, {builder.create<fir::ConvertOp>(loc, i32Ty, field)}));
+}
+
 // IEEE_SUPPORT_ROUNDING
 mlir::Value
 IntrinsicLibrary::genIeeeSupportRounding(mlir::Type resultType,
diff --git a/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp b/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
index 85f38424eabdc4..630281fdb593d7 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Exceptions.cpp
@@ -21,6 +21,14 @@ mlir::Value fir::runtime::genMapExcept(fir::FirOpBuilder &builder,
   return builder.create<fir::CallOp>(loc, func, excepts).getResult(0);
 }
 
+mlir::Value fir::runtime::genSupportHalting(fir::FirOpBuilder &builder,
+                                            mlir::Location loc,
+                                            mlir::Value excepts) {
+  mlir::func::FuncOp func{
+      fir::runtime::getRuntimeFunc<mkRTKey(SupportHalting)>(loc, builder)};
+  return builder.create<fir::CallOp>(loc, func, excepts).getResult(0);
+}
+
 mlir::Value fir::runtime::genGetUnderflowMode(fir::FirOpBuilder &builder,
                                               mlir::Location loc) {
   mlir::func::FuncOp func{
diff --git a/flang/runtime/exceptions.cpp b/flang/runtime/exceptions.cpp
index 993c996c9ce75d..76f8d5168d7b69 100644
--- a/flang/runtime/exceptions.cpp
+++ b/flang/runtime/exceptions.cpp
@@ -81,6 +81,23 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
 // on some systems, e.g. Solaris, so omit object size comparison for now.
 // TODO: consider femode_t object size comparison once its more mature.
 
+// Check if the processor has the ability to control whether to halt or
+// continue execution when a given exception is raised.
+bool RTNAME(SupportHalting)(uint32_t except) {
+  except = RTNAME(MapException)(except);
+  int currentSet = fegetexcept(), flipSet, ok;
+  if (currentSet & except) {
+    ok = fedisableexcept(except);
+    flipSet = fegetexcept();
+    ok |= feenableexcept(except);
+  } else {
+    ok = feenableexcept(except);
+    flipSet = fegetexcept();
+    ok |= fedisableexcept(except);
+  }
+  return ok != -1 && currentSet != flipSet;
+}
+
 bool RTNAME(GetUnderflowMode)(void) {
 #if __x86_64__
   // The MXCSR Flush to Zero flag is the negation of the ieee_get_underflow_mode
diff --git a/flang/test/Evaluate/fold-ieee.f90 b/flang/test/Evaluate/fold-ieee.f90
index e70d558af1668e..99f8526fd23dbf 100644
--- a/flang/test/Evaluate/fold-ieee.f90
+++ b/flang/test/Evaluate/fold-ieee.f90
@@ -26,11 +26,13 @@ module m
   logical, parameter :: test_fl_ix_all = ieee_support_flag(ieee_inexact)
   logical, parameter :: test_fl_ix_4 = ieee_support_flag(ieee_inexact, 1.)
   logical, parameter :: test_fl_ix_8 = ieee_support_flag(ieee_inexact, 1.d0)
+#if __x86_64__
   logical, parameter :: test_halt_in = ieee_support_halting(ieee_invalid)
   logical, parameter :: test_halt_ov = ieee_support_halting(ieee_overflow)
   logical, parameter :: test_halt_d0 = ieee_support_halting(ieee_divide_by_zero)
   logical, parameter :: test_halt_un = ieee_support_halting(ieee_underflow)
   logical, parameter :: test_halt_ix = ieee_support_halting(ieee_inexact)
+#endif
   logical, parameter :: test_inf_all = ieee_support_inf()
   logical, parameter :: test_inf_4 = ieee_support_inf(1.)
   logical, parameter :: test_inf_8 = ieee_support_inf(1.d0)
@@ -58,7 +60,9 @@ module m
   logical, parameter :: test_sn_all = ieee_support_subnormal()
   logical, parameter :: test_sn_4 = ieee_support_subnormal(1.)
   logical, parameter :: test_sn_8 = ieee_support_subnormal(1.d0)
-! logical, parameter :: test_uc_all = .not. ieee_support_underflow_control()
-! logical, parameter :: test_uc_4 = ieee_support_underflow_control(1.)
-! logical, parameter :: test_uc_8 = ieee_support_underflow_control(1.d0)
+#if __x86_64__
+  logical, parameter :: test_uc_all = .not. ieee_support_underflow_control()
+  logical, parameter :: test_uc_4 = ieee_support_underflow_control(1.)
+  logical, parameter :: test_uc_8 = ieee_support_underflow_control(1.d0)
+#endif
 end
diff --git a/flang/test/Lower/Intrinsics/ieee_flag.f90 b/flang/test/Lower/Intrinsics/ieee_flag.f90
index 862cfbd8b28759..e4addc0d658dc4 100644
--- a/flang/test/Lower/Intrinsics/ieee_flag.f90
+++ b/flang/test/Lower/Intrinsics/ieee_flag.f90
@@ -271,7 +271,7 @@
   print*, 'Halting'
 
   ! CHECK:     %[[V_211:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
-  ! CHECK:     %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]], %true) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
+  ! CHECK:     %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]]
   print*, 'support invalid: ', ieee_support_halting(ieee_invalid)
 
   ! CHECK:     %[[V_222:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>

Copy link

github-actions bot commented Dec 20, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@psteinfeld psteinfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All builds and tests successfully and looks good.

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kiranchandramohan, I added you since this is about ARM.

Other than the windows issue, LGTM.

@vdonaldson
Copy link
Contributor Author

I've updated the SupportHalting code in file exceptions.cpp as below to return no support on windows, which should be conservatively correct. If the windows build still fails, or there is a better way to address this issue for windows, please comment. Especially if a simple #include or some such will suffice.

diff --git a/flang/runtime/exceptions.cpp b/flang/runtime/exceptions.cpp
index 76f8d5168d7b..b34fcfef2b04 100644
--- a/flang/runtime/exceptions.cpp
+++ b/flang/runtime/exceptions.cpp
@@ -84,6 +84,8 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
 // Check if the processor has the ability to control whether to halt or
 // continue execution when a given exception is raised.
 bool RTNAME(SupportHalting)(uint32_t except) {
+  bool result = false;
+#ifndef _WIN32
   except = RTNAME(MapException)(except);
   int currentSet = fegetexcept(), flipSet, ok;
   if (currentSet & except) {
@@ -95,7 +97,9 @@ bool RTNAME(SupportHalting)(uint32_t except) {
     flipSet = fegetexcept();
     ok |= fedisableexcept(except);
   }
-  return ok != -1 && currentSet != flipSet;
+  result = ok != -1 && currentSet != flipSet;
+#endif
+  return result;
 }

@klausler
Copy link
Contributor

I've updated the SupportHalting code in file exceptions.cpp as below to return no support on windows, which should be conservatively correct. If the windows build still fails, or there is a better way to address this issue for windows, please comment. Especially if a simple #include or some such will suffice.

diff --git a/flang/runtime/exceptions.cpp b/flang/runtime/exceptions.cpp
index 76f8d5168d7b..b34fcfef2b04 100644
--- a/flang/runtime/exceptions.cpp
+++ b/flang/runtime/exceptions.cpp
@@ -84,6 +84,8 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
 // Check if the processor has the ability to control whether to halt or
 // continue execution when a given exception is raised.
 bool RTNAME(SupportHalting)(uint32_t except) {
+  bool result = false;
+#ifndef _WIN32
   except = RTNAME(MapException)(except);
   int currentSet = fegetexcept(), flipSet, ok;
   if (currentSet & except) {
@@ -95,7 +97,9 @@ bool RTNAME(SupportHalting)(uint32_t except) {
     flipSet = fegetexcept();
     ok |= fedisableexcept(except);
   }
-  return ok != -1 && currentSet != flipSet;
+  result = ok != -1 && currentSet != flipSet;
+#endif
+  return result;
 }

You might need [[maybe_unused]] on the argument, or two definitions of the function (one for windows with no argument name that just returns false).

It might be cleaner to have an #ifdef _WIN32 at the top of the function, if you have just one function.

If you retain bool result, please use braced initialization in the runtime.

@vdonaldson
Copy link
Contributor Author

Thanks, Peter, for the suggestions. It looks like the linux and windows builds were successful after this change, but I'll tweak it some more.

@vdonaldson
Copy link
Contributor Author

Thanks, Peter, for the suggestions. It looks like the linux and windows builds were successful after this change, but I'll tweak it some more.

Done

The F23 standard requires that a call to intrinsic module procedure ieee_support_halting be foldable to a constant at compile time in some contexts. See for example F23 Clause 10.1.11 [Specification expression] list item (13), Clause 1.1.12 [Constant expression] list item (11), and references to specification and constant expressions elsewhere, such as constraints C1012, C853, and C704.

Some Arm processors allow a user to control processor behavior when an arithmetic exception is signaled, and some Arm processors do not have this capability. An Arm executable will run on either type of processor, so it is effectively unknown at compile time whether or not this support will be available at runtime. This is in conflict with the standard requirement.

This patch addresses this conflict by implementing ieee_support_halting calls on Arm processors to check if this capability is present at runtime. A call to ieee_support_halting in a constant context, such as in the specification part of a program unit, will generate a compile time "cannot be computed as a constant value" error. The expectation is that such calls are unlikely to appear in production code.

Code generation for other processors will continue to generate a compile time constant result for ieee_support_halting calls.
@kiranchandramohan
Copy link
Contributor

@kiranchandramohan, I added you since this is about ARM.

Thanks @jeanPerier. I don't know this off the top of my head and I am away for two weeks. I have added Pawel, Tom and David Green. But not sure whether they are around as well. Please go ahead if you are happy with the patch, we can make post-commit comments if we have any.

@vdonaldson vdonaldson merged commit c28a7c1 into llvm:main Dec 23, 2024
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 23, 2024

LLVM Buildbot has detected a new failure on builder ppc64-flang-aix running on ppc64-flang-aix-test while building flang at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/201/builds/215

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
2091.601 [7/8/167] Generating ../../../../include/flang/ieee_features.mod
2091.608 [7/7/168] Generating ../../../../include/flang/iso_c_binding.mod
2091.612 [7/6/169] Generating ../../../../include/flang/iso_fortran_env_impl.mod, iso_fortran_env_impl.o
2091.712 [6/6/170] Generating ../../../../include/flang/cudadevice.mod
2091.755 [6/5/171] Generating ../../../../include/flang/ieee_arithmetic.mod
2091.805 [6/4/172] Generating ../../../../include/flang/ieee_exceptions.mod
2091.928 [6/3/173] Generating ../../../../include/flang/mma.mod
2091.934 [6/2/174] Generating ../../../../include/flang/__ppc_intrinsics.mod
2092.132 [6/1/175] Generating ../../../../include/flang/iso_fortran_env.mod
2092.352 [4/2/176] Building CXX object tools/flang/runtime/CMakeFiles/FortranRuntime.dir/exceptions.cpp.o
FAILED: tools/flang/runtime/CMakeFiles/FortranRuntime.dir/exceptions.cpp.o 
/home/llvm/llvm-external-buildbots/clang.17.0.2/bin/clang++ -DFLANG_BIG_ENDIAN=1 -DFLANG_INCLUDE_TESTS=1 -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LARGE_FILE_API -D_XOPEN_SOURCE=700 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/flang/runtime -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/flang/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/llvm/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/llvm/../mlir/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/mlir/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/clang/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/llvm/../clang/include -mcmodel=large -fPIC -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Werror -Wno-deprecated-copy -Wno-string-conversion -Wno-ctad-maybe-unsupported -Wno-unused-command-line-argument -Wstring-conversion           -Wcovered-switch-default -Wno-nested-anon-types -fno-lto -O3 -DNDEBUG -std=c++17   -U_GLIBCXX_ASSERTIONS -U_LIBCPP_ENABLE_ASSERTIONS -UNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -MD -MT tools/flang/runtime/CMakeFiles/FortranRuntime.dir/exceptions.cpp.o -MF tools/flang/runtime/CMakeFiles/FortranRuntime.dir/exceptions.cpp.o.d -o tools/flang/runtime/CMakeFiles/FortranRuntime.dir/exceptions.cpp.o -c /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:91:20: error: use of undeclared identifier 'fegetexcept'
   91 |   int currentSet = fegetexcept(), flipSet, ok;
      |                    ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:93:10: error: use of undeclared identifier 'fedisableexcept'; did you mean 'feraiseexcept'?
   93 |     ok = fedisableexcept(except);
      |          ^~~~~~~~~~~~~~~
      |          feraiseexcept
/usr/include/fenv.h:75:12: note: 'feraiseexcept' declared here
   75 | extern int feraiseexcept(int);
      |            ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:94:15: error: use of undeclared identifier 'fegetexcept'
   94 |     flipSet = fegetexcept();
      |               ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:95:11: error: use of undeclared identifier 'feenableexcept'; did you mean 'feraiseexcept'?
   95 |     ok |= feenableexcept(except);
      |           ^~~~~~~~~~~~~~
      |           feraiseexcept
/usr/include/fenv.h:75:12: note: 'feraiseexcept' declared here
   75 | extern int feraiseexcept(int);
      |            ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:97:10: error: use of undeclared identifier 'feenableexcept'; did you mean 'feraiseexcept'?
   97 |     ok = feenableexcept(except);
      |          ^~~~~~~~~~~~~~
      |          feraiseexcept
/usr/include/fenv.h:75:12: note: 'feraiseexcept' declared here
   75 | extern int feraiseexcept(int);
      |            ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:98:15: error: use of undeclared identifier 'fegetexcept'
   98 |     flipSet = fegetexcept();
      |               ^
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/runtime/exceptions.cpp:99:11: error: use of undeclared identifier 'fedisableexcept'; did you mean 'feraiseexcept'?
   99 |     ok |= fedisableexcept(except);
      |           ^~~~~~~~~~~~~~~
      |           feraiseexcept
/usr/include/fenv.h:75:12: note: 'feraiseexcept' declared here
   75 | extern int feraiseexcept(int);
      |            ^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:runtime flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants