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 i32 @fneg_fabs_as_int_f32_noimplicitfloat(float %x) noimplicitfloat { 5; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32_noimplicitfloat 6; CHECK-SAME: (float [[X:%.*]]) #[[ATTR0:[0-9]+]] { 7; CHECK-NEXT: [[BC:%.*]] = bitcast float [[X]] to i32 8; CHECK-NEXT: [[OR:%.*]] = or i32 [[BC]], -2147483648 9; CHECK-NEXT: ret i32 [[OR]] 10; 11 %bc = bitcast float %x to i32 12 %or = or i32 %bc, -2147483648 13 ret i32 %or 14} 15 16define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat { 17; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat 18; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] { 19; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> 20; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[BC]], splat (i32 -2147483648) 21; CHECK-NEXT: ret <2 x i32> [[OR]] 22; 23 %bc = bitcast <2 x float> %x to <2 x i32> 24 %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648> 25 ret <2 x i32> %or 26} 27 28define float @fneg_fabs_fabs_as_int_f32_and_or(float %val) { 29; CHECK-LABEL: define float @fneg_fabs_fabs_as_int_f32_and_or 30; CHECK-SAME: (float [[VAL:%.*]]) { 31; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 32; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 33; CHECK-NEXT: ret float [[TMP2]] 34; 35 %bitcast = bitcast float %val to i32 36 %and = and i32 %bitcast, 2147483647 37 %or = or i32 %and, -2147483648 38 %fneg.fabs = bitcast i32 %or to float 39 ret float %fneg.fabs 40} 41 42define float @fneg_fabs_as_int_f32_castback(float %val) { 43; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback 44; CHECK-SAME: (float [[VAL:%.*]]) { 45; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 46; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 47; CHECK-NEXT: ret float [[TMP2]] 48; 49 %bitcast = bitcast float %val to i32 50 %or = or i32 %bitcast, -2147483648 51 %fneg = bitcast i32 %or to float 52 ret float %fneg 53} 54 55define float @not_fneg_fabs_as_int_f32_castback_wrongconst(float %val) { 56; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_castback_wrongconst 57; CHECK-SAME: (float [[VAL:%.*]]) { 58; CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[VAL]] to i32 59; CHECK-NEXT: [[OR:%.*]] = or i32 [[BITCAST]], -2147483647 60; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[OR]] to float 61; CHECK-NEXT: ret float [[FNEG]] 62; 63 %bitcast = bitcast float %val to i32 64 %or = or i32 %bitcast, -2147483647 65 %fneg = bitcast i32 %or to float 66 ret float %fneg 67} 68 69define float @fneg_fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) { 70; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback_multi_use 71; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) { 72; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 73; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 74; CHECK-NEXT: store float [[TMP2]], ptr [[PTR]], align 4 75; CHECK-NEXT: ret float [[TMP2]] 76; 77 %bitcast = bitcast float %val to i32 78 %or = or i32 %bitcast, -2147483648 79 store i32 %or, ptr %ptr 80 %fneg = bitcast i32 %or to float 81 ret float %fneg 82} 83 84define i64 @fneg_fabs_as_int_f64(double %x) { 85; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64 86; CHECK-SAME: (double [[X:%.*]]) { 87; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]]) 88; CHECK-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 89; CHECK-NEXT: [[OR:%.*]] = bitcast double [[TMP2]] to i64 90; CHECK-NEXT: ret i64 [[OR]] 91; 92 %bc = bitcast double %x to i64 93 %or = or i64 %bc, -9223372036854775808 94 ret i64 %or 95} 96 97define <2 x i64> @fneg_fabs_as_int_v2f64(<2 x double> %x) { 98; CHECK-LABEL: define <2 x i64> @fneg_fabs_as_int_v2f64 99; CHECK-SAME: (<2 x double> [[X:%.*]]) { 100; CHECK-NEXT: [[TMP1:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]]) 101; CHECK-NEXT: [[TMP2:%.*]] = fneg <2 x double> [[TMP1]] 102; CHECK-NEXT: [[OR:%.*]] = bitcast <2 x double> [[TMP2]] to <2 x i64> 103; CHECK-NEXT: ret <2 x i64> [[OR]] 104; 105 %bc = bitcast <2 x double> %x to <2 x i64> 106 %or = or <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808> 107 ret <2 x i64> %or 108} 109 110define i64 @fneg_fabs_as_int_f64_swap(double %x) { 111; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_swap 112; CHECK-SAME: (double [[X:%.*]]) { 113; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]]) 114; CHECK-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 115; CHECK-NEXT: [[OR:%.*]] = bitcast double [[TMP2]] to i64 116; CHECK-NEXT: ret i64 [[OR]] 117; 118 %bc = bitcast double %x to i64 119 %or = or i64 -9223372036854775808, %bc 120 ret i64 %or 121} 122 123define i32 @fneg_fabs_as_int_f32(float %x) { 124; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32 125; CHECK-SAME: (float [[X:%.*]]) { 126; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 127; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 128; CHECK-NEXT: [[OR:%.*]] = bitcast float [[TMP2]] to i32 129; CHECK-NEXT: ret i32 [[OR]] 130; 131 %bc = bitcast float %x to i32 132 %or = or i32 %bc, -2147483648 133 ret i32 %or 134} 135 136define <2 x i32> @fneg_fabs_as_int_v2f32(<2 x float> %x) { 137; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32 138; CHECK-SAME: (<2 x float> [[X:%.*]]) { 139; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]]) 140; CHECK-NEXT: [[TMP2:%.*]] = fneg <2 x float> [[TMP1]] 141; CHECK-NEXT: [[OR:%.*]] = bitcast <2 x float> [[TMP2]] to <2 x i32> 142; CHECK-NEXT: ret <2 x i32> [[OR]] 143; 144 %bc = bitcast <2 x float> %x to <2 x i32> 145 %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648> 146 ret <2 x i32> %or 147} 148 149define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat(<2 x float> %x) { 150; CHECK-LABEL: define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat 151; CHECK-SAME: (<2 x float> [[X:%.*]]) { 152; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> 153; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647> 154; CHECK-NEXT: ret <2 x i32> [[OR]] 155; 156 %bc = bitcast <2 x float> %x to <2 x i32> 157 %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483647> 158 ret <2 x i32> %or 159} 160 161define <3 x i32> @fneg_fabs_as_int_v3f32_poison(<3 x float> %x) { 162; CHECK-LABEL: define <3 x i32> @fneg_fabs_as_int_v3f32_poison 163; CHECK-SAME: (<3 x float> [[X:%.*]]) { 164; CHECK-NEXT: [[TMP1:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[X]]) 165; CHECK-NEXT: [[TMP2:%.*]] = fneg <3 x float> [[TMP1]] 166; CHECK-NEXT: [[OR:%.*]] = bitcast <3 x float> [[TMP2]] to <3 x i32> 167; CHECK-NEXT: ret <3 x i32> [[OR]] 168; 169 %bc = bitcast <3 x float> %x to <3 x i32> 170 %or = or <3 x i32> %bc, <i32 -2147483648, i32 poison, i32 -2147483648> 171 ret <3 x i32> %or 172} 173 174; Make sure that only a bitcast is transformed. 175define i64 @fneg_fabs_as_int_f64_not_bitcast(double %x) { 176; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_not_bitcast 177; CHECK-SAME: (double [[X:%.*]]) { 178; CHECK-NEXT: [[BC:%.*]] = fptoui double [[X]] to i64 179; CHECK-NEXT: [[OR:%.*]] = or i64 [[BC]], -9223372036854775808 180; CHECK-NEXT: ret i64 [[OR]] 181; 182 %bc = fptoui double %x to i64 183 %or = or i64 %bc, -9223372036854775808 184 ret i64 %or 185} 186 187define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) { 188; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16 189; CHECK-SAME: (<2 x half> [[VAL:%.*]]) { 190; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32 191; CHECK-NEXT: [[OR:%.*]] = or i32 [[BITCAST]], -2147483648 192; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[OR]] to float 193; CHECK-NEXT: ret float [[FNEG]] 194; 195 %bitcast = bitcast <2 x half> %val to i32 196 %or = or i32 %bitcast, -2147483648 197 %fneg = bitcast i32 %or to float 198 ret float %fneg 199} 200 201define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) { 202; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16 203; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) { 204; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32 205; CHECK-NEXT: [[OR:%.*]] = or i32 [[BITCAST]], -2147483648 206; CHECK-NEXT: [[FNEG:%.*]] = bitcast i32 [[OR]] to float 207; CHECK-NEXT: ret float [[FNEG]] 208; 209 %bitcast = bitcast <2 x i16> %val to i32 210 %or = or i32 %bitcast, -2147483648 211 %fneg = bitcast i32 %or to float 212 ret float %fneg 213} 214 215define i128 @fneg_fabs_as_int_fp128_f64_mask(fp128 %x) { 216; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f64_mask 217; CHECK-SAME: (fp128 [[X:%.*]]) { 218; CHECK-NEXT: [[BC:%.*]] = bitcast fp128 [[X]] to i128 219; CHECK-NEXT: [[OR:%.*]] = or i128 [[BC]], -9223372036854775808 220; CHECK-NEXT: ret i128 [[OR]] 221; 222 %bc = bitcast fp128 %x to i128 223 %or = or i128 %bc, -9223372036854775808 224 ret i128 %or 225} 226 227define i128 @fneg_fabs_as_int_fp128_f128_mask(fp128 %x) { 228; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f128_mask 229; CHECK-SAME: (fp128 [[X:%.*]]) { 230; CHECK-NEXT: [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]]) 231; CHECK-NEXT: [[TMP2:%.*]] = fneg fp128 [[TMP1]] 232; CHECK-NEXT: [[OR:%.*]] = bitcast fp128 [[TMP2]] to i128 233; CHECK-NEXT: ret i128 [[OR]] 234; 235 %bc = bitcast fp128 %x to i128 236 %or = or i128 %bc, -170141183460469231731687303715884105728 237 ret i128 %or 238} 239 240define i16 @fneg_fabs_as_int_f16(half %x) { 241; CHECK-LABEL: define i16 @fneg_fabs_as_int_f16 242; CHECK-SAME: (half [[X:%.*]]) { 243; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]]) 244; CHECK-NEXT: [[TMP2:%.*]] = fneg half [[TMP1]] 245; CHECK-NEXT: [[OR:%.*]] = bitcast half [[TMP2]] to i16 246; CHECK-NEXT: ret i16 [[OR]] 247; 248 %bc = bitcast half %x to i16 249 %or = or i16 %bc, -32768 250 ret i16 %or 251} 252 253define <2 x i16> @fneg_fabs_as_int_v2f16(<2 x half> %x) { 254; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2f16 255; CHECK-SAME: (<2 x half> [[X:%.*]]) { 256; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]]) 257; CHECK-NEXT: [[TMP2:%.*]] = fneg <2 x half> [[TMP1]] 258; CHECK-NEXT: [[OR:%.*]] = bitcast <2 x half> [[TMP2]] to <2 x i16> 259; CHECK-NEXT: ret <2 x i16> [[OR]] 260; 261 %bc = bitcast <2 x half> %x to <2 x i16> 262 %or = or <2 x i16> %bc, <i16 -32768, i16 -32768> 263 ret <2 x i16> %or 264} 265 266define i16 @fneg_fabs_as_int_bf16(bfloat %x) { 267; CHECK-LABEL: define i16 @fneg_fabs_as_int_bf16 268; CHECK-SAME: (bfloat [[X:%.*]]) { 269; CHECK-NEXT: [[TMP1:%.*]] = call bfloat @llvm.fabs.bf16(bfloat [[X]]) 270; CHECK-NEXT: [[TMP2:%.*]] = fneg bfloat [[TMP1]] 271; CHECK-NEXT: [[OR:%.*]] = bitcast bfloat [[TMP2]] to i16 272; CHECK-NEXT: ret i16 [[OR]] 273; 274 %bc = bitcast bfloat %x to i16 275 %or = or i16 %bc, -32768 276 ret i16 %or 277} 278 279define <2 x i16> @fneg_fabs_as_int_v2bf16(<2 x bfloat> %x) { 280; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2bf16 281; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) { 282; CHECK-NEXT: [[TMP1:%.*]] = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> [[X]]) 283; CHECK-NEXT: [[TMP2:%.*]] = fneg <2 x bfloat> [[TMP1]] 284; CHECK-NEXT: [[OR:%.*]] = bitcast <2 x bfloat> [[TMP2]] to <2 x i16> 285; CHECK-NEXT: ret <2 x i16> [[OR]] 286; 287 %bc = bitcast <2 x bfloat> %x to <2 x i16> 288 %or = or <2 x i16> %bc, <i16 -32768, i16 -32768> 289 ret <2 x i16> %or 290} 291 292define i80 @fneg_fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) { 293; CHECK-LABEL: define i80 @fneg_fabs_as_int_x86_fp80_f64_mask 294; CHECK-SAME: (x86_fp80 [[X:%.*]]) { 295; CHECK-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[X]]) 296; CHECK-NEXT: [[TMP2:%.*]] = fneg x86_fp80 [[TMP1]] 297; CHECK-NEXT: [[OR:%.*]] = bitcast x86_fp80 [[TMP2]] to i80 298; CHECK-NEXT: ret i80 [[OR]] 299; 300 %bc = bitcast x86_fp80 %x to i80 301 %or = or i80 %bc, -604462909807314587353088 302 ret i80 %or 303} 304 305define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) { 306; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask 307; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 308; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 309; CHECK-NEXT: [[OR:%.*]] = or i128 [[BC]], -9223372036854775808 310; CHECK-NEXT: ret i128 [[OR]] 311; 312 %bc = bitcast ppc_fp128 %x to i128 313 %or = or i128 %bc, -9223372036854775808 314 ret i128 %or 315} 316 317define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) { 318; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask 319; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 320; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 321; CHECK-NEXT: [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728 322; CHECK-NEXT: ret i128 [[OR]] 323; 324 %bc = bitcast ppc_fp128 %x to i128 325 %or = or i128 %bc, -170141183460469231731687303715884105728 326 ret i128 %or 327} 328