1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s 3 4; SHLD/SHRD manual shifts 5 6define i64 @test1(i64 %hi, i64 %lo, i64 %bits) nounwind { 7; CHECK-LABEL: test1: 8; CHECK: # %bb.0: 9; CHECK-NEXT: movq %rdx, %rcx 10; CHECK-NEXT: movq %rdi, %rax 11; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 12; CHECK-NEXT: shldq %cl, %rsi, %rax 13; CHECK-NEXT: retq 14 %and = and i64 %bits, 63 15 %and64 = sub i64 64, %and 16 %sh_lo = lshr i64 %lo, %and64 17 %sh_hi = shl i64 %hi, %and 18 %sh = or i64 %sh_lo, %sh_hi 19 ret i64 %sh 20} 21 22define i64 @test2(i64 %hi, i64 %lo, i64 %bits) nounwind { 23; CHECK-LABEL: test2: 24; CHECK: # %bb.0: 25; CHECK-NEXT: movq %rdx, %rcx 26; CHECK-NEXT: movq %rsi, %rax 27; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 28; CHECK-NEXT: shrdq %cl, %rdi, %rax 29; CHECK-NEXT: retq 30 %and = and i64 %bits, 63 31 %and64 = sub i64 64, %and 32 %sh_lo = shl i64 %hi, %and64 33 %sh_hi = lshr i64 %lo, %and 34 %sh = or i64 %sh_lo, %sh_hi 35 ret i64 %sh 36} 37 38define i64 @test3(i64 %hi, i64 %lo, i64 %bits) nounwind { 39; CHECK-LABEL: test3: 40; CHECK: # %bb.0: 41; CHECK-NEXT: movq %rdx, %rcx 42; CHECK-NEXT: movq %rdi, %rax 43; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 44; CHECK-NEXT: shldq %cl, %rsi, %rax 45; CHECK-NEXT: retq 46 %bits64 = sub i64 64, %bits 47 %sh_lo = lshr i64 %lo, %bits64 48 %sh_hi = shl i64 %hi, %bits 49 %sh = or i64 %sh_lo, %sh_hi 50 ret i64 %sh 51} 52 53define i64 @test4(i64 %hi, i64 %lo, i64 %bits) nounwind { 54; CHECK-LABEL: test4: 55; CHECK: # %bb.0: 56; CHECK-NEXT: movq %rdx, %rcx 57; CHECK-NEXT: movq %rsi, %rax 58; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 59; CHECK-NEXT: shrdq %cl, %rdi, %rax 60; CHECK-NEXT: retq 61 %bits64 = sub i64 64, %bits 62 %sh_lo = shl i64 %hi, %bits64 63 %sh_hi = lshr i64 %lo, %bits 64 %sh = or i64 %sh_lo, %sh_hi 65 ret i64 %sh 66} 67 68define i64 @test5(i64 %hi, i64 %lo, i64 %bits) nounwind { 69; CHECK-LABEL: test5: 70; CHECK: # %bb.0: 71; CHECK-NEXT: movq %rdx, %rcx 72; CHECK-NEXT: movq %rdi, %rax 73; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 74; CHECK-NEXT: shldq %cl, %rsi, %rax 75; CHECK-NEXT: retq 76 %bits64 = xor i64 %bits, 63 77 %lo2 = lshr i64 %lo, 1 78 %sh_lo = lshr i64 %lo2, %bits64 79 %sh_hi = shl i64 %hi, %bits 80 %sh = or i64 %sh_lo, %sh_hi 81 ret i64 %sh 82} 83 84define i64 @test6(i64 %hi, i64 %lo, i64 %bits) nounwind { 85; CHECK-LABEL: test6: 86; CHECK: # %bb.0: 87; CHECK-NEXT: movq %rdx, %rcx 88; CHECK-NEXT: movq %rdi, %rax 89; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 90; CHECK-NEXT: shrdq %cl, %rsi, %rax 91; CHECK-NEXT: retq 92 %bits64 = xor i64 %bits, 63 93 %lo2 = shl i64 %lo, 1 94 %sh_lo = shl i64 %lo2, %bits64 95 %sh_hi = lshr i64 %hi, %bits 96 %sh = or i64 %sh_lo, %sh_hi 97 ret i64 %sh 98} 99 100define i64 @test7(i64 %hi, i64 %lo, i64 %bits) nounwind { 101; CHECK-LABEL: test7: 102; CHECK: # %bb.0: 103; CHECK-NEXT: movq %rdx, %rcx 104; CHECK-NEXT: movq %rdi, %rax 105; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 106; CHECK-NEXT: shrdq %cl, %rsi, %rax 107; CHECK-NEXT: retq 108 %bits64 = xor i64 %bits, 63 109 %lo2 = add i64 %lo, %lo 110 %sh_lo = shl i64 %lo2, %bits64 111 %sh_hi = lshr i64 %hi, %bits 112 %sh = or i64 %sh_lo, %sh_hi 113 ret i64 %sh 114} 115 116define i64 @test8(i64 %hi, i64 %lo, i64 %bits) nounwind { 117; CHECK-LABEL: test8: 118; CHECK: # %bb.0: 119; CHECK-NEXT: movq %rdx, %rcx 120; CHECK-NEXT: movq %rdi, %rax 121; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx 122; CHECK-NEXT: shldq %cl, %rsi, %rax 123; CHECK-NEXT: retq 124 %tbits = trunc i64 %bits to i8 125 %tand = and i8 %tbits, 63 126 %tand64 = sub i8 64, %tand 127 %and = zext i8 %tand to i64 128 %and64 = zext i8 %tand64 to i64 129 %sh_lo = lshr i64 %lo, %and64 130 %sh_hi = shl i64 %hi, %and 131 %sh = or i64 %sh_lo, %sh_hi 132 ret i64 %sh 133} 134