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