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 @fabs_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat { 5; CHECK-LABEL: define float @fabs_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: [[AND:%.*]] = and i32 [[BITCAST]], 2147483647 9; CHECK-NEXT: [[FABS:%.*]] = bitcast i32 [[AND]] to float 10; CHECK-NEXT: ret float [[FABS]] 11; 12 %bitcast = bitcast float %val to i32 13 %and = and i32 %bitcast, 2147483647 14 %fabs = bitcast i32 %and to float 15 ret float %fabs 16} 17 18define <2 x i32> @fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat { 19; CHECK-LABEL: define <2 x i32> @fabs_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: [[AND:%.*]] = and <2 x i32> [[BC]], splat (i32 2147483647) 23; CHECK-NEXT: ret <2 x i32> [[AND]] 24; 25 %bc = bitcast <2 x float> %x to <2 x i32> 26 %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647> 27 ret <2 x i32> %and 28} 29 30define float @fabs_as_int_f32_castback(float %val) { 31; CHECK-LABEL: define float @fabs_as_int_f32_castback 32; CHECK-SAME: (float [[VAL:%.*]]) { 33; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 34; CHECK-NEXT: ret float [[TMP1]] 35; 36 %bitcast = bitcast float %val to i32 37 %and = and i32 %bitcast, 2147483647 38 %fabs = bitcast i32 %and to float 39 ret float %fabs 40} 41 42define float @not_fabs_as_int_f32_castback_wrongconst(float %val) { 43; CHECK-LABEL: define float @not_fabs_as_int_f32_castback_wrongconst 44; CHECK-SAME: (float [[VAL:%.*]]) { 45; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 46; CHECK-NEXT: ret float [[TMP1]] 47; 48 %bitcast = bitcast float %val to i32 49 %and = and i32 %bitcast, 2147483647 50 %fabs = bitcast i32 %and to float 51 ret float %fabs 52} 53 54define float @fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) { 55; CHECK-LABEL: define float @fabs_as_int_f32_castback_multi_use 56; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) { 57; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]]) 58; CHECK-NEXT: store float [[TMP1]], ptr [[PTR]], align 4 59; CHECK-NEXT: ret float [[TMP1]] 60; 61 %bitcast = bitcast float %val to i32 62 %and = and i32 %bitcast, 2147483647 63 store i32 %and, ptr %ptr 64 %fabs = bitcast i32 %and to float 65 ret float %fabs 66} 67 68define i64 @fabs_as_int_f64(double %x) { 69; CHECK-LABEL: define i64 @fabs_as_int_f64 70; CHECK-SAME: (double [[X:%.*]]) { 71; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]]) 72; CHECK-NEXT: [[AND:%.*]] = bitcast double [[TMP1]] to i64 73; CHECK-NEXT: ret i64 [[AND]] 74; 75 %bc = bitcast double %x to i64 76 %and = and i64 %bc, 9223372036854775807 77 ret i64 %and 78} 79 80define <2 x i64> @fabs_as_int_v2f64(<2 x double> %x) { 81; CHECK-LABEL: define <2 x i64> @fabs_as_int_v2f64 82; CHECK-SAME: (<2 x double> [[X:%.*]]) { 83; CHECK-NEXT: [[TMP1:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]]) 84; CHECK-NEXT: [[AND:%.*]] = bitcast <2 x double> [[TMP1]] to <2 x i64> 85; CHECK-NEXT: ret <2 x i64> [[AND]] 86; 87 %bc = bitcast <2 x double> %x to <2 x i64> 88 %and = and <2 x i64> %bc, <i64 9223372036854775807, i64 9223372036854775807> 89 ret <2 x i64> %and 90} 91 92define i64 @fabs_as_int_f64_swap(double %x) { 93; CHECK-LABEL: define i64 @fabs_as_int_f64_swap 94; CHECK-SAME: (double [[X:%.*]]) { 95; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]]) 96; CHECK-NEXT: [[AND:%.*]] = bitcast double [[TMP1]] to i64 97; CHECK-NEXT: ret i64 [[AND]] 98; 99 %bc = bitcast double %x to i64 100 %and = and i64 9223372036854775807, %bc 101 ret i64 %and 102} 103 104define i32 @fabs_as_int_f32(float %x) { 105; CHECK-LABEL: define i32 @fabs_as_int_f32 106; CHECK-SAME: (float [[X:%.*]]) { 107; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 108; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32 109; CHECK-NEXT: ret i32 [[AND]] 110; 111 %bc = bitcast float %x to i32 112 %and = and i32 %bc, 2147483647 113 ret i32 %and 114} 115 116define <2 x i32> @fabs_as_int_v2f32(<2 x float> %x) { 117; CHECK-LABEL: define <2 x i32> @fabs_as_int_v2f32 118; CHECK-SAME: (<2 x float> [[X:%.*]]) { 119; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]]) 120; CHECK-NEXT: [[AND:%.*]] = bitcast <2 x float> [[TMP1]] to <2 x i32> 121; CHECK-NEXT: ret <2 x i32> [[AND]] 122; 123 %bc = bitcast <2 x float> %x to <2 x i32> 124 %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647> 125 ret <2 x i32> %and 126} 127 128define <2 x i32> @not_fabs_as_int_v2f32_nonsplat(<2 x float> %x) { 129; CHECK-LABEL: define <2 x i32> @not_fabs_as_int_v2f32_nonsplat 130; CHECK-SAME: (<2 x float> [[X:%.*]]) { 131; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> 132; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[BC]], <i32 2147483647, i32 2147483646> 133; CHECK-NEXT: ret <2 x i32> [[AND]] 134; 135 %bc = bitcast <2 x float> %x to <2 x i32> 136 %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483646> 137 ret <2 x i32> %and 138} 139 140define <3 x i32> @fabs_as_int_v3f32_poison(<3 x float> %x) { 141; CHECK-LABEL: define <3 x i32> @fabs_as_int_v3f32_poison 142; CHECK-SAME: (<3 x float> [[X:%.*]]) { 143; CHECK-NEXT: [[TMP1:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[X]]) 144; CHECK-NEXT: [[AND:%.*]] = bitcast <3 x float> [[TMP1]] to <3 x i32> 145; CHECK-NEXT: ret <3 x i32> [[AND]] 146; 147 %bc = bitcast <3 x float> %x to <3 x i32> 148 %and = and <3 x i32> %bc, <i32 2147483647, i32 poison, i32 2147483647> 149 ret <3 x i32> %and 150} 151 152; Make sure that only a bitcast is transformed. 153define i64 @fabs_as_int_f64_not_bitcast(double %x) { 154; CHECK-LABEL: define i64 @fabs_as_int_f64_not_bitcast 155; CHECK-SAME: (double [[X:%.*]]) { 156; CHECK-NEXT: [[BC:%.*]] = fptoui double [[X]] to i64 157; CHECK-NEXT: [[AND:%.*]] = and i64 [[BC]], 9223372036854775807 158; CHECK-NEXT: ret i64 [[AND]] 159; 160 %bc = fptoui double %x to i64 161 %and = and i64 %bc, 9223372036854775807 162 ret i64 %and 163} 164 165define float @not_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) { 166; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2f16 167; CHECK-SAME: (<2 x half> [[VAL:%.*]]) { 168; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32 169; CHECK-NEXT: [[AND:%.*]] = and i32 [[BITCAST]], 2147483647 170; CHECK-NEXT: [[FABS:%.*]] = bitcast i32 [[AND]] to float 171; CHECK-NEXT: ret float [[FABS]] 172; 173 %bitcast = bitcast <2 x half> %val to i32 174 %and = and i32 %bitcast, 2147483647 175 %fabs = bitcast i32 %and to float 176 ret float %fabs 177} 178 179define float @not_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) { 180; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2i16 181; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) { 182; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32 183; CHECK-NEXT: [[AND:%.*]] = and i32 [[BITCAST]], 2147483647 184; CHECK-NEXT: [[FABS:%.*]] = bitcast i32 [[AND]] to float 185; CHECK-NEXT: ret float [[FABS]] 186; 187 %bitcast = bitcast <2 x i16> %val to i32 188 %and = and i32 %bitcast, 2147483647 189 %fabs = bitcast i32 %and to float 190 ret float %fabs 191} 192 193define i128 @fabs_as_int_fp128_f64_mask(fp128 %x) { 194; CHECK-LABEL: define i128 @fabs_as_int_fp128_f64_mask 195; CHECK-SAME: (fp128 [[X:%.*]]) { 196; CHECK-NEXT: [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]]) 197; CHECK-NEXT: [[AND:%.*]] = bitcast fp128 [[TMP1]] to i128 198; CHECK-NEXT: ret i128 [[AND]] 199; 200 %bc = bitcast fp128 %x to i128 201 %and = and i128 %bc, 170141183460469231731687303715884105727 202 ret i128 %and 203} 204 205define i128 @fabs_as_int_fp128_f128_mask(fp128 %x) { 206; CHECK-LABEL: define i128 @fabs_as_int_fp128_f128_mask 207; CHECK-SAME: (fp128 [[X:%.*]]) { 208; CHECK-NEXT: [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]]) 209; CHECK-NEXT: [[AND:%.*]] = bitcast fp128 [[TMP1]] to i128 210; CHECK-NEXT: ret i128 [[AND]] 211; 212 %bc = bitcast fp128 %x to i128 213 %and = and i128 %bc, 170141183460469231731687303715884105727 214 ret i128 %and 215} 216 217define i16 @fabs_as_int_f16(half %x) { 218; CHECK-LABEL: define i16 @fabs_as_int_f16 219; CHECK-SAME: (half [[X:%.*]]) { 220; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]]) 221; CHECK-NEXT: [[AND:%.*]] = bitcast half [[TMP1]] to i16 222; CHECK-NEXT: ret i16 [[AND]] 223; 224 %bc = bitcast half %x to i16 225 %and = and i16 %bc, 32767 226 ret i16 %and 227} 228 229define <2 x i16> @fabs_as_int_v2f16(<2 x half> %x) { 230; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2f16 231; CHECK-SAME: (<2 x half> [[X:%.*]]) { 232; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]]) 233; CHECK-NEXT: [[AND:%.*]] = bitcast <2 x half> [[TMP1]] to <2 x i16> 234; CHECK-NEXT: ret <2 x i16> [[AND]] 235; 236 %bc = bitcast <2 x half> %x to <2 x i16> 237 %and = and <2 x i16> %bc, <i16 32767, i16 32767> 238 ret <2 x i16> %and 239} 240 241define i16 @fabs_as_int_bf16(bfloat %x) { 242; CHECK-LABEL: define i16 @fabs_as_int_bf16 243; CHECK-SAME: (bfloat [[X:%.*]]) { 244; CHECK-NEXT: [[TMP1:%.*]] = call bfloat @llvm.fabs.bf16(bfloat [[X]]) 245; CHECK-NEXT: [[AND:%.*]] = bitcast bfloat [[TMP1]] to i16 246; CHECK-NEXT: ret i16 [[AND]] 247; 248 %bc = bitcast bfloat %x to i16 249 %and = and i16 %bc, 32767 250 ret i16 %and 251} 252 253define <2 x i16> @fabs_as_int_v2bf16(<2 x bfloat> %x) { 254; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2bf16 255; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) { 256; CHECK-NEXT: [[TMP1:%.*]] = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> [[X]]) 257; CHECK-NEXT: [[AND:%.*]] = bitcast <2 x bfloat> [[TMP1]] to <2 x i16> 258; CHECK-NEXT: ret <2 x i16> [[AND]] 259; 260 %bc = bitcast <2 x bfloat> %x to <2 x i16> 261 %and = and <2 x i16> %bc, <i16 32767, i16 32767> 262 ret <2 x i16> %and 263} 264 265define i80 @fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) { 266; CHECK-LABEL: define i80 @fabs_as_int_x86_fp80_f64_mask 267; CHECK-SAME: (x86_fp80 [[X:%.*]]) { 268; CHECK-NEXT: [[BC:%.*]] = bitcast x86_fp80 [[X]] to i80 269; CHECK-NEXT: [[AND:%.*]] = and i80 [[BC]], 9223372036854775807 270; CHECK-NEXT: ret i80 [[AND]] 271; 272 %bc = bitcast x86_fp80 %x to i80 273 %and = and i80 %bc, 9223372036854775807 274 ret i80 %and 275} 276 277define i128 @fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) { 278; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f64_mask 279; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 280; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 281; CHECK-NEXT: [[AND:%.*]] = and i128 [[BC]], 9223372036854775807 282; CHECK-NEXT: ret i128 [[AND]] 283; 284 %bc = bitcast ppc_fp128 %x to i128 285 %and = and i128 %bc, 9223372036854775807 286 ret i128 %and 287} 288 289define i128 @fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) { 290; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f128_mask 291; CHECK-SAME: (ppc_fp128 [[X:%.*]]) { 292; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128 293; CHECK-NEXT: [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727 294; CHECK-NEXT: ret i128 [[AND]] 295; 296 %bc = bitcast ppc_fp128 %x to i128 297 %and = and i128 %bc, 170141183460469231731687303715884105727 298 ret i128 %and 299} 300