xref: /llvm-project/llvm/test/CodeGen/X86/avgflooru-i128.ll (revision 2068b1ba031e258a6448bea372005d19692c802a)
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