• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -march=x86-64 | FileCheck %s
2
3%struct.obj = type { i64 }
4
5; CHECK: _Z7releaseP3obj
6define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp {
7entry:
8; CHECK: decq	(%{{rdi|rcx}})
9; CHECK-NEXT: je
10  %refcnt = getelementptr inbounds %struct.obj* %o, i64 0, i32 0
11  %0 = load i64* %refcnt, align 8, !tbaa !0
12  %dec = add i64 %0, -1
13  store i64 %dec, i64* %refcnt, align 8, !tbaa !0
14  %tobool = icmp eq i64 %dec, 0
15  br i1 %tobool, label %if.end, label %return
16
17if.end:                                           ; preds = %entry
18  %1 = bitcast %struct.obj* %o to i8*
19  tail call void @free(i8* %1)
20  br label %return
21
22return:                                           ; preds = %entry, %if.end
23  ret void
24}
25
26@c = common global i64 0, align 8
27@a = common global i32 0, align 4
28@.str = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 1
29@b = common global i32 0, align 4
30
31; CHECK: test
32define i32 @test() nounwind uwtable ssp {
33entry:
34; CHECK: decq
35; CHECK-NOT: decq
36%0 = load i64* @c, align 8, !tbaa !0
37%dec.i = add nsw i64 %0, -1
38store i64 %dec.i, i64* @c, align 8, !tbaa !0
39%tobool.i = icmp ne i64 %dec.i, 0
40%lor.ext.i = zext i1 %tobool.i to i32
41store i32 %lor.ext.i, i32* @a, align 4, !tbaa !3
42%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %dec.i) nounwind
43ret i32 0
44}
45
46; CHECK: test2
47define i32 @test2() nounwind uwtable ssp {
48entry:
49; CHECK-NOT: decq ({{.*}})
50%0 = load i64* @c, align 8, !tbaa !0
51%dec.i = add nsw i64 %0, -1
52store i64 %dec.i, i64* @c, align 8, !tbaa !0
53%tobool.i = icmp ne i64 %0, 0
54%lor.ext.i = zext i1 %tobool.i to i32
55store i32 %lor.ext.i, i32* @a, align 4, !tbaa !3
56%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %dec.i) nounwind
57ret i32 0
58}
59
60declare i32 @printf(i8* nocapture, ...) nounwind
61
62declare void @free(i8* nocapture) nounwind
63
64!0 = metadata !{metadata !"long", metadata !1}
65!1 = metadata !{metadata !"omnipotent char", metadata !2}
66!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
67!3 = metadata !{metadata !"int", metadata !1}
68
69%struct.obj2 = type { i64, i32, i16, i8 }
70
71declare void @other(%struct.obj2* ) nounwind;
72
73; CHECK: example_dec
74define void @example_dec(%struct.obj2* %o) nounwind uwtable ssp {
75; 64 bit dec
76entry:
77  %s64 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 0
78; CHECK-NOT: load
79  %0 = load i64* %s64, align 8
80; CHECK: decq ({{.*}})
81  %dec = add i64 %0, -1
82  store i64 %dec, i64* %s64, align 8
83  %tobool = icmp eq i64 %dec, 0
84  br i1 %tobool, label %if.end, label %return
85
86; 32 bit dec
87if.end:
88  %s32 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 1
89; CHECK-NOT: load
90  %1 = load i32* %s32, align 4
91; CHECK: decl {{[0-9][0-9]*}}({{.*}})
92  %dec1 = add i32 %1, -1
93  store i32 %dec1, i32* %s32, align 4
94  %tobool2 = icmp eq i32 %dec1, 0
95  br i1 %tobool2, label %if.end1, label %return
96
97; 16 bit dec
98if.end1:
99  %s16 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 2
100; CHECK-NOT: load
101  %2 = load i16* %s16, align 2
102; CHECK: decw {{[0-9][0-9]*}}({{.*}})
103  %dec2 = add i16 %2, -1
104  store i16 %dec2, i16* %s16, align 2
105  %tobool3 = icmp eq i16 %dec2, 0
106  br i1 %tobool3, label %if.end2, label %return
107
108; 8 bit dec
109if.end2:
110  %s8 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 3
111; CHECK-NOT: load
112  %3 = load i8* %s8
113; CHECK: decb {{[0-9][0-9]*}}({{.*}})
114  %dec3 = add i8 %3, -1
115  store i8 %dec3, i8* %s8
116  %tobool4 = icmp eq i8 %dec3, 0
117  br i1 %tobool4, label %if.end4, label %return
118
119if.end4:
120  tail call void @other(%struct.obj2* %o) nounwind
121  br label %return
122
123return:                                           ; preds = %if.end4, %if.end, %entry
124  ret void
125}
126
127; CHECK: example_inc
128define void @example_inc(%struct.obj2* %o) nounwind uwtable ssp {
129; 64 bit inc
130entry:
131  %s64 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 0
132; CHECK-NOT: load
133  %0 = load i64* %s64, align 8
134; CHECK: incq ({{.*}})
135  %inc = add i64 %0, 1
136  store i64 %inc, i64* %s64, align 8
137  %tobool = icmp eq i64 %inc, 0
138  br i1 %tobool, label %if.end, label %return
139
140; 32 bit inc
141if.end:
142  %s32 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 1
143; CHECK-NOT: load
144  %1 = load i32* %s32, align 4
145; CHECK: incl {{[0-9][0-9]*}}({{.*}})
146  %inc1 = add i32 %1, 1
147  store i32 %inc1, i32* %s32, align 4
148  %tobool2 = icmp eq i32 %inc1, 0
149  br i1 %tobool2, label %if.end1, label %return
150
151; 16 bit inc
152if.end1:
153  %s16 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 2
154; CHECK-NOT: load
155  %2 = load i16* %s16, align 2
156; CHECK: incw {{[0-9][0-9]*}}({{.*}})
157  %inc2 = add i16 %2, 1
158  store i16 %inc2, i16* %s16, align 2
159  %tobool3 = icmp eq i16 %inc2, 0
160  br i1 %tobool3, label %if.end2, label %return
161
162; 8 bit inc
163if.end2:
164  %s8 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 3
165; CHECK-NOT: load
166  %3 = load i8* %s8
167; CHECK: incb {{[0-9][0-9]*}}({{.*}})
168  %inc3 = add i8 %3, 1
169  store i8 %inc3, i8* %s8
170  %tobool4 = icmp eq i8 %inc3, 0
171  br i1 %tobool4, label %if.end4, label %return
172
173if.end4:
174  tail call void @other(%struct.obj2* %o) nounwind
175  br label %return
176
177return:
178  ret void
179}
180