[llvm] InstCombine: Add baseline test for fcmp-0-select combine (PR #172380)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 15 15:46:10 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
This is similar to the identity value case; if we know we are
going to be multiplying by 0 and will get the sign right,
we can pull the constant into the select.
---
Patch is 28.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172380.diff
1 Files Affected:
- (added) llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll (+601)
``````````diff
diff --git a/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll b/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll
new file mode 100644
index 0000000000000..660d2a0c0784e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll
@@ -0,0 +1,601 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -p=instcombine < %s | FileCheck %s
+
+define float @select_oeq_fmul_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_oeq_fmul_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @select_oeq_fmul_fabs_or_fabs_src_cmp_neg0(float %x) {
+; CHECK-LABEL: define float @select_oeq_fmul_fabs_or_fabs_src_cmp_neg0(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, -0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @select_oeq_fdiv_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_oeq_fdiv_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x3E70000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fdiv float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @select_oeq_fmul_fneg_or_fneg_src(float %x) {
+; CHECK-LABEL: define float @select_oeq_fmul_fneg_or_fneg_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FNEG_X:%.*]] = fneg float [[X]]
+; CHECK-NEXT: [[MUL_FNEG_X:%.*]] = fmul float [[X]], 0xC170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FNEG_X]], float [[FNEG_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fneg.x = fneg float %x
+ %mul.fneg.x = fmul float %fneg.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fneg.x, float %fneg.x
+ ret float %select
+}
+
+define float @select_oeq_fmul_fneg_fabs_or_fneg_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_oeq_fmul_fneg_fabs_or_fneg_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[FNEG_FABS_X:%.*]] = fneg float [[FABS_X]]
+; CHECK-NEXT: [[MUL_FNEG_FABS_X:%.*]] = fmul float [[FABS_X]], 0xC170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FNEG_FABS_X]], float [[FNEG_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %fneg.fabs.x = fneg float %fabs.x
+ %mul.fneg.fabs.x = fmul float %fneg.fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fneg.fabs.x, float %fneg.fabs.x
+ ret float %select
+}
+
+; Negative test, wrong fdiv operand
+define float @select_oeq_fdiv_swapped_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_oeq_fdiv_swapped_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fdiv float 0x4170000000000000, [[FABS_X]]
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fdiv float 0x4170000000000000, %fabs.x
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+; Negative test, the fadd will not result in a 0
+define float @select_fadd_fabs_or_fabs_tgt(float %x) {
+; CHECK-LABEL: define float @select_fadd_fabs_or_fabs_tgt(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float 0.000000e+00, float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fadd float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float 0.0, float %fabs.x
+ ret float %select
+}
+
+define float @select_fadd0_fabs_or_fabs_tgt(float %x) {
+; CHECK-LABEL: define float @select_fadd0_fabs_or_fabs_tgt(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float 0.000000e+00, float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fadd float %fabs.x, 0.0
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float 0.0, float %fabs.x
+ ret float %select
+}
+
+; Negative test, select operands swapped
+define float @select_oeq_fmul_fabs_or_fabs_src_wrong_order(float %x) {
+; CHECK-LABEL: define float @select_oeq_fmul_fabs_or_fabs_src_wrong_order(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; Negative test, not equality compare
+define float @select_olt_fmul_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_olt_fmul_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp olt float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp olt float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+; Negative test, missing fabs on RHS
+define float @select_fmul_fabs_or_src(float %x) {
+; CHECK-LABEL: define float @select_fmul_fabs_or_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %x
+ ret float %select
+}
+
+; Negative test, missing fabs on fmul
+define float @select_fmul_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_fmul_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @fmul_fabs_neg_constant(float %x) {
+; CHECK-LABEL: define float @fmul_fabs_neg_constant(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], -4.000000e+00
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, -4.0
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @select_fmul_nsz_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_fmul_nsz_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_X:%.*]] = fmul nsz float [[X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.x = fmul nsz float %x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.x, float %fabs.x
+ ret float %select
+}
+
+define float @fmul_nsz_neg_constant(float %x) {
+; CHECK-LABEL: define float @fmul_nsz_neg_constant(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[X]], -4.000000e+00
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %x, -4.0
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @select_ueq_fmul_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_ueq_fmul_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp ueq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.zero = fcmp ueq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+; Unsafe with signaling nans.
+define float @select_one_fmul_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_one_fmul_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp one float %x, 0.0
+ %select = select i1 %x.is.not.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; OK with une and swapped arguments.
+define float @select_une_fmul_fabs_or_fabs_src(float %x) {
+; CHECK-LABEL: define float @select_une_fmul_fabs_or_fabs_src(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp une float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp une float %x, 0.0
+ %select = select i1 %x.is.not.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; No fabs needed with NSZ on fmul
+define float @select_fmul_nsz(float %x) {
+; CHECK-LABEL: define float @select_fmul_nsz(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: ret float [[X]]
+;
+ %mul.x = fmul nsz float %x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.x, float %x
+ ret float %select
+}
+
+; No fabs needed with NSZ on select
+define float @select_nsz(float %x) {
+; CHECK-LABEL: define float @select_nsz(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: ret float [[X]]
+;
+ %mul.x = fmul float %x, 0x4170000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select nsz i1 %x.is.zero, float %mul.x, float %x
+ ret float %select
+}
+
+define float @degenerate_fmul_nan(float %x) {
+; CHECK-LABEL: define float @degenerate_fmul_nan(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float 0x7FF8000000000000, float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x7FF8000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @degenerate_fmul_posinf(float %x) {
+; CHECK-LABEL: define float @degenerate_fmul_posinf(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x7FF0000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x7FF0000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+define float @degenerate_fmul_neginf(float %x) {
+; CHECK-LABEL: define float @degenerate_fmul_neginf(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0xFFF0000000000000
+; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X]], float [[FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0xFFF0000000000000
+ %x.is.zero = fcmp oeq float %x, 0.0
+ %select = select i1 %x.is.zero, float %mul.fabs.x, float %fabs.x
+ ret float %select
+}
+
+; nnan required on any operation, quieting required.
+define float @cmp_one_nnan_fabs(float %x) {
+; CHECK-LABEL: define float @cmp_one_nnan_fabs(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call nnan float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call nnan float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp one float %x, 0.0
+ %select = select i1 %x.is.not.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; nnan required on any operation, quieting required.
+define float @cmp_one_nnan_fmul(float %x) {
+; CHECK-LABEL: define float @cmp_one_nnan_fmul(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul nnan float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul nnan float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp one float %x, 0.0
+ %select = select i1 %x.is.not.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; nnan required on any operation, quieting required.
+define float @cmp_one_nnan_fcmp(float %x) {
+; CHECK-LABEL: define float @cmp_one_nnan_fcmp(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp nnan one float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp nnan one float %x, 0.0
+ %select = select i1 %x.is.not.zero, float %fabs.x, float %mul.fabs.x
+ ret float %select
+}
+
+; nnan required on any operation, quieting required.
+define float @cmp_one_nnan_select(float %x) {
+; CHECK-LABEL: define float @cmp_one_nnan_select(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], 0x4170000000000000
+; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X]], 0.000000e+00
+; CHECK-NEXT: [[SELECT:%.*]] = select nnan i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float [[MUL_FABS_X]]
+; CHECK-NEXT: ret float [[SELECT]]
+;
+ %fabs.x = call float @llvm.fabs.f32(float %x)
+ %mul.fabs.x = fmul float %fabs.x, 0x4170000000000000
+ %x.is.not.zero = fcmp one float %x, 0.0
+ %select = select nnan i1 %x.is.not.zero, float %fabs.x, float %...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/172380
More information about the llvm-commits
mailing list