blob: 79af819fad8a6a8a1ecb9aa841093b1c66e2747f [file] [log] [blame]
Bevin Hansson39baaab2020-01-08 11:12:55 +01001// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
2// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
3
4_Accum a;
5_Fract f;
6long _Fract lf;
7unsigned _Accum ua;
8short unsigned _Accum usa;
9unsigned _Fract uf;
10
11_Sat _Accum sa;
12_Sat _Fract sf;
13_Sat long _Fract slf;
14_Sat unsigned _Accum sua;
15_Sat short unsigned _Accum susa;
16_Sat unsigned _Fract suf;
17
18// CHECK-LABEL: @Increment(
19void Increment() {
20// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
21// CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], -32768
22// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
23 a++;
24
25// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
26// CHECK-NEXT: [[TMP3:%.*]] = sub i16 [[TMP2]], -32768
27// CHECK-NEXT: store i16 [[TMP3]], i16* @f, align 2
28 f++;
29
30// CHECK: [[TMP4:%.*]] = load i32, i32* @lf, align 4
31// CHECK-NEXT: [[TMP5:%.*]] = sub i32 [[TMP4]], -2147483648
32// CHECK-NEXT: store i32 [[TMP5]], i32* @lf, align 4
33 lf++;
34
35// CHECK: [[TMP6:%.*]] = load i32, i32* @ua, align 4
36// SIGNED-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 65536
37// UNSIGNED-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 32768
38// CHECK-NEXT: store i32 [[TMP7]], i32* @ua, align 4
39 ua++;
40
41// CHECK: [[TMP8:%.*]] = load i16, i16* @usa, align 2
42// SIGNED-NEXT: [[TMP9:%.*]] = add i16 [[TMP8]], 256
43// UNSIGNED-NEXT: [[TMP9:%.*]] = add i16 [[TMP8]], 128
44// CHECK-NEXT: store i16 [[TMP9]], i16* @usa, align 2
45 usa++;
46
47// CHECK: [[TMP10:%.*]] = load i16, i16* @uf, align 2
48// SIGNED-NEXT: [[TMP11:%.*]] = add i16 [[TMP10]], undef
49// UNSIGNED-NEXT: [[TMP11:%.*]] = add i16 [[TMP10]], -32768
50// CHECK-NEXT: store i16 [[TMP11]], i16* @uf, align 2
51 uf++;
52
53// CHECK: [[TMP12:%.*]] = load i32, i32* @sa, align 4
54// CHECK-NEXT: [[TMP13:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP12]], i32 -32768)
55// CHECK-NEXT: store i32 [[TMP13]], i32* @sa, align 4
56 sa++;
57
58// CHECK: [[TMP14:%.*]] = load i16, i16* @sf, align 2
59// CHECK-NEXT: [[TMP15:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP14]], i16 -32768)
60// CHECK-NEXT: store i16 [[TMP15]], i16* @sf, align 2
61 sf++;
62
63// CHECK: [[TMP16:%.*]] = load i32, i32* @slf, align 4
64// CHECK-NEXT: [[TMP17:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP16]], i32 -2147483648)
65// CHECK-NEXT: store i32 [[TMP17]], i32* @slf, align 4
66 slf++;
67
68// CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
69// SIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP18]], i32 65536)
70// SIGNED-NEXT: store i32 [[TMP19]], i32* @sua, align 4
71// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
72// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
73// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
74// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
75 sua++;
76
77// CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
78// SIGNED-NEXT: [[TMP21:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP20]], i16 256)
79// SIGNED-NEXT: store i16 [[TMP21]], i16* @susa, align 2
80// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
81// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE2]], i15 128)
82// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
83// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
84 susa++;
85
86// CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
87// SIGNED-NEXT: [[TMP23:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP22]], i16 -1)
88// SIGNED-NEXT: store i16 [[TMP23]], i16* @suf, align 2
89// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
90// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE4]], i15 -1)
91// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
92// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
93 suf++;
94}
95
96// CHECK-LABEL: @Decrement(
97void Decrement() {
98// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
99// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], -32768
100// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
101 a--;
102
103// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
104// CHECK-NEXT: [[TMP3:%.*]] = add i16 [[TMP2]], -32768
105// CHECK-NEXT: store i16 [[TMP3]], i16* @f, align 2
106 f--;
107
108// CHECK: [[TMP4:%.*]] = load i32, i32* @lf, align 4
109// CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], -2147483648
110// CHECK-NEXT: store i32 [[TMP5]], i32* @lf, align 4
111 lf--;
112
113// CHECK: [[TMP6:%.*]] = load i32, i32* @ua, align 4
114// SIGNED-NEXT: [[TMP7:%.*]] = sub i32 [[TMP6]], 65536
115// UNSIGNED-NEXT: [[TMP7:%.*]] = sub i32 [[TMP6]], 32768
116// CHECK-NEXT: store i32 [[TMP7]], i32* @ua, align 4
117 ua--;
118
119// CHECK: [[TMP8:%.*]] = load i16, i16* @usa, align 2
120// SIGNED-NEXT: [[TMP9:%.*]] = sub i16 [[TMP8]], 256
121// UNSIGNED-NEXT: [[TMP9:%.*]] = sub i16 [[TMP8]], 128
122// CHECK-NEXT: store i16 [[TMP9]], i16* @usa, align 2
123 usa--;
124
125// CHECK: [[TMP10:%.*]] = load i16, i16* @uf, align 2
126// SIGNED-NEXT: [[TMP11:%.*]] = sub i16 [[TMP10]], undef
127// UNSIGNED-NEXT: [[TMP11:%.*]] = sub i16 [[TMP10]], -32768
128// CHECK-NEXT: store i16 [[TMP11]], i16* @uf, align 2
129 uf--;
130
131// CHECK: [[TMP12:%.*]] = load i32, i32* @sa, align 4
132// CHECK-NEXT: [[TMP13:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP12]], i32 -32768)
133// CHECK-NEXT: store i32 [[TMP13]], i32* @sa, align 4
134 sa--;
135
136// CHECK: [[TMP14:%.*]] = load i16, i16* @sf, align 2
137// CHECK-NEXT: [[TMP15:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP14]], i16 -32768)
138// CHECK-NEXT: store i16 [[TMP15]], i16* @sf, align 2
139 sf--;
140
141// CHECK: [[TMP16:%.*]] = load i32, i32* @slf, align 4
142// CHECK-NEXT: [[TMP17:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP16]], i32 -2147483648)
143// CHECK-NEXT: store i32 [[TMP17]], i32* @slf, align 4
144 slf--;
145
146// CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
147// SIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP18]], i32 65536)
148// SIGNED-NEXT: store i32 [[TMP19]], i32* @sua, align 4
149// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
150// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
151// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
152// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
153 sua--;
154
155// CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
156// SIGNED-NEXT: [[TMP21:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP20]], i16 256)
157// SIGNED-NEXT: store i16 [[TMP21]], i16* @susa, align 2
158// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
159// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE2]], i15 128)
160// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
161// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
162 susa--;
163
164// CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
165// SIGNED-NEXT: [[TMP23:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP22]], i16 -1)
166// SIGNED-NEXT: store i16 [[TMP23]], i16* @suf, align 2
167// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
168// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE4]], i15 -1)
169// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
170// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
171 suf--;
172}
173
174// CHECK-LABEL: @Minus(
175void Minus() {
176// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
177// CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[TMP0]]
178// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
179 a = -a;
180
181// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
182// CHECK-NEXT: [[TMP3:%.*]] = sub i16 0, [[TMP2]]
183// CHECK-NEXT: store i16 [[TMP3]], i16* @f, align 2
184 f = -f;
185
186// CHECK: [[TMP4:%.*]] = load i16, i16* @usa, align 2
187// CHECK-NEXT: [[TMP5:%.*]] = sub i16 0, [[TMP4]]
188// CHECK-NEXT: store i16 [[TMP5]], i16* @usa, align 2
189 usa = -usa;
190
191// CHECK: [[TMP6:%.*]] = load i16, i16* @uf, align 2
192// CHECK-NEXT: [[TMP7:%.*]] = sub i16 0, [[TMP6]]
193// CHECK-NEXT: store i16 [[TMP7]], i16* @uf, align 2
194 uf = -uf;
195
196// CHECK: [[TMP8:%.*]] = load i32, i32* @sa, align 4
197// CHECK-NEXT: [[TMP9:%.*]] = call i32 @llvm.ssub.sat.i32(i32 0, i32 [[TMP8]])
198// CHECK-NEXT: store i32 [[TMP9]], i32* @sa, align 4
199 sa = -sa;
200
201// CHECK: [[TMP10:%.*]] = load i16, i16* @sf, align 2
202// CHECK-NEXT: [[TMP11:%.*]] = call i16 @llvm.ssub.sat.i16(i16 0, i16 [[TMP10]])
203// CHECK-NEXT: store i16 [[TMP11]], i16* @sf, align 2
204 sf = -sf;
205
206// CHECK: [[TMP12:%.*]] = load i16, i16* @susa, align 2
207// SIGNED-NEXT: [[TMP13:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP12]])
208// SIGNED-NEXT: store i16 [[TMP13]], i16* @susa, align 2
209// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP12]] to i15
210// UNSIGNED-NEXT: [[TMP13:%.*]] = call i15 @llvm.usub.sat.i15(i15 0, i15 [[RESIZE]])
211// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[TMP13]] to i16
212// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @susa, align 2
213 susa = -susa;
214
215// CHECK: [[TMP14:%.*]] = load i16, i16* @suf, align 2
216// SIGNED-NEXT: [[TMP15:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP14]])
217// SIGNED-NEXT: store i16 [[TMP15]], i16* @suf, align 2
218// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP14]] to i15
219// UNSIGNED-NEXT: [[TMP15:%.*]] = call i15 @llvm.usub.sat.i15(i15 0, i15 [[RESIZE2]])
220// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP15]] to i16
221// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @suf, align 2
222 suf = -suf;
223}
224
225// CHECK-LABEL: @Plus(
226void Plus() {
227// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
228// CHECK-NEXT: store i32 [[TMP0]], i32* @a, align 4
229 a = +a;
230
231// CHECK: [[TMP1:%.*]] = load i16, i16* @uf, align 2
232// CHECK-NEXT: store i16 [[TMP1]], i16* @uf, align 2
233 uf = +uf;
234
235// CHECK: [[TMP2:%.*]] = load i32, i32* @sa, align 4
236// CHECK-NEXT: store i32 [[TMP2]], i32* @sa, align 4
237 sa = +sa;
238}
239
240// CHECK-LABEL: @Not(
241void Not() {
242 int i;
243
244// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
245// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
246// CHECK-NEXT: [[LNOT:%.*]] = xor i1 [[TOBOOL]], true
247// CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[LNOT]] to i32
248// CHECK-NEXT: store i32 [[LNOT_EXT]], i32* %i, align 4
249 i = !a;
250
251// CHECK: [[TMP1:%.*]] = load i16, i16* @uf, align 2
252// CHECK-NEXT: [[TOBOOL1:%.*]] = icmp ne i16 [[TMP1]], 0
253// CHECK-NEXT: [[LNOT2:%.*]] = xor i1 [[TOBOOL1]], true
254// CHECK-NEXT: [[LNOT_EXT3:%.*]] = zext i1 [[LNOT2]] to i32
255// CHECK-NEXT: store i32 [[LNOT_EXT3]], i32* %i, align 4
256 i = !uf;
257
258// CHECK: [[TMP2:%.*]] = load i16, i16* @susa, align 2
259// CHECK-NEXT: [[TOBOOL4:%.*]] = icmp ne i16 [[TMP2]], 0
260// CHECK-NEXT: [[LNOT5:%.*]] = xor i1 [[TOBOOL4]], true
261// CHECK-NEXT: [[LNOT_EXT6:%.*]] = zext i1 [[LNOT5]] to i32
262// CHECK-NEXT: store i32 [[LNOT_EXT6]], i32* %i, align 4
263 i = !susa;
264}