Skip to content

Conversation

@vdonaldson
Copy link
Contributor

Implement the kind=2,3 variants of language intrinsic SCALE and intrinsic module procedure IEEE_SCALB, including exception signaling.

Implement the kind=2,3 variants of language intrinsic SCALE and
intrinsic module procedure IEEE_SCALB, including exception signaling.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Apr 11, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

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

Author: None (vdonaldson)

Changes

Implement the kind=2,3 variants of language intrinsic SCALE and intrinsic module procedure IEEE_SCALB, including exception signaling.


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

1 Files Affected:

  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+39-5)
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 16cbdf076e659..1ac0627da9524 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -7593,12 +7593,46 @@ IntrinsicLibrary::genSameTypeAs(mlir::Type resultType,
 mlir::Value IntrinsicLibrary::genScale(mlir::Type resultType,
                                        llvm::ArrayRef<mlir::Value> args) {
   assert(args.size() == 2);
+  mlir::FloatType floatTy = mlir::dyn_cast<mlir::FloatType>(resultType);
+  if (!floatTy.isF16() && !floatTy.isBF16()) // kind=4,8,10,16
+    return builder.createConvert(
+        loc, resultType,
+        fir::runtime::genScale(builder, loc, args[0], args[1]));
 
-  mlir::Value realX = fir::getBase(args[0]);
-  mlir::Value intI = fir::getBase(args[1]);
-
-  return builder.createConvert(
-      loc, resultType, fir::runtime::genScale(builder, loc, realX, intI));
+  // Convert kind=2,3 arg X to kind=4. Convert kind=4 result back to kind=2,3.
+  mlir::Type i1Ty = builder.getI1Type();
+  mlir::Type f32Ty = mlir::Float32Type::get(builder.getContext());
+  mlir::Value result = builder.createConvert(
+      loc, resultType,
+      fir::runtime::genScale(
+          builder, loc, builder.createConvert(loc, f32Ty, args[0]), args[1]));
+
+  // kind=4 runtime::genScale call may not signal kind=2,3 exceptions.
+  // If X is finite and result is infinite, signal IEEE_OVERFLOW
+  // If X is finite and scale(result, -I) != X, signal IEEE_UNDERFLOW
+  fir::IfOp outerIfOp =
+      builder.create<fir::IfOp>(loc, genIsFPClass(i1Ty, args[0], finiteTest),
+                                /*withElseRegion=*/false);
+  builder.setInsertionPointToStart(&outerIfOp.getThenRegion().front());
+  fir::IfOp innerIfOp =
+      builder.create<fir::IfOp>(loc, genIsFPClass(i1Ty, result, infiniteTest),
+                                /*withElseRegion=*/true);
+  builder.setInsertionPointToStart(&innerIfOp.getThenRegion().front());
+  genRaiseExcept(_FORTRAN_RUNTIME_IEEE_OVERFLOW |
+                 _FORTRAN_RUNTIME_IEEE_INEXACT);
+  builder.setInsertionPointToStart(&innerIfOp.getElseRegion().front());
+  mlir::Value minusI = builder.create<mlir::arith::MulIOp>(
+      loc, args[1], builder.createAllOnesInteger(loc, args[1].getType()));
+  mlir::Value reverseResult = builder.createConvert(
+      loc, resultType,
+      fir::runtime::genScale(
+          builder, loc, builder.createConvert(loc, f32Ty, result), minusI));
+  genRaiseExcept(
+      _FORTRAN_RUNTIME_IEEE_UNDERFLOW | _FORTRAN_RUNTIME_IEEE_INEXACT,
+      builder.create<mlir::arith::CmpFOp>(loc, mlir::arith::CmpFPredicate::ONE,
+                                          args[0], reverseResult));
+  builder.setInsertionPointAfter(outerIfOp);
+  return result;
 }
 
 // SCAN

Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

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

Thank you, Val!

I feel like the extra code is only needed for the IEEE version. Please see my comments.

@vzakhari
Copy link
Contributor

Thank you for the replies, Val! Please add a LIT test. LGTM otherwise

@vdonaldson
Copy link
Contributor Author

Thanks for the review Slava. We have end-to-end tests for this new code that I think are better than a lit test.

@vdonaldson vdonaldson merged commit a8da483 into llvm:main Apr 11, 2025
14 checks passed
bcardosolopes added a commit to bcardosolopes/llvm-project that referenced this pull request Apr 11, 2025
* origin/main: (287 commits)
  [Sema] On Windows, silence erroneous warning when building with MSVC
  [lldb][lldbp-dap] On Windoows, silence warnings when building with MSVC
  [lldb] Fix erroneous return value
  [compiler-rt] On Windows, silence warning when building with Clang ToT
  [clang][unittests] On Windows, silence warning when building with MSVC
  [lldb] On Windows, silence warning when building with Clang ToT
  [CIR] Make LLVM & OGCG variables match the same pattern (llvm#135427)
  [mlir][SMT] upstream `SMT` dialect (llvm#131480)
  [clang] fix serialization for SubstNonTypeTemplateParmPackExpr (llvm#135428)
  [flang][openacc] Allow if_present multiple times on host_data and update (llvm#135422)
  [flang][openacc] Allow finalize clause on exit data more than once (llvm#135415)
  [flang] IEEE_SCALB and SCALE - kind=2, kind=3 (llvm#135374)
  [-Wunsafe-buffer-usage] Add findUnsafePointers (llvm#135421)
  [compiler-rt][sanitizer] add Haiku support (llvm#134772)
  [cpp23] Remove usage of std::aligned_union<> in llvm (llvm#135146)
  [mlir][tosa] Add error_if checks for Mul Op (llvm#135075)
  [VPlan] Merge cases using getResultType in inferScalarType (NFC).
  [flang][runtime] Fix recently broken big-endian formatted integer input (llvm#135417)
  [AMDGPU][Verifier] Mark calls to entry functions as invalid in the IR verifier (llvm#134910)
  [llvm][Hexagon] Promote operand v2i1 to v2i32 (llvm#135409)
  ...
@vdonaldson vdonaldson deleted the vkd1 branch April 12, 2025 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants