[llvm] [Hexagon] Optimize sfclass/dfclass compares (PR #165735)

Sumanth Gundapaneni via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 30 08:59:22 PDT 2025


https://github.com/sgundapa updated https://github.com/llvm/llvm-project/pull/165735

>From 8e4e94da894ba6d859ec2f7549f3ca4fa94668f8 Mon Sep 17 00:00:00 2001
From: Sumanth Gundapaneni <sgundapa at qti.qualcomm.com>
Date: Wed, 15 Oct 2025 14:42:41 -0700
Subject: [PATCH 1/3] [Hexagon] Optimize sfclass/dfclass compares

fclass intrinsics generate a sub-optimal code by doing a predicate
transfer and compare. This patch optimizes out and directly uses the
predicate.
---
 llvm/lib/Target/Hexagon/HexagonPatterns.td | 11 +++
 llvm/test/CodeGen/Hexagon/isel-fclass.ll   | 86 ++++++++++++++++++++++
 2 files changed, 97 insertions(+)
 create mode 100644 llvm/test/CodeGen/Hexagon/isel-fclass.ll

diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 85ce9447c2028..44e9d2402d0a3 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -3434,6 +3434,17 @@ let AddedComplexity = 100 in {
            (C2_not (S4_stored_locked I32:$Rs, I64:$Rt))>;
 }
 
+multiclass FloatClass<SDPatternOperator IntOp, InstHexagon MI,
+                      PatFrag RegPred> {
+  def: Pat<(i1 (seteq (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
+            (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;
+  def: Pat<(i1 (setne (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
+           (MI RegPred:$Rs, u5_0ImmPred_timm:$u5)>;
+}
+
+defm : FloatClass<int_hexagon_F2_sfclass, F2_sfclass, F32>;
+defm : FloatClass<int_hexagon_F2_dfclass, F2_dfclass, F64>;
+
 def: Pat<(int_hexagon_instrprof_custom (HexagonAtPcrel tglobaladdr:$addr), u32_0ImmPred:$I),
          (PS_call_instrprof_custom tglobaladdr:$addr, imm:$I)>;
 
diff --git a/llvm/test/CodeGen/Hexagon/isel-fclass.ll b/llvm/test/CodeGen/Hexagon/isel-fclass.ll
new file mode 100644
index 0000000000000..96b02106fa807
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/isel-fclass.ll
@@ -0,0 +1,86 @@
+; Tests lowering of sfclass/dfclass compares.
+; Sub-optimal code
+;         {
+;                p0 = sfclass(r0,#16)
+;                r0 = sfadd(r0,r0)
+;        }
+;        {
+;                r2 = p0
+;        }
+;        {
+;                if (p0.new) r0 = ##1065353216
+;                p0 = cmp.eq(r2,#0)
+;                jumpr r31
+;        }
+; With the patterns added, we should be generating
+;        {
+;                p0 = sfclass(r0,#16)
+;                r0 = sfadd(r0,r0)
+;        }
+;        {
+;                if (!p0) r0 = ##1065353216
+;                jumpr r31
+;        }
+
+; RUN: llc -march=hexagon -stop-after=hexagon-isel %s -o - | FileCheck %s
+
+; CHECK: bb.0.entry1
+; CHECK: F2_sfclass
+; CHECK-NOT: C2_cmp
+; CHECK: C2_not
+; CHECK: F2_sfadd
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define float @test1(float noundef %x) {
+entry1:
+  %0 = tail call i32 @llvm.hexagon.F2.sfclass(float %x, i32 16)
+  %tobool.not = icmp eq i32 %0, 0
+  %add = fadd float %x, %x
+  %spec.select = select i1 %tobool.not, float 1.000000e+00, float %add
+  ret float %spec.select
+}
+
+; CHECK: bb.0.entry2
+; CHECK: F2_sfclass
+; CHECK-NOT: C2_cmp
+; CHECK: F2_sfadd
+define float @test2(float noundef %x) {
+entry2:
+  %0 = tail call i32 @llvm.hexagon.F2.sfclass(float %x, i32 16)
+  %tobool.not = icmp eq i32 %0, 0
+  %add = fadd float %x, %x
+  %spec.select = select i1 %tobool.not, float %add, float 1.000000e+00
+  ret float %spec.select
+}
+
+; CHECK: bb.0.entry3
+; CHECK: F2_dfclass
+; CHECK-NOT: C2_cmp
+; CHECK: C2_not
+; CHECK: F2_dfadd
+define double @test3(double noundef %x) {
+entry3:
+  %0 = tail call i32 @llvm.hexagon.F2.dfclass(double %x, i32 16)
+  %tobool.not = icmp eq i32 %0, 0
+  %add = fadd double %x, %x
+  %spec.select = select i1 %tobool.not, double 1.000000e+00, double %add
+  ret double %spec.select
+}
+
+; CHECK: bb.0.entry4
+; CHECK: F2_dfclass
+; CHECK-NOT: C2_cmp
+; CHECK: F2_dfadd
+define double @test4(double noundef %x) {
+entry4:
+  %0 = tail call i32 @llvm.hexagon.F2.dfclass(double %x, i32 16)
+  %tobool.not = icmp eq i32 %0, 0
+  %add = fadd double %x, %x
+  %spec.select = select i1 %tobool.not, double %add, double 1.000000e+00
+  ret double %spec.select
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare i32 @llvm.hexagon.F2.dfclass(double, i32 immarg)
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare i32 @llvm.hexagon.F2.sfclass(float, i32 immarg)

>From 3f3814ace6daa491435d52b763b9e02ec83e4932 Mon Sep 17 00:00:00 2001
From: Sumanth Gundapaneni <sumanth.gundapaneni at amd.com>
Date: Thu, 30 Oct 2025 10:47:05 -0500
Subject: [PATCH 2/3] Update llvm/lib/Target/Hexagon/HexagonPatterns.td

Co-authored-by: Copilot <175728472+Copilot at users.noreply.github.com>
---
 llvm/lib/Target/Hexagon/HexagonPatterns.td | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 44e9d2402d0a3..0c8c80a37e50d 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -3436,10 +3436,12 @@ let AddedComplexity = 100 in {
 
 multiclass FloatClass<SDPatternOperator IntOp, InstHexagon MI,
                       PatFrag RegPred> {
-  def: Pat<(i1 (seteq (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
-            (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;
-  def: Pat<(i1 (setne (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
-           (MI RegPred:$Rs, u5_0ImmPred_timm:$u5)>;
+  let AddedComplexity = 100 in {
+    def: Pat<(i1 (seteq (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
+              (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;
+    def: Pat<(i1 (setne (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
+             (MI RegPred:$Rs, u5_0ImmPred_timm:$u5)>;
+  }
 }
 
 defm : FloatClass<int_hexagon_F2_sfclass, F2_sfclass, F32>;

>From 566e10e7dfadc3a897a772fd1e94dbde457d7638 Mon Sep 17 00:00:00 2001
From: Sumanth Gundapaneni <sgundapa at qti.qualcomm.com>
Date: Thu, 30 Oct 2025 08:59:02 -0700
Subject: [PATCH 3/3] Fixed indentation

---
 llvm/lib/Target/Hexagon/HexagonPatterns.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 0c8c80a37e50d..e40dbd251b5b7 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -3438,7 +3438,7 @@ multiclass FloatClass<SDPatternOperator IntOp, InstHexagon MI,
                       PatFrag RegPred> {
   let AddedComplexity = 100 in {
     def: Pat<(i1 (seteq (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
-              (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;
+             (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;
     def: Pat<(i1 (setne (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),
              (MI RegPred:$Rs, u5_0ImmPred_timm:$u5)>;
   }



More information about the llvm-commits mailing list