[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