[llvm] InstCombine: Baseline tests for SimplifyDemandedFPClass phi support (PR #184123)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 2 05:55:39 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>



---

Patch is 24.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/184123.diff


1 Files Affected:

- (added) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-phi.ll (+661) 


``````````diff
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-phi.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-phi.ll
new file mode 100644
index 0000000000000..a064d8b65a457
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-phi.ll
@@ -0,0 +1,661 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+declare nofpclass(inf norm sub zero) float @nan_only()
+
+define nofpclass(nan) half @ret_phi_if_ret_0(i1 %cond1, i1 %cond2, half %unknown) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_phi_if_ret_0(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND1]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT]], %[[IF]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br i1 %cond1, label %if, label %ret
+
+if:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %select, %if ], [ 0.0, %entry ]
+  ret half %phi
+}
+
+define nofpclass(nan inf norm sub nzero) half @ret_phi_only_pzero(i1 %cond1, i1 %cond2, half %unknown) {
+; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) half @ret_phi_only_pzero(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br i1 [[COND1]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half 0xH0000
+;
+entry:
+  br i1 %cond1, label %if, label %ret
+
+if:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %select, %if ], [ 0.0, %entry ]
+  ret half %phi
+}
+
+define nofpclass(inf norm sub zero) half @ret_phi_only_nan(i1 %cond1, i1 %cond2, half %unknown) {
+; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_phi_only_nan(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND1]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT]], %[[IF]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br i1 %cond1, label %if, label %ret
+
+if:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %select, %if ], [ 0.0, %entry ]
+  ret half %phi
+}
+
+define nofpclass(nan) half @ret_phi_if_ret_1(i1 %cond1, i1 %cond2, half %unknown) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_phi_if_ret_1(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND1]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ 0xH0000, %[[ENTRY]] ], [ [[SELECT]], %[[IF]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br i1 %cond1, label %if, label %ret
+
+if:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ 0.0, %entry ], [ %select, %if ]
+  ret half %phi
+}
+
+; Make sure all block references use the same simplified value.
+define nofpclass(nan) half @ret_repeated_switch_pred(i8 %switch.cond, i1 %cond2, half %unknown) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_repeated_switch_pred(
+; CHECK-SAME: i8 [[SWITCH_COND:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    switch i8 [[SWITCH_COND]], label %[[DEFAULT:.*]] [
+; CHECK-NEXT:      i8 0, label %[[RET:.*]]
+; CHECK-NEXT:      i8 1, label %[[RET]]
+; CHECK-NEXT:      i8 2, label %[[IF:.*]]
+; CHECK-NEXT:    ]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[DEFAULT]]:
+; CHECK-NEXT:    unreachable
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ 0xH0000, %[[IF]] ], [ [[SELECT]], %[[ENTRY]] ], [ [[SELECT]], %[[ENTRY]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  switch i8 %switch.cond, label %default
+  [ i8 0, label %ret
+  i8 1, label %ret
+  i8 2, label %if
+  ]
+
+if:
+  br label %ret
+
+default:
+  unreachable
+
+ret:
+  %phi = phi half [ 0.0, %if ], [ %select, %entry ], [ %select, %entry ]
+  ret half %phi
+}
+
+
+define nofpclass(nan) half @ret_phi_chain(i1 %cond1, i1 %cond2, i1 %cond3, half %unknown) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_phi_chain(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], i1 [[COND3:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND1]], label %[[IF0:.*]], label %[[IF1:.*]]
+; CHECK:       [[IF0]]:
+; CHECK-NEXT:    [[SELECT0:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    br i1 [[COND2]], label %[[IF1]], label %[[RET:.*]]
+; CHECK:       [[IF1]]:
+; CHECK-NEXT:    [[PHI0:%.*]] = phi half [ [[SELECT0]], %[[IF0]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI1:%.*]] = phi half [ [[PHI0]], %[[IF1]] ], [ 0xH0000, %[[IF0]] ]
+; CHECK-NEXT:    ret half [[PHI1]]
+;
+entry:
+  br i1 %cond1, label %if0, label %if1
+
+if0:
+  %select0 = select i1 %cond2, half 0xH7E00, half %unknown
+  br i1 %cond2, label %if1, label %ret
+
+if1:
+  %phi0 = phi half [ %select0, %if0 ], [ 0.0, %entry ]
+  br label %ret
+
+ret:
+  %phi1 = phi half [ %phi0, %if1 ], [ 0.0, %if0 ]
+  ret half %phi1
+}
+
+
+define nofpclass(nan) half @basic_loop_break_entry_block(i1 %cond1, i1 %cond2, half %unknown, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @basic_loop_break_entry_block(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[LOAD:%.*]], %[[LOOP]] ], [ [[SELECT]], %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD]] = load half, ptr [[P1]], align 2
+; CHECK-NEXT:    [[BREAK_COND:%.*]] = load i1, ptr [[P0]], align 1
+; CHECK-NEXT:    br i1 [[BREAK_COND]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %select = select i1 %cond2, half 0xH7E00, half %unknown
+  br label %loop
+
+loop:
+  %phi = phi half [ %load, %loop ], [ %select, %entry ]
+  %load = load half, ptr %p1
+  %break.cond = load i1, ptr %p0
+  br i1 %break.cond, label %ret, label %loop
+
+ret:
+  ret half %phi
+}
+
+define nofpclass(nan) half @basic_loop_break_mid_loop(i1 %cond1, i1 %cond2, half %unknown, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @basic_loop_break_mid_loop(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], half [[UNKNOWN:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT:%.*]], %[[LOOP]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD:%.*]] = load half, ptr [[P1]], align 2
+; CHECK-NEXT:    [[SELECT]] = select i1 [[COND2]], half 0xH7E00, half [[LOAD]]
+; CHECK-NEXT:    [[BREAK_COND:%.*]] = load i1, ptr [[P0]], align 1
+; CHECK-NEXT:    br i1 [[BREAK_COND]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %select, %loop ], [ 0.0, %entry ]
+  %load = load half, ptr %p1
+  %select = select i1 %cond2, half 0xH7E00, half %load
+  %break.cond = load i1, ptr %p0
+  br i1 %break.cond, label %ret, label %loop
+
+ret:
+  ret half %phi
+}
+
+define nofpclass(inf) half @recurrence(i1 %select.cond, half %unknown, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(inf) half @recurrence(
+; CHECK-SAME: i1 [[SELECT_COND:%.*]], half [[UNKNOWN:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT:%.*]], %[[LOOP]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD:%.*]] = load half, ptr [[P1]], align 2
+; CHECK-NEXT:    [[SELECT]] = select i1 [[SELECT_COND]], half 0xH7C00, half [[LOAD]]
+; CHECK-NEXT:    [[BREAK_COND:%.*]] = load i1, ptr [[P0]], align 1
+; CHECK-NEXT:    br i1 [[BREAK_COND]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %select, %loop ], [ 0.0, %entry ]
+  %load = load half, ptr %p1
+  %select = select i1 %select.cond, half 0xH7C00, half %load
+  %break.cond = load i1, ptr %p0
+  br i1 %break.cond, label %ret, label %loop
+
+ret:
+  ret half %phi
+}
+
+define nofpclass(nan) half @path_dependent(i1 %select.cond, half %unknown, half %x) {
+; CHECK-LABEL: define nofpclass(nan) half @path_dependent(
+; CHECK-SAME: i1 [[SELECT_COND:%.*]], half [[UNKNOWN:%.*]], half [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[X]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NAN]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[SELECT_COND]], half [[X]], half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT]], %[[IF]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %is.nan = fcmp uno half %x, 0.0
+  br i1 %is.nan, label %if, label %ret
+
+if:
+  %select = select i1 %select.cond, half %x, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %select, %if ], [ 0.0, %entry ]
+  ret half %phi
+}
+
+define nofpclass(nan) half @path_dependent_wrong(i1 %select.cond, half %unknown, half %x) {
+; CHECK-LABEL: define nofpclass(nan) half @path_dependent_wrong(
+; CHECK-SAME: i1 [[SELECT_COND:%.*]], half [[UNKNOWN:%.*]], half [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[IS_NOT_NAN:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NOT_NAN]], label %[[IF:.*]], label %[[RET:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[SELECT_COND]], half [[X]], half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT]], %[[IF]] ], [ 0xH0000, %[[ENTRY]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %is.not.nan = fcmp ord half %x, 0.0
+  br i1 %is.not.nan, label %if, label %ret
+
+if:
+  %select = select i1 %select.cond, half %x, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %select, %if ], [ 0.0, %entry ]
+  ret half %phi
+}
+
+
+define nofpclass(nan) half @diamond_same_select(i1 %select.cond, half %unknown, half %x) {
+; CHECK-LABEL: define nofpclass(nan) half @diamond_same_select(
+; CHECK-SAME: i1 [[SELECT_COND:%.*]], half [[UNKNOWN:%.*]], half [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[X]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NAN]], label %[[IF:.*]], label %[[ELSE:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    [[SELECT0:%.*]] = select i1 [[SELECT_COND]], half [[X]], half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[ENDIF:.*]]
+; CHECK:       [[ELSE]]:
+; CHECK-NEXT:    [[SELECT1:%.*]] = select i1 [[SELECT_COND]], half [[X]], half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[ENDIF]]
+; CHECK:       [[ENDIF]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[SELECT0]], %[[IF]] ], [ [[SELECT1]], %[[ELSE]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %is.nan = fcmp uno half %x, 0.0
+  br i1 %is.nan, label %if, label %else
+
+if:
+  %select0 = select i1 %select.cond, half %x, half %unknown
+  br label %endif
+
+else:
+  %select1 = select i1 %select.cond, half %x, half %unknown
+  br label %endif
+
+endif:
+  %phi = phi half [ %select0, %if ], [ %select1, %else ]
+  ret half %phi
+}
+
+define nofpclass(nan) half @remove_nan_start_value(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @remove_nan_start_value(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[LOAD:%.*]], %[[LOOP]] ], [ 0xH7E00, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD]] = load half, ptr [[P1]], align 2
+; CHECK-NEXT:    [[BREAK_COND:%.*]] = load i1, ptr [[P0]], align 1
+; CHECK-NEXT:    br i1 [[BREAK_COND]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %load, %loop ], [ 0xH7E00, %entry ]
+  %load = load half, ptr %p1
+  %break.cond = load i1, ptr %p0
+  br i1 %break.cond, label %ret, label %loop
+
+ret:
+  ret half %phi
+}
+
+define nofpclass(nan) half @keep_nan_start_value_multi_use(i1 %cond1, i1 %cond2, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @keep_nan_start_value_multi_use(
+; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[LOAD:%.*]], %[[LOOP]] ], [ 0xH7E00, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD]] = load half, ptr [[P1]], align 2
+; CHECK-NEXT:    [[BREAK_COND:%.*]] = load i1, ptr [[P0]], align 1
+; CHECK-NEXT:    br i1 [[BREAK_COND]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    store half [[PHI]], ptr [[P0]], align 2
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %load, %loop ], [ 0xH7E00, %entry ]
+  %load = load half, ptr %p1
+  %break.cond = load i1, ptr %p0
+  br i1 %break.cond, label %ret, label %loop
+
+ret:
+  store half %phi, ptr %p0
+  ret half %phi
+}
+
+; TODO: Why doesn't this fold to ret poison?
+define nofpclass(nan) half @loop_break_if_nan(ptr %p0) {
+; CHECK-LABEL: define nofpclass(nan) half @loop_break_if_nan(
+; CHECK-SAME: ptr [[P0:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[LOAD:%.*]], %[[LOOP]] ], [ 0xH7E00, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOAD]] = load half, ptr [[P0]], align 2
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[LOAD]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NAN]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %load, %loop ], [ 0xH7E00, %entry ]
+  %load = load half, ptr %p0
+  %is.nan = fcmp uno half %load, 0.0
+  br i1 %is.nan, label %ret, label %loop
+
+ret:
+  ret half %phi
+}
+
+define nofpclass(nan) half @loop_break_if_nan_abs(ptr %p0) {
+; CHECK-LABEL: define nofpclass(nan) half @loop_break_if_nan_abs(
+; CHECK-SAME: ptr [[P0:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[LOAD:%.*]] = load half, ptr [[P0]], align 2
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[LOAD]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NAN]], label %[[RET:.*]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    ret half poison
+;
+entry:
+  br label %loop
+
+loop:
+  %phi = phi half [ %load, %loop ], [ 0xH7E00, %entry ]
+  %load = load half, ptr %p0
+  %abs = call half @llvm.fabs.f16(half %load)
+  %is.nan = fcmp uno half %load, 0.0
+  br i1 %is.nan, label %ret, label %loop
+
+ret:
+  ret half %abs
+}
+
+define nofpclass(nan) half @ret_loop_under_if_phi(half %unknown, i1 %cond, i1 %cond2, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_loop_under_if_phi(
+; CHECK-SAME: half [[UNKNOWN:%.*]], i1 [[COND:%.*]], i1 [[COND2:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND]], label %[[LOOP:.*]], label %[[RET:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[LOOP_PHI:%.*]] = phi half [ [[LOOP_SELECT:%.*]], %[[LOOP]] ], [ 0xH7E00, %[[ENTRY]] ]
+; CHECK-NEXT:    [[LOOP_SELECT]] = select i1 [[COND2]], half 0xH7E00, half [[UNKNOWN]]
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = load i1, ptr [[P1]], align 1
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[RET]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[OUTER_PHI:%.*]] = phi half [ 0xH7E00, %[[ENTRY]] ], [ [[LOOP_PHI]], %[[LOOP]] ]
+; CHECK-NEXT:    ret half [[OUTER_PHI]]
+;
+entry:
+  %entry.select = select i1 %cond2, half 0xH7E00, half %unknown
+  br i1 %cond, label %loop, label %ret
+
+loop:
+  %loop.phi = phi half [ %loop.select, %loop ], [ 0xH7E00, %entry ]
+  %loop.select = select i1 %cond2, half 0xH7E00, half %unknown
+  %loop.cond = load i1, ptr %p1
+  br i1 %loop.cond, label %ret, label %loop
+
+ret:
+  %outer.phi = phi half [ 0xH7E00, %entry ], [ %loop.phi, %loop ]
+  ret half %outer.phi
+}
+
+
+define nofpclass(nan) half @assume_in_loop(half %assumed.nan.in.loop, half %unknown, i1 %cond, i1 %cond2, ptr %p0, ptr %p1) {
+; CHECK-LABEL: define nofpclass(nan) half @assume_in_loop(
+; CHECK-SAME: half [[ASSUMED_NAN_IN_LOOP:%.*]], half [[UNKNOWN:%.*]], i1 [[COND:%.*]], i1 [[COND2:%.*]], ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[COND]], label %[[LOOP:.*]], label %[[RET:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[LOOP_PHI:%.*]] = phi half [ [[LOOP_SELECT:%.*]], %[[LOOP]] ], [ [[ASSUMED_NAN_IN_LOOP]], %[[ENTRY]] ]
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[ASSUMED_NAN_IN_LOOP]], 0xH0000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_NAN]])
+; CHECK-NEXT:    [[LOOP_SELECT]] = select i1 [[COND2]], half [[ASSUMED_NAN_IN_LOOP]], half [[UNKNOWN]]
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = load i1, ptr [[P1]], align 1
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[RET]], label %[[LOOP]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[OUTER_PHI:%.*]] = phi half [ [[ASSUMED_NAN_IN_LOOP]], %[[ENTRY]] ], [ [[LOOP_PHI]], %[[LOOP]] ]
+; CHECK-NEXT:    ret half [[OUTER_PHI]]
+;
+entry:
+  br i1 %cond, label %loop, label %ret
+
+loop:
+  %loop.phi = phi half [ %loop.select, %loop ], [ %assumed.nan.in.loop, %entry ]
+  %is.nan = fcmp uno half %assumed.nan.in.loop, 0.0
+  call void @llvm.assume(i1 %is.nan)
+  %loop.select = select i1 %cond2, half %assumed.nan.in.loop, half %unknown
+  %loop.cond = load i1, ptr %p1
+  br i1 %loop.cond, label %ret, label %loop
+
+ret:
+  %outer.phi = phi half [ %assumed.nan.in.loop, %entry ], [ %loop.phi, %loop ]
+  ret half %outer.phi
+}
+
+
+define nofpclass(nan) half @ret_phi_nan_check(half %checked.if.nan, half %unknown, i1 %cond) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_phi_nan_check(
+; CHECK-SAME: half [[CHECKED_IF_NAN:%.*]], half [[UNKNOWN:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno half [[CHECKED_IF_NAN]], 0xH0000
+; CHECK-NEXT:    br i1 [[IS_NAN]], label %[[IF_NAN:.*]], label %[[RET:.*]]
+; CHECK:       [[IF_NAN]]:
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[CHECKED_IF_NAN]], half [[UNKNOWN]]
+; CHECK-NEXT:    br label %[[RET]]
+; CHECK:       [[RET]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi half [ [[CHECKED_IF_NAN]], %[[ENTRY]] ], [ [[SELECT]], %[[IF_NAN]] ]
+; CHECK-NEXT:    ret half [[PHI]]
+;
+entry:
+  %is.nan = fcmp uno half %checked.if.nan, 0.0
+  br i1 %is.nan, label %if_nan, label %ret
+
+if_nan:
+  %select = select i1 %cond, half %checked.if.nan, half %unknown
+  br label %ret
+
+ret:
+  %phi = phi half [ %checked.if.nan, %entry ], [ %select, %if_nan ]
+  ret half %phi
+}
+
+define nofpclass(nan inf) half @edge_case_if_chain(half %x, i1 %cond, ptr %p0, ptr %p1, ptr %p2) {
+; CHECK-LABEL: define nofpclass(nan inf) half @edge_case_if_chain(...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list