Commit e4c445a6 authored by Adéla Štěpková's avatar Adéla Štěpková
Browse files

fix comparison of floating point numbers

parent ede5884d
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -350,13 +350,29 @@ public:
        return newI;
    }

    /// @brief Create ICmp EQ or FCmp OEQ based on the value's type
    /// @brief Create ICmp EQ or FCmp UEQ based on the value's type
    Value* CreateCmpEQ(Value* LHS, Value* RHS, const Twine& Name = "", Value* registerTo = nullptr)
    {
        if (LHS->getType()->isIntOrIntVectorTy()) {
            return CreateICmpEQ(LHS, RHS, Name, registerTo);
        }
        return CreateFCmpOEQ(LHS, RHS, Name, nullptr, registerTo);
        else if (LHS->getType()->isFPOrFPVectorTy()) {
            return equalFloats(LHS, RHS, Name, registerTo);
        }
        assert(false && "cannot compare type that is not integer of floating point");
    }

    /// @brief Compare two floats for equality -- return an instruction that is true if either both
    /// are ordered and equal, or both are NaN. Used for comparisons of nondeterministic values 
    /// generated during reversing.
    Value* equalFloats(Value* LHS, Value* RHS, const Twine& Name = "", Value* registerTo = nullptr)
    {
        auto* orderedEq = CreateFCmpOEQ(LHS, RHS);
        auto* isLHSNan = CreateFCmp(CmpInst::Predicate::FCMP_UNO, LHS, LHS);
        auto* isRHSNan = CreateFCmp(CmpInst::Predicate::FCMP_UNO, RHS, RHS);
        auto* bothNan = CreateAnd(isLHSNan, isRHSNan);
        auto* oequalOrBothNan = CreateOr(orderedEq, bothNan, Name, registerTo);
        return oequalOrBothNan;
    }

    Value* CreateICmpEQ(Value* LHS, Value* RHS, const Twine& Name = "", Value* registerTo = nullptr)
@@ -374,6 +390,14 @@ public:
        return newI;
    }

    Value* CreateFCmpUEQ(Value* LHS, Value* RHS, const Twine& Name = "",
                         MDNode* FPMathTag = nullptr, Value* registerTo = nullptr)
    {
        auto* newI = _builder.CreateFCmpUEQ(LHS, RHS, Name, FPMathTag);
        registerValue(registerTo, newI);
        return newI;
    }

    Value* CreateICmp(CmpInst::Predicate P, Value* LHS, Value* RHS, const Twine& Name = "",
                      Value* registerTo = nullptr)
    {
@@ -487,7 +511,7 @@ public:
    Value* CreateFDiv(Value* L, Value* R, const Twine& Name = "", MDNode* FPMD = nullptr,
                      Value* registerTo = nullptr)
    {
        auto* newI = _builder.CreateFMul(L, R, Name, FPMD);
        auto* newI = _builder.CreateFDiv(L, R, Name, FPMD);
        registerValue(registerTo, newI);
        return newI;
    }