[llvm] 1266086 - InstCombine: Add baseline test for detecting fneg/fabs as bitcasted integer

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 31 16:09:35 PDT 2023


Author: Matt Arsenault
Date: 2023-08-31T18:44:39-04:00
New Revision: 12660867307816cd808e0c21be4471a385154658

URL: https://github.com/llvm/llvm-project/commit/12660867307816cd808e0c21be4471a385154658
DIFF: https://github.com/llvm/llvm-project/commit/12660867307816cd808e0c21be4471a385154658.diff

LOG: InstCombine: Add baseline test for detecting fneg/fabs as bitcasted integer

Added: 
    llvm/test/Transforms/InstCombine/fabs-as-int.ll
    llvm/test/Transforms/InstCombine/fneg-as-int.ll
    llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/fabs-as-int.ll b/llvm/test/Transforms/InstCombine/fabs-as-int.ll
new file mode 100644
index 00000000000000..1b0ce274a09a9c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fabs-as-int.ll
@@ -0,0 +1,305 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+
+define float @fabs_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat {
+; CHECK-LABEL: define float @fabs_as_int_f32_castback_noimplicitfloat
+; CHECK-SAME: (float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast float %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define <2 x i32> @fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
+; CHECK-LABEL: define <2 x i32> @fabs_as_int_v2f32_noimplicitfloat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[BC]], <i32 2147483647, i32 2147483647>
+; CHECK-NEXT:    ret <2 x i32> [[AND]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647>
+  ret <2 x i32> %and
+}
+
+define float @fabs_as_int_f32_castback(float %val) {
+; CHECK-LABEL: define float @fabs_as_int_f32_castback
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast float %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define float @not_fabs_as_int_f32_castback_wrongconst(float %val) {
+; CHECK-LABEL: define float @not_fabs_as_int_f32_castback_wrongconst
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast float %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define float @fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
+; CHECK-LABEL: define float @fabs_as_int_f32_castback_multi_use
+; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    store i32 [[AND]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast float %val to i32
+  %and = and i32 %bitcast, 2147483647
+  store i32 %and, ptr %ptr
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define i64 @fabs_as_int_f64(double %x) {
+; CHECK-LABEL: define i64 @fabs_as_int_f64
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[AND:%.*]] = and i64 [[BC]], 9223372036854775807
+; CHECK-NEXT:    ret i64 [[AND]]
+;
+  %bc = bitcast double %x to i64
+  %and = and i64 %bc, 9223372036854775807
+  ret i64 %and
+}
+
+define <2 x i64> @fabs_as_int_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x i64> @fabs_as_int_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x double> [[X]] to <2 x i64>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i64> [[BC]], <i64 9223372036854775807, i64 9223372036854775807>
+; CHECK-NEXT:    ret <2 x i64> [[AND]]
+;
+  %bc = bitcast <2 x double> %x to <2 x i64>
+  %and = and <2 x i64> %bc, <i64 9223372036854775807, i64 9223372036854775807>
+  ret <2 x i64> %and
+}
+
+define i64 @fabs_as_int_f64_swap(double %x) {
+; CHECK-LABEL: define i64 @fabs_as_int_f64_swap
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[AND:%.*]] = and i64 [[BC]], 9223372036854775807
+; CHECK-NEXT:    ret i64 [[AND]]
+;
+  %bc = bitcast double %x to i64
+  %and = and i64 9223372036854775807, %bc
+  ret i64 %and
+}
+
+define i32 @fabs_as_int_f32(float %x) {
+; CHECK-LABEL: define i32 @fabs_as_int_f32
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BC]], 2147483647
+; CHECK-NEXT:    ret i32 [[AND]]
+;
+  %bc = bitcast float %x to i32
+  %and = and i32 %bc, 2147483647
+  ret i32 %and
+}
+
+define <2 x i32> @fabs_as_int_v2f32(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @fabs_as_int_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[BC]], <i32 2147483647, i32 2147483647>
+; CHECK-NEXT:    ret <2 x i32> [[AND]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647>
+  ret <2 x i32> %and
+}
+
+define <2 x i32> @not_fabs_as_int_v2f32_nonsplat(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @not_fabs_as_int_v2f32_nonsplat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[BC]], <i32 2147483647, i32 2147483646>
+; CHECK-NEXT:    ret <2 x i32> [[AND]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483646>
+  ret <2 x i32> %and
+}
+
+define <3 x i32> @fabs_as_int_v3f32_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x i32> @fabs_as_int_v3f32_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <3 x float> [[X]] to <3 x i32>
+; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[BC]], <i32 2147483647, i32 undef, i32 2147483647>
+; CHECK-NEXT:    ret <3 x i32> [[AND]]
+;
+  %bc = bitcast <3 x float> %x to <3 x i32>
+  %and = and <3 x i32> %bc, <i32 2147483647, i32 undef, i32 2147483647>
+  ret <3 x i32> %and
+}
+
+; Make sure that only a bitcast is transformed.
+define i64 @fabs_as_int_f64_not_bitcast(double %x) {
+; CHECK-LABEL: define i64 @fabs_as_int_f64_not_bitcast
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
+; CHECK-NEXT:    [[AND:%.*]] = and i64 [[BC]], 9223372036854775807
+; CHECK-NEXT:    ret i64 [[AND]]
+;
+  %bc = fptoui double %x to i64
+  %and = and i64 %bc, 9223372036854775807
+  ret i64 %and
+}
+
+define float @not_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
+; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2f16
+; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast <2 x half> %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define float @not_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
+; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2i16
+; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
+; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %bitcast = bitcast <2 x i16> %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %fabs = bitcast i32 %and to float
+  ret float %fabs
+}
+
+define i128 @fabs_as_int_fp128_f64_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fabs_as_int_fp128_f64_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
+; CHECK-NEXT:    ret i128 [[AND]]
+;
+  %bc = bitcast fp128 %x to i128
+  %and = and i128 %bc, 170141183460469231731687303715884105727
+  ret i128 %and
+}
+
+define i128 @fabs_as_int_fp128_f128_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fabs_as_int_fp128_f128_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
+; CHECK-NEXT:    ret i128 [[AND]]
+;
+  %bc = bitcast fp128 %x to i128
+  %and = and i128 %bc, 170141183460469231731687303715884105727
+  ret i128 %and
+}
+
+define i16 @fabs_as_int_f16(half %x) {
+; CHECK-LABEL: define i16 @fabs_as_int_f16
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast half [[X]] to i16
+; CHECK-NEXT:    [[AND:%.*]] = and i16 [[BC]], 32767
+; CHECK-NEXT:    ret i16 [[AND]]
+;
+  %bc = bitcast half %x to i16
+  %and = and i16 %bc, 32767
+  ret i16 %and
+}
+
+define <2 x i16> @fabs_as_int_v2f16(<2 x half> %x) {
+; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x half> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i16> [[BC]], <i16 32767, i16 32767>
+; CHECK-NEXT:    ret <2 x i16> [[AND]]
+;
+  %bc = bitcast <2 x half> %x to <2 x i16>
+  %and = and <2 x i16> %bc, <i16 32767, i16 32767>
+  ret <2 x i16> %and
+}
+
+define i16 @fabs_as_int_bf16(bfloat %x) {
+; CHECK-LABEL: define i16 @fabs_as_int_bf16
+; CHECK-SAME: (bfloat [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast bfloat [[X]] to i16
+; CHECK-NEXT:    [[AND:%.*]] = and i16 [[BC]], 32767
+; CHECK-NEXT:    ret i16 [[AND]]
+;
+  %bc = bitcast bfloat %x to i16
+  %and = and i16 %bc, 32767
+  ret i16 %and
+}
+
+define <2 x i16> @fabs_as_int_v2bf16(<2 x bfloat> %x) {
+; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2bf16
+; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x bfloat> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i16> [[BC]], <i16 32767, i16 32767>
+; CHECK-NEXT:    ret <2 x i16> [[AND]]
+;
+  %bc = bitcast <2 x bfloat> %x to <2 x i16>
+  %and = and <2 x i16> %bc, <i16 32767, i16 32767>
+  ret <2 x i16> %and
+}
+
+define i80 @fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
+; CHECK-LABEL: define i80 @fabs_as_int_x86_fp80_f64_mask
+; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast x86_fp80 [[X]] to i80
+; CHECK-NEXT:    [[AND:%.*]] = and i80 [[BC]], 9223372036854775807
+; CHECK-NEXT:    ret i80 [[AND]]
+;
+  %bc = bitcast x86_fp80 %x to i80
+  %and = and i80 %bc, 9223372036854775807
+  ret i80 %and
+}
+
+define i128 @fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f64_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 9223372036854775807
+; CHECK-NEXT:    ret i128 [[AND]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %and = and i128 %bc, 9223372036854775807
+  ret i128 %and
+}
+
+define i128 @fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f128_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
+; CHECK-NEXT:    ret i128 [[AND]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %and = and i128 %bc, 170141183460469231731687303715884105727
+  ret i128 %and
+}

diff  --git a/llvm/test/Transforms/InstCombine/fneg-as-int.ll b/llvm/test/Transforms/InstCombine/fneg-as-int.ll
new file mode 100644
index 00000000000000..550dcf25ab3c21
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fneg-as-int.ll
@@ -0,0 +1,305 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+
+define float @fneg_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat {
+; CHECK-LABEL: define float @fneg_as_int_f32_castback_noimplicitfloat
+; CHECK-SAME: (float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %xor = xor i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
+; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT:    ret <2 x i32> [[XOR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
+  ret <2 x i32> %xor
+}
+
+define float @fneg_as_int_f32_castback(float %val) {
+; CHECK-LABEL: define float @fneg_as_int_f32_castback
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %xor = xor i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define float @not_fneg_as_int_f32_castback_wrongconst(float %val) {
+; CHECK-LABEL: define float @not_fneg_as_int_f32_castback_wrongconst
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483647
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %xor = xor i32 %bitcast, -2147483647
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define float @fneg_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
+; CHECK-LABEL: define float @fneg_as_int_f32_castback_multi_use
+; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    store i32 [[XOR]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %xor = xor i32 %bitcast, -2147483648
+  store i32 %xor, ptr %ptr
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define i64 @fneg_as_int_f64(double %x) {
+; CHECK-LABEL: define i64 @fneg_as_int_f64
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[XOR]]
+;
+  %bc = bitcast double %x to i64
+  %xor = xor i64 %bc, -9223372036854775808
+  ret i64 %xor
+}
+
+define <2 x i64> @fneg_as_int_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x i64> @fneg_as_int_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x double> [[X]] to <2 x i64>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i64> [[BC]], <i64 -9223372036854775808, i64 -9223372036854775808>
+; CHECK-NEXT:    ret <2 x i64> [[XOR]]
+;
+  %bc = bitcast <2 x double> %x to <2 x i64>
+  %xor = xor <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808>
+  ret <2 x i64> %xor
+}
+
+define i64 @fneg_as_int_f64_swap(double %x) {
+; CHECK-LABEL: define i64 @fneg_as_int_f64_swap
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[XOR]]
+;
+  %bc = bitcast double %x to i64
+  %xor = xor i64 -9223372036854775808, %bc
+  ret i64 %xor
+}
+
+define i32 @fneg_as_int_f32(float %x) {
+; CHECK-LABEL: define i32 @fneg_as_int_f32
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BC]], -2147483648
+; CHECK-NEXT:    ret i32 [[XOR]]
+;
+  %bc = bitcast float %x to i32
+  %xor = xor i32 %bc, -2147483648
+  ret i32 %xor
+}
+
+define <2 x i32> @fneg_as_int_v2f32(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT:    ret <2 x i32> [[XOR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
+  ret <2 x i32> %xor
+}
+
+define <2 x i32> @not_fneg_as_int_v2f32_nonsplat(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @not_fneg_as_int_v2f32_nonsplat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647>
+; CHECK-NEXT:    ret <2 x i32> [[XOR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483647>
+  ret <2 x i32> %xor
+}
+
+define <3 x i32> @fneg_as_int_v3f32_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x i32> @fneg_as_int_v3f32_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <3 x float> [[X]] to <3 x i32>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <3 x i32> [[BC]], <i32 -2147483648, i32 undef, i32 -2147483648>
+; CHECK-NEXT:    ret <3 x i32> [[XOR]]
+;
+  %bc = bitcast <3 x float> %x to <3 x i32>
+  %xor = xor <3 x i32> %bc, <i32 -2147483648, i32 undef, i32 -2147483648>
+  ret <3 x i32> %xor
+}
+
+; Make sure that only a bitcast is transformed.
+define i64 @fneg_as_int_f64_not_bitcast(double %x) {
+; CHECK-LABEL: define i64 @fneg_as_int_f64_not_bitcast
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
+; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[XOR]]
+;
+  %bc = fptoui double %x to i64
+  %xor = xor i64 %bc, -9223372036854775808
+  ret i64 %xor
+}
+
+define float @not_fneg_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
+; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2f16
+; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast <2 x half> %val to i32
+  %xor = xor i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define float @not_fneg_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
+; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2i16
+; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast <2 x i16> %val to i32
+  %xor = xor i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %xor to float
+  ret float %fneg
+}
+
+define i128 @fneg_as_int_fp128_f64_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_as_int_fp128_f64_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i128 [[XOR]]
+;
+  %bc = bitcast fp128 %x to i128
+  %xor = xor i128 %bc, -9223372036854775808
+  ret i128 %xor
+}
+
+define i128 @fneg_as_int_fp128_f128_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_as_int_fp128_f128_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT:    ret i128 [[XOR]]
+;
+  %bc = bitcast fp128 %x to i128
+  %xor = xor i128 %bc, -170141183460469231731687303715884105728
+  ret i128 %xor
+}
+
+define i16 @fneg_as_int_f16(half %x) {
+; CHECK-LABEL: define i16 @fneg_as_int_f16
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast half [[X]] to i16
+; CHECK-NEXT:    [[XOR:%.*]] = xor i16 [[BC]], -32768
+; CHECK-NEXT:    ret i16 [[XOR]]
+;
+  %bc = bitcast half %x to i16
+  %xor = xor i16 %bc, -32768
+  ret i16 %xor
+}
+
+define <2 x i16> @fneg_as_int_v2f16(<2 x half> %x) {
+; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x half> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i16> [[BC]], <i16 -32768, i16 -32768>
+; CHECK-NEXT:    ret <2 x i16> [[XOR]]
+;
+  %bc = bitcast <2 x half> %x to <2 x i16>
+  %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768>
+  ret <2 x i16> %xor
+}
+
+define i16 @fneg_as_int_bf16(bfloat %x) {
+; CHECK-LABEL: define i16 @fneg_as_int_bf16
+; CHECK-SAME: (bfloat [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast bfloat [[X]] to i16
+; CHECK-NEXT:    [[XOR:%.*]] = xor i16 [[BC]], -32768
+; CHECK-NEXT:    ret i16 [[XOR]]
+;
+  %bc = bitcast bfloat %x to i16
+  %xor = xor i16 %bc, -32768
+  ret i16 %xor
+}
+
+define <2 x i16> @fneg_as_int_v2bf16(<2 x bfloat> %x) {
+; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2bf16
+; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x bfloat> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i16> [[BC]], <i16 -32768, i16 -32768>
+; CHECK-NEXT:    ret <2 x i16> [[XOR]]
+;
+  %bc = bitcast <2 x bfloat> %x to <2 x i16>
+  %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768>
+  ret <2 x i16> %xor
+}
+
+define i80 @fneg_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
+; CHECK-LABEL: define i80 @fneg_as_int_x86_fp80_f64_mask
+; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast x86_fp80 [[X]] to i80
+; CHECK-NEXT:    [[XOR:%.*]] = xor i80 [[BC]], -604462909807314587353088
+; CHECK-NEXT:    ret i80 [[XOR]]
+;
+  %bc = bitcast x86_fp80 %x to i80
+  %xor = xor i80 %bc, -604462909807314587353088
+  ret i80 %xor
+}
+
+define i128 @fneg_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f64_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i128 [[XOR]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %xor = xor i128 %bc, -9223372036854775808
+  ret i128 %xor
+}
+
+define i128 @fneg_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f128_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT:    ret i128 [[XOR]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %xor = xor i128 %bc, -170141183460469231731687303715884105728
+  ret i128 %xor
+}

diff  --git a/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll b/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll
new file mode 100644
index 00000000000000..eae8ed2670660a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll
@@ -0,0 +1,318 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+
+define i32 @fneg_fabs_as_int_f32_noimplicitfloat(float %x) noimplicitfloat {
+; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32_noimplicitfloat
+; CHECK-SAME: (float [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BC]], -2147483648
+; CHECK-NEXT:    ret i32 [[OR]]
+;
+  %bc = bitcast float %x to i32
+  %or = or i32 %bc, -2147483648
+  ret i32 %or
+}
+
+define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
+; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT:    ret <2 x i32> [[OR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
+  ret <2 x i32> %or
+}
+
+define float @fneg_fabs_fabs_as_int_f32_and_or(float %val) {
+; CHECK-LABEL: define float @fneg_fabs_fabs_as_int_f32_and_or
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG_FABS:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG_FABS]]
+;
+  %bitcast = bitcast float %val to i32
+  %and = and i32 %bitcast, 2147483647
+  %or = or i32 %and, -2147483648
+  %fneg.fabs = bitcast i32 %or to float
+  ret float %fneg.fabs
+}
+
+define float @fneg_fabs_as_int_f32_castback(float %val) {
+; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %or = or i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %or to float
+  ret float %fneg
+}
+
+define float @not_fneg_fabs_as_int_f32_castback_wrongconst(float %val) {
+; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_castback_wrongconst
+; CHECK-SAME: (float [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483647
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %or = or i32 %bitcast, -2147483647
+  %fneg = bitcast i32 %or to float
+  ret float %fneg
+}
+
+define float @fneg_fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
+; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback_multi_use
+; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    store i32 [[OR]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast float %val to i32
+  %or = or i32 %bitcast, -2147483648
+  store i32 %or, ptr %ptr
+  %fneg = bitcast i32 %or to float
+  ret float %fneg
+}
+
+define i64 @fneg_fabs_as_int_f64(double %x) {
+; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[OR:%.*]] = or i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[OR]]
+;
+  %bc = bitcast double %x to i64
+  %or = or i64 %bc, -9223372036854775808
+  ret i64 %or
+}
+
+define <2 x i64> @fneg_fabs_as_int_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x i64> @fneg_fabs_as_int_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x double> [[X]] to <2 x i64>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[BC]], <i64 -9223372036854775808, i64 -9223372036854775808>
+; CHECK-NEXT:    ret <2 x i64> [[OR]]
+;
+  %bc = bitcast <2 x double> %x to <2 x i64>
+  %or = or <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808>
+  ret <2 x i64> %or
+}
+
+define i64 @fneg_fabs_as_int_f64_swap(double %x) {
+; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_swap
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[OR:%.*]] = or i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[OR]]
+;
+  %bc = bitcast double %x to i64
+  %or = or i64 -9223372036854775808, %bc
+  ret i64 %or
+}
+
+define i32 @fneg_fabs_as_int_f32(float %x) {
+; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BC]], -2147483648
+; CHECK-NEXT:    ret i32 [[OR]]
+;
+  %bc = bitcast float %x to i32
+  %or = or i32 %bc, -2147483648
+  ret i32 %or
+}
+
+define <2 x i32> @fneg_fabs_as_int_v2f32(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT:    ret <2 x i32> [[OR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
+  ret <2 x i32> %or
+}
+
+define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat(<2 x float> %x) {
+; CHECK-LABEL: define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647>
+; CHECK-NEXT:    ret <2 x i32> [[OR]]
+;
+  %bc = bitcast <2 x float> %x to <2 x i32>
+  %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483647>
+  ret <2 x i32> %or
+}
+
+define <3 x i32> @fneg_fabs_as_int_v3f32_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x i32> @fneg_fabs_as_int_v3f32_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <3 x float> [[X]] to <3 x i32>
+; CHECK-NEXT:    [[OR:%.*]] = or <3 x i32> [[BC]], <i32 -2147483648, i32 undef, i32 -2147483648>
+; CHECK-NEXT:    ret <3 x i32> [[OR]]
+;
+  %bc = bitcast <3 x float> %x to <3 x i32>
+  %or = or <3 x i32> %bc, <i32 -2147483648, i32 undef, i32 -2147483648>
+  ret <3 x i32> %or
+}
+
+; Make sure that only a bitcast is transformed.
+define i64 @fneg_fabs_as_int_f64_not_bitcast(double %x) {
+; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_not_bitcast
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
+; CHECK-NEXT:    [[OR:%.*]] = or i64 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i64 [[OR]]
+;
+  %bc = fptoui double %x to i64
+  %or = or i64 %bc, -9223372036854775808
+  ret i64 %or
+}
+
+define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
+; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16
+; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast <2 x half> %val to i32
+  %or = or i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %or to float
+  ret float %fneg
+}
+
+define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
+; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16
+; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
+; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
+; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
+; CHECK-NEXT:    ret float [[FNEG]]
+;
+  %bitcast = bitcast <2 x i16> %val to i32
+  %or = or i32 %bitcast, -2147483648
+  %fneg = bitcast i32 %or to float
+  ret float %fneg
+}
+
+define i128 @fneg_fabs_as_int_fp128_f64_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f64_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i128 [[OR]]
+;
+  %bc = bitcast fp128 %x to i128
+  %or = or i128 %bc, -9223372036854775808
+  ret i128 %or
+}
+
+define i128 @fneg_fabs_as_int_fp128_f128_mask(fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f128_mask
+; CHECK-SAME: (fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
+; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT:    ret i128 [[OR]]
+;
+  %bc = bitcast fp128 %x to i128
+  %or = or i128 %bc, -170141183460469231731687303715884105728
+  ret i128 %or
+}
+
+define i16 @fneg_fabs_as_int_f16(half %x) {
+; CHECK-LABEL: define i16 @fneg_fabs_as_int_f16
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast half [[X]] to i16
+; CHECK-NEXT:    [[OR:%.*]] = or i16 [[BC]], -32768
+; CHECK-NEXT:    ret i16 [[OR]]
+;
+  %bc = bitcast half %x to i16
+  %or = or i16 %bc, -32768
+  ret i16 %or
+}
+
+define <2 x i16> @fneg_fabs_as_int_v2f16(<2 x half> %x) {
+; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x half> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i16> [[BC]], <i16 -32768, i16 -32768>
+; CHECK-NEXT:    ret <2 x i16> [[OR]]
+;
+  %bc = bitcast <2 x half> %x to <2 x i16>
+  %or = or <2 x i16> %bc, <i16 -32768, i16 -32768>
+  ret <2 x i16> %or
+}
+
+define i16 @fneg_fabs_as_int_bf16(bfloat %x) {
+; CHECK-LABEL: define i16 @fneg_fabs_as_int_bf16
+; CHECK-SAME: (bfloat [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast bfloat [[X]] to i16
+; CHECK-NEXT:    [[OR:%.*]] = or i16 [[BC]], -32768
+; CHECK-NEXT:    ret i16 [[OR]]
+;
+  %bc = bitcast bfloat %x to i16
+  %or = or i16 %bc, -32768
+  ret i16 %or
+}
+
+define <2 x i16> @fneg_fabs_as_int_v2bf16(<2 x bfloat> %x) {
+; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2bf16
+; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x bfloat> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i16> [[BC]], <i16 -32768, i16 -32768>
+; CHECK-NEXT:    ret <2 x i16> [[OR]]
+;
+  %bc = bitcast <2 x bfloat> %x to <2 x i16>
+  %or = or <2 x i16> %bc, <i16 -32768, i16 -32768>
+  ret <2 x i16> %or
+}
+
+define i80 @fneg_fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
+; CHECK-LABEL: define i80 @fneg_fabs_as_int_x86_fp80_f64_mask
+; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast x86_fp80 [[X]] to i80
+; CHECK-NEXT:    [[OR:%.*]] = or i80 [[BC]], -604462909807314587353088
+; CHECK-NEXT:    ret i80 [[OR]]
+;
+  %bc = bitcast x86_fp80 %x to i80
+  %or = or i80 %bc, -604462909807314587353088
+  ret i80 %or
+}
+
+define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -9223372036854775808
+; CHECK-NEXT:    ret i128 [[OR]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %or = or i128 %bc, -9223372036854775808
+  ret i128 %or
+}
+
+define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
+; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask
+; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
+; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
+; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT:    ret i128 [[OR]]
+;
+  %bc = bitcast ppc_fp128 %x to i128
+  %or = or i128 %bc, -170141183460469231731687303715884105728
+  ret i128 %or
+}


        


More information about the llvm-commits mailing list