1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; Widen a select of constants to eliminate an extend. 5 6define i16 @sel_sext_constants(i1 %cmp) { 7; CHECK-LABEL: @sel_sext_constants( 8; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i16 -1, i16 42 9; CHECK-NEXT: ret i16 [[EXT]] 10; 11 %sel = select i1 %cmp, i8 255, i8 42 12 %ext = sext i8 %sel to i16 13 ret i16 %ext 14} 15 16define i16 @sel_zext_constants(i1 %cmp) { 17; CHECK-LABEL: @sel_zext_constants( 18; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i16 255, i16 42 19; CHECK-NEXT: ret i16 [[EXT]] 20; 21 %sel = select i1 %cmp, i8 255, i8 42 22 %ext = zext i8 %sel to i16 23 ret i16 %ext 24} 25 26define double @sel_fpext_constants(i1 %cmp) { 27; CHECK-LABEL: @sel_fpext_constants( 28; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], double -2.550000e+02, double 4.200000e+01 29; CHECK-NEXT: ret double [[EXT]] 30; 31 %sel = select i1 %cmp, float -255.0, float 42.0 32 %ext = fpext float %sel to double 33 ret double %ext 34} 35 36; FIXME: We should not grow the size of the select in the next 4 cases. 37 38define i64 @sel_sext(i32 %a, i1 %cmp) { 39; CHECK-LABEL: @sel_sext( 40; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[A:%.*]] to i64 41; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 42; CHECK-NEXT: ret i64 [[EXT]] 43; 44 %sel = select i1 %cmp, i32 %a, i32 42 45 %ext = sext i32 %sel to i64 46 ret i64 %ext 47} 48 49define <4 x i64> @sel_sext_vec(<4 x i32> %a, <4 x i1> %cmp) { 50; CHECK-LABEL: @sel_sext_vec( 51; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64> 52; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 53; CHECK-NEXT: ret <4 x i64> [[EXT]] 54; 55 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 56 %ext = sext <4 x i32> %sel to <4 x i64> 57 ret <4 x i64> %ext 58} 59 60define i64 @sel_zext(i32 %a, i1 %cmp) { 61; CHECK-LABEL: @sel_zext( 62; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64 63; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 64; CHECK-NEXT: ret i64 [[EXT]] 65; 66 %sel = select i1 %cmp, i32 %a, i32 42 67 %ext = zext i32 %sel to i64 68 ret i64 %ext 69} 70 71define <4 x i64> @sel_zext_vec(<4 x i32> %a, <4 x i1> %cmp) { 72; CHECK-LABEL: @sel_zext_vec( 73; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> [[A:%.*]] to <4 x i64> 74; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 75; CHECK-NEXT: ret <4 x i64> [[EXT]] 76; 77 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 78 %ext = zext <4 x i32> %sel to <4 x i64> 79 ret <4 x i64> %ext 80} 81 82; FIXME: The next 18 tests cycle through trunc+select and {larger,smaller,equal} {sext,zext,fpext} {scalar,vector}. 83; The only cases where we eliminate an instruction are equal zext with scalar/vector, so that's probably the only 84; way to justify widening the select. 85 86define i64 @trunc_sel_larger_sext(i32 %a, i1 %cmp) { 87; CHECK-LABEL: @trunc_sel_larger_sext( 88; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16 89; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i64 90; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 91; CHECK-NEXT: ret i64 [[EXT]] 92; 93 %trunc = trunc i32 %a to i16 94 %sel = select i1 %cmp, i16 %trunc, i16 42 95 %ext = sext i16 %sel to i64 96 ret i64 %ext 97} 98 99define <2 x i64> @trunc_sel_larger_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 100; CHECK-LABEL: @trunc_sel_larger_sext_vec( 101; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i16> 102; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i16> [[TRUNC]] to <2 x i64> 103; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i64> [[TMP1]], <2 x i64> <i64 42, i64 43> 104; CHECK-NEXT: ret <2 x i64> [[EXT]] 105; 106 %trunc = trunc <2 x i32> %a to <2 x i16> 107 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 108 %ext = sext <2 x i16> %sel to <2 x i64> 109 ret <2 x i64> %ext 110} 111 112define i32 @trunc_sel_smaller_sext(i64 %a, i1 %cmp) { 113; CHECK-LABEL: @trunc_sel_smaller_sext( 114; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[A:%.*]] to i16 115; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i32 116; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP1]], i32 42 117; CHECK-NEXT: ret i32 [[EXT]] 118; 119 %trunc = trunc i64 %a to i16 120 %sel = select i1 %cmp, i16 %trunc, i16 42 121 %ext = sext i16 %sel to i32 122 ret i32 %ext 123} 124 125define <2 x i32> @trunc_sel_smaller_sext_vec(<2 x i64> %a, <2 x i1> %cmp) { 126; CHECK-LABEL: @trunc_sel_smaller_sext_vec( 127; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i16> 128; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i16> [[TRUNC]] to <2 x i32> 129; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 130; CHECK-NEXT: ret <2 x i32> [[EXT]] 131; 132 %trunc = trunc <2 x i64> %a to <2 x i16> 133 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 134 %ext = sext <2 x i16> %sel to <2 x i32> 135 ret <2 x i32> %ext 136} 137 138define i32 @trunc_sel_equal_sext(i32 %a, i1 %cmp) { 139; CHECK-LABEL: @trunc_sel_equal_sext( 140; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[A:%.*]], 16 141; CHECK-NEXT: [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 16 142; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP2]], i32 42 143; CHECK-NEXT: ret i32 [[EXT]] 144; 145 %trunc = trunc i32 %a to i16 146 %sel = select i1 %cmp, i16 %trunc, i16 42 147 %ext = sext i16 %sel to i32 148 ret i32 %ext 149} 150 151define <2 x i32> @trunc_sel_equal_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 152; CHECK-LABEL: @trunc_sel_equal_sext_vec( 153; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[A:%.*]], <i32 16, i32 16> 154; CHECK-NEXT: [[TMP2:%.*]] = ashr exact <2 x i32> [[TMP1]], <i32 16, i32 16> 155; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP2]], <2 x i32> <i32 42, i32 43> 156; CHECK-NEXT: ret <2 x i32> [[EXT]] 157; 158 %trunc = trunc <2 x i32> %a to <2 x i16> 159 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 160 %ext = sext <2 x i16> %sel to <2 x i32> 161 ret <2 x i32> %ext 162} 163 164define i64 @trunc_sel_larger_zext(i32 %a, i1 %cmp) { 165; CHECK-LABEL: @trunc_sel_larger_zext( 166; CHECK-NEXT: [[TRUNC_MASK:%.*]] = and i32 [[A:%.*]], 65535 167; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TRUNC_MASK]] to i64 168; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 169; CHECK-NEXT: ret i64 [[EXT]] 170; 171 %trunc = trunc i32 %a to i16 172 %sel = select i1 %cmp, i16 %trunc, i16 42 173 %ext = zext i16 %sel to i64 174 ret i64 %ext 175} 176 177define <2 x i64> @trunc_sel_larger_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 178; CHECK-LABEL: @trunc_sel_larger_zext_vec( 179; CHECK-NEXT: [[TRUNC_MASK:%.*]] = and <2 x i32> [[A:%.*]], <i32 65535, i32 65535> 180; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i32> [[TRUNC_MASK]] to <2 x i64> 181; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i64> [[TMP1]], <2 x i64> <i64 42, i64 43> 182; CHECK-NEXT: ret <2 x i64> [[EXT]] 183; 184 %trunc = trunc <2 x i32> %a to <2 x i16> 185 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 186 %ext = zext <2 x i16> %sel to <2 x i64> 187 ret <2 x i64> %ext 188} 189 190define i32 @trunc_sel_smaller_zext(i64 %a, i1 %cmp) { 191; CHECK-LABEL: @trunc_sel_smaller_zext( 192; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i32 193; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 65535 194; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP2]], i32 42 195; CHECK-NEXT: ret i32 [[EXT]] 196; 197 %trunc = trunc i64 %a to i16 198 %sel = select i1 %cmp, i16 %trunc, i16 42 199 %ext = zext i16 %sel to i32 200 ret i32 %ext 201} 202 203define <2 x i32> @trunc_sel_smaller_zext_vec(<2 x i64> %a, <2 x i1> %cmp) { 204; CHECK-LABEL: @trunc_sel_smaller_zext_vec( 205; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32> 206; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 65535, i32 65535> 207; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP2]], <2 x i32> <i32 42, i32 43> 208; CHECK-NEXT: ret <2 x i32> [[EXT]] 209; 210 %trunc = trunc <2 x i64> %a to <2 x i16> 211 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 212 %ext = zext <2 x i16> %sel to <2 x i32> 213 ret <2 x i32> %ext 214} 215 216define i32 @trunc_sel_equal_zext(i32 %a, i1 %cmp) { 217; CHECK-LABEL: @trunc_sel_equal_zext( 218; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 65535 219; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP1]], i32 42 220; CHECK-NEXT: ret i32 [[EXT]] 221; 222 %trunc = trunc i32 %a to i16 223 %sel = select i1 %cmp, i16 %trunc, i16 42 224 %ext = zext i16 %sel to i32 225 ret i32 %ext 226} 227 228define <2 x i32> @trunc_sel_equal_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 229; CHECK-LABEL: @trunc_sel_equal_zext_vec( 230; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 65535, i32 65535> 231; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 232; CHECK-NEXT: ret <2 x i32> [[EXT]] 233; 234 %trunc = trunc <2 x i32> %a to <2 x i16> 235 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 236 %ext = zext <2 x i16> %sel to <2 x i32> 237 ret <2 x i32> %ext 238} 239 240define double @trunc_sel_larger_fpext(float %a, i1 %cmp) { 241; CHECK-LABEL: @trunc_sel_larger_fpext( 242; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float [[A:%.*]] to half 243; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to double 244; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], double [[TMP1]], double 4.200000e+01 245; CHECK-NEXT: ret double [[EXT]] 246; 247 %trunc = fptrunc float %a to half 248 %sel = select i1 %cmp, half %trunc, half 42.0 249 %ext = fpext half %sel to double 250 ret double %ext 251} 252 253define <2 x double> @trunc_sel_larger_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 254; CHECK-LABEL: @trunc_sel_larger_fpext_vec( 255; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half> 256; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x double> 257; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x double> [[TMP1]], <2 x double> <double 4.200000e+01, double 4.300000e+01> 258; CHECK-NEXT: ret <2 x double> [[EXT]] 259; 260 %trunc = fptrunc <2 x float> %a to <2 x half> 261 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 262 %ext = fpext <2 x half> %sel to <2 x double> 263 ret <2 x double> %ext 264} 265 266define float @trunc_sel_smaller_fpext(double %a, i1 %cmp) { 267; CHECK-LABEL: @trunc_sel_smaller_fpext( 268; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double [[A:%.*]] to half 269; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 270; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], float [[TMP1]], float 4.200000e+01 271; CHECK-NEXT: ret float [[EXT]] 272; 273 %trunc = fptrunc double %a to half 274 %sel = select i1 %cmp, half %trunc, half 42.0 275 %ext = fpext half %sel to float 276 ret float %ext 277} 278 279define <2 x float> @trunc_sel_smaller_fpext_vec(<2 x double> %a, <2 x i1> %cmp) { 280; CHECK-LABEL: @trunc_sel_smaller_fpext_vec( 281; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x double> [[A:%.*]] to <2 x half> 282; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 283; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 284; CHECK-NEXT: ret <2 x float> [[EXT]] 285; 286 %trunc = fptrunc <2 x double> %a to <2 x half> 287 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 288 %ext = fpext <2 x half> %sel to <2 x float> 289 ret <2 x float> %ext 290} 291 292define float @trunc_sel_equal_fpext(float %a, i1 %cmp) { 293; CHECK-LABEL: @trunc_sel_equal_fpext( 294; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float [[A:%.*]] to half 295; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 296; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], float [[TMP1]], float 4.200000e+01 297; CHECK-NEXT: ret float [[EXT]] 298; 299 %trunc = fptrunc float %a to half 300 %sel = select i1 %cmp, half %trunc, half 42.0 301 %ext = fpext half %sel to float 302 ret float %ext 303} 304 305define <2 x float> @trunc_sel_equal_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 306; CHECK-LABEL: @trunc_sel_equal_fpext_vec( 307; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half> 308; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 309; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 310; CHECK-NEXT: ret <2 x float> [[EXT]] 311; 312 %trunc = fptrunc <2 x float> %a to <2 x half> 313 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 314 %ext = fpext <2 x half> %sel to <2 x float> 315 ret <2 x float> %ext 316} 317 318define i32 @test_sext1(i1 %cca, i1 %ccb) { 319; CHECK-LABEL: @test_sext1( 320; CHECK-NEXT: [[NARROW:%.*]] = and i1 [[CCB:%.*]], [[CCA:%.*]] 321; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32 322; CHECK-NEXT: ret i32 [[R]] 323; 324 %ccax = sext i1 %cca to i32 325 %r = select i1 %ccb, i32 %ccax, i32 0 326 ret i32 %r 327} 328 329define i32 @test_sext2(i1 %cca, i1 %ccb) { 330; CHECK-LABEL: @test_sext2( 331; CHECK-NEXT: [[NARROW:%.*]] = or i1 [[CCB:%.*]], [[CCA:%.*]] 332; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32 333; CHECK-NEXT: ret i32 [[R]] 334; 335 %ccax = sext i1 %cca to i32 336 %r = select i1 %ccb, i32 -1, i32 %ccax 337 ret i32 %r 338} 339 340define i32 @test_sext3(i1 %cca, i1 %ccb) { 341; CHECK-LABEL: @test_sext3( 342; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 [[CCB:%.*]], true 343; CHECK-NEXT: [[NARROW:%.*]] = and i1 [[NOT_CCB]], [[CCA:%.*]] 344; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32 345; CHECK-NEXT: ret i32 [[R]] 346; 347 %ccax = sext i1 %cca to i32 348 %r = select i1 %ccb, i32 0, i32 %ccax 349 ret i32 %r 350} 351 352define i32 @test_sext4(i1 %cca, i1 %ccb) { 353; CHECK-LABEL: @test_sext4( 354; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 [[CCB:%.*]], true 355; CHECK-NEXT: [[NARROW:%.*]] = or i1 [[NOT_CCB]], [[CCA:%.*]] 356; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32 357; CHECK-NEXT: ret i32 [[R]] 358; 359 %ccax = sext i1 %cca to i32 360 %r = select i1 %ccb, i32 %ccax, i32 -1 361 ret i32 %r 362} 363 364define i32 @test_zext1(i1 %cca, i1 %ccb) { 365; CHECK-LABEL: @test_zext1( 366; CHECK-NEXT: [[NARROW:%.*]] = and i1 [[CCB:%.*]], [[CCA:%.*]] 367; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32 368; CHECK-NEXT: ret i32 [[R]] 369; 370 %ccax = zext i1 %cca to i32 371 %r = select i1 %ccb, i32 %ccax, i32 0 372 ret i32 %r 373} 374 375define i32 @test_zext2(i1 %cca, i1 %ccb) { 376; CHECK-LABEL: @test_zext2( 377; CHECK-NEXT: [[NARROW:%.*]] = or i1 [[CCB:%.*]], [[CCA:%.*]] 378; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32 379; CHECK-NEXT: ret i32 [[R]] 380; 381 %ccax = zext i1 %cca to i32 382 %r = select i1 %ccb, i32 1, i32 %ccax 383 ret i32 %r 384} 385 386define i32 @test_zext3(i1 %cca, i1 %ccb) { 387; CHECK-LABEL: @test_zext3( 388; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 [[CCB:%.*]], true 389; CHECK-NEXT: [[NARROW:%.*]] = and i1 [[NOT_CCB]], [[CCA:%.*]] 390; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32 391; CHECK-NEXT: ret i32 [[R]] 392; 393 %ccax = zext i1 %cca to i32 394 %r = select i1 %ccb, i32 0, i32 %ccax 395 ret i32 %r 396} 397 398define i32 @test_zext4(i1 %cca, i1 %ccb) { 399; CHECK-LABEL: @test_zext4( 400; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 [[CCB:%.*]], true 401; CHECK-NEXT: [[NARROW:%.*]] = or i1 [[NOT_CCB]], [[CCA:%.*]] 402; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32 403; CHECK-NEXT: ret i32 [[R]] 404; 405 %ccax = zext i1 %cca to i32 406 %r = select i1 %ccb, i32 %ccax, i32 1 407 ret i32 %r 408} 409 410define i32 @test_negative_sext(i1 %a, i1 %cc) { 411; CHECK-LABEL: @test_negative_sext( 412; CHECK-NEXT: [[A_EXT:%.*]] = sext i1 [[A:%.*]] to i32 413; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i32 [[A_EXT]], i32 1 414; CHECK-NEXT: ret i32 [[R]] 415; 416 %a.ext = sext i1 %a to i32 417 %r = select i1 %cc, i32 %a.ext, i32 1 418 ret i32 %r 419} 420 421define i32 @test_negative_zext(i1 %a, i1 %cc) { 422; CHECK-LABEL: @test_negative_zext( 423; CHECK-NEXT: [[A_EXT:%.*]] = zext i1 [[A:%.*]] to i32 424; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i32 [[A_EXT]], i32 -1 425; CHECK-NEXT: ret i32 [[R]] 426; 427 %a.ext = zext i1 %a to i32 428 %r = select i1 %cc, i32 %a.ext, i32 -1 429 ret i32 %r 430} 431 432define i32 @test_bits_sext(i8 %a, i1 %cc) { 433; CHECK-LABEL: @test_bits_sext( 434; CHECK-NEXT: [[A_EXT:%.*]] = sext i8 [[A:%.*]] to i32 435; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i32 [[A_EXT]], i32 -128 436; CHECK-NEXT: ret i32 [[R]] 437; 438 %a.ext = sext i8 %a to i32 439 %r = select i1 %cc, i32 %a.ext, i32 -128 440 ret i32 %r 441} 442 443define i32 @test_bits_zext(i8 %a, i1 %cc) { 444; CHECK-LABEL: @test_bits_zext( 445; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 [[A:%.*]] to i32 446; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i32 [[A_EXT]], i32 255 447; CHECK-NEXT: ret i32 [[R]] 448; 449 %a.ext = zext i8 %a to i32 450 %r = select i1 %cc, i32 %a.ext, i32 255 451 ret i32 %r 452} 453 454define i32 @test_op_op(i32 %a, i32 %b, i32 %c) { 455; CHECK-LABEL: @test_op_op( 456; CHECK-NEXT: [[CCA:%.*]] = icmp sgt i32 [[A:%.*]], 0 457; CHECK-NEXT: [[CCB:%.*]] = icmp sgt i32 [[B:%.*]], 0 458; CHECK-NEXT: [[CCC:%.*]] = icmp sgt i32 [[C:%.*]], 0 459; CHECK-NEXT: [[R_V:%.*]] = select i1 [[CCC]], i1 [[CCA]], i1 [[CCB]] 460; CHECK-NEXT: [[R:%.*]] = sext i1 [[R_V]] to i32 461; CHECK-NEXT: ret i32 [[R]] 462; 463 %cca = icmp sgt i32 %a, 0 464 %ccax = sext i1 %cca to i32 465 %ccb = icmp sgt i32 %b, 0 466 %ccbx = sext i1 %ccb to i32 467 %ccc = icmp sgt i32 %c, 0 468 %r = select i1 %ccc, i32 %ccax, i32 %ccbx 469 ret i32 %r 470} 471 472define <2 x i32> @test_vectors_sext(<2 x i1> %cca, <2 x i1> %ccb) { 473; CHECK-LABEL: @test_vectors_sext( 474; CHECK-NEXT: [[NARROW:%.*]] = and <2 x i1> [[CCB:%.*]], [[CCA:%.*]] 475; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 476; CHECK-NEXT: ret <2 x i32> [[R]] 477; 478 %ccax = sext <2 x i1> %cca to <2 x i32> 479 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 480 ret <2 x i32> %r 481} 482 483define <2 x i32> @test_vectors_sext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 484; CHECK-LABEL: @test_vectors_sext_nonsplat( 485; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> <i1 false, i1 true> 486; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 487; CHECK-NEXT: ret <2 x i32> [[R]] 488; 489 %ccax = sext <2 x i1> %cca to <2 x i32> 490 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 -1> 491 ret <2 x i32> %r 492} 493 494define <2 x i32> @test_vectors_zext(<2 x i1> %cca, <2 x i1> %ccb) { 495; CHECK-LABEL: @test_vectors_zext( 496; CHECK-NEXT: [[NARROW:%.*]] = and <2 x i1> [[CCB:%.*]], [[CCA:%.*]] 497; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 498; CHECK-NEXT: ret <2 x i32> [[R]] 499; 500 %ccax = zext <2 x i1> %cca to <2 x i32> 501 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 502 ret <2 x i32> %r 503} 504 505define <2 x i32> @test_vectors_zext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 506; CHECK-LABEL: @test_vectors_zext_nonsplat( 507; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> <i1 true, i1 false> 508; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 509; CHECK-NEXT: ret <2 x i32> [[R]] 510; 511 %ccax = zext <2 x i1> %cca to <2 x i32> 512 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 1, i32 0> 513 ret <2 x i32> %r 514} 515 516define <2 x i32> @scalar_select_of_vectors_sext(<2 x i1> %cca, i1 %ccb) { 517; CHECK-LABEL: @scalar_select_of_vectors_sext( 518; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> zeroinitializer 519; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 520; CHECK-NEXT: ret <2 x i32> [[R]] 521; 522 %ccax = sext <2 x i1> %cca to <2 x i32> 523 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 524 ret <2 x i32> %r 525} 526 527define <2 x i32> @scalar_select_of_vectors_zext(<2 x i1> %cca, i1 %ccb) { 528; CHECK-LABEL: @scalar_select_of_vectors_zext( 529; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> zeroinitializer 530; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 531; CHECK-NEXT: ret <2 x i32> [[R]] 532; 533 %ccax = zext <2 x i1> %cca to <2 x i32> 534 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 535 ret <2 x i32> %r 536} 537 538define i32 @sext_true_val_must_be_all_ones(i1 %x) { 539; CHECK-LABEL: @sext_true_val_must_be_all_ones( 540; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 -1, i32 42, !prof !0 541; CHECK-NEXT: ret i32 [[SEL]] 542; 543 %ext = sext i1 %x to i32 544 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 545 ret i32 %sel 546} 547 548define <2 x i32> @sext_true_val_must_be_all_ones_vec(<2 x i1> %x) { 549; CHECK-LABEL: @sext_true_val_must_be_all_ones_vec( 550; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 42, i32 12>, !prof !0 551; CHECK-NEXT: ret <2 x i32> [[SEL]] 552; 553 %ext = sext <2 x i1> %x to <2 x i32> 554 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 555 ret <2 x i32> %sel 556} 557 558define i32 @zext_true_val_must_be_one(i1 %x) { 559; CHECK-LABEL: @zext_true_val_must_be_one( 560; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 1, i32 42, !prof !0 561; CHECK-NEXT: ret i32 [[SEL]] 562; 563 %ext = zext i1 %x to i32 564 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 565 ret i32 %sel 566} 567 568define <2 x i32> @zext_true_val_must_be_one_vec(<2 x i1> %x) { 569; CHECK-LABEL: @zext_true_val_must_be_one_vec( 570; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 42, i32 12>, !prof !0 571; CHECK-NEXT: ret <2 x i32> [[SEL]] 572; 573 %ext = zext <2 x i1> %x to <2 x i32> 574 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 575 ret <2 x i32> %sel 576} 577 578define i32 @sext_false_val_must_be_zero(i1 %x) { 579; CHECK-LABEL: @sext_false_val_must_be_zero( 580; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 42, i32 0, !prof !0 581; CHECK-NEXT: ret i32 [[SEL]] 582; 583 %ext = sext i1 %x to i32 584 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 585 ret i32 %sel 586} 587 588define <2 x i32> @sext_false_val_must_be_zero_vec(<2 x i1> %x) { 589; CHECK-LABEL: @sext_false_val_must_be_zero_vec( 590; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 591; CHECK-NEXT: ret <2 x i32> [[SEL]] 592; 593 %ext = sext <2 x i1> %x to <2 x i32> 594 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 595 ret <2 x i32> %sel 596} 597 598define i32 @zext_false_val_must_be_zero(i1 %x) { 599; CHECK-LABEL: @zext_false_val_must_be_zero( 600; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 42, i32 0, !prof !0 601; CHECK-NEXT: ret i32 [[SEL]] 602; 603 %ext = zext i1 %x to i32 604 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 605 ret i32 %sel 606} 607 608define <2 x i32> @zext_false_val_must_be_zero_vec(<2 x i1> %x) { 609; CHECK-LABEL: @zext_false_val_must_be_zero_vec( 610; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 611; CHECK-NEXT: ret <2 x i32> [[SEL]] 612; 613 %ext = zext <2 x i1> %x to <2 x i32> 614 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 615 ret <2 x i32> %sel 616} 617 618!0 = !{!"branch_weights", i32 3, i32 5} 619 620