1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc -mtriple=x86_64 < %s | FileCheck %s 3 4define i128 @avgflooru_i128(i128 %x, i128 %y) { 5; CHECK-LABEL: avgflooru_i128: 6; CHECK: # %bb.0: # %start 7; CHECK-NEXT: movq %rdi, %rax 8; CHECK-NEXT: addq %rdx, %rax 9; CHECK-NEXT: adcq %rcx, %rsi 10; CHECK-NEXT: setb %cl 11; CHECK-NEXT: shrdq $1, %rsi, %rax 12; CHECK-NEXT: movzbl %cl, %edx 13; CHECK-NEXT: shldq $63, %rsi, %rdx 14; CHECK-NEXT: retq 15start: 16 %xor = xor i128 %y, %x 17 %lshr = lshr i128 %xor, 1 18 %and = and i128 %y, %x 19 %add = add i128 %lshr, %and 20 ret i128 %add 21} 22 23declare void @use(i8) 24 25define i128 @avgflooru_i128_multi_use(i128 %x, i128 %y) nounwind { 26; CHECK-LABEL: avgflooru_i128_multi_use: 27; CHECK: # %bb.0: # %start 28; CHECK-NEXT: pushq %rbp 29; CHECK-NEXT: pushq %r15 30; CHECK-NEXT: pushq %r14 31; CHECK-NEXT: pushq %r13 32; CHECK-NEXT: pushq %r12 33; CHECK-NEXT: pushq %rbx 34; CHECK-NEXT: pushq %rax 35; CHECK-NEXT: movq %rcx, %rbx 36; CHECK-NEXT: movq %rdx, %r14 37; CHECK-NEXT: movq %rsi, %r15 38; CHECK-NEXT: movq %rdi, %r12 39; CHECK-NEXT: movq %rdx, %r13 40; CHECK-NEXT: xorq %rdi, %r13 41; CHECK-NEXT: movq %rcx, %rbp 42; CHECK-NEXT: xorq %rsi, %rbp 43; CHECK-NEXT: movq %r13, %rdi 44; CHECK-NEXT: movq %rbp, %rsi 45; CHECK-NEXT: callq use@PLT 46; CHECK-NEXT: shrdq $1, %rbp, %r13 47; CHECK-NEXT: shrq %rbp 48; CHECK-NEXT: movq %r13, %rdi 49; CHECK-NEXT: movq %rbp, %rsi 50; CHECK-NEXT: callq use@PLT 51; CHECK-NEXT: addq %r14, %r12 52; CHECK-NEXT: adcq %rbx, %r15 53; CHECK-NEXT: setb %al 54; CHECK-NEXT: shrdq $1, %r15, %r12 55; CHECK-NEXT: movzbl %al, %edx 56; CHECK-NEXT: shldq $63, %r15, %rdx 57; CHECK-NEXT: movq %r12, %rax 58; CHECK-NEXT: addq $8, %rsp 59; CHECK-NEXT: popq %rbx 60; CHECK-NEXT: popq %r12 61; CHECK-NEXT: popq %r13 62; CHECK-NEXT: popq %r14 63; CHECK-NEXT: popq %r15 64; CHECK-NEXT: popq %rbp 65; CHECK-NEXT: retq 66start: 67 %xor = xor i128 %y, %x 68 call void @use(i128 %xor) 69 %lshr = lshr i128 %xor, 1 70 call void @use(i128 %lshr) 71 %and = and i128 %y, %x 72 %add = add i128 %lshr, %and 73 ret i128 %add 74} 75 76; This test case shouldn't combine because it's not 77; an avgflooru operation 78 79define i128 @avgflooru_i128_negative(i128 %x, i128 %y) { 80; CHECK-LABEL: avgflooru_i128_negative: 81; CHECK: # %bb.0: # %start 82; CHECK-NEXT: movq %rdi, %rax 83; CHECK-NEXT: andq %rsi, %rcx 84; CHECK-NEXT: notq %rsi 85; CHECK-NEXT: andq %rdi, %rdx 86; CHECK-NEXT: notq %rax 87; CHECK-NEXT: addq %rdx, %rax 88; CHECK-NEXT: adcq %rcx, %rsi 89; CHECK-NEXT: movq %rsi, %rdx 90; CHECK-NEXT: retq 91start: 92 %xor = xor i128 %x, -1 93 %and = and i128 %y, %x 94 %add = add i128 %xor, %and 95 ret i128 %add 96} 97 98; This negative test case shouldn't combine, i32 is already properly 99; handled in terms of legalization, compared to the i128 100 101define i32 @avgflooru_i128_negative2(i32 %x, i32 %y) { 102; CHECK-LABEL: avgflooru_i128_negative2: 103; CHECK: # %bb.0: # %start 104; CHECK-NEXT: movl %edi, %ecx 105; CHECK-NEXT: movl %esi, %eax 106; CHECK-NEXT: addq %rcx, %rax 107; CHECK-NEXT: shrq %rax 108; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 109; CHECK-NEXT: retq 110start: 111 %xor = xor i32 %y, %x 112 %lshr = lshr i32 %xor, 1 113 %and = and i32 %y, %x 114 %add = add i32 %lshr, %and 115 ret i32 %add 116} 117 118define <2 x i128> @avgflooru_i128_vec(<2 x i128> %x, <2 x i128> %y) { 119; CHECK-LABEL: avgflooru_i128_vec: 120; CHECK: # %bb.0: # %start 121; CHECK-NEXT: movq %rdi, %rax 122; CHECK-NEXT: addq %r9, %rsi 123; CHECK-NEXT: adcq {{[0-9]+}}(%rsp), %rdx 124; CHECK-NEXT: setb %dil 125; CHECK-NEXT: movzbl %dil, %edi 126; CHECK-NEXT: shldq $63, %rdx, %rdi 127; CHECK-NEXT: addq {{[0-9]+}}(%rsp), %rcx 128; CHECK-NEXT: adcq {{[0-9]+}}(%rsp), %r8 129; CHECK-NEXT: setb %r9b 130; CHECK-NEXT: movzbl %r9b, %r9d 131; CHECK-NEXT: shldq $63, %r8, %r9 132; CHECK-NEXT: shldq $63, %rsi, %rdx 133; CHECK-NEXT: shldq $63, %rcx, %r8 134; CHECK-NEXT: movq %r8, 16(%rax) 135; CHECK-NEXT: movq %rdx, (%rax) 136; CHECK-NEXT: movq %r9, 24(%rax) 137; CHECK-NEXT: movq %rdi, 8(%rax) 138; CHECK-NEXT: retq 139start: 140 %xor = xor <2 x i128> %y, %x 141 %lshr = lshr <2 x i128> %xor, <i128 1, i128 1> 142 %and = and <2 x i128> %y, %x 143 %add = add <2 x i128> %lshr, %and 144 ret <2 x i128> %add 145} 146