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:%.*]] = zext <2 x i32> %a to <2 x i64> 102; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i64> [[TRUNC]], <i64 48, i64 48> 103; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i64> [[SEXT]], <i64 48, i64 48> 104; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i64> [[TMP1]], <2 x i64> <i64 42, i64 43> 105; CHECK-NEXT: ret <2 x i64> [[EXT]] 106; 107 %trunc = trunc <2 x i32> %a to <2 x i16> 108 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 109 %ext = sext <2 x i16> %sel to <2 x i64> 110 ret <2 x i64> %ext 111} 112 113define i32 @trunc_sel_smaller_sext(i64 %a, i1 %cmp) { 114; CHECK-LABEL: @trunc_sel_smaller_sext( 115; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 %a to i16 116; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i32 117; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 118; CHECK-NEXT: ret i32 [[EXT]] 119; 120 %trunc = trunc i64 %a to i16 121 %sel = select i1 %cmp, i16 %trunc, i16 42 122 %ext = sext i16 %sel to i32 123 ret i32 %ext 124} 125 126define <2 x i32> @trunc_sel_smaller_sext_vec(<2 x i64> %a, <2 x i1> %cmp) { 127; CHECK-LABEL: @trunc_sel_smaller_sext_vec( 128; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> %a to <2 x i32> 129; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i32> [[TRUNC]], <i32 16, i32 16> 130; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[SEXT]], <i32 16, i32 16> 131; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 132; CHECK-NEXT: ret <2 x i32> [[EXT]] 133; 134 %trunc = trunc <2 x i64> %a to <2 x i16> 135 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 136 %ext = sext <2 x i16> %sel to <2 x i32> 137 ret <2 x i32> %ext 138} 139 140define i32 @trunc_sel_equal_sext(i32 %a, i1 %cmp) { 141; CHECK-LABEL: @trunc_sel_equal_sext( 142; CHECK-NEXT: [[SEXT:%.*]] = shl i32 %a, 16 143; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[SEXT]], 16 144; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 145; CHECK-NEXT: ret i32 [[EXT]] 146; 147 %trunc = trunc i32 %a to i16 148 %sel = select i1 %cmp, i16 %trunc, i16 42 149 %ext = sext i16 %sel to i32 150 ret i32 %ext 151} 152 153define <2 x i32> @trunc_sel_equal_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 154; CHECK-LABEL: @trunc_sel_equal_sext_vec( 155; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i32> %a, <i32 16, i32 16> 156; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[SEXT]], <i32 16, i32 16> 157; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 158; CHECK-NEXT: ret <2 x i32> [[EXT]] 159; 160 %trunc = trunc <2 x i32> %a to <2 x i16> 161 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 162 %ext = sext <2 x i16> %sel to <2 x i32> 163 ret <2 x i32> %ext 164} 165 166define i64 @trunc_sel_larger_zext(i32 %a, i1 %cmp) { 167; CHECK-LABEL: @trunc_sel_larger_zext( 168; CHECK-NEXT: [[TRUNC_MASK:%.*]] = and i32 %a, 65535 169; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TRUNC_MASK]] to i64 170; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42 171; CHECK-NEXT: ret i64 [[EXT]] 172; 173 %trunc = trunc i32 %a to i16 174 %sel = select i1 %cmp, i16 %trunc, i16 42 175 %ext = zext i16 %sel to i64 176 ret i64 %ext 177} 178 179define <2 x i64> @trunc_sel_larger_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 180; CHECK-LABEL: @trunc_sel_larger_zext_vec( 181; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %a, <i32 65535, i32 65535> 182; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64> 183; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i64> [[TMP2]], <2 x i64> <i64 42, i64 43> 184; CHECK-NEXT: ret <2 x i64> [[EXT]] 185; 186 %trunc = trunc <2 x i32> %a to <2 x i16> 187 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 188 %ext = zext <2 x i16> %sel to <2 x i64> 189 ret <2 x i64> %ext 190} 191 192define i32 @trunc_sel_smaller_zext(i64 %a, i1 %cmp) { 193; CHECK-LABEL: @trunc_sel_smaller_zext( 194; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %a to i32 195; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 65535 196; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP2]], i32 42 197; CHECK-NEXT: ret i32 [[EXT]] 198; 199 %trunc = trunc i64 %a to i16 200 %sel = select i1 %cmp, i16 %trunc, i16 42 201 %ext = zext i16 %sel to i32 202 ret i32 %ext 203} 204 205define <2 x i32> @trunc_sel_smaller_zext_vec(<2 x i64> %a, <2 x i1> %cmp) { 206; CHECK-LABEL: @trunc_sel_smaller_zext_vec( 207; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> %a to <2 x i32> 208; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[TRUNC]], <i32 65535, i32 65535> 209; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 210; CHECK-NEXT: ret <2 x i32> [[EXT]] 211; 212 %trunc = trunc <2 x i64> %a to <2 x i16> 213 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 214 %ext = zext <2 x i16> %sel to <2 x i32> 215 ret <2 x i32> %ext 216} 217 218define i32 @trunc_sel_equal_zext(i32 %a, i1 %cmp) { 219; CHECK-LABEL: @trunc_sel_equal_zext( 220; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 65535 221; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 222; CHECK-NEXT: ret i32 [[EXT]] 223; 224 %trunc = trunc i32 %a to i16 225 %sel = select i1 %cmp, i16 %trunc, i16 42 226 %ext = zext i16 %sel to i32 227 ret i32 %ext 228} 229 230define <2 x i32> @trunc_sel_equal_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 231; CHECK-LABEL: @trunc_sel_equal_zext_vec( 232; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %a, <i32 65535, i32 65535> 233; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 234; CHECK-NEXT: ret <2 x i32> [[EXT]] 235; 236 %trunc = trunc <2 x i32> %a to <2 x i16> 237 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 238 %ext = zext <2 x i16> %sel to <2 x i32> 239 ret <2 x i32> %ext 240} 241 242define double @trunc_sel_larger_fpext(float %a, i1 %cmp) { 243; CHECK-LABEL: @trunc_sel_larger_fpext( 244; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float %a to half 245; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to double 246; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, double [[TMP1]], double 4.200000e+01 247; CHECK-NEXT: ret double [[EXT]] 248; 249 %trunc = fptrunc float %a to half 250 %sel = select i1 %cmp, half %trunc, half 42.0 251 %ext = fpext half %sel to double 252 ret double %ext 253} 254 255define <2 x double> @trunc_sel_larger_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 256; CHECK-LABEL: @trunc_sel_larger_fpext_vec( 257; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> %a to <2 x half> 258; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x double> 259; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x double> [[TMP1]], <2 x double> <double 4.200000e+01, double 4.300000e+01> 260; CHECK-NEXT: ret <2 x double> [[EXT]] 261; 262 %trunc = fptrunc <2 x float> %a to <2 x half> 263 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 264 %ext = fpext <2 x half> %sel to <2 x double> 265 ret <2 x double> %ext 266} 267 268define float @trunc_sel_smaller_fpext(double %a, i1 %cmp) { 269; CHECK-LABEL: @trunc_sel_smaller_fpext( 270; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double %a to half 271; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 272; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, float [[TMP1]], float 4.200000e+01 273; CHECK-NEXT: ret float [[EXT]] 274; 275 %trunc = fptrunc double %a to half 276 %sel = select i1 %cmp, half %trunc, half 42.0 277 %ext = fpext half %sel to float 278 ret float %ext 279} 280 281define <2 x float> @trunc_sel_smaller_fpext_vec(<2 x double> %a, <2 x i1> %cmp) { 282; CHECK-LABEL: @trunc_sel_smaller_fpext_vec( 283; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x double> %a to <2 x half> 284; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 285; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 286; CHECK-NEXT: ret <2 x float> [[EXT]] 287; 288 %trunc = fptrunc <2 x double> %a to <2 x half> 289 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 290 %ext = fpext <2 x half> %sel to <2 x float> 291 ret <2 x float> %ext 292} 293 294define float @trunc_sel_equal_fpext(float %a, i1 %cmp) { 295; CHECK-LABEL: @trunc_sel_equal_fpext( 296; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float %a to half 297; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 298; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, float [[TMP1]], float 4.200000e+01 299; CHECK-NEXT: ret float [[EXT]] 300; 301 %trunc = fptrunc float %a to half 302 %sel = select i1 %cmp, half %trunc, half 42.0 303 %ext = fpext half %sel to float 304 ret float %ext 305} 306 307define <2 x float> @trunc_sel_equal_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 308; CHECK-LABEL: @trunc_sel_equal_fpext_vec( 309; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> %a to <2 x half> 310; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 311; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 312; CHECK-NEXT: ret <2 x float> [[EXT]] 313; 314 %trunc = fptrunc <2 x float> %a to <2 x half> 315 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 316 %ext = fpext <2 x half> %sel to <2 x float> 317 ret <2 x float> %ext 318} 319 320define i32 @test_sext1(i1 %cca, i1 %ccb) { 321; CHECK-LABEL: @test_sext1( 322; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 %ccb, %cca 323; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 324; CHECK-NEXT: ret i32 [[R]] 325; 326 %ccax = sext i1 %cca to i32 327 %r = select i1 %ccb, i32 %ccax, i32 0 328 ret i32 %r 329} 330 331define i32 @test_sext2(i1 %cca, i1 %ccb) { 332; CHECK-LABEL: @test_sext2( 333; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 %ccb, %cca 334; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 335; CHECK-NEXT: ret i32 [[R]] 336; 337 %ccax = sext i1 %cca to i32 338 %r = select i1 %ccb, i32 -1, i32 %ccax 339 ret i32 %r 340} 341 342define i32 @test_sext3(i1 %cca, i1 %ccb) { 343; CHECK-LABEL: @test_sext3( 344; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 345; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 [[NOT_CCB]], %cca 346; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 347; CHECK-NEXT: ret i32 [[R]] 348; 349 %ccax = sext i1 %cca to i32 350 %r = select i1 %ccb, i32 0, i32 %ccax 351 ret i32 %r 352} 353 354define i32 @test_sext4(i1 %cca, i1 %ccb) { 355; CHECK-LABEL: @test_sext4( 356; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 357; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 [[NOT_CCB]], %cca 358; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 359; CHECK-NEXT: ret i32 [[R]] 360; 361 %ccax = sext i1 %cca to i32 362 %r = select i1 %ccb, i32 %ccax, i32 -1 363 ret i32 %r 364} 365 366define i32 @test_zext1(i1 %cca, i1 %ccb) { 367; CHECK-LABEL: @test_zext1( 368; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 %ccb, %cca 369; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 370; CHECK-NEXT: ret i32 [[R]] 371; 372 %ccax = zext i1 %cca to i32 373 %r = select i1 %ccb, i32 %ccax, i32 0 374 ret i32 %r 375} 376 377define i32 @test_zext2(i1 %cca, i1 %ccb) { 378; CHECK-LABEL: @test_zext2( 379; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 %ccb, %cca 380; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 381; CHECK-NEXT: ret i32 [[R]] 382; 383 %ccax = zext i1 %cca to i32 384 %r = select i1 %ccb, i32 1, i32 %ccax 385 ret i32 %r 386} 387 388define i32 @test_zext3(i1 %cca, i1 %ccb) { 389; CHECK-LABEL: @test_zext3( 390; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 391; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 [[NOT_CCB]], %cca 392; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 393; CHECK-NEXT: ret i32 [[R]] 394; 395 %ccax = zext i1 %cca to i32 396 %r = select i1 %ccb, i32 0, i32 %ccax 397 ret i32 %r 398} 399 400define i32 @test_zext4(i1 %cca, i1 %ccb) { 401; CHECK-LABEL: @test_zext4( 402; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 403; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 [[NOT_CCB]], %cca 404; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 405; CHECK-NEXT: ret i32 [[R]] 406; 407 %ccax = zext i1 %cca to i32 408 %r = select i1 %ccb, i32 %ccax, i32 1 409 ret i32 %r 410} 411 412define i32 @test_negative_sext(i1 %a, i1 %cc) { 413; CHECK-LABEL: @test_negative_sext( 414; CHECK-NEXT: [[A_EXT:%.*]] = sext i1 %a to i32 415; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 1 416; CHECK-NEXT: ret i32 [[R]] 417; 418 %a.ext = sext i1 %a to i32 419 %r = select i1 %cc, i32 %a.ext, i32 1 420 ret i32 %r 421} 422 423define i32 @test_negative_zext(i1 %a, i1 %cc) { 424; CHECK-LABEL: @test_negative_zext( 425; CHECK-NEXT: [[A_EXT:%.*]] = zext i1 %a to i32 426; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 -1 427; CHECK-NEXT: ret i32 [[R]] 428; 429 %a.ext = zext i1 %a to i32 430 %r = select i1 %cc, i32 %a.ext, i32 -1 431 ret i32 %r 432} 433 434define i32 @test_bits_sext(i8 %a, i1 %cc) { 435; CHECK-LABEL: @test_bits_sext( 436; CHECK-NEXT: [[A_EXT:%.*]] = sext i8 %a to i32 437; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 -128 438; CHECK-NEXT: ret i32 [[R]] 439; 440 %a.ext = sext i8 %a to i32 441 %r = select i1 %cc, i32 %a.ext, i32 -128 442 ret i32 %r 443} 444 445define i32 @test_bits_zext(i8 %a, i1 %cc) { 446; CHECK-LABEL: @test_bits_zext( 447; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 %a to i32 448; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 255 449; CHECK-NEXT: ret i32 [[R]] 450; 451 %a.ext = zext i8 %a to i32 452 %r = select i1 %cc, i32 %a.ext, i32 255 453 ret i32 %r 454} 455 456define i32 @test_op_op(i32 %a, i32 %b, i32 %c) { 457; CHECK-LABEL: @test_op_op( 458; CHECK-NEXT: [[CCA:%.*]] = icmp sgt i32 %a, 0 459; CHECK-NEXT: [[CCB:%.*]] = icmp sgt i32 %b, 0 460; CHECK-NEXT: [[CCC:%.*]] = icmp sgt i32 %c, 0 461; CHECK-NEXT: [[R_V:%.*]] = select i1 [[CCC]], i1 [[CCA]], i1 [[CCB]] 462; CHECK-NEXT: [[R:%.*]] = sext i1 [[R:%.*]].v to i32 463; CHECK-NEXT: ret i32 [[R]] 464; 465 %cca = icmp sgt i32 %a, 0 466 %ccax = sext i1 %cca to i32 467 %ccb = icmp sgt i32 %b, 0 468 %ccbx = sext i1 %ccb to i32 469 %ccc = icmp sgt i32 %c, 0 470 %r = select i1 %ccc, i32 %ccax, i32 %ccbx 471 ret i32 %r 472} 473 474define <2 x i32> @test_vectors_sext(<2 x i1> %cca, <2 x i1> %ccb) { 475; CHECK-LABEL: @test_vectors_sext( 476; CHECK-NEXT: [[FOLD_R:%.*]] = and <2 x i1> %ccb, %cca 477; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[FOLD_R]] to <2 x i32> 478; CHECK-NEXT: ret <2 x i32> [[R]] 479; 480 %ccax = sext <2 x i1> %cca to <2 x i32> 481 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 482 ret <2 x i32> %r 483} 484 485define <2 x i32> @test_vectors_sext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 486; CHECK-LABEL: @test_vectors_sext_nonsplat( 487; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> %ccb, <2 x i1> %cca, <2 x i1> <i1 false, i1 true> 488; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 489; CHECK-NEXT: ret <2 x i32> [[R]] 490; 491 %ccax = sext <2 x i1> %cca to <2 x i32> 492 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 -1> 493 ret <2 x i32> %r 494} 495 496define <2 x i32> @test_vectors_zext(<2 x i1> %cca, <2 x i1> %ccb) { 497; CHECK-LABEL: @test_vectors_zext( 498; CHECK-NEXT: [[FOLD_R:%.*]] = and <2 x i1> %ccb, %cca 499; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[FOLD_R]] to <2 x i32> 500; CHECK-NEXT: ret <2 x i32> [[R]] 501; 502 %ccax = zext <2 x i1> %cca to <2 x i32> 503 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 504 ret <2 x i32> %r 505} 506 507define <2 x i32> @test_vectors_zext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 508; CHECK-LABEL: @test_vectors_zext_nonsplat( 509; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> %ccb, <2 x i1> %cca, <2 x i1> <i1 true, i1 false> 510; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 511; CHECK-NEXT: ret <2 x i32> [[R]] 512; 513 %ccax = zext <2 x i1> %cca to <2 x i32> 514 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 1, i32 0> 515 ret <2 x i32> %r 516} 517 518define <2 x i32> @scalar_select_of_vectors_sext(<2 x i1> %cca, i1 %ccb) { 519; CHECK-LABEL: @scalar_select_of_vectors_sext( 520; CHECK-NEXT: [[FOLD_R:%.*]] = select i1 %ccb, <2 x i1> %cca, <2 x i1> zeroinitializer 521; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[FOLD_R]] to <2 x i32> 522; CHECK-NEXT: ret <2 x i32> [[R]] 523; 524 %ccax = sext <2 x i1> %cca to <2 x i32> 525 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 526 ret <2 x i32> %r 527} 528 529define <2 x i32> @scalar_select_of_vectors_zext(<2 x i1> %cca, i1 %ccb) { 530; CHECK-LABEL: @scalar_select_of_vectors_zext( 531; CHECK-NEXT: [[FOLD_R:%.*]] = select i1 %ccb, <2 x i1> %cca, <2 x i1> zeroinitializer 532; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[FOLD_R]] to <2 x i32> 533; CHECK-NEXT: ret <2 x i32> [[R]] 534; 535 %ccax = zext <2 x i1> %cca to <2 x i32> 536 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 537 ret <2 x i32> %r 538} 539 540define i32 @sext_true_val_must_be_all_ones(i1 %x) { 541; CHECK-LABEL: @sext_true_val_must_be_all_ones( 542; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 -1, i32 42, !prof !0 543; CHECK-NEXT: ret i32 [[SEL]] 544; 545 %ext = sext i1 %x to i32 546 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 547 ret i32 %sel 548} 549 550define <2 x i32> @sext_true_val_must_be_all_ones_vec(<2 x i1> %x) { 551; CHECK-LABEL: @sext_true_val_must_be_all_ones_vec( 552; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 42, i32 12>, !prof !0 553; CHECK-NEXT: ret <2 x i32> [[SEL]] 554; 555 %ext = sext <2 x i1> %x to <2 x i32> 556 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 557 ret <2 x i32> %sel 558} 559 560define i32 @zext_true_val_must_be_one(i1 %x) { 561; CHECK-LABEL: @zext_true_val_must_be_one( 562; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 1, i32 42, !prof !0 563; CHECK-NEXT: ret i32 [[SEL]] 564; 565 %ext = zext i1 %x to i32 566 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 567 ret i32 %sel 568} 569 570define <2 x i32> @zext_true_val_must_be_one_vec(<2 x i1> %x) { 571; CHECK-LABEL: @zext_true_val_must_be_one_vec( 572; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 42, i32 12>, !prof !0 573; CHECK-NEXT: ret <2 x i32> [[SEL]] 574; 575 %ext = zext <2 x i1> %x to <2 x i32> 576 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 577 ret <2 x i32> %sel 578} 579 580define i32 @sext_false_val_must_be_zero(i1 %x) { 581; CHECK-LABEL: @sext_false_val_must_be_zero( 582; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 42, i32 0, !prof !0 583; CHECK-NEXT: ret i32 [[SEL]] 584; 585 %ext = sext i1 %x to i32 586 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 587 ret i32 %sel 588} 589 590define <2 x i32> @sext_false_val_must_be_zero_vec(<2 x i1> %x) { 591; CHECK-LABEL: @sext_false_val_must_be_zero_vec( 592; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 593; CHECK-NEXT: ret <2 x i32> [[SEL]] 594; 595 %ext = sext <2 x i1> %x to <2 x i32> 596 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 597 ret <2 x i32> %sel 598} 599 600define i32 @zext_false_val_must_be_zero(i1 %x) { 601; CHECK-LABEL: @zext_false_val_must_be_zero( 602; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 42, i32 0, !prof !0 603; CHECK-NEXT: ret i32 [[SEL]] 604; 605 %ext = zext i1 %x to i32 606 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 607 ret i32 %sel 608} 609 610define <2 x i32> @zext_false_val_must_be_zero_vec(<2 x i1> %x) { 611; CHECK-LABEL: @zext_false_val_must_be_zero_vec( 612; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 613; CHECK-NEXT: ret <2 x i32> [[SEL]] 614; 615 %ext = zext <2 x i1> %x to <2 x i32> 616 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 617 ret <2 x i32> %sel 618} 619 620!0 = !{!"branch_weights", i32 3, i32 5} 621 622