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