• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -machine-combiner-verify-pattern-order=true | FileCheck %s
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -stop-after machine-combiner -machine-combiner-verify-pattern-order=true -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:    movl  %edx, %eax
66; CHECK-NEXT:    subb  %sil, %dil
67; CHECK-NEXT:    andb  %cl, %al
68; CHECK-NEXT:    andb  %dil, %al
69; CHECK-NEXT:    # kill
70; CHECK-NEXT:    retq
71  %t0 = sub i8 %x0, %x1
72  %t1 = and i8 %x2, %t0
73  %t2 = and i8 %x3, %t1
74  ret i8 %t2
75}
76
77; TODO: No way to test i16? These appear to always get promoted to i32.
78
79define i32 @reassociate_ands_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
80; CHECK-LABEL: reassociate_ands_i32:
81; CHECK:       # %bb.0:
82; CHECK-NEXT:    movl  %edx, %eax
83; CHECK-NEXT:    subl  %esi, %edi
84; CHECK-NEXT:    andl  %ecx, %eax
85; CHECK-NEXT:    andl  %edi, %eax
86; CHECK-NEXT:    retq
87  %t0 = sub i32 %x0, %x1
88  %t1 = and i32 %x2, %t0
89  %t2 = and i32 %x3, %t1
90  ret i32 %t2
91}
92
93define i64 @reassociate_ands_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
94; CHECK-LABEL: reassociate_ands_i64:
95; CHECK:       # %bb.0:
96; CHECK-NEXT:    movq  %rdx, %rax
97; CHECK-NEXT:    subq  %rsi, %rdi
98; CHECK-NEXT:    andq  %rcx, %rax
99; CHECK-NEXT:    andq  %rdi, %rax
100; CHECK-NEXT:    retq
101  %t0 = sub i64 %x0, %x1
102  %t1 = and i64 %x2, %t0
103  %t2 = and i64 %x3, %t1
104  ret i64 %t2
105}
106
107; Verify that integer 'ors' are reassociated. The first 'or' in
108; each test should be independent of the result of the preceding sub.
109
110define i8 @reassociate_ors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) {
111; CHECK-LABEL: reassociate_ors_i8:
112; CHECK:       # %bb.0:
113; CHECK-NEXT:    movl  %edx, %eax
114; CHECK-NEXT:    subb  %sil, %dil
115; CHECK-NEXT:    orb   %cl, %al
116; CHECK-NEXT:    orb   %dil, %al
117; CHECK-NEXT:    # kill
118; CHECK-NEXT:    retq
119  %t0 = sub i8 %x0, %x1
120  %t1 = or i8 %x2, %t0
121  %t2 = or i8 %x3, %t1
122  ret i8 %t2
123}
124
125; TODO: No way to test i16? These appear to always get promoted to i32.
126
127define i32 @reassociate_ors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
128; CHECK-LABEL: reassociate_ors_i32:
129; CHECK:       # %bb.0:
130; CHECK-NEXT:    movl  %edx, %eax
131; CHECK-NEXT:    subl  %esi, %edi
132; CHECK-NEXT:    orl   %ecx, %eax
133; CHECK-NEXT:    orl   %edi, %eax
134; CHECK-NEXT:    retq
135  %t0 = sub i32 %x0, %x1
136  %t1 = or i32 %x2, %t0
137  %t2 = or i32 %x3, %t1
138  ret i32 %t2
139}
140
141define i64 @reassociate_ors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
142; CHECK-LABEL: reassociate_ors_i64:
143; CHECK:       # %bb.0:
144; CHECK-NEXT:    movq  %rdx, %rax
145; CHECK-NEXT:    subq  %rsi, %rdi
146; CHECK-NEXT:    orq   %rcx, %rax
147; CHECK-NEXT:    orq   %rdi, %rax
148; CHECK-NEXT:    retq
149  %t0 = sub i64 %x0, %x1
150  %t1 = or i64 %x2, %t0
151  %t2 = or i64 %x3, %t1
152  ret i64 %t2
153}
154
155; Verify that integer 'xors' are reassociated. The first 'xor' in
156; each test should be independent of the result of the preceding sub.
157
158define i8 @reassociate_xors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) {
159; CHECK-LABEL: reassociate_xors_i8:
160; CHECK:       # %bb.0:
161; CHECK-NEXT:    movl  %edx, %eax
162; CHECK-NEXT:    subb  %sil, %dil
163; CHECK-NEXT:    xorb  %cl, %al
164; CHECK-NEXT:    xorb  %dil, %al
165; CHECK-NEXT:    # kill
166; CHECK-NEXT:    retq
167  %t0 = sub i8 %x0, %x1
168  %t1 = xor i8 %x2, %t0
169  %t2 = xor i8 %x3, %t1
170  ret i8 %t2
171}
172
173; TODO: No way to test i16? These appear to always get promoted to i32.
174
175define i32 @reassociate_xors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
176; CHECK-LABEL: reassociate_xors_i32:
177; CHECK:       # %bb.0:
178; CHECK-NEXT:    movl  %edx, %eax
179; CHECK-NEXT:    subl  %esi, %edi
180; CHECK-NEXT:    xorl  %ecx, %eax
181; CHECK-NEXT:    xorl  %edi, %eax
182; CHECK-NEXT:    retq
183  %t0 = sub i32 %x0, %x1
184  %t1 = xor i32 %x2, %t0
185  %t2 = xor i32 %x3, %t1
186  ret i32 %t2
187}
188
189define i64 @reassociate_xors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) {
190; CHECK-LABEL: reassociate_xors_i64:
191; CHECK:       # %bb.0:
192; CHECK-NEXT:    movq  %rdx, %rax
193; CHECK-NEXT:    subq  %rsi, %rdi
194; CHECK-NEXT:    xorq  %rcx, %rax
195; CHECK-NEXT:    xorq  %rdi, %rax
196; CHECK-NEXT:    retq
197  %t0 = sub i64 %x0, %x1
198  %t1 = xor i64 %x2, %t0
199  %t2 = xor i64 %x3, %t1
200  ret i64 %t2
201}
202
203