xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/materialize.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64
3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-pc-win32 -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECKWIN64
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdefine i32 @one32_nooptsize() {
6*9880d681SAndroid Build Coastguard Workerentry:
7*9880d681SAndroid Build Coastguard Worker  ret i32 1
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; When not optimizing for size, use mov.
10*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32_nooptsize:
11*9880d681SAndroid Build Coastguard Worker; CHECK32:       movl $1, %eax
12*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
13*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32_nooptsize:
14*9880d681SAndroid Build Coastguard Worker; CHECK64:       movl $1, %eax
15*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT:  retq
16*9880d681SAndroid Build Coastguard Worker}
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Workerdefine i32 @one32() optsize {
19*9880d681SAndroid Build Coastguard Workerentry:
20*9880d681SAndroid Build Coastguard Worker  ret i32 1
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32:
23*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
24*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  incl %eax
25*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker; FIXME: Figure out the best approach in 64-bit mode.
28*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32:
29*9880d681SAndroid Build Coastguard Worker; CHECK64:       movl $1, %eax
30*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT:  retq
31*9880d681SAndroid Build Coastguard Worker}
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerdefine i32 @one32_minsize() minsize {
34*9880d681SAndroid Build Coastguard Workerentry:
35*9880d681SAndroid Build Coastguard Worker  ret i32 1
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; On 32-bit, xor-inc is preferred over push-pop.
38*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32_minsize:
39*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
40*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  incl %eax
41*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; On 64-bit we don't do xor-inc yet, so push-pop it is. Note that we have to
44*9880d681SAndroid Build Coastguard Worker; pop into a 64-bit register even when we just need 32 bits.
45*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32_minsize:
46*9880d681SAndroid Build Coastguard Worker; CHECK64:       pushq $1
47*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset 8
48*9880d681SAndroid Build Coastguard Worker; CHECK64:       popq %rax
49*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset -8
50*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT:  retq
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker; On Win64 we can't adjust the stack unless there's a frame pointer.
53*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-LABEL: one32_minsize:
54*9880d681SAndroid Build Coastguard Worker; CHECKWIN64:       movl $1, %eax
55*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-NEXT:  retq
56*9880d681SAndroid Build Coastguard Worker}
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Workerdefine i32 @pr26023() minsize {
59*9880d681SAndroid Build Coastguard Workerentry:
60*9880d681SAndroid Build Coastguard Worker  %x = alloca [120 x i8]
61*9880d681SAndroid Build Coastguard Worker  %0 = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 0
62*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "imr,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0)
63*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 119
64*9880d681SAndroid Build Coastguard Worker  store volatile i8 -2, i8* %arrayidx
65*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(i32 5)
66*9880d681SAndroid Build Coastguard Worker  %1 = load volatile i8, i8* %arrayidx
67*9880d681SAndroid Build Coastguard Worker  %conv = sext i8 %1 to i32
68*9880d681SAndroid Build Coastguard Worker  ret i32 %conv
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; The function writes to the redzone, so push/pop cannot be used.
71*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: pr26023:
72*9880d681SAndroid Build Coastguard Worker; CHECK64:       movl $5, %ecx
73*9880d681SAndroid Build Coastguard Worker; CHECK64:       retq
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; 32-bit X86 doesn't have a redzone.
76*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: pr26023:
77*9880d681SAndroid Build Coastguard Worker; CHECK32:       pushl $5
78*9880d681SAndroid Build Coastguard Worker; CHECK32:       popl %ecx
79*9880d681SAndroid Build Coastguard Worker; CHECK32:       retl
80*9880d681SAndroid Build Coastguard Worker}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Workerdefine i64 @one64_minsize() minsize {
84*9880d681SAndroid Build Coastguard Workerentry:
85*9880d681SAndroid Build Coastguard Worker  ret i64 1
86*9880d681SAndroid Build Coastguard Worker; On 64-bit we don't do xor-inc yet, so push-pop it is.
87*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one64_minsize:
88*9880d681SAndroid Build Coastguard Worker; CHECK64:       pushq $1
89*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset 8
90*9880d681SAndroid Build Coastguard Worker; CHECK64:       popq %rax
91*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset -8
92*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT:  retq
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker; On Win64 we can't adjust the stack unless there's a frame pointer.
95*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-LABEL: one64_minsize:
96*9880d681SAndroid Build Coastguard Worker; CHECKWIN64:       movl $1, %eax
97*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-NEXT:  retq
98*9880d681SAndroid Build Coastguard Worker}
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_one32() optsize {
101*9880d681SAndroid Build Coastguard Workerentry:
102*9880d681SAndroid Build Coastguard Worker  ret i32 -1
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one32:
105*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
106*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %eax
107*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
108*9880d681SAndroid Build Coastguard Worker}
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_one32_minsize() minsize {
111*9880d681SAndroid Build Coastguard Workerentry:
112*9880d681SAndroid Build Coastguard Worker  ret i32 -1
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker; xor-dec is preferred over push-pop.
115*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one32_minsize:
116*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
117*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %eax
118*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
119*9880d681SAndroid Build Coastguard Worker}
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Workerdefine i16 @one16() optsize {
122*9880d681SAndroid Build Coastguard Workerentry:
123*9880d681SAndroid Build Coastguard Worker  ret i16 1
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one16:
126*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
127*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  incl %eax
128*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  # kill
129*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
130*9880d681SAndroid Build Coastguard Worker}
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerdefine i16 @minus_one16() optsize {
133*9880d681SAndroid Build Coastguard Workerentry:
134*9880d681SAndroid Build Coastguard Worker  ret i16 -1
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one16:
137*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
138*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %eax
139*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  # kill
140*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  retl
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_five32() minsize {
144*9880d681SAndroid Build Coastguard Workerentry:
145*9880d681SAndroid Build Coastguard Worker  ret i32 -5
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_five32:
148*9880d681SAndroid Build Coastguard Worker; CHECK32: pushl $-5
149*9880d681SAndroid Build Coastguard Worker; CHECK32: popl %eax
150*9880d681SAndroid Build Coastguard Worker; CHECK32: retl
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Workerdefine i64 @minus_five64() minsize {
154*9880d681SAndroid Build Coastguard Workerentry:
155*9880d681SAndroid Build Coastguard Worker  ret i64 -5
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: minus_five64:
158*9880d681SAndroid Build Coastguard Worker; CHECK64: pushq $-5
159*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset 8
160*9880d681SAndroid Build Coastguard Worker; CHECK64: popq %rax
161*9880d681SAndroid Build Coastguard Worker; CHECK64:       .cfi_adjust_cfa_offset -8
162*9880d681SAndroid Build Coastguard Worker; CHECK64: retq
163*9880d681SAndroid Build Coastguard Worker}
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Workerdefine i32 @rematerialize_minus_one() optsize {
166*9880d681SAndroid Build Coastguard Workerentry:
167*9880d681SAndroid Build Coastguard Worker  ; Materialize -1 (thiscall forces it into %ecx).
168*9880d681SAndroid Build Coastguard Worker  tail call x86_thiscallcc void @f(i32 -1)
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
171*9880d681SAndroid Build Coastguard Worker  ; spilling it to the stack.
172*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker  ; -1 should be re-materialized here instead of getting spilled above.
175*9880d681SAndroid Build Coastguard Worker  ret i32 -1
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: rematerialize_minus_one
178*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %ecx, %ecx
179*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %ecx
180*9880d681SAndroid Build Coastguard Worker; CHECK32:       calll
181*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %eax, %eax
182*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %eax
183*9880d681SAndroid Build Coastguard Worker; CHECK32-NOT:   %eax
184*9880d681SAndroid Build Coastguard Worker; CHECK32:       retl
185*9880d681SAndroid Build Coastguard Worker}
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Workerdefine i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
188*9880d681SAndroid Build Coastguard Workerentry:
189*9880d681SAndroid Build Coastguard Worker  ; Materialize -1 (thiscall forces it into %ecx).
190*9880d681SAndroid Build Coastguard Worker  tail call x86_thiscallcc void @f(i32 -1)
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
193*9880d681SAndroid Build Coastguard Worker  ; spilling it to the stack.
194*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker  ; Define eflags.
197*9880d681SAndroid Build Coastguard Worker  %a = icmp ne i32 %x, 123
198*9880d681SAndroid Build Coastguard Worker  %b = zext i1 %a to i32
199*9880d681SAndroid Build Coastguard Worker  ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.
200*9880d681SAndroid Build Coastguard Worker  ; It must therefore not use the xor-dec lowering.
201*9880d681SAndroid Build Coastguard Worker  %c = select i1 %a, i32 %b, i32 -1
202*9880d681SAndroid Build Coastguard Worker  ret i32 %c
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: rematerialize_minus_one_eflags
205*9880d681SAndroid Build Coastguard Worker; CHECK32:       xorl %ecx, %ecx
206*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT:  decl %ecx
207*9880d681SAndroid Build Coastguard Worker; CHECK32:       calll
208*9880d681SAndroid Build Coastguard Worker; CHECK32:       cmpl
209*9880d681SAndroid Build Coastguard Worker; CHECK32:       setne
210*9880d681SAndroid Build Coastguard Worker; CHECK32-NOT:   xorl
211*9880d681SAndroid Build Coastguard Worker; CHECK32:       movl $-1
212*9880d681SAndroid Build Coastguard Worker; CHECK32:       cmov
213*9880d681SAndroid Build Coastguard Worker; CHECK32:       retl
214*9880d681SAndroid Build Coastguard Worker}
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Workerdeclare x86_thiscallcc void @f(i32)
217