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