Matt Arsenault 2502e3b7ba
IR: Promote "denormal-fp-math" to a first class attribute (#174293)
Convert "denormal-fp-math" and "denormal-fp-math-f32" into a first
class denormal_fpenv attribute. Previously the query for the effective
denormal mode involved two string attribute queries with parsing. I'm
introducing more uses of this, so it makes sense to convert this
to a more efficient encoding. The old representation was also awkward
since it was split across two separate attributes. The new encoding
just stores the default and float modes as bitfields, largely avoiding
the need to consider if the other mode is set.

The syntax in the common cases looks like this:
  `denormal_fpenv(preservesign,preservesign)`
  `denormal_fpenv(float: preservesign,preservesign)`
  `denormal_fpenv(dynamic,dynamic float: preservesign,preservesign)`

I wasn't sure about reusing the float type name instead of adding a
new keyword. It's parsed as a type but only accepts float. I'm also
debating switching the name to subnormal to match the current
preferred IEEE terminology (also used by nofpclass and other
contexts).

This has a behavior change when using the command flag debug
options to set the denormal mode. The behavior of the flag
ignored functions with an explicit attribute set, per
the default and f32 version. Now that these are one attribute,
the flag logic can't distinguish which of the two components
were explicitly set on the function. Only one test appeared to
rely on this behavior, so I just avoided using the flags in it.

This also does not perform all the code cleanups this enables.
In particular the attributor handling could be cleaned up.

I also guessed at how to support this in MLIR. I followed
MemoryEffects as a reference; it appears bitfields are expanded
into arguments to attributes, so the representation there is
a bit uglier with the 2 2-element fields flattened into 4 arguments.
2026-02-05 13:31:26 +00:00

1011 lines
36 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=instsimplify %s | FileCheck %s
define float @canonicalize_zero() {
; CHECK-LABEL: @canonicalize_zero(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float 0.0)
ret float %ret
}
define float @canonicalize_negzero() {
; CHECK-LABEL: @canonicalize_negzero(
; CHECK-NEXT: ret float -0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float -0.0)
ret float %ret
}
define <2 x float> @canonicalize_zero_vector() {
; CHECK-LABEL: @canonicalize_zero_vector(
; CHECK-NEXT: ret <2 x float> zeroinitializer
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> zeroinitializer)
ret <2 x float> %ret
}
define <2 x float> @canonicalize_negzero_vector() {
; CHECK-LABEL: @canonicalize_negzero_vector(
; CHECK-NEXT: ret <2 x float> splat (float -0.000000e+00)
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float -0.0, float -0.0>)
ret <2 x float> %ret
}
define <2 x float> @canonicalize_negzero_vector_partialundef() {
; CHECK-LABEL: @canonicalize_negzero_vector_partialundef(
; CHECK-NEXT: ret <2 x float> <float -0.000000e+00, float 0.000000e+00>
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float -0.0, float undef>)
ret <2 x float> %ret
}
define float @canonicalize_undef() {
; CHECK-LABEL: @canonicalize_undef(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float undef)
ret float %ret
}
define <2 x float> @canonicalize_undef_vector() {
; CHECK-LABEL: @canonicalize_undef_vector(
; CHECK-NEXT: ret <2 x float> zeroinitializer
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> undef)
ret <2 x float> %ret
}
define float @canonicalize_poison() {
; CHECK-LABEL: @canonicalize_poison(
; CHECK-NEXT: ret float poison
;
%ret = call float @llvm.canonicalize.f32(float poison)
ret float %ret
}
define <2 x float> @canonicalize_poison_vector() {
; CHECK-LABEL: @canonicalize_poison_vector(
; CHECK-NEXT: ret <2 x float> poison
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> poison)
ret <2 x float> %ret
}
define float @canonicalize_denorm() {
; CHECK-LABEL: @canonicalize_denorm(
; CHECK-NEXT: ret float 0x380FFFFFC0000000
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_pos_denorm_preserve_sign_output() denormal_fpenv(preservesign|ieee) {
; CHECK-LABEL: @canonicalize_pos_denorm_preserve_sign_output(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_pos_denorm_preserve_sign_input() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @canonicalize_pos_denorm_preserve_sign_input(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_preserve_sign_output() denormal_fpenv(preservesign|ieee) {
; CHECK-LABEL: @canonicalize_neg_denorm_preserve_sign_output(
; CHECK-NEXT: ret float -0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_preserve_sign_input() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @canonicalize_neg_denorm_preserve_sign_input(
; CHECK-NEXT: ret float -0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_pos_denorm_positive_zero_output() denormal_fpenv(positivezero|ieee) {
; CHECK-LABEL: @canonicalize_pos_denorm_positive_zero_output(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_pos_denorm_positive_zero_input() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @canonicalize_pos_denorm_positive_zero_input(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_positive_zero_output() denormal_fpenv(positivezero|ieee) {
; CHECK-LABEL: @canonicalize_neg_denorm_positive_zero_output(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_positive_zero_input() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @canonicalize_neg_denorm_positive_zero_input(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_pos_denorm_dynamic_dynamic() denormal_fpenv(dynamic) {
; CHECK-LABEL: @canonicalize_pos_denorm_dynamic_dynamic(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x380FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_dynamic_dynamic() denormal_fpenv(dynamic) {
; CHECK-LABEL: @canonicalize_neg_denorm_dynamic_dynamic(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0xB80FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
; Dynamic output - cannot flush
define float @canonicalize_pos_denorm_dynamic_output() denormal_fpenv(dynamic|ieee) {
; CHECK-LABEL: @canonicalize_pos_denorm_dynamic_output(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x380FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
; Dynamic output - cannot flush
define float @canonicalize_neg_denorm_dynamic_output() denormal_fpenv(dynamic|ieee) {
; CHECK-LABEL: @canonicalize_neg_denorm_dynamic_output(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0xB80FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
; Dynamic input - cannot flush
define float @canonicalize_pos_denorm_dynamic_input() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @canonicalize_pos_denorm_dynamic_input(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x380FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
; Dynamic input - cannot flush
define float @canonicalize_neg_denorm_dynamic_input() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @canonicalize_neg_denorm_dynamic_input(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0xB80FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
; Input is flushed, can fold
define float @canonicalize_pos_denorm_dynamic_output_preserve_sign_input() denormal_fpenv(dynamic|preservesign) {
; CHECK-LABEL: @canonicalize_pos_denorm_dynamic_output_preserve_sign_input(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
; Input is flushed, can fold
define float @canonicalize_neg_denorm_dynamic_output_preserve_sign_input() denormal_fpenv(dynamic|preservesign) {
; CHECK-LABEL: @canonicalize_neg_denorm_dynamic_output_preserve_sign_input(
; CHECK-NEXT: ret float -0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
; Output is known flushed, can fold
define float @canonicalize_pos_preserve_sign_output_denorm_dynamic_input() denormal_fpenv(preservesign|dynamic) {
; CHECK-LABEL: @canonicalize_pos_preserve_sign_output_denorm_dynamic_input(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x380FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
ret float %ret
}
; Output is known flushed, can fold
define float @canonicalize_neg_denorm_preserve_sign_output_dynamic_input() denormal_fpenv(preservesign|dynamic) {
; CHECK-LABEL: @canonicalize_neg_denorm_preserve_sign_output_dynamic_input(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0xB80FFFFFC0000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_inf() {
; CHECK-LABEL: @canonicalize_inf(
; CHECK-NEXT: ret float 0x7FF0000000000000
;
%ret = call float @llvm.canonicalize.f32(float 0x7FF0000000000000)
ret float %ret
}
define float @canonicalize_neg_inf() {
; CHECK-LABEL: @canonicalize_neg_inf(
; CHECK-NEXT: ret float 0xFFF0000000000000
;
%ret = call float @llvm.canonicalize.f32(float 0xFFF0000000000000)
ret float %ret
}
define float @canonicalize_qnan() {
; CHECK-LABEL: @canonicalize_qnan(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x7FF8000000000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float 0x7FF8000000000000)
ret float %ret
}
define float @canonicalize_snan() {
; CHECK-LABEL: @canonicalize_snan(
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x7FF0000020000000)
; CHECK-NEXT: ret float [[RET]]
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 2139095041 to float))
ret float %ret
}
define float @canonicalize_pos_normal() {
; CHECK-LABEL: @canonicalize_pos_normal(
; CHECK-NEXT: ret float 4.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float 4.0)
ret float %ret
}
define float @canonicalize_neg_normal() {
; CHECK-LABEL: @canonicalize_neg_normal(
; CHECK-NEXT: ret float -4.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float -4.0)
ret float %ret
}
define <2 x float> @canonicalize_pos_denorm_preserve_sign_output_mixed_vector() denormal_fpenv(preservesign|ieee) {
; CHECK-LABEL: @canonicalize_pos_denorm_preserve_sign_output_mixed_vector(
; CHECK-NEXT: ret <2 x float> <float 0.000000e+00, float -0.000000e+00>
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float bitcast (i32 8388607 to float), float bitcast (i32 -2139095041 to float)>)
ret <2 x float> %ret
}
define <2 x float> @canonicalize_pos_denorm_preserve_sign_input_mixed_vector() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @canonicalize_pos_denorm_preserve_sign_input_mixed_vector(
; CHECK-NEXT: ret <2 x float> <float -0.000000e+00, float 0.000000e+00>
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float bitcast (i32 -2139095041 to float), float bitcast (i32 8388607 to float)>)
ret <2 x float> %ret
}
define <2 x float> @canonicalize_pos_denorm_positive_zero_output_mixed_vector() denormal_fpenv(positivezero|ieee) {
; CHECK-LABEL: @canonicalize_pos_denorm_positive_zero_output_mixed_vector(
; CHECK-NEXT: ret <2 x float> zeroinitializer
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float bitcast (i32 8388607 to float), float bitcast (i32 -2139095041 to float)>)
ret <2 x float> %ret
}
define <2 x float> @canonicalize_pos_denorm_positive_zero_input_mixed_vector() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @canonicalize_pos_denorm_positive_zero_input_mixed_vector(
; CHECK-NEXT: ret <2 x float> zeroinitializer
;
%ret = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> <float bitcast (i32 -2139095041 to float), float bitcast (i32 8388607 to float)>)
ret <2 x float> %ret
}
define float @canonicalize_neg_denorm_preserve_sign_output_positive_zero_input() denormal_fpenv(preservesign|positivezero) {
; CHECK-LABEL: @canonicalize_neg_denorm_preserve_sign_output_positive_zero_input(
; CHECK-NEXT: ret float 0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
define float @canonicalize_neg_denorm_positive_zero_output_preserve_sign_input() denormal_fpenv(positivezero|preservesign) {
; CHECK-LABEL: @canonicalize_neg_denorm_positive_zero_output_preserve_sign_input(
; CHECK-NEXT: ret float -0.000000e+00
;
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 -2139095041 to float))
ret float %ret
}
; --------------------------------------------------------------------
; f64 handling
; --------------------------------------------------------------------
define double @canonicalize_zero_f64() {
; CHECK-LABEL: @canonicalize_zero_f64(
; CHECK-NEXT: ret double 0.000000e+00
;
%ret = call double @llvm.canonicalize.f64(double 0.0)
ret double %ret
}
define double @canonicalize_negzero_f64() {
; CHECK-LABEL: @canonicalize_negzero_f64(
; CHECK-NEXT: ret double -0.000000e+00
;
%ret = call double @llvm.canonicalize.f64(double -0.0)
ret double %ret
}
define double @canonicalize_1.0_f64() {
; CHECK-LABEL: @canonicalize_1.0_f64(
; CHECK-NEXT: ret double 1.000000e+00
;
%ret = call double @llvm.canonicalize.f64(double 1.0)
ret double %ret
}
define double @canonicalize_0x00000000000001_f64() {
; CHECK-LABEL: @canonicalize_0x00000000000001_f64(
; CHECK-NEXT: ret double 4.940660e-324
;
%ret = call double @llvm.canonicalize.f64(double 0x00000000000001)
ret double %ret
}
define double @canonicalize_inf_f64() {
; CHECK-LABEL: @canonicalize_inf_f64(
; CHECK-NEXT: ret double 0x7FF0000000000000
;
%ret = call double @llvm.canonicalize.f64(double 0x7FF0000000000000)
ret double %ret
}
define double @canonicalize_ninf_f64() {
; CHECK-LABEL: @canonicalize_ninf_f64(
; CHECK-NEXT: ret double 0xFFF0000000000000
;
%ret = call double @llvm.canonicalize.f64(double 0xFFF0000000000000)
ret double %ret
}
; --------------------------------------------------------------------
; f16 handling
; --------------------------------------------------------------------
define half @canonicalize_zero_f16() {
; CHECK-LABEL: @canonicalize_zero_f16(
; CHECK-NEXT: ret half 0xH0000
;
%ret = call half @llvm.canonicalize.f16(half 0.0)
ret half %ret
}
define half @canonicalize_1.0_f16() {
; CHECK-LABEL: @canonicalize_1.0_f16(
; CHECK-NEXT: ret half 0xH3C00
;
%ret = call half @llvm.canonicalize.f16(half 1.0)
ret half %ret
}
define half @canonicalize_0x0001_f16() {
; CHECK-LABEL: @canonicalize_0x0001_f16(
; CHECK-NEXT: ret half 0xH0001
;
%ret = call half @llvm.canonicalize.f16(half 0xH0001)
ret half %ret
}
define half @canonicalize_inf_f16() {
; CHECK-LABEL: @canonicalize_inf_f16(
; CHECK-NEXT: ret half 0xH7C00
;
%ret = call half @llvm.canonicalize.f16(half 0xH7C00)
ret half %ret
}
define half @canonicalize_neg_inf_f16() {
; CHECK-LABEL: @canonicalize_neg_inf_f16(
; CHECK-NEXT: ret half 0xHFC00
;
%ret = call half @llvm.canonicalize.f16(half 0xHFC00)
ret half %ret
}
; --------------------------------------------------------------------
; fp128 handling
; --------------------------------------------------------------------
define fp128 @canonicalize_zero_fp128() {
; CHECK-LABEL: @canonicalize_zero_fp128(
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000000000000000000000)
ret fp128 %ret
}
define fp128 @canonicalize_1.0_fp128() {
; CHECK-LABEL: @canonicalize_1.0_fp128(
; CHECK-NEXT: ret fp128 0xL00000000000000003FFF000000000000
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000003FFF000000000000)
ret fp128 %ret
}
define fp128 @canonicalize_0x00000000000000000000000000000001_fp128() {
; CHECK-LABEL: @canonicalize_0x00000000000000000000000000000001_fp128(
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000001
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000000000000000000001)
ret fp128 %ret
}
define fp128 @canonicalize_inf_fp128() {
; CHECK-LABEL: @canonicalize_inf_fp128(
; CHECK-NEXT: ret fp128 0xL00000000000000007FFF000000000000
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000007FFF000000000000)
ret fp128 %ret
}
define fp128 @canonicalize_neg_inf_fp128() {
; CHECK-LABEL: @canonicalize_neg_inf_fp128(
; CHECK-NEXT: ret fp128 0xL0000000000000000FFFF000000000000
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL0000000000000000FFFF000000000000)
ret fp128 %ret
}
define fp128 @canonicalize_nan_fp128() {
; CHECK-LABEL: @canonicalize_nan_fp128(
; CHECK-NEXT: [[RET:%.*]] = call fp128 @llvm.canonicalize.f128(fp128 0xL00000000000000007FFF800000000000)
; CHECK-NEXT: ret fp128 [[RET]]
;
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000007FFF800000000000)
ret fp128 %ret
}
; --------------------------------------------------------------------
; bfloat handling
; --------------------------------------------------------------------
define bfloat @canonicalize_zero_bf16() {
; CHECK-LABEL: @canonicalize_zero_bf16(
; CHECK-NEXT: ret bfloat 0xR0000
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0.0)
ret bfloat %ret
}
define bfloat @canonicalize_1.0_bf16() {
; CHECK-LABEL: @canonicalize_1.0_bf16(
; CHECK-NEXT: ret bfloat 0xR3F80
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 1.0)
ret bfloat %ret
}
define bfloat @canonicalize_0x0001_bf16() {
; CHECK-LABEL: @canonicalize_0x0001_bf16(
; CHECK-NEXT: ret bfloat 0xR0001
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xR0001)
ret bfloat %ret
}
define bfloat @canonicalize_inf_bf16() {
; CHECK-LABEL: @canonicalize_inf_bf16(
; CHECK-NEXT: ret bfloat 0xR7F80
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xR7F80)
ret bfloat %ret
}
define bfloat @canonicalize_neg_inf_bf16() {
; CHECK-LABEL: @canonicalize_neg_inf_bf16(
; CHECK-NEXT: ret bfloat 0xRFF80
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xRFF80)
ret bfloat %ret
}
define bfloat @canonicalize_nan_bf16() {
; CHECK-LABEL: @canonicalize_nan_bf16(
; CHECK-NEXT: [[RET:%.*]] = call bfloat @llvm.canonicalize.bf16(bfloat 0xR7FC0)
; CHECK-NEXT: ret bfloat [[RET]]
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xR7FC0)
ret bfloat %ret
}
define bfloat @canonicalize_0xff_bf16() {
; CHECK-LABEL: @canonicalize_0xff_bf16(
; CHECK-NEXT: ret bfloat 0xR00FF
;
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xR00FF)
ret bfloat %ret
}
; --------------------------------------------------------------------
; f80 handling
; --------------------------------------------------------------------
define x86_fp80 @canonicalize_poison_f80() {
; CHECK-LABEL: @canonicalize_poison_f80(
; CHECK-NEXT: ret x86_fp80 poison
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 poison)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_undef_f80() {
; CHECK-LABEL: @canonicalize_undef_f80(
; CHECK-NEXT: ret x86_fp80 0xK00000000000000000000
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 undef)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_zero_f80() {
; CHECK-LABEL: @canonicalize_zero_f80(
; CHECK-NEXT: ret x86_fp80 0xK00000000000000000000
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK00000000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_negzero_f80() {
; CHECK-LABEL: @canonicalize_negzero_f80(
; CHECK-NEXT: ret x86_fp80 0xK80000000000000000000
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK80000000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_inf_f80() {
; CHECK-LABEL: @canonicalize_inf_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK7FFF8000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK7FFF8000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_ninf_f80() {
; CHECK-LABEL: @canonicalize_ninf_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFF8000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFF8000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_qnan_f80() {
; CHECK-LABEL: @canonicalize_qnan_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFFC000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFFC000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_snan_f80() {
; CHECK-LABEL: @canonicalize_snan_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFFE000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKFFFFE000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_1.0_f80() {
; CHECK-LABEL: @canonicalize_1.0_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK3FFF8000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK3FFF8000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_neg1.0_f80() {
; CHECK-LABEL: @canonicalize_neg1.0_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKBFFF8000000000000000)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xKBFFF8000000000000000)
ret x86_fp80 %ret
}
define x86_fp80 @canonicalize_0xK00000000000000000001_f80() {
; CHECK-LABEL: @canonicalize_0xK00000000000000000001_f80(
; CHECK-NEXT: [[RET:%.*]] = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK00000000000000000001)
; CHECK-NEXT: ret x86_fp80 [[RET]]
;
%ret = call x86_fp80 @llvm.canonicalize.f80(x86_fp80 0xK00000000000000000001)
ret x86_fp80 %ret
}
; --------------------------------------------------------------------
; ppc_fp128 handling
; --------------------------------------------------------------------
define ppc_fp128 @canonicalize_poison_ppcf128() {
; CHECK-LABEL: @canonicalize_poison_ppcf128(
; CHECK-NEXT: ret ppc_fp128 poison
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 poison)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_undef_ppcf128() {
; CHECK-LABEL: @canonicalize_undef_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM00000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 undef)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_zero_ppcf128() {
; CHECK-LABEL: @canonicalize_zero_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM00000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM00000000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_negzero_ppcf128() {
; CHECK-LABEL: @canonicalize_negzero_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM80000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM80000000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_noncanonical_zero_0_ppcf128() {
; CHECK-LABEL: @canonicalize_noncanonical_zero_0_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM00000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM0000000000000000ffffffffffffffff)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_noncanonical_zero_1_ppcf128() {
; CHECK-LABEL: @canonicalize_noncanonical_zero_1_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM00000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM00000000000000000000000000000001)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_noncanonical_negzero_0_ppcf128() {
; CHECK-LABEL: @canonicalize_noncanonical_negzero_0_ppcf128(
; CHECK-NEXT: ret ppc_fp128 0xM80000000000000000000000000000000
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM8000000000000000ffffffffffffffff)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_inf_ppcf128() {
; CHECK-LABEL: @canonicalize_inf_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM7FF00000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM7FF00000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_neginf_ppcf128() {
; CHECK-LABEL: @canonicalize_neginf_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFF00000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFF00000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_qnan_ppcf128() {
; CHECK-LABEL: @canonicalize_qnan_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFF80000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFF80000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_snan_ppcf128() {
; CHECK-LABEL: @canonicalize_snan_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFFC0000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMFFFC0000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_1.0_ppcf128() {
; CHECK-LABEL: @canonicalize_1.0_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM3FF00000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xM3FF00000000000000000000000000000)
ret ppc_fp128 %ret
}
define ppc_fp128 @canonicalize_neg1.0_ppcf128() {
; CHECK-LABEL: @canonicalize_neg1.0_ppcf128(
; CHECK-NEXT: [[RET:%.*]] = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMBFF00000000000000000000000000000)
; CHECK-NEXT: ret ppc_fp128 [[RET]]
;
%ret = call ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128 0xMBFF00000000000000000000000000000)
ret ppc_fp128 %ret
}
; --------------------------------------------------------------------
; Test folds of using canonicalize + is.fpclass to inspect the denormal mode.
; --------------------------------------------------------------------
define i1 @is_poszero_daz_enabled_check_dynamic() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_dynamic(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 64)
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_preserve_sign_daz_enabled_check_dynamic() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_dynamic(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
; CHECK-NEXT: [[IS_NEG_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 32)
; CHECK-NEXT: ret i1 [[IS_NEG_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
ret i1 %is.neg.zero
}
define i1 @is_positive_zero_daz_enabled_check_dynamic() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_dynamic(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 64)
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_any_daz_enabled_check_dynamic() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_any_daz_enabled_check_dynamic(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
; CHECK-NEXT: [[IS_ANY_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 96)
; CHECK-NEXT: ret i1 [[IS_ANY_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
ret i1 %is.any.zero
}
define i1 @is_not_daz_enabled_check_dynamic() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_not_daz_enabled_check_dynamic(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
; CHECK-NEXT: [[IS_NOT_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 959)
; CHECK-NEXT: ret i1 [[IS_NOT_POS_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
ret i1 %is.not.pos.zero
}
define i1 @is_poszero_daz_enabled_check_ieee() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_ieee(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_preserve_sign_daz_enabled_check_ieee() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_ieee(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
ret i1 %is.neg.zero
}
define i1 @is_positive_zero_daz_enabled_check_ieee() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_ieee(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_any_daz_enabled_check_ieee() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_any_daz_enabled_check_ieee(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
ret i1 %is.any.zero
}
define i1 @is_not_daz_enabled_check_ieee() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_not_daz_enabled_check_ieee(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
ret i1 %is.not.pos.zero
}
define i1 @is_poszero_daz_enabled_check_preserve_sign() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_preserve_sign(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_preserve_sign_daz_enabled_check_preserve_sign() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_preserve_sign(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
ret i1 %is.neg.zero
}
define i1 @is_positive_zero_daz_enabled_check_preserve_sign() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_preserve_sign(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_any_daz_enabled_check_preserve_sign() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_any_daz_enabled_check_preserve_sign(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
ret i1 %is.any.zero
}
define i1 @is_not_daz_enabled_check_preserve_sign() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_not_daz_enabled_check_preserve_sign(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
ret i1 %is.not.pos.zero
}
define i1 @is_poszero_daz_enabled_check_positive_zero() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_positive_zero(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_preserve_sign_daz_enabled_check_positive_zero() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_positive_zero(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
ret i1 %is.neg.zero
}
define i1 @is_positive_zero_daz_enabled_check_positive_zero() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_positive_zero(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
ret i1 %is.pos.zero
}
define i1 @is_any_daz_enabled_check_positive_zero() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_any_daz_enabled_check_positive_zero(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
ret i1 %is.any.zero
}
define i1 @is_not_daz_enabled_check_positive_zero() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_not_daz_enabled_check_positive_zero(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
ret i1 %is.not.pos.zero
}
define i1 @is_poszero_daz_enabled_check_dynamic_bitcast() denormal_fpenv(ieee|dynamic) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_dynamic_bitcast(
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[CANONICAL]] to i32
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = icmp eq i32 [[BITCAST]], 0
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%bitcast = bitcast float %canonical to i32
%is.pos.zero = icmp eq i32 %bitcast, 0
ret i1 %is.pos.zero
}
define i1 @is_poszero_daz_enabled_check_preserve_sign_bitcast() denormal_fpenv(ieee|preservesign) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_preserve_sign_bitcast(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%bitcast = bitcast float %canonical to i32
%is.pos.zero = icmp eq i32 %bitcast, 0
ret i1 %is.pos.zero
}
define i1 @is_poszero_daz_enabled_check_positive_zero_bitcast() denormal_fpenv(ieee|positivezero) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_positive_zero_bitcast(
; CHECK-NEXT: ret i1 true
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%bitcast = bitcast float %canonical to i32
%is.pos.zero = icmp eq i32 %bitcast, 0
ret i1 %is.pos.zero
}
define i1 @is_poszero_daz_enabled_check_ieee_bitcast() denormal_fpenv(ieee|ieee) {
; CHECK-LABEL: @is_poszero_daz_enabled_check_ieee_bitcast(
; CHECK-NEXT: ret i1 false
;
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
%bitcast = bitcast float %canonical to i32
%is.pos.zero = icmp eq i32 %bitcast, 0
ret i1 %is.pos.zero
}
declare bfloat @llvm.canonicalize.bf16(bfloat)
declare half @llvm.canonicalize.f16(half)
declare float @llvm.canonicalize.f32(float)
declare <2 x float> @llvm.canonicalize.v2f32(<2 x float>)
declare double @llvm.canonicalize.f64(double)
declare fp128 @llvm.canonicalize.fp128(fp128)
declare x86_fp80 @llvm.canonicalize.f80(x86_fp80)
declare ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128)
declare i1 @llvm.is.fpclass.f32(float, i32 immarg)