Skip to content

Conversation

@dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Nov 12, 2025

When convertToInteger fails, the integer result is undefined. In this case, we cannot use it in the subsequent steps.
Close #167627.

@llvmbot
Copy link
Member

llvmbot commented Nov 12, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Yingwei Zheng (dtcxzyw)

Changes

When convertToInteger fails, the integer result is undefined. In this case, we cannot use it in the subsequent steps.
Close #167627.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/Float2Int.cpp (+8-4)
  • (added) llvm/test/Transforms/Float2Int/pr167627.ll (+18)
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index 14686ce8c2ab6..37822cf05f144 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -237,10 +237,14 @@ std::optional<ConstantRange> Float2IntPass::calcRange(Instruction *I) {
       // OK, it's representable. Now get it.
       APSInt Int(MaxIntegerBW+1, false);
       bool Exact;
-      CF->getValueAPF().convertToInteger(Int,
-                                         APFloat::rmNearestTiesToEven,
-                                         &Exact);
-      OpRanges.push_back(ConstantRange(Int));
+      APFloat::opStatus Status = CF->getValueAPF().convertToInteger(
+          Int, APFloat::rmNearestTiesToEven, &Exact);
+      // Although the round above is loseless, we still need to check if the
+      // floating-point value can be represented in the integer type.
+      if (Status == APFloat::opOK || Status == APFloat::opInexact)
+        OpRanges.push_back(ConstantRange(Int));
+      else
+        return badRange();
     } else {
       llvm_unreachable("Should have already marked this as badRange!");
     }
diff --git a/llvm/test/Transforms/Float2Int/pr167627.ll b/llvm/test/Transforms/Float2Int/pr167627.ll
new file mode 100644
index 0000000000000..a170c21af7a2a
--- /dev/null
+++ b/llvm/test/Transforms/Float2Int/pr167627.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=float2int < %s | FileCheck %s
+
+; Make sure that we don't demote constant floating-point values when
+; it cannot be represented by target integer type.
+
+define i1 @pr167627() {
+; CHECK-LABEL: define i1 @pr167627() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[FADD:%.*]] = fadd float 0xC5AAD8ABE0000000, 0xC57E819700000000
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[FADD]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %fadd = fadd float 0xC5AAD8ABE0000000, 0xC57E819700000000
+  %cmp = fcmp one float %fadd, 0.000000e+00
+  ret i1 %cmp
+}

Copy link
Contributor

@antoniofrighetto antoniofrighetto left a comment

Choose a reason for hiding this comment

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

Does make sense, thanks.

@dtcxzyw dtcxzyw merged commit edd8b29 into llvm:main Nov 13, 2025
12 checks passed
@dtcxzyw dtcxzyw deleted the fix-167627 branch November 13, 2025 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Float2Int] Miscompilation at O3

3 participants