diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCompares.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCompares.cpp index fc40533cf3dc9..764199ee4a27f 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCompares.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCompares.cpp @@ -74,6 +74,9 @@ bool CombinerHelper::constantFoldFCmp(const GFCmp &FCmp, APFloat LHS = LHSCst.getScalarValue(); APFloat RHS = RHSCst.getScalarValue(); + if (&LHS.getSemantics() != &RHS.getSemantics()) + return false; + bool Result = FCmpInst::compare(LHS, RHS, Pred); MatchInfo = [=](MachineIRBuilder &B) { diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index 15e81f5773b69..df438a79fd5e6 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -452,8 +452,24 @@ std::optional llvm::getFConstantVRegValWithLookThrough( VReg, MRI, LookThroughInstrs); if (!Reg) return std::nullopt; - return FPValueAndVReg{getConstantFPVRegVal(Reg->VReg, MRI)->getValueAPF(), - Reg->VReg}; + + auto getFloatSemantics = [](unsigned BitWidth) -> const llvm::fltSemantics & { + switch (BitWidth) { + default: + llvm_unreachable("Unsupported floating-point semantics!"); + case 16: + return APFloat::IEEEhalf(); + case 32: + return APFloat::IEEEsingle(); + case 64: + return APFloat::IEEEdouble(); + case 128: + return APFloat::IEEEquad(); + } + }; + + APFloat FloatVal(getFloatSemantics(Reg->Value.getBitWidth()), Reg->Value); + return FPValueAndVReg{FloatVal, Reg->VReg}; } const ConstantFP * diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir index 94204611095db..8c9885ef37934 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir @@ -117,3 +117,17 @@ body: | %res:_(s32) = afn G_FCMP floatpred(oge), %lhs(s64), %rhs $w0 = COPY %res(s32) ... +--- +name: test_fcmp_no_same_semantics +body: | + bb.1: + ; CHECK-LABEL: name: test_fcmp_no_same_semantics + ; CHECK: %res:_(s32) = G_CONSTANT i32 0 + ; CHECK-NEXT: $w0 = COPY %res(s32) + %lhs:_(s64) = G_FCONSTANT double 2.0 + %fabs:_(s64) = G_FABS %lhs + %trunc:_(s32) = G_TRUNC %fabs(s64) + %rhs:_(s32) = G_FCONSTANT float 1.0 + %res:_(s32) = G_FCMP floatpred(oge), %trunc(s32), %rhs + $w0 = COPY %res(s32) +...