1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" 5 6declare i32 @llvm.ctpop.i32(i32) 7declare i32 @llvm.ctlz.i32(i32, i1) 8declare i32 @llvm.cttz.i32(i32, i1) 9declare void @use(i8) 10declare void @use_vec(<2 x i5>) 11 12define i64 @test1(i32 %x) { 13; CHECK-LABEL: @test1( 14; CHECK-NEXT: [[T:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]]) 15; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 16; CHECK-NEXT: ret i64 [[S]] 17; 18 %t = call i32 @llvm.ctpop.i32(i32 %x) 19 %s = sext i32 %t to i64 20 ret i64 %s 21} 22 23define i64 @test2(i32 %x) { 24; CHECK-LABEL: @test2( 25; CHECK-NEXT: [[T:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true) 26; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 27; CHECK-NEXT: ret i64 [[S]] 28; 29 %t = call i32 @llvm.ctlz.i32(i32 %x, i1 true) 30 %s = sext i32 %t to i64 31 ret i64 %s 32} 33 34define i64 @test3(i32 %x) { 35; CHECK-LABEL: @test3( 36; CHECK-NEXT: [[T:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true) 37; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 38; CHECK-NEXT: ret i64 [[S]] 39; 40 %t = call i32 @llvm.cttz.i32(i32 %x, i1 true) 41 %s = sext i32 %t to i64 42 ret i64 %s 43} 44 45define i64 @test4(i32 %x) { 46; CHECK-LABEL: @test4( 47; CHECK-NEXT: [[T:%.*]] = udiv i32 [[X:%.*]], 3 48; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 49; CHECK-NEXT: ret i64 [[S]] 50; 51 %t = udiv i32 %x, 3 52 %s = sext i32 %t to i64 53 ret i64 %s 54} 55 56define i64 @test5(i32 %x) { 57; CHECK-LABEL: @test5( 58; CHECK-NEXT: [[T:%.*]] = urem i32 [[X:%.*]], 30000 59; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 60; CHECK-NEXT: ret i64 [[S]] 61; 62 %t = urem i32 %x, 30000 63 %s = sext i32 %t to i64 64 ret i64 %s 65} 66 67define i64 @test6(i32 %x) { 68; CHECK-LABEL: @test6( 69; CHECK-NEXT: [[U:%.*]] = lshr i32 [[X:%.*]], 3 70; CHECK-NEXT: [[T:%.*]] = mul nuw nsw i32 [[U]], 3 71; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[T]] to i64 72; CHECK-NEXT: ret i64 [[S]] 73; 74 %u = lshr i32 %x, 3 75 %t = mul i32 %u, 3 76 %s = sext i32 %t to i64 77 ret i64 %s 78} 79 80define i64 @test7(i32 %x) { 81; CHECK-LABEL: @test7( 82; CHECK-NEXT: [[T:%.*]] = and i32 [[X:%.*]], 511 83; CHECK-NEXT: [[U:%.*]] = sub nuw nsw i32 20000, [[T]] 84; CHECK-NEXT: [[S:%.*]] = zext nneg i32 [[U]] to i64 85; CHECK-NEXT: ret i64 [[S]] 86; 87 %t = and i32 %x, 511 88 %u = sub i32 20000, %t 89 %s = sext i32 %u to i64 90 ret i64 %s 91} 92 93define i32 @test8(i8 %a, i32 %f, i1 %p, ptr %z) { 94; CHECK-LABEL: @test8( 95; CHECK-NEXT: [[D:%.*]] = lshr i32 [[F:%.*]], 24 96; CHECK-NEXT: [[N:%.*]] = select i1 [[P:%.*]], i32 [[D]], i32 0 97; CHECK-NEXT: ret i32 [[N]] 98; 99 %d = lshr i32 %f, 24 100 %e = select i1 %p, i32 %d, i32 0 101 %s = trunc i32 %e to i16 102 %n = sext i16 %s to i32 103 ret i32 %n 104} 105 106; rdar://6013816 107define i16 @test9(i16 %t, i1 %cond) { 108; CHECK-LABEL: @test9( 109; CHECK-NEXT: entry: 110; CHECK-NEXT: br i1 [[COND:%.*]], label [[TBB:%.*]], label [[FBB:%.*]] 111; CHECK: TBB: 112; CHECK-NEXT: br label [[FBB]] 113; CHECK: FBB: 114; CHECK-NEXT: [[V_OFF0:%.*]] = phi i16 [ [[T:%.*]], [[TBB]] ], [ 42, [[ENTRY:%.*]] ] 115; CHECK-NEXT: ret i16 [[V_OFF0]] 116; 117entry: 118 br i1 %cond, label %TBB, label %FBB 119 120TBB: 121 %t2 = sext i16 %t to i32 122 br label %FBB 123 124FBB: 125 %V = phi i32 [%t2, %TBB], [42, %entry] 126 %W = trunc i32 %V to i16 127 ret i16 %W 128} 129 130; PR2638 131define i32 @test10(i32 %i) { 132; CHECK-LABEL: @test10( 133; CHECK-NEXT: [[D1:%.*]] = shl i32 [[I:%.*]], 30 134; CHECK-NEXT: [[D:%.*]] = ashr exact i32 [[D1]], 30 135; CHECK-NEXT: ret i32 [[D]] 136; 137 %A = trunc i32 %i to i8 138 %B = shl i8 %A, 6 139 %C = ashr i8 %B, 6 140 %D = sext i8 %C to i32 141 ret i32 %D 142} 143 144define <2 x i32> @test10_vec(<2 x i32> %i) { 145; CHECK-LABEL: @test10_vec( 146; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], splat (i32 30) 147; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], splat (i32 30) 148; CHECK-NEXT: ret <2 x i32> [[D]] 149; 150 %A = trunc <2 x i32> %i to <2 x i8> 151 %B = shl <2 x i8> %A, <i8 6, i8 6> 152 %C = ashr <2 x i8> %B, <i8 6, i8 6> 153 %D = sext <2 x i8> %C to <2 x i32> 154 ret <2 x i32> %D 155} 156 157define <2 x i32> @test10_vec_nonuniform(<2 x i32> %i) { 158; CHECK-LABEL: @test10_vec_nonuniform( 159; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 27> 160; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], <i32 30, i32 27> 161; CHECK-NEXT: ret <2 x i32> [[D]] 162; 163 %A = trunc <2 x i32> %i to <2 x i8> 164 %B = shl <2 x i8> %A, <i8 6, i8 3> 165 %C = ashr <2 x i8> %B, <i8 6, i8 3> 166 %D = sext <2 x i8> %C to <2 x i32> 167 ret <2 x i32> %D 168} 169 170define <2 x i32> @test10_vec_poison0(<2 x i32> %i) { 171; CHECK-LABEL: @test10_vec_poison0( 172; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 poison> 173; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], <i32 30, i32 poison> 174; CHECK-NEXT: ret <2 x i32> [[D]] 175; 176 %A = trunc <2 x i32> %i to <2 x i8> 177 %B = shl <2 x i8> %A, <i8 6, i8 0> 178 %C = ashr <2 x i8> %B, <i8 6, i8 poison> 179 %D = sext <2 x i8> %C to <2 x i32> 180 ret <2 x i32> %D 181} 182define <2 x i32> @test10_vec_poison1(<2 x i32> %i) { 183; CHECK-LABEL: @test10_vec_poison1( 184; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 undef> 185; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], <i32 30, i32 undef> 186; CHECK-NEXT: ret <2 x i32> [[D]] 187; 188 %A = trunc <2 x i32> %i to <2 x i8> 189 %B = shl <2 x i8> %A, <i8 6, i8 poison> 190 %C = ashr <2 x i8> %B, <i8 6, i8 0> 191 %D = sext <2 x i8> %C to <2 x i32> 192 ret <2 x i32> %D 193} 194define <2 x i32> @test10_vec_poison2(<2 x i32> %i) { 195; CHECK-LABEL: @test10_vec_poison2( 196; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 poison> 197; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], <i32 30, i32 poison> 198; CHECK-NEXT: ret <2 x i32> [[D]] 199; 200 %A = trunc <2 x i32> %i to <2 x i8> 201 %B = shl <2 x i8> %A, <i8 6, i8 poison> 202 %C = ashr <2 x i8> %B, <i8 6, i8 poison> 203 %D = sext <2 x i8> %C to <2 x i32> 204 ret <2 x i32> %D 205} 206 207define void @test11(<2 x i16> %srcA, <2 x i16> %srcB, ptr %dst) { 208; CHECK-LABEL: @test11( 209; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i16> [[SRCB:%.*]], [[SRCA:%.*]] 210; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i16> 211; CHECK-NEXT: store <2 x i16> [[SEXT]], ptr [[DST:%.*]], align 4 212; CHECK-NEXT: ret void 213; 214 %cmp = icmp eq <2 x i16> %srcB, %srcA 215 %sext = sext <2 x i1> %cmp to <2 x i16> 216 %tmask = ashr <2 x i16> %sext, <i16 15, i16 15> 217 store <2 x i16> %tmask, ptr %dst 218 ret void 219} 220 221define i64 @test12(i32 %x) { 222; CHECK-LABEL: @test12( 223; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 1 224; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[SHR]] 225; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[SUB]] to i64 226; CHECK-NEXT: ret i64 [[CONV]] 227; 228 %shr = lshr i32 %x, 1 229 %sub = sub nsw i32 0, %shr 230 %conv = sext i32 %sub to i64 231 ret i64 %conv 232} 233 234define i32 @test13(i32 %x) { 235; CHECK-LABEL: @test13( 236; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[X:%.*]], 3 237; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 1 238; CHECK-NEXT: [[SEXT:%.*]] = add nsw i32 [[TMP1]], -1 239; CHECK-NEXT: ret i32 [[SEXT]] 240; 241 %and = and i32 %x, 8 242 %cmp = icmp eq i32 %and, 0 243 %ext = sext i1 %cmp to i32 244 ret i32 %ext 245} 246 247define i32 @test14(i16 %x) { 248; CHECK-LABEL: @test14( 249; CHECK-NEXT: [[AND:%.*]] = lshr i16 [[X:%.*]], 4 250; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[AND]], 1 251; CHECK-NEXT: [[SEXT:%.*]] = add nsw i16 [[TMP1]], -1 252; CHECK-NEXT: [[EXT:%.*]] = sext i16 [[SEXT]] to i32 253; CHECK-NEXT: ret i32 [[EXT]] 254; 255 %and = and i16 %x, 16 256 %cmp = icmp ne i16 %and, 16 257 %ext = sext i1 %cmp to i32 258 ret i32 %ext 259} 260 261define i32 @test15(i32 %x) { 262; CHECK-LABEL: @test15( 263; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 27 264; CHECK-NEXT: [[SEXT:%.*]] = ashr i32 [[AND]], 31 265; CHECK-NEXT: ret i32 [[SEXT]] 266; 267 %and = and i32 %x, 16 268 %cmp = icmp ne i32 %and, 0 269 %ext = sext i1 %cmp to i32 270 ret i32 %ext 271} 272 273define i32 @test16(i16 %x) { 274; CHECK-LABEL: @test16( 275; CHECK-NEXT: [[AND:%.*]] = shl i16 [[X:%.*]], 12 276; CHECK-NEXT: [[SEXT:%.*]] = ashr i16 [[AND]], 15 277; CHECK-NEXT: [[EXT:%.*]] = sext i16 [[SEXT]] to i32 278; CHECK-NEXT: ret i32 [[EXT]] 279; 280 %and = and i16 %x, 8 281 %cmp = icmp eq i16 %and, 8 282 %ext = sext i1 %cmp to i32 283 ret i32 %ext 284} 285 286define i32 @test17(i1 %x) { 287; CHECK-LABEL: @test17( 288; CHECK-NEXT: [[C1_NEG:%.*]] = zext i1 [[X:%.*]] to i32 289; CHECK-NEXT: ret i32 [[C1_NEG]] 290; 291 %c1 = sext i1 %x to i32 292 %c2 = sub i32 0, %c1 293 ret i32 %c2 294} 295 296define i32 @test18(i16 %x) { 297; CHECK-LABEL: @test18( 298; CHECK-NEXT: [[SEL:%.*]] = call i16 @llvm.smax.i16(i16 [[X:%.*]], i16 0) 299; CHECK-NEXT: [[EXT:%.*]] = zext nneg i16 [[SEL]] to i32 300; CHECK-NEXT: ret i32 [[EXT]] 301; 302 %cmp = icmp slt i16 %x, 0 303 %sel = select i1 %cmp, i16 0, i16 %x 304 %ext = sext i16 %sel to i32 305 ret i32 %ext 306} 307 308define i10 @test19(i10 %i) { 309; CHECK-LABEL: @test19( 310; CHECK-NEXT: [[A:%.*]] = trunc i10 [[I:%.*]] to i3 311; CHECK-NEXT: [[TMP1:%.*]] = and i3 [[A]], 1 312; CHECK-NEXT: [[C:%.*]] = sub nsw i3 0, [[TMP1]] 313; CHECK-NEXT: [[D:%.*]] = sext i3 [[C]] to i10 314; CHECK-NEXT: ret i10 [[D]] 315; 316 %a = trunc i10 %i to i3 317 %b = shl i3 %a, 2 318 %c = ashr i3 %b, 2 319 %d = sext i3 %c to i10 320 ret i10 %d 321} 322 323define i32 @smear_set_bit(i32 %x) { 324; CHECK-LABEL: @smear_set_bit( 325; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24 326; CHECK-NEXT: [[S:%.*]] = ashr i32 [[TMP1]], 31 327; CHECK-NEXT: ret i32 [[S]] 328; 329 %t = trunc i32 %x to i8 330 %a = ashr i8 %t, 7 331 %s = sext i8 %a to i32 332 ret i32 %s 333} 334 335; extra use of trunc is ok because we still shorten the use chain 336 337define <2 x i32> @smear_set_bit_vec_use1(<2 x i32> %x) { 338; CHECK-LABEL: @smear_set_bit_vec_use1( 339; CHECK-NEXT: [[T:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i5> 340; CHECK-NEXT: call void @use_vec(<2 x i5> [[T]]) 341; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X]], splat (i32 27) 342; CHECK-NEXT: [[S:%.*]] = ashr <2 x i32> [[TMP1]], splat (i32 31) 343; CHECK-NEXT: ret <2 x i32> [[S]] 344; 345 %t = trunc <2 x i32> %x to <2 x i5> 346 call void @use_vec(<2 x i5> %t) 347 %a = ashr <2 x i5> %t, <i5 4, i5 4> 348 %s = sext <2 x i5> %a to <2 x i32> 349 ret <2 x i32> %s 350} 351 352; negative test - extra use 353 354define i32 @smear_set_bit_use2(i32 %x) { 355; CHECK-LABEL: @smear_set_bit_use2( 356; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8 357; CHECK-NEXT: [[A:%.*]] = ashr i8 [[T]], 7 358; CHECK-NEXT: call void @use(i8 [[A]]) 359; CHECK-NEXT: [[S:%.*]] = sext i8 [[A]] to i32 360; CHECK-NEXT: ret i32 [[S]] 361; 362 %t = trunc i32 %x to i8 363 %a = ashr i8 %t, 7 364 call void @use(i8 %a) 365 %s = sext i8 %a to i32 366 ret i32 %s 367} 368 369; negative test - must shift all the way across 370 371define i32 @smear_set_bit_wrong_shift_amount(i32 %x) { 372; CHECK-LABEL: @smear_set_bit_wrong_shift_amount( 373; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8 374; CHECK-NEXT: [[A:%.*]] = ashr i8 [[T]], 6 375; CHECK-NEXT: [[S:%.*]] = sext i8 [[A]] to i32 376; CHECK-NEXT: ret i32 [[S]] 377; 378 %t = trunc i32 %x to i8 379 %a = ashr i8 %t, 6 380 %s = sext i8 %a to i32 381 ret i32 %s 382} 383 384define i16 @smear_set_bit_different_dest_type(i32 %x) { 385; CHECK-LABEL: @smear_set_bit_different_dest_type( 386; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24 387; CHECK-NEXT: [[TMP2:%.*]] = ashr i32 [[TMP1]], 31 388; CHECK-NEXT: [[S:%.*]] = trunc nsw i32 [[TMP2]] to i16 389; CHECK-NEXT: ret i16 [[S]] 390; 391 %t = trunc i32 %x to i8 392 %a = ashr i8 %t, 7 393 %s = sext i8 %a to i16 394 ret i16 %s 395} 396 397; negative test - extra use 398 399define i16 @smear_set_bit_different_dest_type_extra_use(i32 %x) { 400; CHECK-LABEL: @smear_set_bit_different_dest_type_extra_use( 401; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8 402; CHECK-NEXT: call void @use(i8 [[T]]) 403; CHECK-NEXT: [[A:%.*]] = ashr i8 [[T]], 7 404; CHECK-NEXT: [[S:%.*]] = sext i8 [[A]] to i16 405; CHECK-NEXT: ret i16 [[S]] 406; 407 %t = trunc i32 %x to i8 408 call void @use(i8 %t) 409 %a = ashr i8 %t, 7 410 %s = sext i8 %a to i16 411 ret i16 %s 412} 413 414define i64 @smear_set_bit_different_dest_type_wider_dst(i32 %x) { 415; CHECK-LABEL: @smear_set_bit_different_dest_type_wider_dst( 416; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24 417; CHECK-NEXT: [[TMP2:%.*]] = ashr i32 [[TMP1]], 31 418; CHECK-NEXT: [[S:%.*]] = sext i32 [[TMP2]] to i64 419; CHECK-NEXT: ret i64 [[S]] 420; 421 %t = trunc i32 %x to i8 422 %a = ashr i8 %t, 7 423 %s = sext i8 %a to i64 424 ret i64 %s 425} 426