Skip to content

[flang][NFC] make IR generation for ieee_next deterministic #125055

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
Jan 30, 2025

Conversation

jeanPerier
Copy link
Contributor

C++ function call argument evaluation order is unspecified. When piping functions that generates IR, this creates indeterminism in the IR generated by flang (e.g., depend which C++ compiler compiled flang).

While it has interesting fuzzing property for flang (Initially, most of expression lowering used that pattern for binary operation where Fortran also does not specify any order, and we did found bugs exposed by some of the IR version and not the other), it is not ideal for lit tests (I found this because of a CI failure when not properly adding -DAG in test updates), and many people also really value bit to bit reproducibility from compilers.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Jan 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 30, 2025

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

Author: None (jeanPerier)

Changes

C++ function call argument evaluation order is unspecified. When piping functions that generates IR, this creates indeterminism in the IR generated by flang (e.g., depend which C++ compiler compiled flang).

While it has interesting fuzzing property for flang (Initially, most of expression lowering used that pattern for binary operation where Fortran also does not specify any order, and we did found bugs exposed by some of the IR version and not the other), it is not ideal for lit tests (I found this because of a CI failure when not properly adding -DAG in test updates), and many people also really value bit to bit reproducibility from compilers.


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

1 Files Affected:

  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+8-7)
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 970fb2b1c2f701..a6a77dd58677b1 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -6366,10 +6366,12 @@ mlir::Value IntrinsicLibrary::genNearest(mlir::Type resultType,
   mlir::FloatType xType = mlir::dyn_cast<mlir::FloatType>(x.getType());
   const unsigned xBitWidth = xType.getWidth();
   mlir::Type i1Ty = builder.getI1Type();
-  if constexpr (proc == NearestProc::NextAfter)
+  if constexpr (proc == NearestProc::NextAfter) {
     // If isNan(Y), set X to a qNaN that will propagate to the resultIsX result.
-    x = builder.create<mlir::arith::SelectOp>(
-        loc, genIsFPClass(i1Ty, args[1], nanTest), genQNan(xType), x);
+    mlir::Value qNan = genQNan(xType);
+    mlir::Value isFPClass = genIsFPClass(i1Ty, args[1], nanTest);
+    x = builder.create<mlir::arith::SelectOp>(loc, isFPClass, qNan, x);
+  }
   mlir::Value resultIsX = genIsFPClass(i1Ty, x, nanTest);
   mlir::Type intType = builder.getIntegerType(xBitWidth);
   mlir::Value one = builder.createIntegerConstant(loc, intType, 1);
@@ -6489,12 +6491,11 @@ mlir::Value IntrinsicLibrary::genNearest(mlir::Type resultType,
   } else {
     // Kind 2, 3, 4, 8, 16. Increment or decrement X cast to integer.
     mlir::Value intX = builder.create<mlir::arith::BitcastOp>(loc, intType, x);
+    mlir::Value add = builder.create<mlir::arith::AddIOp>(loc, intX, one);
+    mlir::Value sub = builder.create<mlir::arith::SubIOp>(loc, intX, one);
     result = builder.create<mlir::arith::BitcastOp>(
         loc, resultType,
-        builder.create<mlir::arith::SelectOp>(
-            loc, magnitudeUp,
-            builder.create<mlir::arith::AddIOp>(loc, intX, one),
-            builder.create<mlir::arith::SubIOp>(loc, intX, one)));
+        builder.create<mlir::arith::SelectOp>(loc, magnitudeUp, add, sub));
     if constexpr (proc == NearestProc::Nearest ||
                   proc == NearestProc::NextAfter) {
       genRaiseExcept(_FORTRAN_RUNTIME_IEEE_OVERFLOW |

@jeanPerier jeanPerier merged commit 2e581dc into llvm:main Jan 30, 2025
11 checks passed
@jeanPerier jeanPerier deleted the determinsitic-ir branch January 30, 2025 13:24
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