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