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 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 +}