xref: /llvm-project/llvm/test/CodeGen/X86/rd-mod-wr-eflags.ll (revision ee5585ed09aff2e54cb540fad4c33f0c93626b1b)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s
3
4%struct.obj = type { i64 }
5
6define dso_local void @_Z7releaseP3obj(ptr nocapture %o) nounwind uwtable ssp {
7; CHECK-LABEL: _Z7releaseP3obj:
8; CHECK:       # %bb.0: # %entry
9; CHECK-NEXT:    decq (%rdi)
10; CHECK-NEXT:    je free # TAILCALL
11; CHECK-NEXT:  # %bb.1: # %return
12; CHECK-NEXT:    retq
13entry:
14  %0 = load i64, ptr %o, align 8
15  %dec = add i64 %0, -1
16  store i64 %dec, ptr %o, align 8
17  %tobool = icmp eq i64 %dec, 0
18  br i1 %tobool, label %if.end, label %return
19
20if.end:                                           ; preds = %entry
21  tail call void @free(ptr %o)
22  br label %return
23
24return:                                           ; preds = %entry, %if.end
25  ret void
26}
27
28@c = common dso_local global i64 0, align 8
29@a = common dso_local global i32 0, align 4
30@.str = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 1
31@b = common dso_local global i32 0, align 4
32
33define dso_local i32 @test() nounwind uwtable ssp {
34; CHECK-LABEL: test:
35; CHECK:       # %bb.0: # %entry
36; CHECK-NEXT:    pushq %rax
37; CHECK-NEXT:    .cfi_def_cfa_offset 16
38; CHECK-NEXT:    movq c(%rip), %rsi
39; CHECK-NEXT:    xorl %eax, %eax
40; CHECK-NEXT:    decq %rsi
41; CHECK-NEXT:    movq %rsi, c(%rip)
42; CHECK-NEXT:    setne %al
43; CHECK-NEXT:    movl %eax, a(%rip)
44; CHECK-NEXT:    movl $.L.str, %edi
45; CHECK-NEXT:    xorl %eax, %eax
46; CHECK-NEXT:    callq printf@PLT
47; CHECK-NEXT:    xorl %eax, %eax
48; CHECK-NEXT:    popq %rcx
49; CHECK-NEXT:    .cfi_def_cfa_offset 8
50; CHECK-NEXT:    retq
51entry:
52%0 = load i64, ptr @c, align 8
53%dec.i = add nsw i64 %0, -1
54store i64 %dec.i, ptr @c, align 8
55%tobool.i = icmp ne i64 %dec.i, 0
56%lor.ext.i = zext i1 %tobool.i to i32
57store i32 %lor.ext.i, ptr @a, align 4
58%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %dec.i) nounwind
59ret i32 0
60}
61
62define dso_local i32 @test2() nounwind uwtable ssp {
63; CHECK-LABEL: test2:
64; CHECK:       # %bb.0: # %entry
65; CHECK-NEXT:    pushq %rax
66; CHECK-NEXT:    .cfi_def_cfa_offset 16
67; CHECK-NEXT:    movq c(%rip), %rsi
68; CHECK-NEXT:    xorl %eax, %eax
69; CHECK-NEXT:    addq $-1, %rsi
70; CHECK-NEXT:    setb %al
71; CHECK-NEXT:    movq %rsi, c(%rip)
72; CHECK-NEXT:    movl %eax, a(%rip)
73; CHECK-NEXT:    movl $.L.str, %edi
74; CHECK-NEXT:    xorl %eax, %eax
75; CHECK-NEXT:    callq printf@PLT
76; CHECK-NEXT:    xorl %eax, %eax
77; CHECK-NEXT:    popq %rcx
78; CHECK-NEXT:    .cfi_def_cfa_offset 8
79; CHECK-NEXT:    retq
80entry:
81%0 = load i64, ptr @c, align 8
82%dec.i = add nsw i64 %0, -1
83store i64 %dec.i, ptr @c, align 8
84%tobool.i = icmp ne i64 %0, 0
85%lor.ext.i = zext i1 %tobool.i to i32
86store i32 %lor.ext.i, ptr @a, align 4
87%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %dec.i) nounwind
88ret i32 0
89}
90
91declare i32 @printf(ptr nocapture, ...) nounwind
92
93declare dso_local void @free(ptr nocapture) nounwind
94
95%struct.obj2 = type { i64, i32, i16, i8 }
96
97declare dso_local void @other(ptr ) nounwind;
98
99define dso_local void @example_dec(ptr %o) nounwind uwtable ssp {
100; 64 bit dec
101; CHECK-LABEL: example_dec:
102; CHECK:       # %bb.0: # %entry
103; CHECK-NEXT:    decq (%rdi)
104; CHECK-NEXT:    jne .LBB3_4
105; CHECK-NEXT:  # %bb.1: # %if.end
106; CHECK-NEXT:    decl 8(%rdi)
107; CHECK-NEXT:    jne .LBB3_4
108; CHECK-NEXT:  # %bb.2: # %if.end1
109; CHECK-NEXT:    decw 12(%rdi)
110; CHECK-NEXT:    jne .LBB3_4
111; CHECK-NEXT:  # %bb.3: # %if.end2
112; CHECK-NEXT:    decb 14(%rdi)
113; CHECK-NEXT:    je other # TAILCALL
114; CHECK-NEXT:  .LBB3_4: # %return
115; CHECK-NEXT:    retq
116entry:
117  %0 = load i64, ptr %o, align 8
118  %dec = add i64 %0, -1
119  store i64 %dec, ptr %o, align 8
120  %tobool = icmp eq i64 %dec, 0
121  br i1 %tobool, label %if.end, label %return
122
123; 32 bit dec
124if.end:
125  %s32 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 1
126  %1 = load i32, ptr %s32, align 4
127  %dec1 = add i32 %1, -1
128  store i32 %dec1, ptr %s32, align 4
129  %tobool2 = icmp eq i32 %dec1, 0
130  br i1 %tobool2, label %if.end1, label %return
131
132; 16 bit dec
133if.end1:
134  %s16 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 2
135  %2 = load i16, ptr %s16, align 2
136  %dec2 = add i16 %2, -1
137  store i16 %dec2, ptr %s16, align 2
138  %tobool3 = icmp eq i16 %dec2, 0
139  br i1 %tobool3, label %if.end2, label %return
140
141; 8 bit dec
142if.end2:
143  %s8 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 3
144  %3 = load i8, ptr %s8
145  %dec3 = add i8 %3, -1
146  store i8 %dec3, ptr %s8
147  %tobool4 = icmp eq i8 %dec3, 0
148  br i1 %tobool4, label %if.end4, label %return
149
150if.end4:
151  tail call void @other(ptr %o) nounwind
152  br label %return
153
154return:                                           ; preds = %if.end4, %if.end, %entry
155  ret void
156}
157
158define dso_local void @example_inc(ptr %o) nounwind uwtable ssp {
159; 64 bit inc
160; CHECK-LABEL: example_inc:
161; CHECK:       # %bb.0: # %entry
162; CHECK-NEXT:    incq (%rdi)
163; CHECK-NEXT:    jne .LBB4_4
164; CHECK-NEXT:  # %bb.1: # %if.end
165; CHECK-NEXT:    incl 8(%rdi)
166; CHECK-NEXT:    jne .LBB4_4
167; CHECK-NEXT:  # %bb.2: # %if.end1
168; CHECK-NEXT:    incw 12(%rdi)
169; CHECK-NEXT:    jne .LBB4_4
170; CHECK-NEXT:  # %bb.3: # %if.end2
171; CHECK-NEXT:    incb 14(%rdi)
172; CHECK-NEXT:    je other # TAILCALL
173; CHECK-NEXT:  .LBB4_4: # %return
174; CHECK-NEXT:    retq
175entry:
176  %0 = load i64, ptr %o, align 8
177  %inc = add i64 %0, 1
178  store i64 %inc, ptr %o, align 8
179  %tobool = icmp eq i64 %inc, 0
180  br i1 %tobool, label %if.end, label %return
181
182; 32 bit inc
183if.end:
184  %s32 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 1
185  %1 = load i32, ptr %s32, align 4
186  %inc1 = add i32 %1, 1
187  store i32 %inc1, ptr %s32, align 4
188  %tobool2 = icmp eq i32 %inc1, 0
189  br i1 %tobool2, label %if.end1, label %return
190
191; 16 bit inc
192if.end1:
193  %s16 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 2
194  %2 = load i16, ptr %s16, align 2
195  %inc2 = add i16 %2, 1
196  store i16 %inc2, ptr %s16, align 2
197  %tobool3 = icmp eq i16 %inc2, 0
198  br i1 %tobool3, label %if.end2, label %return
199
200; 8 bit inc
201if.end2:
202  %s8 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 3
203  %3 = load i8, ptr %s8
204  %inc3 = add i8 %3, 1
205  store i8 %inc3, ptr %s8
206  %tobool4 = icmp eq i8 %inc3, 0
207  br i1 %tobool4, label %if.end4, label %return
208
209if.end4:
210  tail call void @other(ptr %o) nounwind
211  br label %return
212
213return:
214  ret void
215}
216
217; Deal with TokenFactor chain
218; rdar://11236106
219@foo = external dso_local global ptr, align 8
220
221define dso_local void @test3() nounwind ssp {
222; CHECK-LABEL: test3:
223; CHECK:       # %bb.0: # %entry
224; CHECK-NEXT:    movq foo(%rip), %rax
225; CHECK-NEXT:    decq 16(%rax)
226; CHECK-NEXT:    je baz # TAILCALL
227; CHECK-NEXT:  # %bb.1: # %if.end
228; CHECK-NEXT:    retq
229entry:
230  %0 = load ptr, ptr @foo, align 8
231  %arrayidx = getelementptr inbounds i64, ptr %0, i64 2
232  %1 = load i64, ptr %arrayidx, align 8
233  %dec = add i64 %1, -1
234  store i64 %dec, ptr %arrayidx, align 8
235  %cmp = icmp eq i64 %dec, 0
236  br i1 %cmp, label %if.then, label %if.end
237
238if.then:
239  tail call void @baz() nounwind
240  br label %if.end
241
242if.end:
243  ret void
244}
245
246declare dso_local void @baz()
247
248; Avoid creating a cycle in the DAG which would trigger an assert in the
249; scheduler.
250; PR12565
251; rdar://11451474
252@x = external dso_local global i32, align 4
253@y = external dso_local global i32, align 4
254@z = external dso_local global i32, align 4
255
256define dso_local void @test4() nounwind uwtable ssp {
257; CHECK-LABEL: test4:
258; CHECK:       # %bb.0: # %entry
259; CHECK-NEXT:    xorl %eax, %eax
260; CHECK-NEXT:    decl y(%rip)
261; CHECK-NEXT:    je .LBB6_2
262; CHECK-NEXT:  # %bb.1: # %entry
263; CHECK-NEXT:    movl x(%rip), %eax
264; CHECK-NEXT:  .LBB6_2: # %entry
265; CHECK-NEXT:    movl %eax, z(%rip)
266; CHECK-NEXT:    retq
267entry:
268  %0 = load i32, ptr @x, align 4
269  %1 = load i32, ptr @y, align 4
270  %dec = add nsw i32 %1, -1
271  store i32 %dec, ptr @y, align 4
272  %tobool.i = icmp ne i32 %dec, 0
273  %cond.i = select i1 %tobool.i, i32 %0, i32 0
274  store i32 %cond.i, ptr @z, align 4
275  ret void
276}
277