Skip to content

Commit 2e581dc

Browse files
authored
[flang][NFC] make IR generation for ieee_next deterministic (#125055)
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](#124966)), and many people also really value bit to bit reproducibility from compilers.
1 parent 104c2b8 commit 2e581dc

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6366,10 +6366,12 @@ mlir::Value IntrinsicLibrary::genNearest(mlir::Type resultType,
63666366
mlir::FloatType xType = mlir::dyn_cast<mlir::FloatType>(x.getType());
63676367
const unsigned xBitWidth = xType.getWidth();
63686368
mlir::Type i1Ty = builder.getI1Type();
6369-
if constexpr (proc == NearestProc::NextAfter)
6369+
if constexpr (proc == NearestProc::NextAfter) {
63706370
// If isNan(Y), set X to a qNaN that will propagate to the resultIsX result.
6371-
x = builder.create<mlir::arith::SelectOp>(
6372-
loc, genIsFPClass(i1Ty, args[1], nanTest), genQNan(xType), x);
6371+
mlir::Value qNan = genQNan(xType);
6372+
mlir::Value isFPClass = genIsFPClass(i1Ty, args[1], nanTest);
6373+
x = builder.create<mlir::arith::SelectOp>(loc, isFPClass, qNan, x);
6374+
}
63736375
mlir::Value resultIsX = genIsFPClass(i1Ty, x, nanTest);
63746376
mlir::Type intType = builder.getIntegerType(xBitWidth);
63756377
mlir::Value one = builder.createIntegerConstant(loc, intType, 1);
@@ -6489,12 +6491,11 @@ mlir::Value IntrinsicLibrary::genNearest(mlir::Type resultType,
64896491
} else {
64906492
// Kind 2, 3, 4, 8, 16. Increment or decrement X cast to integer.
64916493
mlir::Value intX = builder.create<mlir::arith::BitcastOp>(loc, intType, x);
6494+
mlir::Value add = builder.create<mlir::arith::AddIOp>(loc, intX, one);
6495+
mlir::Value sub = builder.create<mlir::arith::SubIOp>(loc, intX, one);
64926496
result = builder.create<mlir::arith::BitcastOp>(
64936497
loc, resultType,
6494-
builder.create<mlir::arith::SelectOp>(
6495-
loc, magnitudeUp,
6496-
builder.create<mlir::arith::AddIOp>(loc, intX, one),
6497-
builder.create<mlir::arith::SubIOp>(loc, intX, one)));
6498+
builder.create<mlir::arith::SelectOp>(loc, magnitudeUp, add, sub));
64986499
if constexpr (proc == NearestProc::Nearest ||
64996500
proc == NearestProc::NextAfter) {
65006501
genRaiseExcept(_FORTRAN_RUNTIME_IEEE_OVERFLOW |

0 commit comments

Comments
 (0)