1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4declare void @use(i32) 5declare void @usef32(float) 6 7declare i32 @llvm.ctlz.i32(i32, i1) 8declare <3 x i17> @llvm.ctlz.v3i17(<3 x i17>, i1) 9 10declare i32 @llvm.cttz.i32(i32, i1) 11declare <3 x i5> @llvm.cttz.v3i5(<3 x i5>, i1) 12 13declare i32 @llvm.ctpop.i32(i32) 14declare <3 x i7> @llvm.ctpop.v3i7(<3 x i7>) 15 16declare i32 @llvm.usub.sat.i32(i32, i32) 17 18define i32 @ctlz_sel_const_true_false(i1 %b) { 19; CHECK-LABEL: @ctlz_sel_const_true_false( 20; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 29, i32 0 21; CHECK-NEXT: ret i32 [[C]] 22; 23 %s = select i1 %b, i32 5, i32 -7 24 %c = call i32 @llvm.ctlz.i32(i32 %s, i1 true) 25 ret i32 %c 26} 27 28define i32 @ctlz_sel_const_true(i1 %b, i32 %x) { 29; CHECK-LABEL: @ctlz_sel_const_true( 30; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false) 31; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 29, i32 [[TMP1]] 32; CHECK-NEXT: ret i32 [[C]] 33; 34 %s = select i1 %b, i32 5, i32 %x 35 %c = call i32 @llvm.ctlz.i32(i32 %s, i1 false) 36 ret i32 %c 37} 38 39define <3 x i17> @ctlz_sel_const_false(<3 x i1> %b, <3 x i17> %x) { 40; CHECK-LABEL: @ctlz_sel_const_false( 41; CHECK-NEXT: [[TMP1:%.*]] = call range(i17 0, 18) <3 x i17> @llvm.ctlz.v3i17(<3 x i17> [[X:%.*]], i1 true) 42; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i17> [[TMP1]], <3 x i17> <i17 14, i17 0, i17 poison> 43; CHECK-NEXT: ret <3 x i17> [[C]] 44; 45 %s = select <3 x i1> %b, <3 x i17> %x, <3 x i17> <i17 7, i17 -1, i17 0> 46 %c = call <3 x i17> @llvm.ctlz.v3i17(<3 x i17> %s, i1 true) 47 ret <3 x i17> %c 48} 49 50define i32 @ctlz_sel_const_true_false_extra_use(i1 %b) { 51; CHECK-LABEL: @ctlz_sel_const_true_false_extra_use( 52; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 -1, i32 7 53; CHECK-NEXT: call void @use(i32 [[S]]) 54; CHECK-NEXT: [[C:%.*]] = call range(i32 0, 30) i32 @llvm.ctlz.i32(i32 [[S]], i1 true) 55; CHECK-NEXT: ret i32 [[C]] 56; 57 %s = select i1 %b, i32 -1, i32 7 58 call void @use(i32 %s) 59 %c = call i32 @llvm.ctlz.i32(i32 %s, i1 false) 60 ret i32 %c 61} 62 63define i32 @cttz_sel_const_true_false(i1 %b) { 64; CHECK-LABEL: @cttz_sel_const_true_false( 65; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 0 66; CHECK-NEXT: ret i32 [[C]] 67; 68 %s = select i1 %b, i32 4, i32 -7 69 %c = call i32 @llvm.cttz.i32(i32 %s, i1 false) 70 ret i32 %c 71} 72 73define i32 @cttz_sel_const_true(i1 %b, i32 %x) { 74; CHECK-LABEL: @cttz_sel_const_true( 75; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true) 76; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 [[TMP1]] 77; CHECK-NEXT: ret i32 [[C]] 78; 79 %s = select i1 %b, i32 5, i32 %x 80 %c = call i32 @llvm.cttz.i32(i32 %s, i1 true) 81 ret i32 %c 82} 83 84define <3 x i5> @cttz_sel_const_false(<3 x i1> %b, <3 x i5> %x) { 85; CHECK-LABEL: @cttz_sel_const_false( 86; CHECK-NEXT: [[TMP1:%.*]] = call range(i5 0, 6) <3 x i5> @llvm.cttz.v3i5(<3 x i5> [[X:%.*]], i1 false) 87; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i5> [[TMP1]], <3 x i5> <i5 0, i5 0, i5 5> 88; CHECK-NEXT: ret <3 x i5> [[C]] 89; 90 %s = select <3 x i1> %b, <3 x i5> %x, <3 x i5> <i5 7, i5 -1, i5 0> 91 %c = call <3 x i5> @llvm.cttz.v3i5(<3 x i5> %s, i1 false) 92 ret <3 x i5> %c 93} 94 95define i32 @cttz_sel_const_true_false_extra_use(i1 %b) { 96; CHECK-LABEL: @cttz_sel_const_true_false_extra_use( 97; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 -8 98; CHECK-NEXT: call void @use(i32 [[S]]) 99; CHECK-NEXT: [[C:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[S]], i1 true) 100; CHECK-NEXT: ret i32 [[C]] 101; 102 %s = select i1 %b, i32 5, i32 -8 103 call void @use(i32 %s) 104 %c = call i32 @llvm.cttz.i32(i32 %s, i1 true) 105 ret i32 %c 106} 107 108define i32 @ctpop_sel_const_true_false(i1 %b) { 109; CHECK-LABEL: @ctpop_sel_const_true_false( 110; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 30 111; CHECK-NEXT: ret i32 [[C]] 112; 113 %s = select i1 %b, i32 5, i32 -7 114 %c = call i32 @llvm.ctpop.i32(i32 %s) 115 ret i32 %c 116} 117 118define i32 @ctpop_sel_const_true(i1 %b, i32 %x) { 119; CHECK-LABEL: @ctpop_sel_const_true( 120; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]]) 121; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 [[TMP1]] 122; CHECK-NEXT: ret i32 [[C]] 123; 124 %s = select i1 %b, i32 5, i32 %x 125 %c = call i32 @llvm.ctpop.i32(i32 %s) 126 ret i32 %c 127} 128 129define <3 x i7> @ctpop_sel_const_false(<3 x i1> %b, <3 x i7> %x) { 130; CHECK-LABEL: @ctpop_sel_const_false( 131; CHECK-NEXT: [[TMP1:%.*]] = call range(i7 0, 8) <3 x i7> @llvm.ctpop.v3i7(<3 x i7> [[X:%.*]]) 132; CHECK-NEXT: [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i7> [[TMP1]], <3 x i7> <i7 3, i7 7, i7 0> 133; CHECK-NEXT: ret <3 x i7> [[C]] 134; 135 %s = select <3 x i1> %b, <3 x i7> %x, <3 x i7> <i7 7, i7 -1, i7 0> 136 %c = call <3 x i7> @llvm.ctpop.v3i7(<3 x i7> %s) 137 ret <3 x i7> %c 138} 139 140define i32 @ctpop_sel_const_true_false_extra_use(i1 %b) { 141; CHECK-LABEL: @ctpop_sel_const_true_false_extra_use( 142; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 7 143; CHECK-NEXT: call void @use(i32 [[S]]) 144; CHECK-NEXT: [[C:%.*]] = call range(i32 2, 4) i32 @llvm.ctpop.i32(i32 [[S]]) 145; CHECK-NEXT: ret i32 [[C]] 146; 147 %s = select i1 %b, i32 5, i32 7 148 call void @use(i32 %s) 149 %c = call i32 @llvm.ctpop.i32(i32 %s) 150 ret i32 %c 151} 152 153define i32 @usub_sat_rhs_const_select_all_const(i1 %b) { 154; CHECK-LABEL: @usub_sat_rhs_const_select_all_const( 155; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 3 156; CHECK-NEXT: ret i32 [[C]] 157; 158 %s = select i1 %b, i32 5, i32 10 159 %c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7) 160 ret i32 %c 161} 162 163define i32 @usub_sat_rhs_var_select_all_const(i1 %b, i32 %x) { 164; CHECK-LABEL: @usub_sat_rhs_var_select_all_const( 165; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 5, i32 10 166; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[S]], i32 [[X:%.*]]) 167; CHECK-NEXT: ret i32 [[C]] 168; 169 %s = select i1 %b, i32 5, i32 10 170 %c = call i32 @llvm.usub.sat.i32(i32 %s, i32 %x) 171 ret i32 %c 172} 173 174define i32 @usub_sat_rhs_const_select_one_const(i1 %b, i32 %x) { 175; CHECK-LABEL: @usub_sat_rhs_const_select_one_const( 176; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X:%.*]], i32 7) 177; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 0, i32 [[TMP1]] 178; CHECK-NEXT: ret i32 [[C]] 179; 180 %s = select i1 %b, i32 5, i32 %x 181 %c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7) 182 ret i32 %c 183} 184 185define i32 @usub_sat_rhs_const_select_no_const(i1 %b, i32 %x, i32 %y) { 186; CHECK-LABEL: @usub_sat_rhs_const_select_no_const( 187; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[Y:%.*]], i32 [[X:%.*]] 188; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[S]], i32 7) 189; CHECK-NEXT: ret i32 [[C]] 190; 191 %s = select i1 %b, i32 %y, i32 %x 192 %c = call i32 @llvm.usub.sat.i32(i32 %s, i32 7) 193 ret i32 %c 194} 195 196define i32 @usub_sat_lhs_const_select_all_const(i1 %b) { 197; CHECK-LABEL: @usub_sat_lhs_const_select_all_const( 198; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i32 2, i32 0 199; CHECK-NEXT: ret i32 [[C]] 200; 201 %s = select i1 %b, i32 5, i32 10 202 %c = call i32 @llvm.usub.sat.i32(i32 7, i32 %s) 203 ret i32 %c 204} 205 206@g1 = constant <2 x i32> zeroinitializer 207@g2 = external global i8 208declare <2 x i32> @llvm.masked.load.v2i32.p0(ptr, i32, <2 x i1>, <2 x i32>) 209 210define <2 x i32> @non_speculatable(i1 %b) { 211; CHECK-LABEL: @non_speculatable( 212; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], ptr @g1, ptr @g2 213; CHECK-NEXT: [[C:%.*]] = call <2 x i32> @llvm.masked.load.v2i32.p0(ptr nonnull [[S]], i32 64, <2 x i1> <i1 true, i1 false>, <2 x i32> poison) 214; CHECK-NEXT: ret <2 x i32> [[C]] 215; 216 %s = select i1 %b, ptr @g1, ptr @g2 217 %c = call <2 x i32> @llvm.masked.load.v2i32.p0(ptr %s, i32 64, <2 x i1> <i1 true, i1 false>, <2 x i32> poison) 218 ret <2 x i32> %c 219} 220 221declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>) 222 223define i32 @vec_to_scalar_select_scalar(i1 %b) { 224; CHECK-LABEL: @vec_to_scalar_select_scalar( 225; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> 226; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[S]]) 227; CHECK-NEXT: ret i32 [[C]] 228; 229 %s = select i1 %b, <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> 230 %c = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %s) 231 ret i32 %c 232} 233 234define i32 @vec_to_scalar_select_vector(<2 x i1> %b) { 235; CHECK-LABEL: @vec_to_scalar_select_vector( 236; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[B:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> 237; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[S]]) 238; CHECK-NEXT: ret i32 [[C]] 239; 240 %s = select <2 x i1> %b, <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> 241 %c = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %s) 242 ret i32 %c 243} 244 245define i8 @test_drop_noundef(i1 %cond, i8 %val) { 246; CHECK-LABEL: @test_drop_noundef( 247; CHECK-NEXT: entry: 248; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.smin.i8(i8 [[VAL:%.*]], i8 0) 249; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 -1, i8 [[TMP0]] 250; CHECK-NEXT: ret i8 [[RET]] 251; 252entry: 253 %sel = select i1 %cond, i8 -1, i8 %val 254 %ret = call noundef i8 @llvm.smin.i8(i8 %sel, i8 0) 255 ret i8 %ret 256} 257 258define i1 @pr85536(i32 %a) { 259; CHECK-LABEL: @pr85536( 260; CHECK-NEXT: entry: 261; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 31 262; CHECK-NEXT: [[SHL1:%.*]] = shl nsw i32 -1, [[A]] 263; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL1]] to i64 264; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[ZEXT]], 48 265; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[SHL2]], 48 266; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smin.i64(i64 [[SHR]], i64 0) 267; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65535 268; CHECK-NEXT: [[RET1:%.*]] = icmp eq i64 [[TMP1]], 0 269; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i1 [[RET1]], i1 false 270; CHECK-NEXT: ret i1 [[RET]] 271; 272entry: 273 %cmp1 = icmp ugt i32 %a, 30 274 %shl1 = shl nsw i32 -1, %a 275 %zext = zext i32 %shl1 to i64 276 %shl2 = shl i64 %zext, 48 277 %shr = ashr exact i64 %shl2, 48 278 %sel = select i1 %cmp1, i64 -1, i64 %shr 279 %smin = call noundef i64 @llvm.smin.i64(i64 %sel, i64 0) 280 %masked = and i64 %smin, 65535 281 %ret = icmp eq i64 %masked, 0 282 ret i1 %ret 283} 284 285define double @test_fabs_select1(double %a) { 286; CHECK-LABEL: @test_fabs_select1( 287; CHECK-NEXT: [[COND:%.*]] = fcmp uno double [[A:%.*]], 0.000000e+00 288; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], double 0x7FF8000000000000, double [[A]] 289; CHECK-NEXT: ret double [[SEL1]] 290; 291 %cond = fcmp uno double %a, 0.000000e+00 292 %sel1 = select i1 %cond, double 0x7FF8000000000000, double %a 293 %fabs = call double @llvm.fabs.f64(double %sel1) 294 %sel2 = select i1 %cond, double %fabs, double %a 295 ret double %sel2 296} 297 298define <2 x double> @test_fabs_select1_vec(<2 x double> %a) { 299; CHECK-LABEL: @test_fabs_select1_vec( 300; CHECK-NEXT: [[COND:%.*]] = fcmp uno <2 x double> [[A:%.*]], zeroinitializer 301; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[COND]], <2 x double> splat (double 0x7FF8000000000000), <2 x double> [[A]] 302; CHECK-NEXT: ret <2 x double> [[SEL2]] 303; 304 %cond = fcmp uno <2 x double> %a, zeroinitializer 305 %sel1 = select <2 x i1> %cond, <2 x double> splat(double 0x7FF8000000000000), <2 x double> %a 306 %fabs = call <2 x double> @llvm.fabs.v2f64(<2 x double> %sel1) 307 %sel2 = select <2 x i1> %cond, <2 x double> %fabs, <2 x double> %a 308 ret <2 x double> %sel2 309} 310 311define double @test_fabs_select2(double %a) { 312; CHECK-LABEL: @test_fabs_select2( 313; CHECK-NEXT: [[ABS1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]]) 314; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[ABS1]], 0x7FF0000000000000 315; CHECK-NEXT: [[ABS2:%.*]] = select i1 [[CMP]], double 0.000000e+00, double [[ABS1]] 316; CHECK-NEXT: ret double [[ABS2]] 317; 318 %abs1 = call double @llvm.fabs.f64(double %a) 319 %cmp = fcmp oeq double %abs1, 0x7FF0000000000000 320 %sel = select i1 %cmp, double -0.000000e+00, double %abs1 321 %abs2 = call double @llvm.fabs.f64(double %sel) 322 ret double %abs2 323} 324 325; nsz flag should be dropped. 326 327define double @test_fabs_select_fmf1(i1 %cond, double %a) { 328; CHECK-LABEL: @test_fabs_select_fmf1( 329; CHECK-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[A1:%.*]]) 330; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[COND:%.*]], double 0.000000e+00, double [[A]] 331; CHECK-NEXT: ret double [[FABS]] 332; 333 %sel1 = select nnan ninf nsz i1 %cond, double 0.0, double %a 334 %fabs = call double @llvm.fabs.f64(double %sel1) 335 ret double %fabs 336} 337 338define double @test_fabs_select_fmf2(i1 %cond, double %a) { 339; CHECK-LABEL: @test_fabs_select_fmf2( 340; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]]) 341; CHECK-NEXT: [[SEL1:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], double 0.000000e+00, double [[TMP1]] 342; CHECK-NEXT: ret double [[SEL1]] 343; 344 %sel1 = select i1 %cond, double 0.0, double %a 345 %fabs = call nnan ninf nsz double @llvm.fabs.f64(double %sel1) 346 ret double %fabs 347} 348 349define float @test_fabs_select_multiuse(i1 %cond, float %x) { 350; CHECK-LABEL: @test_fabs_select_multiuse( 351; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float [[X:%.*]], float 0x7FF0000000000000 352; CHECK-NEXT: call void @usef32(float [[SELECT]]) 353; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]]) 354; CHECK-NEXT: ret float [[FABS]] 355; 356 %select = select i1 %cond, float %x, float 0x7FF0000000000000 357 call void @usef32(float %select) 358 %fabs = call float @llvm.fabs.f32(float %select) 359 ret float %fabs 360} 361 362define float @test_fabs_select_multiuse_both_constant(i1 %cond, float %x) { 363; CHECK-LABEL: @test_fabs_select_multiuse_both_constant( 364; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float -1.000000e+00, float -2.000000e+00 365; CHECK-NEXT: call void @usef32(float [[SELECT]]) 366; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float 1.000000e+00, float 2.000000e+00 367; CHECK-NEXT: ret float [[FABS]] 368; 369 %select = select i1 %cond, float -1.0, float -2.0 370 call void @usef32(float %select) 371 %fabs = call float @llvm.fabs.f32(float %select) 372 ret float %fabs 373} 374