[llvm] [llubi] Initial support for floating-point numbers (PR #188453)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 12:06:26 PDT 2026
================
@@ -219,6 +283,92 @@ class InstExecutor : public InstVisitor<InstExecutor, void> {
});
}
+ void visitFPBinOp(
+ Instruction &I,
+ function_ref<AnyValue(const APFloat &, const APFloat &)> ScalarFn) {
+ FastMathFlags FMF = cast<FPMathOperator>(I).getFastMathFlags();
+ DenormalMode DenormMode = CurrentFrame->Func.getDenormalMode(
+ I.getType()->getScalarType()->getFltSemantics());
+
+ visitBinOp(I, [&](const AnyValue &LHS, const AnyValue &RHS) -> AnyValue {
+ if (LHS.isPoison() || RHS.isPoison())
+ return AnyValue::poison();
+
+ if (auto ValidateRes = handleFMFFlags(LHS, FMF); ValidateRes.isPoison())
+ return ValidateRes;
+ if (auto ValidateRes = handleFMFFlags(RHS, FMF); ValidateRes.isPoison())
+ return ValidateRes;
+
+ // Flush input denormals
+ APFloat FLHS = handleDenormal(LHS.asFloat(), DenormMode.Input);
+ APFloat FRHS = handleDenormal(RHS.asFloat(), DenormMode.Input);
+
+ APFloat RawResult = ScalarFn(FLHS, FRHS).asFloat();
+
+ // Flush output denormals and handle fast-math flags.
+ AnyValue FResult = handleFMFFlags(
+ handleDenormal(RawResult, DenormMode.Output, true), FMF);
+
+ if (FResult.isPoison())
+ return FResult;
+
+ APFloat Result = FResult.asFloat();
+ // NaN payload propagation
+ if (Result.isNaN()) {
+ NaNPropagationBehavior Choice = Ctx.getNaNPropagationBehavior();
+ if (Choice == NaNPropagationBehavior::NonDeterministic) {
+ uint64_t NonDetChoice = Ctx.getRandomUInt64() % 4 + 1;
+ Choice = static_cast<NaNPropagationBehavior>(NonDetChoice);
+ }
+ const bool Sign = Ctx.getRandomBool();
+ if (Choice == NaNPropagationBehavior::PreferredNaN) {
+ // Preferred NaN: the quiet bit is set and the payload is all-zero
+ return APFloat::getQNaN(Result.getSemantics(), Sign);
+ }
+ if (Choice == NaNPropagationBehavior::QuietingNaN) {
+ // Quieting NaN propagation: the quiet bit is set and the payload is
+ // copied from any input operand that is a NaN. We implement this by
+ // directly set the quiet bit of the input NaN, and
+ // non-deterministically flip its sign bit
+ auto QuietNaN = [&](APFloat &Input) {
+ APFloat Quieted = Input.makeQuiet();
+ if (Sign)
+ Quieted.changeSign();
+ return Quieted;
+ };
+ if (FLHS.isNaN())
+ return QuietNaN(FLHS);
+ if (FRHS.isNaN())
+ return QuietNaN(FRHS);
+ return QuietNaN(Result);
+ }
+ if (Choice == NaNPropagationBehavior::UnchangedNaN) {
+ // Unchanged NaN propagation: the quiet bit and payload are copied
+ // from any input operand that is a NaN
+ auto FlipSign = [&](APFloat &Input) {
+ if (Sign)
+ Input.changeSign();
+ return Input;
+ };
+ if (FLHS.isNaN())
+ return FlipSign(FLHS);
+ if (FRHS.isNaN())
+ return FlipSign(FRHS);
+ return FlipSign(Result);
+ }
+ if (Choice == NaNPropagationBehavior::TargetSpecificNaN) {
+ // Target-specific NaN: the quiet bit is set and the payload is picked
+ // from a target-specific set of "extra" possible NaN payloads. We
+ // approximate this by filling the payload with random values.
+ auto Payload = APInt(64, Ctx.getRandomUInt64());
----------------
dtcxzyw wrote:
```suggestion
APInt Payload(64, Ctx.getRandomUInt64());
```
https://github.com/llvm/llvm-project/pull/188453
More information about the llvm-commits
mailing list