1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -S -passes=instcombine %s | FileCheck %s 3 4define float @fneg_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat { 5; CHECK-LABEL: define float @fneg_as_int_f32_castback_noimplicitfloat 6; CHECK-SAME: (float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { 7; CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[VAL]] to i32 8; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648 9; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[XOR]] to float 10; CHECK-NEXT: ret float [[FNEG]] 11; 12 %bitcast = bitcast float %val to i32 13 %xor = xor i32 %bitcast, -2147483648 14 %fneg = bitcast i32 %xor to float 15 ret float %fneg 16} 17 18define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat { 19; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat 20; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] { 21; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> 22; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[BC]], splat (i32 -2147483648) 23; CHECK-NEXT: ret <2 x i32> [[XOR]] 24; 25 %bc = bitcast <2 x float> %x to <2 x i32> 26 %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648> 27 ret <2 x i32> %xor 28} 29 30define float @fneg_as_int_f32_castback(float %val) { 31; CHECK-LABEL: define float @fneg_as_int_f32_castback 32; CHECK-SAME: (float [[VAL:%.*]]) { 33; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[VAL]] 34; CHECK-NEXT: ret float [[TMP1]] 35; 36 %bitcast = bitcast float %val to i32 37 %xor = xor i32 %bitcast, -2147483648 38 %fneg = bitcast i32 %xor to float 39 ret float %fneg 40} 41 42define float @not_fneg_as_int_f32_castback_wrongconst(float %val) { 43; CHECK-LABEL: define float @not_fneg_as_int_f32_castback_wrongconst 44; CHECK-SAME: (float [[VAL:%.*]]) { 45; CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[VAL]] to i32 46; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483647 47; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[XOR]] to float 48; CHECK-NEXT: ret float [[FNEG]] 49; 50 %bitcast = bitcast float %val to i32 51 %xor = xor i32 %bitcast, -2147483647 52 %fneg = bitcast i32 %xor to float 53 ret float %fneg 54} 55 56define float @fneg_as_int_f32_castback_multi_use(float %val, ptr %ptr) { 57; CHECK-LABEL: define float @fneg_as_int_f32_castback_multi_use 58; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) { 59; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[VAL]] 60; CHECK-NEXT: store float [[TMP1]], ptr [[PTR]], align 4 61; CHECK-NEXT: ret float [[TMP1]] 62; 63 %bitcast = bitcast float %val to i32 64 %xor = xor i32 %bitcast, -2147483648 65 store i32 %xor, ptr %ptr 66 %fneg = bitcast i32 %xor to float 67 ret float %fneg 68} 69 70define i64 @fneg_as_int_f64(double %x) { 71; CHECK-LABEL: define i64 @fneg_as_int_f64 72; CHECK-SAME: (double [[X:%.*]]) { 73; CHECK-NEXT: [[TMP1:%.*]] = fneg double [[X]] 74; CHECK-NEXT: [[XOR:%.*]] = bitcast double [[TMP1]] to i64 75; CHECK-NEXT: ret i64 [[XOR]] 76; 77 %bc = bitcast double %x to i64 78 %xor = xor i64 %bc, -9223372036854775808 79 ret i64 %xor 80} 81 82define <2 x i64> @fneg_as_int_v2f64(<2 x double> %x) { 83; CHECK-LABEL: define <2 x i64> @fneg_as_int_v2f64 84; CHECK-SAME: (<2 x double> [[X:%.*]]) { 85; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x double> [[X]] 86; CHECK-NEXT: [[XOR:%.*]] = bitcast <2 x double> [[TMP1]] to <2 x i64> 87; CHECK-NEXT: ret <2 x i64> [[XOR]] 88; 89 %bc = bitcast <2 x double> %x to <2 x i64> 90 %xor = xor <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808> 91 ret <2 x i64> %xor 92} 93 94define i64 @fneg_as_int_f64_swap(double %x) { 95; CHECK-LABEL: define i64 @fneg_as_int_f64_swap 96; CHECK-SAME: (double [[X:%.*]]) { 97; CHECK-NEXT: [[TMP1:%.*]] = fneg double [[X]] 98; CHECK-NEXT: [[XOR:%.*]] = bitcast double [[TMP1]] to i64 99; CHECK-NEXT: ret i64 [[XOR]] 100; 101 %bc = bitcast double %x to i64 102 %xor = xor i64 -9223372036854775808, %bc 103 ret i64 %xor 104} 105 106define i32 @fneg_as_int_f32(float %x) { 107; CHECK-LABEL: define i32 @fneg_as_int_f32 108; CHECK-SAME: (float [[X:%.*]]) { 109; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X]] 110; CHECK-NEXT: [[XOR:%.*]] = bitcast float [[TMP1]] to i32 111; CHECK-NEXT: ret i32 [[XOR]] 112; 113 %bc = bitcast float %x to i32 114 %xor = xor i32 %bc, -2147483648 115 ret i32 %xor 116} 117 118define <2 x i32> @fneg_as_int_v2f32(<2 x float> %x) { 119; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32 120; CHECK-SAME: (<2 x float> [[X:%.*]]) { 121; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X]] 122; CHECK-NEXT: [[XOR:%.*]] = bitcast <2 x float> [[TMP1]] to <2 x i32> 123; CHECK-NEXT: ret <2 x i32> [[XOR]] 124; 125 %bc = bitcast <2 x float> %x to <2 x i32> 126 %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648> 127 ret <2 x i32> %xor 128} 129 130define <2 x i32> @not_fneg_as_int_v2f32_nonsplat(<2 x float> %x) { 131; CHECK-LABEL: define <2 x i32> @not_fneg_as_int_v2f32_nonsplat 132; CHECK-SAME: (<2 x float> [[X:%.*]]) { 133; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> 134; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647> 135; CHECK-NEXT: ret <2 x i32> [[XOR]] 136; 137 %bc = bitcast <2 x float> %x to <2 x i32> 138 %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483647> 139 ret <2 x i32> %xor 140} 141 142define <3 x i32> @fneg_as_int_v3f32_poison(<3 x float> %x) { 143; CHECK-LABEL: define <3 x i32> @fneg_as_int_v3f32_poison 144; CHECK-SAME: (<3 x float> [[X:%.*]]) { 145; CHECK-NEXT: [[TMP1:%.*]] = fneg <3 x float> [[X]] 146; CHECK-NEXT: [[XOR:%.*]] = bitcast <3 x float> [[TMP1]] to <3 x i32> 147; CHECK-NEXT: ret <3 x i32> [[XOR]] 148; 149 %bc = bitcast <3 x float> %x to <3 x i32> 150 %xor = xor <3 x i32> %bc, <i32 -2147483648, i32 poison, i32 -2147483648> 151 ret <3 x i32> %xor 152} 153 154; Make sure that only a bitcast is transformed. 155define i64 @fneg_as_int_f64_not_bitcast(double %x) { 156; CHECK-LABEL: define i64 @fneg_as_int_f64_not_bitcast 157; CHECK-SAME: (double [[X:%.*]]) { 158; CHECK-NEXT: [[BC:%.*]] = fptoui double [[X]] to i64 159; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[BC]], -9223372036854775808 160; CHECK-NEXT: ret i64 [[XOR]] 161; 162 %bc = fptoui double %x to i64 163 %xor = xor i64 %bc, -9223372036854775808 164 ret i64 %xor 165} 166 167define float @not_fneg_as_int_f32_bitcast_from_v2f16(<2 x half> %val) { 168; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2f16 169; CHECK-SAME: (<2 x half> [[VAL:%.*]]) { 170; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32 171; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648 172; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[XOR]] to float 173; CHECK-NEXT: ret float [[FNEG]] 174; 175 %bitcast = bitcast <2 x half> %val to i32 176 %xor = xor i32 %bitcast, -2147483648 177 %fneg = bitcast i32 %xor to float 178 ret float %fneg 179} 180 181define float @not_fneg_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) { 182; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2i16 183; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) { 184; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32 185; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648 186; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[XOR]] to float 187; CHECK-NEXT: ret float [[FNEG]] 188; 189 %bitcast = bitcast <2 x i16> %val to i32 190 %xor = xor i32 %bitcast, -2147483648 191 %fneg = bitcast i32 %xor to float 192 ret float %fneg 193} 194 195define i128 @fneg_as_int_fp128_f64_mask(fp128 %x) { 196; CHECK-LABEL: define i128 @fneg_as_int_fp128_f64_mask 197; CHECK-SAME: (fp128 [[X:%.*]]) { 198; CHECK-NEXT: [[BC:%.*]] = bitcast fp128 [[X]] to i128 199; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808 200; CHECK-NEXT: ret i128 [[XOR]] 201; 202 %bc = bitcast fp128 %x to i128 203 %xor = xor i128 %bc, -9223372036854775808 204 ret i128 %xor 205} 206 207define i128 @fneg_as_int_fp128_f128_mask(fp128 %x) { 208; CHECK-LABEL: define i128 @fneg_as_int_fp128_f128_mask 209; CHECK-SAME: (fp128 [[X:%.*]]) { 210; CHECK-NEXT: [[TMP1:%.*]] = fneg fp128 [[X]] 211; CHECK-NEXT: [[XOR:%.*]] = bitcast fp128 [[TMP1]] to i128 212; CHECK-NEXT: ret i128 [[XOR]] 213; 214 %bc = bitcast fp128 %x to i128 215 %xor = xor i128 %bc, -170141183460469231731687303715884105728 216 ret i128 %xor 217} 218 219define i16 @fneg_as_int_f16(half %x) { 220; CHECK-LABEL: define i16 @fneg_as_int_f16 221; CHECK-SAME: (half [[X:%.*]]) { 222; CHECK-NEXT: [[TMP1:%.*]] = fneg half [[X]] 223; CHECK-NEXT: [[XOR:%.*]] = bitcast half [[TMP1]] to i16 224; CHECK-NEXT: ret i16 [[XOR]] 225; 226 %bc = bitcast half %x to i16 227 %xor = xor i16 %bc, -32768 228 ret i16 %xor 229} 230 231define <2 x i16> @fneg_as_int_v2f16(<2 x half> %x) { 232; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2f16 233; CHECK-SAME: (<2 x half> [[X:%.*]]) { 234; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x half> [[X]] 235; CHECK-NEXT: [[XOR:%.*]] = bitcast <2 x half> [[TMP1]] to <2 x i16> 236; CHECK-NEXT: ret <2 x i16> [[XOR]] 237; 238 %bc = bitcast <2 x half> %x to <2 x i16> 239 %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768> 240 ret <2 x i16> %xor 241} 242 243define i16 @fneg_as_int_bf16(bfloat %x) { 244; CHECK-LABEL: define i16 @fneg_as_int_bf16 245; CHECK-SAME: (bfloat [[X:%.*]]) { 246; CHECK-NEXT: [[TMP1:%.*]] = fneg bfloat [[X]] 247; CHECK-NEXT: [[XOR:%.*]] = bitcast bfloat [[TMP1]] to i16 248; CHECK-NEXT: ret i16 [[XOR]] 249; 250 %bc = bitcast bfloat %x to i16 251 %xor = xor i16 %bc, -32768 252 ret i16 %xor 253} 254 255define <2 x i16> @fneg_as_int_v2bf16(<2 x bfloat> %x) { 256; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2bf16 257; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) { 258; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x bfloat> [[X]] 259; CHECK-NEXT: [[XOR:%.*]] = bitcast <2 x bfloat> [[TMP1]] to <2 x i16> 260; CHECK-NEXT: ret <2 x i16> [[XOR]] 261; 262 %bc = bitcast <2 x bfloat> %x to <2 x i16> 263 %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768> 264 ret <2 x i16> %xor 265} 266 267define i80 @fneg_as_int_x86_fp80_f64_mask(x86_fp80 %x) { 268; CHECK-LABEL: define i80 @fneg_as_int_x86_fp80_f64_mask 269; CHECK-SAME: (x86_fp80 [[X:%.*]]) { 270; CHECK-NEXT: [[TMP1:%.*]] = fneg x86_fp80 [[X]] 271; CHECK-NEXT: [[XOR:%.*]] = bitcast x86_fp80 [[TMP1]] to i80 272; CHECK-NEXT: ret i80 [[XOR]] 273; 274 %bc = bitcast x86_fp80 %x to i80 275 %xor = xor i80 %bc, -604462909807314587353088 276 ret i80 %xor 277} 278 279define i128 @fneg_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) { 280; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f64_mask 281; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 282; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 283; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808 284; CHECK-NEXT: ret i128 [[XOR]] 285; 286 %bc = bitcast ppc_fp128 %x to i128 287 %xor = xor i128 %bc, -9223372036854775808 288 ret i128 %xor 289} 290 291define i128 @fneg_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) { 292; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f128_mask 293; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 294; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 295; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728 296; CHECK-NEXT: ret i128 [[XOR]] 297; 298 %bc = bitcast ppc_fp128 %x to i128 299 %xor = xor i128 %bc, -170141183460469231731687303715884105728 300 ret i128 %xor 301} 302