[llvm] [GISel] Use GISelValueTracking in isKnownNeverNaN (PR #190542)

Tim Gymnich via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 04:54:16 PDT 2026


================
@@ -0,0 +1,159 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -run-pass=legalizer %s -o - | FileCheck %s
+
+# Tests for G_PHI handling in GISelValueTracking::computeKnownFPClass.
+#
+# When all incoming values of a G_PHI are known to have certain FP classes,
+# the intersection of their known classes is propagated through the PHI.
+# This allows the legalizer to skip NaN fixup code in G_FMINIMUM/G_FMAXIMUM.
+#
+# Structure:
+#   bb.0 (entry):  defines entry constants, jumps to bb.1
+#   bb.1 (header): G_PHI of non-NaN constants, conditional branch to bb.2 or bb.3
+#   bb.2 (body):   defines back-edge constants, jumps back to bb.1
+#   bb.3 (exit):   uses PHI value in G_FMINIMUM
+
+---
+# Both operands of G_FMINIMUM are PHIs whose all incoming values are non-NaN
+# constants (1.0/2.0 and 3.0/4.0).  The legalizer should fully skip the NaN
+# fixup: no G_FCMP ord + G_SELECT, just G_FMINNUM_IEEE.
+name: test_fminimum_phi_both_nnan
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: test_fminimum_phi_both_nnan
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $sgpr0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $sgpr0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 3.000000e+00
+  ; CHECK-NEXT:   G_BR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1 (machine-block-address-taken):
+  ; CHECK-NEXT:   successors: %bb.2(0x40000000), %bb.3(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[C]](s32), %bb.0, %4(s32), %bb.2
+  ; CHECK-NEXT:   [[PHI1:%[0-9]+]]:_(s32) = G_PHI [[C1]](s32), %bb.0, %6(s32), %bb.2
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
+  ; CHECK-NEXT:   G_BRCOND [[TRUNC]](s1), %bb.3
+  ; CHECK-NEXT:   G_BR %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+  ; CHECK-NEXT:   [[C3:%[0-9]+]]:_(s32) = G_FCONSTANT float 4.000000e+00
+  ; CHECK-NEXT:   G_BR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   [[FMINNUM_IEEE:%[0-9]+]]:_(s32) = G_FMINNUM_IEEE [[PHI]], [[PHI1]]
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY [[FMINNUM_IEEE]](s32)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[COPY1]](s32)
+  ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
+
+  bb.0:
+    liveins: $sgpr0
+    successors: %bb.1(0x80000000)
+
+    %0:_(s32) = COPY $sgpr0
+    %1:_(s32) = G_FCONSTANT float 1.000000e+00
+    %2:_(s32) = G_FCONSTANT float 3.000000e+00
+    G_BR %bb.1
+
+  bb.1 (machine-block-address-taken):
+    ; liveins: %0, %1, %2 -- virtual reg liveins not expressible as $phys, use undef
+    successors: %bb.2(0x40000000), %bb.3(0x40000000)
+
+    ; PHI merges two non-NaN constants: 1.0/2.0 and 3.0/4.0
+    %5:_(s32) = G_PHI %1(s32), %bb.0, %3(s32), %bb.2
+    %6:_(s32) = G_PHI %2(s32), %bb.0, %4(s32), %bb.2
+    %7:_(s1) = G_TRUNC %0(s32)
+    G_BRCOND %7(s1), %bb.3
+    G_BR %bb.2
+
+  bb.2:
+    successors: %bb.1(0x80000000)
+
+    %3:_(s32) = G_FCONSTANT float 2.000000e+00
+    %4:_(s32) = G_FCONSTANT float 4.000000e+00
+    G_BR %bb.1
+
+  bb.3:
+    ; G_FMINIMUM of two PHIs both known non-NaN.
+    ; NaN fixup entirely skipped: no G_FCMP ord + G_SELECT, just G_FMINNUM_IEEE.
+    %8:_(s32) = G_FMINIMUM %5, %6
+    $vgpr0 = COPY %8(s32)
+    SI_RETURN implicit $vgpr0
+...
+
+---
+# One operand of G_FMINIMUM is a PHI whose incoming values are all non-NaN
+# constants; the other is an unknown COPY (potentially NaN).
+# The NaN fixup IS emitted because the COPY may be NaN.
+name: test_fminimum_phi_one_nnan
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: test_fminimum_phi_one_nnan
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $sgpr0, $vgpr0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $sgpr0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+  ; CHECK-NEXT:   G_BR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1 (machine-block-address-taken):
+  ; CHECK-NEXT:   successors: %bb.2(0x40000000), %bb.3(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[C]](s32), %bb.0, %4(s32), %bb.2
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
+  ; CHECK-NEXT:   G_BRCOND [[TRUNC]](s1), %bb.3
+  ; CHECK-NEXT:   G_BR %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+  ; CHECK-NEXT:   G_BR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   [[FMINNUM_IEEE:%[0-9]+]]:_(s32) = G_FMINNUM_IEEE [[PHI]], [[COPY1]]
+  ; CHECK-NEXT:   [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(ord), [[PHI]](s32), [[COPY1]]
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+  ; CHECK-NEXT:   [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[FCMP]](s1), [[FMINNUM_IEEE]], [[C2]]
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY [[SELECT]](s32)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[COPY2]](s32)
+  ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
+
+  bb.0:
+    liveins: $sgpr0, $vgpr0
+    successors: %bb.1(0x80000000)
+
+    %0:_(s32) = COPY $sgpr0
+    %9:_(s32) = COPY $vgpr0
+    %1:_(s32) = G_FCONSTANT float 1.000000e+00
+    G_BR %bb.1
+
+  bb.1 (machine-block-address-taken):
----------------
tgymnich wrote:

removed

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


More information about the llvm-commits mailing list