[llvm] [ARM] Lower isnan(x) | isnan(never-nan) to x != x, and lower !isnan(x) & !isnan(never-nan) to x == x (PR #194932)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 29 11:59:27 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: LumioseSil (LumioseSil)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/194932.diff


2 Files Affected:

- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+19) 
- (modified) llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll (+12-20) 


``````````diff
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 71cc6cf8e1f82..22026f730c41d 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -6587,6 +6587,25 @@ static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG,
     return SDValue();
 
   if (Op1.getValueType().isFloatingPoint()) {
+
+    // Lower isnan(x) | isnan(never-nan) to x != x.
+    // Lower !isnan(x) & !isnan(never-nan) to x == x.
+    if (SetCCOpcode == ISD::SETUO || SetCCOpcode == ISD::SETO) {
+      bool OneNaN = false;
+      if (Op0 == Op1) {
+        OneNaN = true;
+      } else if (DAG.isKnownNeverNaN(Op1)) {
+        OneNaN = true;
+        Op1 = Op0;
+      } else if (DAG.isKnownNeverNaN(Op0)) {
+        OneNaN = true;
+        Op0 = Op1;
+      }
+      if (OneNaN) {
+        SetCCOpcode = SetCCOpcode == ISD::SETUO ? ISD::SETUNE : ISD::SETOEQ;
+      }
+    }
+
     switch (SetCCOpcode) {
     default: llvm_unreachable("Illegal FP comparison");
     case ISD::SETUNE:
diff --git a/llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll b/llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll
index de8b413bf24e5..84fadcbaeecbf 100644
--- a/llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll
@@ -463,9 +463,8 @@ define arm_aapcs_vfpcc <4 x float> @vcmp_ord_v4f32(<4 x float> %src, <4 x float>
 ;
 ; CHECK-MVEFP-LABEL: vcmp_ord_v4f32:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f32 ge, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f32 lt, q0, zr
-; CHECK-MVEFP-NEXT:    vpsel q0, q2, q1
+; CHECK-MVEFP-NEXT:    vcmp.f32 eq, q0, q0
+; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
   %c = fcmp ord <4 x float> %src, zeroinitializer
@@ -500,8 +499,7 @@ define arm_aapcs_vfpcc <4 x float> @vcmp_uno_v4f32(<4 x float> %src, <4 x float>
 ;
 ; CHECK-MVEFP-LABEL: vcmp_uno_v4f32:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f32 ge, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f32 lt, q0, zr
+; CHECK-MVEFP-NEXT:    vcmp.f32 ne, q0, q0
 ; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
@@ -1441,9 +1439,8 @@ define arm_aapcs_vfpcc <8 x half> @vcmp_ord_v8f16(<8 x half> %src, <8 x half> %a
 ;
 ; CHECK-MVEFP-LABEL: vcmp_ord_v8f16:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f16 ge, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f16 lt, q0, zr
-; CHECK-MVEFP-NEXT:    vpsel q0, q2, q1
+; CHECK-MVEFP-NEXT:    vcmp.f16 eq, q0, q0
+; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
   %c = fcmp ord <8 x half> %src, zeroinitializer
@@ -1514,8 +1511,7 @@ define arm_aapcs_vfpcc <8 x half> @vcmp_uno_v8f16(<8 x half> %src, <8 x half> %a
 ;
 ; CHECK-MVEFP-LABEL: vcmp_uno_v8f16:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f16 ge, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f16 lt, q0, zr
+; CHECK-MVEFP-NEXT:    vcmp.f16 ne, q0, q0
 ; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
@@ -1988,9 +1984,8 @@ define arm_aapcs_vfpcc <4 x float> @vcmp_r_ord_v4f32(<4 x float> %src, <4 x floa
 ;
 ; CHECK-MVEFP-LABEL: vcmp_r_ord_v4f32:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f32 le, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f32 gt, q0, zr
-; CHECK-MVEFP-NEXT:    vpsel q0, q2, q1
+; CHECK-MVEFP-NEXT:    vcmp.f32 eq, q0, q0
+; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
   %c = fcmp ord <4 x float> zeroinitializer, %src
@@ -2025,8 +2020,7 @@ define arm_aapcs_vfpcc <4 x float> @vcmp_r_uno_v4f32(<4 x float> %src, <4 x floa
 ;
 ; CHECK-MVEFP-LABEL: vcmp_r_uno_v4f32:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f32 le, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f32 gt, q0, zr
+; CHECK-MVEFP-NEXT:    vcmp.f32 ne, q0, q0
 ; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
@@ -2966,9 +2960,8 @@ define arm_aapcs_vfpcc <8 x half> @vcmp_r_ord_v8f16(<8 x half> %src, <8 x half>
 ;
 ; CHECK-MVEFP-LABEL: vcmp_r_ord_v8f16:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f16 le, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f16 gt, q0, zr
-; CHECK-MVEFP-NEXT:    vpsel q0, q2, q1
+; CHECK-MVEFP-NEXT:    vcmp.f16 eq, q0, q0
+; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:
   %c = fcmp ord <8 x half> zeroinitializer, %src
@@ -3039,8 +3032,7 @@ define arm_aapcs_vfpcc <8 x half> @vcmp_r_uno_v8f16(<8 x half> %src, <8 x half>
 ;
 ; CHECK-MVEFP-LABEL: vcmp_r_uno_v8f16:
 ; CHECK-MVEFP:       @ %bb.0: @ %entry
-; CHECK-MVEFP-NEXT:    vpt.f16 le, q0, zr
-; CHECK-MVEFP-NEXT:    vcmpt.f16 gt, q0, zr
+; CHECK-MVEFP-NEXT:    vcmp.f16 ne, q0, q0
 ; CHECK-MVEFP-NEXT:    vpsel q0, q1, q2
 ; CHECK-MVEFP-NEXT:    bx lr
 entry:

``````````

</details>


https://github.com/llvm/llvm-project/pull/194932


More information about the llvm-commits mailing list