[llvm] [KnownFPClass] Refine known classes for `KnownFPClass::bitcast` (PR #215708)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 23:31:13 PDT 2026


================
@@ -0,0 +1,463 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal < %s | FileCheck %s
+
+define float @bitcast_to_float_unknown(i32 %x) {
+; CHECK-LABEL: define float @bitcast_to_float_unknown(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[X]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %cast = bitcast i32 %x to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_positive_one(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @bitcast_to_float_positive_one(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], 1065353216
+; CHECK-NEXT:    [[BITS:%.*]] = or i32 [[MASKED]], 1065353216
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[BITS]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0x3F800000
+  %bits = or i32 %masked, u0x3F800000
+  %cast = bitcast i32 %bits to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_negative_inf(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float @bitcast_to_float_negative_inf(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -8388608
+; CHECK-NEXT:    [[BITS:%.*]] = or i32 [[MASKED]], -8388608
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[BITS]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0xFF800000
+  %bits = or i32 %masked, u0xFF800000
+  %cast = bitcast i32 %bits to float
+  ret float %cast
+}
+
+; Test that no nofpclass deductions are made for poison values.
+define float @bitcast_to_float_poison(<1 x i32> %x, <1 x i32> %y) {
+; CHECK-LABEL: define float @bitcast_to_float_poison(
+; CHECK-SAME: <1 x i32> [[X:%.*]], <1 x i32> [[Y:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[POISON:%.*]] = shufflevector <1 x i32> [[X]], <1 x i32> [[Y]], <1 x i32> poison
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast <1 x i32> [[POISON]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %poison = shufflevector <1 x i32> %x, <1 x i32> %y, <1 x i32> poison
+  %cast = bitcast <1 x i32> %poison to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_positive_sign(i32 %x) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @bitcast_to_float_positive_sign(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], 2147483647
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0x7FFFFFFF
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_negative_sign(i32 %x) {
+; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @bitcast_to_float_negative_sign(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[X]], -2147483648
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = or i32 %x, u0x80000000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_exponent_all_zeros(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan inf norm) float @bitcast_to_float_exponent_all_zeros(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -2139095041
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0x807FFFFF
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_exponent_all_ones(i32 %x) {
+; CHECK-LABEL: define nofpclass(zero sub norm) float @bitcast_to_float_exponent_all_ones(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[X]], 2139095040
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = or i32 %x, u0x7F800000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_exponent_nonzero_not_all_ones(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub) float @bitcast_to_float_exponent_nonzero_not_all_ones(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[SET:%.*]] = or i32 [[X]], 8388608
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[SET]], -16777217
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %set = or i32 %x, u0x00800000
+  %masked = and i32 %set, u0xFEFFFFFF
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_exponent_nonzero(i32 %x) {
+; CHECK-LABEL: define nofpclass(zero sub) float @bitcast_to_float_exponent_nonzero(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[X]], 8388608
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = or i32 %x, u0x00800000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_exponent_not_all_ones(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan inf) float @bitcast_to_float_exponent_not_all_ones(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -8388609
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0xFF7FFFFF
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_mantissa_all_zeros(i32 %x) {
+; CHECK-LABEL: define nofpclass(nan sub) float @bitcast_to_float_mantissa_all_zeros(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -8388608
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0xFF800000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_mantissa_low_bit_zero(i32 %x) {
+; CHECK-LABEL: define float @bitcast_to_float_mantissa_low_bit_zero(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -2
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0xFFFFFFFE
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_mantissa_nonzero(i32 %x) {
+; CHECK-LABEL: define nofpclass(inf zero) float @bitcast_to_float_mantissa_nonzero(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[X]], 1
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = or i32 %x, 1
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_quiet_bit_set(i32 %x) {
+; CHECK-LABEL: define nofpclass(snan inf zero) float @bitcast_to_float_quiet_bit_set(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[X]], 4194304
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = or i32 %x, u0x00400000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_quiet_bit_clear(i32 %x) {
+; CHECK-LABEL: define nofpclass(qnan) float @bitcast_to_float_quiet_bit_clear(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[X]], -4194305
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %masked = and i32 %x, u0xFFBFFFFF
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_inf_or_snan(i32 %x) {
+; CHECK-LABEL: define nofpclass(qnan zero sub norm) float @bitcast_to_float_inf_or_snan(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[QUIET_BIT_ZERO:%.*]] = and i32 [[X]], -4194305
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[QUIET_BIT_ZERO]], 2139095040
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %quiet_bit_zero = and i32 %x, u0xFFBFFFFF
+  %masked = or i32 %quiet_bit_zero, u0x7F800000
+  %cast = bitcast i32 %masked to float
+  ret float %cast
+}
+
+define float @bitcast_to_float_snan(i32 %x) {
+; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) float @bitcast_to_float_snan(
+; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[QUIET_BIT_ZERO:%.*]] = and i32 [[X]], -4194305
+; CHECK-NEXT:    [[EXPONENT_ONE:%.*]] = or i32 [[QUIET_BIT_ZERO]], 2139095040
+; CHECK-NEXT:    [[MASKED:%.*]] = or i32 [[EXPONENT_ONE]], 1
+; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[MASKED]] to float
+; CHECK-NEXT:    ret float [[CAST]]
+;
+  %quiet_bit_zero = and i32 %x, u0xFFBFFFFF
+  %exponent_one = or i32 %quiet_bit_zero, u0x7F800000
+  %masked = or i32 %exponent_one, 1
----------------
ZERICO2005 wrote:

I will need to fix some of the variable names

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


More information about the llvm-commits mailing list