blob: 48a01f73adac68a6b10e07aa3ee0ee5e06f981f9 [file] [edit]
; 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: [[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 = 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: [[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 = 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: [[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 = 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: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float 0.000000e+00, 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: [[X_IS_NOT_ZERO:%.*]] = fcmp une float [[X]], 0.000000e+00
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[FABS_X]], float 0.000000e+00
; 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 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 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 %mul.fabs.x
ret float %select
}
define <2 x float> @select_oeq_fmul_fabs_or_fabs_src_vector(<2 x float> %x) {
; CHECK-LABEL: define <2 x float> @select_oeq_fmul_fabs_or_fabs_src_vector(
; CHECK-SAME: <2 x float> [[X:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X]], zeroinitializer
; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> zeroinitializer, <2 x float> [[FABS_X]]
; CHECK-NEXT: ret <2 x float> [[SELECT]]
;
%fabs.x = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
%mul.fabs.x = fmul <2 x float> %fabs.x, <float 20.0, float 40.0>
%x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
%select = select <2 x i1> %x.is.zero, <2 x float> %mul.fabs.x, <2 x float> %fabs.x
ret <2 x float> %select
}
define <3 x float> @select_oeq_fmul_fabs_or_fabs_src_vector_mixed_sign_zero(<3 x float> %x) {
; CHECK-LABEL: define <3 x float> @select_oeq_fmul_fabs_or_fabs_src_vector_mixed_sign_zero(
; CHECK-SAME: <3 x float> [[X:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[X]])
; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <3 x float> [[X]], zeroinitializer
; CHECK-NEXT: [[SELECT:%.*]] = select <3 x i1> [[X_IS_ZERO]], <3 x float> zeroinitializer, <3 x float> [[FABS_X]]
; CHECK-NEXT: ret <3 x float> [[SELECT]]
;
%fabs.x = call <3 x float> @llvm.fabs.v3f32(<3 x float> %x)
%mul.fabs.x = fmul <3 x float> %fabs.x, splat (float 0x4170000000000000)
%x.is.zero = fcmp oeq <3 x float> %x, <float 0.0, float poison, float -0.0>
%select = select <3 x i1> %x.is.zero, <3 x float> %mul.fabs.x, <3 x float> %fabs.x
ret <3 x float> %select
}
; TODO: Should be able to handle this
define float @test_ldexp_fabs(float %x, i32 %n) {
; CHECK-LABEL: define float @test_ldexp_fabs(
; CHECK-SAME: float [[X:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[MUL_FABS_X:%.*]] = call float @llvm.ldexp.f32.i32(float [[FABS_X]], i32 [[N]])
; 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 = call float @llvm.ldexp.f32(float %fabs.x, i32 %n)
%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_nonconst_unknown_fabs_or_fabs_src(float %x, float %y) {
; CHECK-LABEL: define float @select_oeq_fmul_nonconst_unknown_fabs_or_fabs_src(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], [[Y]]
; 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, %y
%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_nonconst_ppos_fabs_or_fabs_src(float %x, float %y) {
; CHECK-LABEL: define float @select_oeq_fmul_nonconst_ppos_fabs_or_fabs_src(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X]], [[Y]]
; CHECK-NEXT: [[MUL_FABS_X1:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])
; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_FABS_X1]], float [[FABS_X]]
; CHECK-NEXT: ret float [[SELECT]]
;
%fabs.x = call float @llvm.fabs.f32(float %x)
%fabs.y = call float @llvm.fabs.f32(float %y)
%mul.fabs.x = fmul float %fabs.x, %fabs.y
%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_copysign_or_copysign_src(float %x, float %sign) {
; CHECK-LABEL: define float @select_oeq_fmul_copysign_or_copysign_src(
; CHECK-SAME: float [[X:%.*]], float [[SIGN:%.*]]) {
; CHECK-NEXT: [[SIGN_X:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[SIGN]])
; CHECK-NEXT: [[MUL_SIGN_X:%.*]] = fmul float [[SIGN_X]], 0x4170000000000000
; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_SIGN_X]], float [[SIGN_X]]
; CHECK-NEXT: ret float [[SELECT]]
;
%sign.x = call float @llvm.copysign.f32(float %x, float %sign)
%mul.sign.x = fmul float %sign.x, 0x4170000000000000
%x.is.zero = fcmp oeq float %x, 0.0
%select = select i1 %x.is.zero, float %mul.sign.x, float %sign.x
ret float %select
}
define float @select_oeq_fmul_copysign_or_src(float %x, float %sign) {
; CHECK-LABEL: define float @select_oeq_fmul_copysign_or_src(
; CHECK-SAME: float [[X:%.*]], float [[SIGN:%.*]]) {
; CHECK-NEXT: [[SIGN_X:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[SIGN]])
; CHECK-NEXT: [[MUL_SIGN_X:%.*]] = fmul float [[SIGN_X]], 0x4170000000000000
; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float [[MUL_SIGN_X]], float [[X]]
; CHECK-NEXT: ret float [[SELECT]]
;
%sign.x = call float @llvm.copysign.f32(float %x, float %sign)
%mul.sign.x = fmul float %sign.x, 0x4170000000000000
%x.is.zero = fcmp oeq float %x, 0.0
%select = select i1 %x.is.zero, float %mul.sign.x, float %x
ret float %select
}
; Negative test, +0 with a negative constant will still be -0
define float @select_oeq_fmul_neg_const(float %x) {
; CHECK-LABEL: define float @select_oeq_fmul_neg_const(
; CHECK-SAME: float [[X:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], -3.200000e+01
; 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, -32.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_oeq_fmul_unknown_var(float %x, float %unknown) {
; CHECK-LABEL: define float @select_oeq_fmul_unknown_var(
; CHECK-SAME: float [[X:%.*]], float [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], [[UNKNOWN]]
; 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, %unknown
%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_known_positive_var(float %x, float nofpclass(ninf nsub nnorm nzero) %known.positive) {
; CHECK-LABEL: define float @select_oeq_fmul_known_positive_var(
; CHECK-SAME: float [[X:%.*]], float nofpclass(ninf nzero nsub nnorm) [[KNOWN_POSITIVE:%.*]]) {
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[MUL_FABS_X:%.*]] = fmul float [[FABS_X]], [[KNOWN_POSITIVE]]
; 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, %known.positive
%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
}