1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4declare void @use32(i32) 5 6; Widen a select of constants to eliminate an extend. 7 8define i16 @sel_sext_constants(i1 %cmp) { 9; CHECK-LABEL: @sel_sext_constants( 10; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i16 -1, i16 42 11; CHECK-NEXT: ret i16 [[EXT]] 12; 13 %sel = select i1 %cmp, i8 255, i8 42 14 %ext = sext i8 %sel to i16 15 ret i16 %ext 16} 17 18define i16 @sel_zext_constants(i1 %cmp) { 19; CHECK-LABEL: @sel_zext_constants( 20; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i16 255, i16 42 21; CHECK-NEXT: ret i16 [[EXT]] 22; 23 %sel = select i1 %cmp, i8 255, i8 42 24 %ext = zext i8 %sel to i16 25 ret i16 %ext 26} 27 28define double @sel_fpext_constants(i1 %cmp) { 29; CHECK-LABEL: @sel_fpext_constants( 30; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], double -2.550000e+02, double 4.200000e+01 31; CHECK-NEXT: ret double [[EXT]] 32; 33 %sel = select i1 %cmp, float -255.0, float 42.0 34 %ext = fpext float %sel to double 35 ret double %ext 36} 37 38; FIXME: We should not grow the size of the select in the next 4 cases. 39 40define i64 @sel_sext(i32 %a, i1 %cmp) { 41; CHECK-LABEL: @sel_sext( 42; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[A:%.*]] to i64 43; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 44; CHECK-NEXT: ret i64 [[EXT]] 45; 46 %sel = select i1 %cmp, i32 %a, i32 42 47 %ext = sext i32 %sel to i64 48 ret i64 %ext 49} 50 51define <4 x i64> @sel_sext_vec(<4 x i32> %a, <4 x i1> %cmp) { 52; CHECK-LABEL: @sel_sext_vec( 53; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64> 54; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 55; CHECK-NEXT: ret <4 x i64> [[EXT]] 56; 57 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 58 %ext = sext <4 x i32> %sel to <4 x i64> 59 ret <4 x i64> %ext 60} 61 62define i64 @sel_zext(i32 %a, i1 %cmp) { 63; CHECK-LABEL: @sel_zext( 64; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64 65; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 66; CHECK-NEXT: ret i64 [[EXT]] 67; 68 %sel = select i1 %cmp, i32 %a, i32 42 69 %ext = zext i32 %sel to i64 70 ret i64 %ext 71} 72 73define <4 x i64> @sel_zext_vec(<4 x i32> %a, <4 x i1> %cmp) { 74; CHECK-LABEL: @sel_zext_vec( 75; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> [[A:%.*]] to <4 x i64> 76; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 77; CHECK-NEXT: ret <4 x i64> [[EXT]] 78; 79 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 80 %ext = zext <4 x i32> %sel to <4 x i64> 81 ret <4 x i64> %ext 82} 83 84; FIXME: The next 18 tests cycle through trunc+select and {larger,smaller,equal} {sext,zext,fpext} {scalar,vector}. 85; The only cases where we eliminate an instruction are equal zext with scalar/vector, so that's probably the only 86; way to justify widening the select. 87 88define i64 @trunc_sel_larger_sext(i32 %a, i1 %cmp) { 89; CHECK-LABEL: @trunc_sel_larger_sext( 90; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16 91; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i64 92; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i64 [[TMP1]], i64 42 93; CHECK-NEXT: ret i64 [[EXT]] 94; 95 %trunc = trunc i32 %a to i16 96 %sel = select i1 %cmp, i16 %trunc, i16 42 97 %ext = sext i16 %sel to i64 98 ret i64 %ext 99} 100 101define <2 x i64> @trunc_sel_larger_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 102; CHECK-LABEL: @trunc_sel_larger_sext_vec( 103; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i16> 104; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i16> [[TRUNC]] to <2 x i64> 105; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i64> [[TMP1]], <2 x i64> <i64 42, i64 43> 106; CHECK-NEXT: ret <2 x i64> [[EXT]] 107; 108 %trunc = trunc <2 x i32> %a to <2 x i16> 109 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 110 %ext = sext <2 x i16> %sel to <2 x i64> 111 ret <2 x i64> %ext 112} 113 114define i32 @trunc_sel_smaller_sext(i64 %a, i1 %cmp) { 115; CHECK-LABEL: @trunc_sel_smaller_sext( 116; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[A:%.*]] to i16 117; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i32 118; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP1]], i32 42 119; CHECK-NEXT: ret i32 [[EXT]] 120; 121 %trunc = trunc i64 %a to i16 122 %sel = select i1 %cmp, i16 %trunc, i16 42 123 %ext = sext i16 %sel to i32 124 ret i32 %ext 125} 126 127define <2 x i32> @trunc_sel_smaller_sext_vec(<2 x i64> %a, <2 x i1> %cmp) { 128; CHECK-LABEL: @trunc_sel_smaller_sext_vec( 129; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i16> 130; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i16> [[TRUNC]] to <2 x i32> 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: [[TMP1:%.*]] = shl i32 [[A:%.*]], 16 143; CHECK-NEXT: [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 16 144; CHECK-NEXT: [[EXT:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP2]], 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: [[TMP1:%.*]] = shl <2 x i32> [[A:%.*]], <i32 16, i32 16> 156; CHECK-NEXT: [[TMP2:%.*]] = ashr exact <2 x i32> [[TMP1]], <i32 16, i32 16> 157; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP2]], <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: [[TRUNC_MASK:%.*]] = and <2 x i32> [[A:%.*]], <i32 65535, i32 65535> 182; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i32> [[TRUNC_MASK]] to <2 x i64> 183; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i64> [[TMP1]], <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: [[TMP1:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32> 208; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 65535, i32 65535> 209; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i32> [[TMP2]], <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: [[NARROW:%.*]] = and i1 [[CCB:%.*]], [[CCA:%.*]] 323; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] 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: [[NARROW:%.*]] = or i1 [[CCB:%.*]], [[CCA:%.*]] 334; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] 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: [[NARROW:%.*]] = and i1 [[NOT_CCB]], [[CCA:%.*]] 346; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] 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: [[NARROW:%.*]] = or i1 [[NOT_CCB]], [[CCA:%.*]] 358; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] 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: [[NARROW:%.*]] = and i1 [[CCB:%.*]], [[CCA:%.*]] 369; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] 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: [[NARROW:%.*]] = or i1 [[CCB:%.*]], [[CCA:%.*]] 380; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] 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: [[NARROW:%.*]] = and i1 [[NOT_CCB]], [[CCA:%.*]] 392; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] 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: [[NARROW:%.*]] = or i1 [[NOT_CCB]], [[CCA:%.*]] 404; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] 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 @sel_sext_const_uses(i8 %a, i8 %x) { 457; CHECK-LABEL: @sel_sext_const_uses( 458; CHECK-NEXT: [[COND:%.*]] = icmp ugt i8 [[X:%.*]], 15 459; CHECK-NEXT: [[A_EXT:%.*]] = sext i8 [[A:%.*]] to i32 460; CHECK-NEXT: call void @use32(i32 [[A_EXT]]) 461; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i32 [[A_EXT]], i32 127 462; CHECK-NEXT: ret i32 [[R]] 463; 464 %cond = icmp ugt i8 %x, 15 465 %a.ext = sext i8 %a to i32 466 call void @use32(i32 %a.ext) 467 %r = select i1 %cond, i32 %a.ext, i32 127 468 ret i32 %r 469} 470 471define i32 @sel_zext_const_uses(i8 %a, i8 %x) { 472; CHECK-LABEL: @sel_zext_const_uses( 473; CHECK-NEXT: [[COND:%.*]] = icmp sgt i8 [[X:%.*]], 15 474; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 [[A:%.*]] to i32 475; CHECK-NEXT: call void @use32(i32 [[A_EXT]]) 476; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i32 255, i32 [[A_EXT]] 477; CHECK-NEXT: ret i32 [[R]] 478; 479 %cond = icmp sgt i8 %x, 15 480 %a.ext = zext i8 %a to i32 481 call void @use32(i32 %a.ext) 482 %r = select i1 %cond, i32 255, i32 %a.ext 483 ret i32 %r 484} 485 486define i32 @test_op_op(i32 %a, i32 %b, i32 %c) { 487; CHECK-LABEL: @test_op_op( 488; CHECK-NEXT: [[CCA:%.*]] = icmp sgt i32 [[A:%.*]], 0 489; CHECK-NEXT: [[CCB:%.*]] = icmp sgt i32 [[B:%.*]], 0 490; CHECK-NEXT: [[CCC:%.*]] = icmp sgt i32 [[C:%.*]], 0 491; CHECK-NEXT: [[R_V:%.*]] = select i1 [[CCC]], i1 [[CCA]], i1 [[CCB]] 492; CHECK-NEXT: [[R:%.*]] = sext i1 [[R_V]] to i32 493; CHECK-NEXT: ret i32 [[R]] 494; 495 %cca = icmp sgt i32 %a, 0 496 %ccax = sext i1 %cca to i32 497 %ccb = icmp sgt i32 %b, 0 498 %ccbx = sext i1 %ccb to i32 499 %ccc = icmp sgt i32 %c, 0 500 %r = select i1 %ccc, i32 %ccax, i32 %ccbx 501 ret i32 %r 502} 503 504define <2 x i32> @test_vectors_sext(<2 x i1> %cca, <2 x i1> %ccb) { 505; CHECK-LABEL: @test_vectors_sext( 506; CHECK-NEXT: [[NARROW:%.*]] = and <2 x i1> [[CCB:%.*]], [[CCA:%.*]] 507; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 508; CHECK-NEXT: ret <2 x i32> [[R]] 509; 510 %ccax = sext <2 x i1> %cca to <2 x i32> 511 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 512 ret <2 x i32> %r 513} 514 515define <2 x i32> @test_vectors_sext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 516; CHECK-LABEL: @test_vectors_sext_nonsplat( 517; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> <i1 false, i1 true> 518; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 519; CHECK-NEXT: ret <2 x i32> [[R]] 520; 521 %ccax = sext <2 x i1> %cca to <2 x i32> 522 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 -1> 523 ret <2 x i32> %r 524} 525 526define <2 x i32> @test_vectors_zext(<2 x i1> %cca, <2 x i1> %ccb) { 527; CHECK-LABEL: @test_vectors_zext( 528; CHECK-NEXT: [[NARROW:%.*]] = and <2 x i1> [[CCB:%.*]], [[CCA:%.*]] 529; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 530; CHECK-NEXT: ret <2 x i32> [[R]] 531; 532 %ccax = zext <2 x i1> %cca to <2 x i32> 533 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 534 ret <2 x i32> %r 535} 536 537define <2 x i32> @test_vectors_zext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 538; CHECK-LABEL: @test_vectors_zext_nonsplat( 539; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> <i1 true, i1 false> 540; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 541; CHECK-NEXT: ret <2 x i32> [[R]] 542; 543 %ccax = zext <2 x i1> %cca to <2 x i32> 544 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 1, i32 0> 545 ret <2 x i32> %r 546} 547 548define <2 x i32> @scalar_select_of_vectors_sext(<2 x i1> %cca, i1 %ccb) { 549; CHECK-LABEL: @scalar_select_of_vectors_sext( 550; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> zeroinitializer 551; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 552; CHECK-NEXT: ret <2 x i32> [[R]] 553; 554 %ccax = sext <2 x i1> %cca to <2 x i32> 555 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 556 ret <2 x i32> %r 557} 558 559define <2 x i32> @scalar_select_of_vectors_zext(<2 x i1> %cca, i1 %ccb) { 560; CHECK-LABEL: @scalar_select_of_vectors_zext( 561; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[CCB:%.*]], <2 x i1> [[CCA:%.*]], <2 x i1> zeroinitializer 562; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 563; CHECK-NEXT: ret <2 x i32> [[R]] 564; 565 %ccax = zext <2 x i1> %cca to <2 x i32> 566 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 567 ret <2 x i32> %r 568} 569 570define i32 @sext_true_val_must_be_all_ones(i1 %x) { 571; CHECK-LABEL: @sext_true_val_must_be_all_ones( 572; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 -1, i32 42, !prof !0 573; CHECK-NEXT: ret i32 [[SEL]] 574; 575 %ext = sext i1 %x to i32 576 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 577 ret i32 %sel 578} 579 580define <2 x i32> @sext_true_val_must_be_all_ones_vec(<2 x i1> %x) { 581; CHECK-LABEL: @sext_true_val_must_be_all_ones_vec( 582; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 42, i32 12>, !prof !0 583; CHECK-NEXT: ret <2 x i32> [[SEL]] 584; 585 %ext = sext <2 x i1> %x to <2 x i32> 586 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 587 ret <2 x i32> %sel 588} 589 590define i32 @zext_true_val_must_be_one(i1 %x) { 591; CHECK-LABEL: @zext_true_val_must_be_one( 592; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 1, i32 42, !prof !0 593; CHECK-NEXT: ret i32 [[SEL]] 594; 595 %ext = zext i1 %x to i32 596 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 597 ret i32 %sel 598} 599 600define <2 x i32> @zext_true_val_must_be_one_vec(<2 x i1> %x) { 601; CHECK-LABEL: @zext_true_val_must_be_one_vec( 602; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 42, i32 12>, !prof !0 603; CHECK-NEXT: ret <2 x i32> [[SEL]] 604; 605 %ext = zext <2 x i1> %x to <2 x i32> 606 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 607 ret <2 x i32> %sel 608} 609 610define i32 @sext_false_val_must_be_zero(i1 %x) { 611; CHECK-LABEL: @sext_false_val_must_be_zero( 612; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 42, i32 0, !prof !0 613; CHECK-NEXT: ret i32 [[SEL]] 614; 615 %ext = sext i1 %x to i32 616 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 617 ret i32 %sel 618} 619 620define <2 x i32> @sext_false_val_must_be_zero_vec(<2 x i1> %x) { 621; CHECK-LABEL: @sext_false_val_must_be_zero_vec( 622; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 623; CHECK-NEXT: ret <2 x i32> [[SEL]] 624; 625 %ext = sext <2 x i1> %x to <2 x i32> 626 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 627 ret <2 x i32> %sel 628} 629 630define i32 @zext_false_val_must_be_zero(i1 %x) { 631; CHECK-LABEL: @zext_false_val_must_be_zero( 632; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i32 42, i32 0, !prof !0 633; CHECK-NEXT: ret i32 [[SEL]] 634; 635 %ext = zext i1 %x to i32 636 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 637 ret i32 %sel 638} 639 640define <2 x i32> @zext_false_val_must_be_zero_vec(<2 x i1> %x) { 641; CHECK-LABEL: @zext_false_val_must_be_zero_vec( 642; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 643; CHECK-NEXT: ret <2 x i32> [[SEL]] 644; 645 %ext = zext <2 x i1> %x to <2 x i32> 646 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 647 ret <2 x i32> %sel 648} 649 650!0 = !{!"branch_weights", i32 3, i32 5} 651 652