• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -stop-after machine-combiner -o - | FileCheck %s --check-prefix=DEAD
3
4; Verify that integer multiplies are reassociated. The first multiply in
5; each test should be independent of the result of the preceding add (lea).
6
7; TODO: This test does not actually test i16 machine instruction reassociation
8; because the operands are being promoted to i32 types.
9
10define i16 @reassociate_muls_i16(i16 %x0, i16 %x1, i16 %x2, i16 %x3) {
11; CHECK-LABEL: reassociate_muls_i16:
12; CHECK:       # BB#0:
13; CHECK-NEXT:    # kill
14; CHECK-NEXT:    # kill
15; CHECK-NEXT:    leal   (%rdi,%rsi), %eax
16; CHECK-NEXT:    imull  %ecx, %edx
17; CHECK-NEXT:    imull  %edx, %eax
18; CHECK-NEXT:    # kill
19; CHECK-NEXT:    retq
20  %t0 = add i16 %x0, %x1
21  %t1 = mul i16 %x2, %t0
22  %t2 = mul i16 %x3, %t1
23  ret i16 %t2
24}
25
26define i32 @reassociate_muls_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
27; CHECK-LABEL: reassociate_muls_i32:
28; CHECK:       # BB#0:
29; CHECK-NEXT:    # kill
30; CHECK-NEXT:    # kill
31; CHECK-NEXT:    leal   (%rdi,%rsi), %eax
32; CHECK-NEXT:    imull  %ecx, %edx
33; CHECK-NEXT:    imull  %edx, %eax
34; CHECK-NEXT:    retq
35
36; DEAD:       ADD32rr
37; DEAD-NEXT:  IMUL32rr{{.*}}implicit-def dead %eflags
38; DEAD-NEXT:  IMUL32rr{{.*}}implicit-def dead %eflags
39
40  %t0 = add i32 %x0, %x1
41  %t1 = mul i32 %x2, %t0
42  %t2 = mul i32 %x3, %t1
43  ret i32 %t2
44}
45
46define i64 @reassociate_muls_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
47; CHECK-LABEL: reassociate_muls_i64:
48; CHECK:       # BB#0:
49; CHECK-NEXT:    leaq   (%rdi,%rsi), %rax
50; CHECK-NEXT:    imulq  %rcx, %rdx
51; CHECK-NEXT:    imulq  %rdx, %rax
52; CHECK-NEXT:    retq
53  %t0 = add i64 %x0, %x1
54  %t1 = mul i64 %x2, %t0
55  %t2 = mul i64 %x3, %t1
56  ret i64 %t2
57}
58
59; Verify that integer 'ands' are reassociated. The first 'and' in
60; each test should be independent of the result of the preceding sub.
61
62define i8 @reassociate_ands_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) {
63; CHECK-LABEL: reassociate_ands_i8:
64; CHECK:       # BB#0:
65; CHECK-NEXT:    subb  %sil, %dil
66; CHECK-NEXT:    andb  %cl, %dl
67; CHECK-NEXT:    andb  %dil, %dl
68; CHECK-NEXT:    movl  %edx, %eax
69; CHECK-NEXT:    retq
70  %t0 = sub i8 %x0, %x1
71  %t1 = and i8 %x2, %t0
72  %t2 = and i8 %x3, %t1
73  ret i8 %t2
74}
75
76; TODO: No way to test i16? These appear to always get promoted to i32.
77
78define i32 @reassociate_ands_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
79; CHECK-LABEL: reassociate_ands_i32:
80; CHECK:       # BB#0:
81; CHECK-NEXT:    subl  %esi, %edi
82; CHECK-NEXT:    andl  %ecx, %edx
83; CHECK-NEXT:    andl  %edi, %edx
84; CHECK-NEXT:    movl  %edx, %eax
85; CHECK-NEXT:    retq
86  %t0 = sub i32 %x0, %x1
87  %t1 = and i32 %x2, %t0
88  %t2 = and i32 %x3, %t1
89  ret i32 %t2
90}
91
92define i64 @reassociate_ands_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
93; CHECK-LABEL: reassociate_ands_i64:
94; CHECK:       # BB#0:
95; CHECK-NEXT:    subq  %rsi, %rdi
96; CHECK-NEXT:    andq  %rcx, %rdx
97; CHECK-NEXT:    andq  %rdi, %rdx
98; CHECK-NEXT:    movq  %rdx, %rax
99; CHECK-NEXT:    retq
100  %t0 = sub i64 %x0, %x1
101  %t1 = and i64 %x2, %t0
102  %t2 = and i64 %x3, %t1
103  ret i64 %t2
104}
105
106; Verify that integer 'ors' are reassociated. The first 'or' in
107; each test should be independent of the result of the preceding sub.
108
109define i8 @reassociate_ors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) {
110; CHECK-LABEL: reassociate_ors_i8:
111; CHECK:       # BB#0:
112; CHECK-NEXT:    subb  %sil, %dil
113; CHECK-NEXT:    orb   %cl, %dl
114; CHECK-NEXT:    orb   %dil, %dl
115; CHECK-NEXT:    movl  %edx, %eax
116; CHECK-NEXT:    retq
117  %t0 = sub i8 %x0, %x1
118  %t1 = or i8 %x2, %t0
119  %t2 = or i8 %x3, %t1
120  ret i8 %t2
121}
122
123; TODO: No way to test i16? These appear to always get promoted to i32.
124
125define i32 @reassociate_ors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
126; CHECK-LABEL: reassociate_ors_i32:
127; CHECK:       # BB#0:
128; CHECK-NEXT:    subl  %esi, %edi
129; CHECK-NEXT:    orl   %ecx, %edx
130; CHECK-NEXT:    orl   %edi, %edx
131; CHECK-NEXT:    movl  %edx, %eax
132; CHECK-NEXT:    retq
133  %t0 = sub i32 %x0, %x1
134  %t1 = or i32 %x2, %t0
135  %t2 = or i32 %x3, %t1
136  ret i32 %t2
137}
138
139define i64 @reassociate_ors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
140; CHECK-LABEL: reassociate_ors_i64:
141; CHECK:       # BB#0:
142; CHECK-NEXT:    subq  %rsi, %rdi
143; CHECK-NEXT:    orq   %rcx, %rdx
144; CHECK-NEXT:    orq   %rdi, %rdx
145; CHECK-NEXT:    movq  %rdx, %rax
146; CHECK-NEXT:    retq
147  %t0 = sub i64 %x0, %x1
148  %t1 = or i64 %x2, %t0
149  %t2 = or i64 %x3, %t1
150  ret i64 %t2
151}
152
153; Verify that integer 'xors' are reassociated. The first 'xor' in
154; each test should be independent of the result of the preceding sub.
155
156define i8 @reassociate_xors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) {
157; CHECK-LABEL: reassociate_xors_i8:
158; CHECK:       # BB#0:
159; CHECK-NEXT:    subb  %sil, %dil
160; CHECK-NEXT:    xorb  %cl, %dl
161; CHECK-NEXT:    xorb  %dil, %dl
162; CHECK-NEXT:    movl  %edx, %eax
163; CHECK-NEXT:    retq
164  %t0 = sub i8 %x0, %x1
165  %t1 = xor i8 %x2, %t0
166  %t2 = xor i8 %x3, %t1
167  ret i8 %t2
168}
169
170; TODO: No way to test i16? These appear to always get promoted to i32.
171
172define i32 @reassociate_xors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
173; CHECK-LABEL: reassociate_xors_i32:
174; CHECK:       # BB#0:
175; CHECK-NEXT:    subl  %esi, %edi
176; CHECK-NEXT:    xorl  %ecx, %edx
177; CHECK-NEXT:    xorl  %edi, %edx
178; CHECK-NEXT:    movl  %edx, %eax
179; CHECK-NEXT:    retq
180  %t0 = sub i32 %x0, %x1
181  %t1 = xor i32 %x2, %t0
182  %t2 = xor i32 %x3, %t1
183  ret i32 %t2
184}
185
186define i64 @reassociate_xors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
187; CHECK-LABEL: reassociate_xors_i64:
188; CHECK:       # BB#0:
189; CHECK-NEXT:    subq  %rsi, %rdi
190; CHECK-NEXT:    xorq  %rcx, %rdx
191; CHECK-NEXT:    xorq  %rdi, %rdx
192; CHECK-NEXT:    movq  %rdx, %rax
193; CHECK-NEXT:    retq
194  %t0 = sub i64 %x0, %x1
195  %t1 = xor i64 %x2, %t0
196  %t2 = xor i64 %x3, %t1
197  ret i64 %t2
198}
199
200