[llvm] [InstCombine] Avoid constant folding of different FP types in FCMP (PR #171878)

Joel Fuentes via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 11 09:58:47 PST 2025


https://github.com/jfuentes created https://github.com/llvm/llvm-project/pull/171878

The instruction combine ``canonicalize_fcmp`` tries to fold constant values in fcmp, however, it fails when the source defs have different FP types. This occurs because it uses
``getFConstantVRegValWithLookThrough`` to get the constants value def, even through trunc, zext, or sext.

This fix avoids the compiler to crash while a final solution is implemented, e.g. use the constant value after trunc/zext/sext for the constant folding.

Related to #171856

>From 920654b9059cc3fbb30f9e64882afab80c7d40c3 Mon Sep 17 00:00:00 2001
From: Joel Fuentes <joel.fuentes at intel.com>
Date: Thu, 11 Dec 2025 09:41:49 -0800
Subject: [PATCH] [InstCombine] Avoid constant folding of different FP types in
 FCMP

The instruction combine ``canonicalize_fcmp`` tries to fold constant
values in fcmp, however, it fails when the source defs have different
FP types. This occurs because it uses
``getFConstantVRegValWithLookThrough`` to get the constants value def, even
through trunc, zext, or sext.

This fix avoids the compiler to crash while a final solution is
implemented, e.g. use the constant value after trunc/zext/sext for
the constant folding.

Related to #171856
---
 .../GlobalISel/CombinerHelperCompares.cpp       |  3 +++
 .../GlobalISel/combine-cannonicalize-fcmp.mir   | 17 +++++++++++++++++
 2 files changed, 20 insertions(+)

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/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir
index 94204611095db..d68eda67d2b80 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cannonicalize-fcmp.mir
@@ -117,3 +117,20 @@ 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: %lhs:_(s64) = G_FCONSTANT double 0x5D3B0B8040DF92C9
+    ; CHECK-NEXT: %trunc:_(s32) = G_TRUNC %lhs(s64)
+    ; CHECK-NEXT: %rhs:_(s32) = G_FCONSTANT float 0x3E6BBDE420000000
+    ; CHECK-NEXT: %res:_(s32) = G_FCMP floatpred(oge), %trunc(s32), %rhs
+    ; CHECK-NEXT: $w0 = COPY %res(s32)
+    %lhs:_(s64) = G_FCONSTANT double 0x5D3B0B8040DF92C9
+    %fabs:_(s64) = G_FABS %lhs
+    %trunc:_(s32) = G_TRUNC %fabs(s64)
+    %rhs:_(s32) = G_FCONSTANT float 0x3E6BBDE420000000
+    %res:_(s32) = G_FCMP floatpred(oge), %trunc(s32), %rhs
+    $w0 = COPY %res(s32)
+...



More information about the llvm-commits mailing list