[llvm] [ARM] Refine shouldConvertFpToSat to not check for !FPVT.isSimple() (PR #194499)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 07:10:26 PDT 2026


https://github.com/LumioseSil updated https://github.com/llvm/llvm-project/pull/194499

>From 51afb1701d4fb00b8b46bc0a1f969c666899a30a Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 27 Apr 2026 20:10:43 -0400
Subject: [PATCH] [ARM] Refine shouldConvertFpToSat to not check for
 !FPVT.isSimple()

This hinders optimizations on Thumb2.
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  29 ++--
 .../CodeGen/Thumb2/mve-fpclamptosat_vec.ll    | 124 ++++--------------
 2 files changed, 42 insertions(+), 111 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index cbff40f697b9b..f254141c67fff 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -13791,22 +13791,25 @@ bool ARMTargetLowering::preferIncOfAddToSubOfNot(EVT VT) const {
 
 bool ARMTargetLowering::shouldConvertFpToSat(unsigned Op, EVT FPVT,
                                              EVT VT) const {
-  if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
+  if (FPVT == MVT::f16 && !Subtarget->hasFullFP16())
     return false;
 
-  switch (FPVT.getSimpleVT().SimpleTy) {
-  case MVT::f16:
-    return Subtarget->hasVFP2Base();
-  case MVT::f32:
-    return Subtarget->hasVFP2Base();
-  case MVT::f64:
-    return Subtarget->hasFP64();
-  case MVT::v4f32:
-  case MVT::v8f16:
-    return Subtarget->hasMVEFloatOps();
-  default:
+  if (FPVT == MVT::f32 && !Subtarget->hasVFP2Base())
     return false;
-  }
+
+  if (FPVT == MVT::f64 && !Subtarget->hasFP64())
+    return false;
+
+  if (FPVT == MVT::v4f32 && !Subtarget->hasMVEFloatOps())
+    return false;
+
+  if (FPVT == MVT::v4f16 && !Subtarget->hasFullFP16())
+    return false;
+
+  if (FPVT == MVT::v8f16 && !Subtarget->hasMVEFloatOps())
+    return false;
+
+  return TargetLowering::shouldConvertFpToSat(Op, FPVT, VT);
 }
 
 static SDValue PerformSHLSimplify(SDNode *N,
diff --git a/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll b/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
index 0134ee48ad421..a3762980921b1 100644
--- a/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
@@ -275,55 +275,19 @@ entry:
 define arm_aapcs_vfpcc <4 x i32> @ustest_f16i32(<4 x half> %x) {
 ; CHECK-LABEL: ustest_f16i32:
 ; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    .save {r4, r5, r6, lr}
-; CHECK-NEXT:    push {r4, r5, r6, lr}
-; CHECK-NEXT:    .vsave {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    vpush {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    vmov.u16 r0, q0[2]
-; CHECK-NEXT:    vmov q4, q0
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    mov r4, r0
-; CHECK-NEXT:    vmov.u16 r0, q4[3]
-; CHECK-NEXT:    mov r5, r1
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    rsbs r2, r4, #0
-; CHECK-NEXT:    mov.w r6, #0
-; CHECK-NEXT:    sbcs.w r2, r6, r5
-; CHECK-NEXT:    vmov q0[2], q0[0], r4, r0
-; CHECK-NEXT:    csetm r2, lt
-; CHECK-NEXT:    rsbs r0, r0, #0
-; CHECK-NEXT:    mov.w r3, #0
-; CHECK-NEXT:    sbcs.w r0, r6, r1
-; CHECK-NEXT:    bfi r3, r2, #0, #8
-; CHECK-NEXT:    csetm r0, lt
-; CHECK-NEXT:    bfi r3, r0, #8, #8
-; CHECK-NEXT:    vmov.u16 r0, q4[0]
-; CHECK-NEXT:    vmov.i32 q5, #0x0
-; CHECK-NEXT:    vmov q0[3], q0[1], r5, r1
-; CHECK-NEXT:    vmsr p0, r3
-; CHECK-NEXT:    vpsel q6, q0, q5
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    mov r4, r0
-; CHECK-NEXT:    vmov.u16 r0, q4[1]
-; CHECK-NEXT:    mov r5, r1
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    rsbs r2, r4, #0
-; CHECK-NEXT:    vmov q0[2], q0[0], r4, r0
-; CHECK-NEXT:    sbcs.w r2, r6, r5
-; CHECK-NEXT:    vmov q0[3], q0[1], r5, r1
-; CHECK-NEXT:    csetm r2, lt
-; CHECK-NEXT:    rsbs r0, r0, #0
-; CHECK-NEXT:    sbcs.w r0, r6, r1
-; CHECK-NEXT:    bfi r6, r2, #0, #8
-; CHECK-NEXT:    csetm r0, lt
-; CHECK-NEXT:    bfi r6, r0, #8, #8
-; CHECK-NEXT:    vmsr p0, r6
-; CHECK-NEXT:    vpsel q0, q0, q5
-; CHECK-NEXT:    vmov.f32 s1, s2
-; CHECK-NEXT:    vmov.f32 s2, s24
-; CHECK-NEXT:    vmov.f32 s3, s26
-; CHECK-NEXT:    vpop {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    pop {r4, r5, r6, pc}
+; CHECK-NEXT:    vmovx.f16 s2, s1
+; CHECK-NEXT:    vcvt.u32.f16 s4, s2
+; CHECK-NEXT:    vmovx.f16 s2, s0
+; CHECK-NEXT:    vcvt.u32.f16 s6, s2
+; CHECK-NEXT:    vcvt.u32.f16 s2, s1
+; CHECK-NEXT:    vcvt.u32.f16 s0, s0
+; CHECK-NEXT:    vmov r0, s2
+; CHECK-NEXT:    vmov r1, s0
+; CHECK-NEXT:    vmov q0[2], q0[0], r1, r0
+; CHECK-NEXT:    vmov r0, s4
+; CHECK-NEXT:    vmov r1, s6
+; CHECK-NEXT:    vmov q0[3], q0[1], r1, r0
+; CHECK-NEXT:    bx lr
 entry:
   %conv = fptosi <4 x half> %x to <4 x i64>
   %0 = icmp slt <4 x i64> %conv, <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
@@ -1349,55 +1313,19 @@ entry:
 define arm_aapcs_vfpcc <4 x i32> @ustest_f16i32_mm(<4 x half> %x) {
 ; CHECK-LABEL: ustest_f16i32_mm:
 ; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    .save {r4, r5, r6, lr}
-; CHECK-NEXT:    push {r4, r5, r6, lr}
-; CHECK-NEXT:    .vsave {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    vpush {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    vmov.u16 r0, q0[2]
-; CHECK-NEXT:    vmov q4, q0
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    mov r4, r0
-; CHECK-NEXT:    vmov.u16 r0, q4[3]
-; CHECK-NEXT:    mov r5, r1
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    rsbs r2, r4, #0
-; CHECK-NEXT:    mov.w r6, #0
-; CHECK-NEXT:    sbcs.w r2, r6, r5
-; CHECK-NEXT:    vmov q0[2], q0[0], r4, r0
-; CHECK-NEXT:    csetm r2, lt
-; CHECK-NEXT:    rsbs r0, r0, #0
-; CHECK-NEXT:    mov.w r3, #0
-; CHECK-NEXT:    sbcs.w r0, r6, r1
-; CHECK-NEXT:    bfi r3, r2, #0, #8
-; CHECK-NEXT:    csetm r0, lt
-; CHECK-NEXT:    bfi r3, r0, #8, #8
-; CHECK-NEXT:    vmov.u16 r0, q4[0]
-; CHECK-NEXT:    vmov.i32 q5, #0x0
-; CHECK-NEXT:    vmov q0[3], q0[1], r5, r1
-; CHECK-NEXT:    vmsr p0, r3
-; CHECK-NEXT:    vpsel q6, q0, q5
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    mov r4, r0
-; CHECK-NEXT:    vmov.u16 r0, q4[1]
-; CHECK-NEXT:    mov r5, r1
-; CHECK-NEXT:    bl __fixhfdi
-; CHECK-NEXT:    rsbs r2, r4, #0
-; CHECK-NEXT:    vmov q0[2], q0[0], r4, r0
-; CHECK-NEXT:    sbcs.w r2, r6, r5
-; CHECK-NEXT:    vmov q0[3], q0[1], r5, r1
-; CHECK-NEXT:    csetm r2, lt
-; CHECK-NEXT:    rsbs r0, r0, #0
-; CHECK-NEXT:    sbcs.w r0, r6, r1
-; CHECK-NEXT:    bfi r6, r2, #0, #8
-; CHECK-NEXT:    csetm r0, lt
-; CHECK-NEXT:    bfi r6, r0, #8, #8
-; CHECK-NEXT:    vmsr p0, r6
-; CHECK-NEXT:    vpsel q0, q0, q5
-; CHECK-NEXT:    vmov.f32 s1, s2
-; CHECK-NEXT:    vmov.f32 s2, s24
-; CHECK-NEXT:    vmov.f32 s3, s26
-; CHECK-NEXT:    vpop {d8, d9, d10, d11, d12, d13}
-; CHECK-NEXT:    pop {r4, r5, r6, pc}
+; CHECK-NEXT:    vmovx.f16 s2, s1
+; CHECK-NEXT:    vcvt.u32.f16 s4, s2
+; CHECK-NEXT:    vmovx.f16 s2, s0
+; CHECK-NEXT:    vcvt.u32.f16 s6, s2
+; CHECK-NEXT:    vcvt.u32.f16 s2, s1
+; CHECK-NEXT:    vcvt.u32.f16 s0, s0
+; CHECK-NEXT:    vmov r0, s2
+; CHECK-NEXT:    vmov r1, s0
+; CHECK-NEXT:    vmov q0[2], q0[0], r1, r0
+; CHECK-NEXT:    vmov r0, s4
+; CHECK-NEXT:    vmov r1, s6
+; CHECK-NEXT:    vmov q0[3], q0[1], r1, r0
+; CHECK-NEXT:    bx lr
 entry:
   %conv = fptosi <4 x half> %x to <4 x i64>
   %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)



More information about the llvm-commits mailing list