1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64 4 5; Shift i64 integers on 32-bit target 6 7define i64 @test1(i64 %X, i8 %C) nounwind { 8; X86-LABEL: test1: 9; X86: # %bb.0: 10; X86-NEXT: pushl %esi 11; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 12; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 13; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 14; X86-NEXT: movl %esi, %eax 15; X86-NEXT: shll %cl, %eax 16; X86-NEXT: shldl %cl, %esi, %edx 17; X86-NEXT: testb $32, %cl 18; X86-NEXT: je .LBB0_2 19; X86-NEXT: # %bb.1: 20; X86-NEXT: movl %eax, %edx 21; X86-NEXT: xorl %eax, %eax 22; X86-NEXT: .LBB0_2: 23; X86-NEXT: popl %esi 24; X86-NEXT: retl 25; 26; X64-LABEL: test1: 27; X64: # %bb.0: 28; X64-NEXT: movl %esi, %ecx 29; X64-NEXT: movq %rdi, %rax 30; X64-NEXT: # kill: def $cl killed $cl killed $ecx 31; X64-NEXT: shlq %cl, %rax 32; X64-NEXT: retq 33 %shift.upgrd.1 = zext i8 %C to i64 ; <i64> [#uses=1] 34 %Y = shl i64 %X, %shift.upgrd.1 ; <i64> [#uses=1] 35 ret i64 %Y 36} 37 38define i64 @test2(i64 %X, i8 %C) nounwind { 39; X86-LABEL: test2: 40; X86: # %bb.0: 41; X86-NEXT: pushl %esi 42; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 43; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 44; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 45; X86-NEXT: movl %esi, %edx 46; X86-NEXT: sarl %cl, %edx 47; X86-NEXT: shrdl %cl, %esi, %eax 48; X86-NEXT: testb $32, %cl 49; X86-NEXT: je .LBB1_2 50; X86-NEXT: # %bb.1: 51; X86-NEXT: sarl $31, %esi 52; X86-NEXT: movl %edx, %eax 53; X86-NEXT: movl %esi, %edx 54; X86-NEXT: .LBB1_2: 55; X86-NEXT: popl %esi 56; X86-NEXT: retl 57; 58; X64-LABEL: test2: 59; X64: # %bb.0: 60; X64-NEXT: movl %esi, %ecx 61; X64-NEXT: movq %rdi, %rax 62; X64-NEXT: # kill: def $cl killed $cl killed $ecx 63; X64-NEXT: sarq %cl, %rax 64; X64-NEXT: retq 65 %shift.upgrd.2 = zext i8 %C to i64 ; <i64> [#uses=1] 66 %Y = ashr i64 %X, %shift.upgrd.2 ; <i64> [#uses=1] 67 ret i64 %Y 68} 69 70define i64 @test3(i64 %X, i8 %C) nounwind { 71; X86-LABEL: test3: 72; X86: # %bb.0: 73; X86-NEXT: pushl %esi 74; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 75; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 76; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 77; X86-NEXT: movl %esi, %edx 78; X86-NEXT: shrl %cl, %edx 79; X86-NEXT: shrdl %cl, %esi, %eax 80; X86-NEXT: testb $32, %cl 81; X86-NEXT: je .LBB2_2 82; X86-NEXT: # %bb.1: 83; X86-NEXT: movl %edx, %eax 84; X86-NEXT: xorl %edx, %edx 85; X86-NEXT: .LBB2_2: 86; X86-NEXT: popl %esi 87; X86-NEXT: retl 88; 89; X64-LABEL: test3: 90; X64: # %bb.0: 91; X64-NEXT: movl %esi, %ecx 92; X64-NEXT: movq %rdi, %rax 93; X64-NEXT: # kill: def $cl killed $cl killed $ecx 94; X64-NEXT: shrq %cl, %rax 95; X64-NEXT: retq 96 %shift.upgrd.3 = zext i8 %C to i64 ; <i64> [#uses=1] 97 %Y = lshr i64 %X, %shift.upgrd.3 ; <i64> [#uses=1] 98 ret i64 %Y 99} 100 101; Combine 2xi32/2xi16 shifts into SHLD 102 103define i32 @test4(i32 %A, i32 %B, i8 %C) nounwind { 104; X86-LABEL: test4: 105; X86: # %bb.0: 106; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 107; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 108; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 109; X86-NEXT: shldl %cl, %edx, %eax 110; X86-NEXT: retl 111; 112; X64-LABEL: test4: 113; X64: # %bb.0: 114; X64-NEXT: movl %edx, %ecx 115; X64-NEXT: movl %edi, %eax 116; X64-NEXT: # kill: def $cl killed $cl killed $ecx 117; X64-NEXT: shldl %cl, %esi, %eax 118; X64-NEXT: retq 119 %shift.upgrd.4 = zext i8 %C to i32 ; <i32> [#uses=1] 120 %X = shl i32 %A, %shift.upgrd.4 ; <i32> [#uses=1] 121 %Cv = sub i8 32, %C ; <i8> [#uses=1] 122 %shift.upgrd.5 = zext i8 %Cv to i32 ; <i32> [#uses=1] 123 %Y = lshr i32 %B, %shift.upgrd.5 ; <i32> [#uses=1] 124 %Z = or i32 %Y, %X ; <i32> [#uses=1] 125 ret i32 %Z 126} 127 128define i16 @test5(i16 %A, i16 %B, i8 %C) nounwind { 129; X86-LABEL: test5: 130; X86: # %bb.0: 131; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 132; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx 133; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 134; X86-NEXT: shldw %cl, %dx, %ax 135; X86-NEXT: retl 136; 137; X64-LABEL: test5: 138; X64: # %bb.0: 139; X64-NEXT: movl %edx, %ecx 140; X64-NEXT: movl %edi, %eax 141; X64-NEXT: # kill: def $cl killed $cl killed $ecx 142; X64-NEXT: shldw %cl, %si, %ax 143; X64-NEXT: # kill: def $ax killed $ax killed $eax 144; X64-NEXT: retq 145 %shift.upgrd.6 = zext i8 %C to i16 ; <i16> [#uses=1] 146 %X = shl i16 %A, %shift.upgrd.6 ; <i16> [#uses=1] 147 %Cv = sub i8 16, %C ; <i8> [#uses=1] 148 %shift.upgrd.7 = zext i8 %Cv to i16 ; <i16> [#uses=1] 149 %Y = lshr i16 %B, %shift.upgrd.7 ; <i16> [#uses=1] 150 %Z = or i16 %Y, %X ; <i16> [#uses=1] 151 ret i16 %Z 152} 153 154; Combine 2xi32/2xi16 shifts into SHRD 155 156define i32 @test6(i32 %A, i32 %B, i8 %C) nounwind { 157; X86-LABEL: test6: 158; X86: # %bb.0: 159; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 160; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 161; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 162; X86-NEXT: shrdl %cl, %edx, %eax 163; X86-NEXT: retl 164; 165; X64-LABEL: test6: 166; X64: # %bb.0: 167; X64-NEXT: movl %edx, %ecx 168; X64-NEXT: movl %edi, %eax 169; X64-NEXT: # kill: def $cl killed $cl killed $ecx 170; X64-NEXT: shrdl %cl, %esi, %eax 171; X64-NEXT: retq 172 %shift.upgrd.4 = zext i8 %C to i32 ; <i32> [#uses=1] 173 %X = lshr i32 %A, %shift.upgrd.4 ; <i32> [#uses=1] 174 %Cv = sub i8 32, %C ; <i8> [#uses=1] 175 %shift.upgrd.5 = zext i8 %Cv to i32 ; <i32> [#uses=1] 176 %Y = shl i32 %B, %shift.upgrd.5 ; <i32> [#uses=1] 177 %Z = or i32 %Y, %X ; <i32> [#uses=1] 178 ret i32 %Z 179} 180 181define i16 @test7(i16 %A, i16 %B, i8 %C) nounwind { 182; X86-LABEL: test7: 183; X86: # %bb.0: 184; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 185; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx 186; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 187; X86-NEXT: shrdw %cl, %dx, %ax 188; X86-NEXT: retl 189; 190; X64-LABEL: test7: 191; X64: # %bb.0: 192; X64-NEXT: movl %edx, %ecx 193; X64-NEXT: movl %edi, %eax 194; X64-NEXT: # kill: def $cl killed $cl killed $ecx 195; X64-NEXT: shrdw %cl, %si, %ax 196; X64-NEXT: # kill: def $ax killed $ax killed $eax 197; X64-NEXT: retq 198 %shift.upgrd.6 = zext i8 %C to i16 ; <i16> [#uses=1] 199 %X = lshr i16 %A, %shift.upgrd.6 ; <i16> [#uses=1] 200 %Cv = sub i8 16, %C ; <i8> [#uses=1] 201 %shift.upgrd.7 = zext i8 %Cv to i16 ; <i16> [#uses=1] 202 %Y = shl i16 %B, %shift.upgrd.7 ; <i16> [#uses=1] 203 %Z = or i16 %Y, %X ; <i16> [#uses=1] 204 ret i16 %Z 205} 206 207; Shift i64 integers on 32-bit target by shift value less then 32 (PR14593) 208 209define i64 @test8(i64 %val, i32 %bits) nounwind { 210; X86-LABEL: test8: 211; X86: # %bb.0: 212; X86-NEXT: pushl %esi 213; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 214; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 215; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 216; X86-NEXT: movl %esi, %eax 217; X86-NEXT: shll %cl, %eax 218; X86-NEXT: shldl %cl, %esi, %edx 219; X86-NEXT: popl %esi 220; X86-NEXT: retl 221; 222; X64-LABEL: test8: 223; X64: # %bb.0: 224; X64-NEXT: movl %esi, %ecx 225; X64-NEXT: movq %rdi, %rax 226; X64-NEXT: andb $31, %cl 227; X64-NEXT: # kill: def $cl killed $cl killed $ecx 228; X64-NEXT: shlq %cl, %rax 229; X64-NEXT: retq 230 %and = and i32 %bits, 31 231 %sh_prom = zext i32 %and to i64 232 %shl = shl i64 %val, %sh_prom 233 ret i64 %shl 234} 235 236define i64 @test9(i64 %val, i32 %bits) nounwind { 237; X86-LABEL: test9: 238; X86: # %bb.0: 239; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 240; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 241; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 242; X86-NEXT: shrdl %cl, %edx, %eax 243; X86-NEXT: sarl %cl, %edx 244; X86-NEXT: retl 245; 246; X64-LABEL: test9: 247; X64: # %bb.0: 248; X64-NEXT: movl %esi, %ecx 249; X64-NEXT: movq %rdi, %rax 250; X64-NEXT: andb $31, %cl 251; X64-NEXT: # kill: def $cl killed $cl killed $ecx 252; X64-NEXT: sarq %cl, %rax 253; X64-NEXT: retq 254 %and = and i32 %bits, 31 255 %sh_prom = zext i32 %and to i64 256 %ashr = ashr i64 %val, %sh_prom 257 ret i64 %ashr 258} 259 260define i64 @test10(i64 %val, i32 %bits) nounwind { 261; X86-LABEL: test10: 262; X86: # %bb.0: 263; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 264; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 265; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 266; X86-NEXT: shrdl %cl, %edx, %eax 267; X86-NEXT: shrl %cl, %edx 268; X86-NEXT: retl 269; 270; X64-LABEL: test10: 271; X64: # %bb.0: 272; X64-NEXT: movl %esi, %ecx 273; X64-NEXT: movq %rdi, %rax 274; X64-NEXT: andb $31, %cl 275; X64-NEXT: # kill: def $cl killed $cl killed $ecx 276; X64-NEXT: shrq %cl, %rax 277; X64-NEXT: retq 278 %and = and i32 %bits, 31 279 %sh_prom = zext i32 %and to i64 280 %lshr = lshr i64 %val, %sh_prom 281 ret i64 %lshr 282} 283 284; SHLD/SHRD manual shifts 285 286define i32 @test11(i32 %hi, i32 %lo, i32 %bits) nounwind { 287; X86-LABEL: test11: 288; X86: # %bb.0: 289; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 290; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 291; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 292; X86-NEXT: andl $31, %ecx 293; X86-NEXT: # kill: def $cl killed $cl killed $ecx 294; X86-NEXT: shldl %cl, %edx, %eax 295; X86-NEXT: retl 296; 297; X64-LABEL: test11: 298; X64: # %bb.0: 299; X64-NEXT: movl %edx, %ecx 300; X64-NEXT: movl %edi, %eax 301; X64-NEXT: andl $31, %ecx 302; X64-NEXT: # kill: def $cl killed $cl killed $ecx 303; X64-NEXT: shldl %cl, %esi, %eax 304; X64-NEXT: retq 305 %and = and i32 %bits, 31 306 %and32 = sub i32 32, %and 307 %sh_lo = lshr i32 %lo, %and32 308 %sh_hi = shl i32 %hi, %and 309 %sh = or i32 %sh_lo, %sh_hi 310 ret i32 %sh 311} 312 313define i32 @test12(i32 %hi, i32 %lo, i32 %bits) nounwind { 314; X86-LABEL: test12: 315; X86: # %bb.0: 316; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 317; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 318; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 319; X86-NEXT: andl $31, %ecx 320; X86-NEXT: # kill: def $cl killed $cl killed $ecx 321; X86-NEXT: shrdl %cl, %edx, %eax 322; X86-NEXT: retl 323; 324; X64-LABEL: test12: 325; X64: # %bb.0: 326; X64-NEXT: movl %edx, %ecx 327; X64-NEXT: movl %esi, %eax 328; X64-NEXT: andl $31, %ecx 329; X64-NEXT: # kill: def $cl killed $cl killed $ecx 330; X64-NEXT: shrdl %cl, %edi, %eax 331; X64-NEXT: retq 332 %and = and i32 %bits, 31 333 %and32 = sub i32 32, %and 334 %sh_lo = shl i32 %hi, %and32 335 %sh_hi = lshr i32 %lo, %and 336 %sh = or i32 %sh_lo, %sh_hi 337 ret i32 %sh 338} 339 340define i32 @test13(i32 %hi, i32 %lo, i32 %bits) nounwind { 341; X86-LABEL: test13: 342; X86: # %bb.0: 343; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 344; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 345; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 346; X86-NEXT: shldl %cl, %edx, %eax 347; X86-NEXT: retl 348; 349; X64-LABEL: test13: 350; X64: # %bb.0: 351; X64-NEXT: movl %edx, %ecx 352; X64-NEXT: movl %edi, %eax 353; X64-NEXT: # kill: def $cl killed $cl killed $ecx 354; X64-NEXT: shldl %cl, %esi, %eax 355; X64-NEXT: retq 356 %bits32 = sub i32 32, %bits 357 %sh_lo = lshr i32 %lo, %bits32 358 %sh_hi = shl i32 %hi, %bits 359 %sh = or i32 %sh_lo, %sh_hi 360 ret i32 %sh 361} 362 363define i32 @test14(i32 %hi, i32 %lo, i32 %bits) nounwind { 364; X86-LABEL: test14: 365; X86: # %bb.0: 366; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 367; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 368; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 369; X86-NEXT: shrdl %cl, %edx, %eax 370; X86-NEXT: retl 371; 372; X64-LABEL: test14: 373; X64: # %bb.0: 374; X64-NEXT: movl %edx, %ecx 375; X64-NEXT: movl %esi, %eax 376; X64-NEXT: # kill: def $cl killed $cl killed $ecx 377; X64-NEXT: shrdl %cl, %edi, %eax 378; X64-NEXT: retq 379 %bits32 = sub i32 32, %bits 380 %sh_lo = shl i32 %hi, %bits32 381 %sh_hi = lshr i32 %lo, %bits 382 %sh = or i32 %sh_lo, %sh_hi 383 ret i32 %sh 384} 385 386define i32 @test15(i32 %hi, i32 %lo, i32 %bits) nounwind { 387; X86-LABEL: test15: 388; X86: # %bb.0: 389; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 390; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 391; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 392; X86-NEXT: shldl %cl, %edx, %eax 393; X86-NEXT: retl 394; 395; X64-LABEL: test15: 396; X64: # %bb.0: 397; X64-NEXT: movl %edx, %ecx 398; X64-NEXT: movl %edi, %eax 399; X64-NEXT: # kill: def $cl killed $cl killed $ecx 400; X64-NEXT: shldl %cl, %esi, %eax 401; X64-NEXT: retq 402 %bits32 = xor i32 %bits, 31 403 %lo2 = lshr i32 %lo, 1 404 %sh_lo = lshr i32 %lo2, %bits32 405 %sh_hi = shl i32 %hi, %bits 406 %sh = or i32 %sh_lo, %sh_hi 407 ret i32 %sh 408} 409 410define i32 @test16(i32 %hi, i32 %lo, i32 %bits) nounwind { 411; X86-LABEL: test16: 412; X86: # %bb.0: 413; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 414; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 415; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 416; X86-NEXT: shrdl %cl, %edx, %eax 417; X86-NEXT: retl 418; 419; X64-LABEL: test16: 420; X64: # %bb.0: 421; X64-NEXT: movl %edx, %ecx 422; X64-NEXT: movl %edi, %eax 423; X64-NEXT: # kill: def $cl killed $cl killed $ecx 424; X64-NEXT: shrdl %cl, %esi, %eax 425; X64-NEXT: retq 426 %bits32 = xor i32 %bits, 31 427 %lo2 = shl i32 %lo, 1 428 %sh_lo = shl i32 %lo2, %bits32 429 %sh_hi = lshr i32 %hi, %bits 430 %sh = or i32 %sh_lo, %sh_hi 431 ret i32 %sh 432} 433 434define i32 @test17(i32 %hi, i32 %lo, i32 %bits) nounwind { 435; X86-LABEL: test17: 436; X86: # %bb.0: 437; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 438; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 439; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 440; X86-NEXT: shrdl %cl, %edx, %eax 441; X86-NEXT: retl 442; 443; X64-LABEL: test17: 444; X64: # %bb.0: 445; X64-NEXT: movl %edx, %ecx 446; X64-NEXT: movl %edi, %eax 447; X64-NEXT: # kill: def $cl killed $cl killed $ecx 448; X64-NEXT: shrdl %cl, %esi, %eax 449; X64-NEXT: retq 450 %bits32 = xor i32 %bits, 31 451 %lo2 = add i32 %lo, %lo 452 %sh_lo = shl i32 %lo2, %bits32 453 %sh_hi = lshr i32 %hi, %bits 454 %sh = or i32 %sh_lo, %sh_hi 455 ret i32 %sh 456} 457 458; PR34641 - Masked Shift Counts 459 460define i32 @shld_safe_i32(i32, i32, i32) { 461; X86-LABEL: shld_safe_i32: 462; X86: # %bb.0: 463; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 464; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 465; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 466; X86-NEXT: shldl %cl, %edx, %eax 467; X86-NEXT: retl 468; 469; X64-LABEL: shld_safe_i32: 470; X64: # %bb.0: 471; X64-NEXT: movl %edx, %ecx 472; X64-NEXT: movl %edi, %eax 473; X64-NEXT: # kill: def $cl killed $cl killed $ecx 474; X64-NEXT: shldl %cl, %esi, %eax 475; X64-NEXT: retq 476 %4 = and i32 %2, 31 477 %5 = shl i32 %0, %4 478 %6 = sub i32 0, %2 479 %7 = and i32 %6, 31 480 %8 = lshr i32 %1, %7 481 %9 = or i32 %5, %8 482 ret i32 %9 483} 484 485define i32 @shrd_safe_i32(i32, i32, i32) { 486; X86-LABEL: shrd_safe_i32: 487; X86: # %bb.0: 488; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 489; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 490; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 491; X86-NEXT: shrdl %cl, %edx, %eax 492; X86-NEXT: retl 493; 494; X64-LABEL: shrd_safe_i32: 495; X64: # %bb.0: 496; X64-NEXT: movl %edx, %ecx 497; X64-NEXT: movl %edi, %eax 498; X64-NEXT: # kill: def $cl killed $cl killed $ecx 499; X64-NEXT: shrdl %cl, %esi, %eax 500; X64-NEXT: retq 501 %4 = and i32 %2, 31 502 %5 = lshr i32 %0, %4 503 %6 = sub i32 0, %2 504 %7 = and i32 %6, 31 505 %8 = shl i32 %1, %7 506 %9 = or i32 %5, %8 507 ret i32 %9 508} 509