xref: /llvm-project/llvm/unittests/ADT/APFixedPointTest.cpp (revision 255a99c29f9fa1a89b03a85a3a73d6f44d03c6c1)
1 //===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/APFixedPoint.h"
10 #include "llvm/ADT/APFloat.h"
11 #include "llvm/ADT/APSInt.h"
12 #include "gtest/gtest.h"
13 
14 using llvm::APFixedPoint;
15 using llvm::APFloat;
16 using llvm::APInt;
17 using llvm::APSInt;
18 using llvm::FixedPointSemantics;
19 
20 namespace {
21 
22 FixedPointSemantics Saturated(FixedPointSemantics Sema) {
23   Sema.setSaturated(true);
24   return Sema;
25 }
26 
27 FixedPointSemantics getSAccumSema() {
28   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/true,
29                              /*isSaturated=*/false,
30                              /*hasUnsignedPadding=*/false);
31 }
32 
33 FixedPointSemantics getAccumSema() {
34   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/true,
35                              /*isSaturated=*/false,
36                              /*hasUnsignedPadding=*/false);
37 }
38 
39 FixedPointSemantics getLAccumSema() {
40   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/true,
41                              /*isSaturated=*/false,
42                              /*hasUnsignedPadding=*/false);
43 }
44 
45 FixedPointSemantics getSFractSema() {
46   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/true,
47                              /*isSaturated=*/false,
48                              /*hasUnsignedPadding=*/false);
49 }
50 
51 FixedPointSemantics getFractSema() {
52   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/true,
53                              /*isSaturated=*/false,
54                              /*hasUnsignedPadding=*/false);
55 }
56 
57 FixedPointSemantics getLFractSema() {
58   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/true,
59                              /*isSaturated=*/false,
60                              /*hasUnsignedPadding=*/false);
61 }
62 
63 FixedPointSemantics getUSAccumSema() {
64   return FixedPointSemantics(/*width=*/16, /*scale=*/8, /*isSigned=*/false,
65                              /*isSaturated=*/false,
66                              /*hasUnsignedPadding=*/false);
67 }
68 
69 FixedPointSemantics getUAccumSema() {
70   return FixedPointSemantics(/*width=*/32, /*scale=*/16, /*isSigned=*/false,
71                              /*isSaturated=*/false,
72                              /*hasUnsignedPadding=*/false);
73 }
74 
75 FixedPointSemantics getULAccumSema() {
76   return FixedPointSemantics(/*width=*/64, /*scale=*/32, /*isSigned=*/false,
77                              /*isSaturated=*/false,
78                              /*hasUnsignedPadding=*/false);
79 }
80 
81 FixedPointSemantics getUSFractSema() {
82   return FixedPointSemantics(/*width=*/8, /*scale=*/8, /*isSigned=*/false,
83                              /*isSaturated=*/false,
84                              /*hasUnsignedPadding=*/false);
85 }
86 
87 FixedPointSemantics getUFractSema() {
88   return FixedPointSemantics(/*width=*/16, /*scale=*/16, /*isSigned=*/false,
89                              /*isSaturated=*/false,
90                              /*hasUnsignedPadding=*/false);
91 }
92 
93 FixedPointSemantics getULFractSema() {
94   return FixedPointSemantics(/*width=*/32, /*scale=*/32, /*isSigned=*/false,
95                              /*isSaturated=*/false,
96                              /*hasUnsignedPadding=*/false);
97 }
98 
99 FixedPointSemantics getPadUSAccumSema() {
100   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/false,
101                              /*isSaturated=*/false,
102                              /*hasUnsignedPadding=*/true);
103 }
104 
105 FixedPointSemantics getPadUAccumSema() {
106   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/false,
107                              /*isSaturated=*/false,
108                              /*hasUnsignedPadding=*/true);
109 }
110 
111 FixedPointSemantics getPadULAccumSema() {
112   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/false,
113                              /*isSaturated=*/false,
114                              /*hasUnsignedPadding=*/true);
115 }
116 
117 FixedPointSemantics getPadUSFractSema() {
118   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/false,
119                              /*isSaturated=*/false,
120                              /*hasUnsignedPadding=*/true);
121 }
122 
123 FixedPointSemantics getPadUFractSema() {
124   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/false,
125                              /*isSaturated=*/false,
126                              /*hasUnsignedPadding=*/true);
127 }
128 
129 FixedPointSemantics getPadULFractSema() {
130   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/false,
131                              /*isSaturated=*/false,
132                              /*hasUnsignedPadding=*/true);
133 }
134 
135 FixedPointSemantics getU8Neg10() {
136   return FixedPointSemantics(/*width=*/8, /*lsb=*/FixedPointSemantics::Lsb{-10},
137                              /*isSigned=*/false,
138                              /*isSaturated=*/false,
139                              /*hasUnsignedPadding=*/false);
140 }
141 
142 FixedPointSemantics getS16Neg18() {
143   return FixedPointSemantics(/*width=*/16,
144                              /*lsb=*/FixedPointSemantics::Lsb{-18},
145                              /*isSigned=*/true,
146                              /*isSaturated=*/false,
147                              /*hasUnsignedPadding=*/false);
148 }
149 
150 FixedPointSemantics getU8Pos4() {
151   return FixedPointSemantics(/*width=*/8, /*lsb=*/FixedPointSemantics::Lsb{4},
152                              /*isSigned=*/false,
153                              /*isSaturated=*/false,
154                              /*hasUnsignedPadding=*/false);
155 }
156 
157 FixedPointSemantics getS32Pos2() {
158   return FixedPointSemantics(/*width=*/32, /*lsb=*/FixedPointSemantics::Lsb{2},
159                              /*isSigned=*/true,
160                              /*isSaturated=*/false,
161                              /*hasUnsignedPadding=*/false);
162 }
163 
164 void CheckUnpaddedMax(const FixedPointSemantics &Sema) {
165   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
166             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()));
167 }
168 
169 void CheckPaddedMax(const FixedPointSemantics &Sema) {
170   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
171             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()) >> 1);
172 }
173 
174 void CheckMin(const FixedPointSemantics &Sema) {
175   ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(),
176             APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned()));
177 }
178 
179 TEST(FixedPointTest, getMax) {
180   CheckUnpaddedMax(getSAccumSema());
181   CheckUnpaddedMax(getAccumSema());
182   CheckUnpaddedMax(getLAccumSema());
183   CheckUnpaddedMax(getUSAccumSema());
184   CheckUnpaddedMax(getUAccumSema());
185   CheckUnpaddedMax(getULAccumSema());
186   CheckUnpaddedMax(getSFractSema());
187   CheckUnpaddedMax(getFractSema());
188   CheckUnpaddedMax(getLFractSema());
189   CheckUnpaddedMax(getUSFractSema());
190   CheckUnpaddedMax(getUFractSema());
191   CheckUnpaddedMax(getULFractSema());
192   CheckUnpaddedMax(getU8Neg10());
193   CheckUnpaddedMax(getS16Neg18());
194   CheckUnpaddedMax(getU8Pos4());
195   CheckUnpaddedMax(getS32Pos2());
196 
197   CheckPaddedMax(getPadUSAccumSema());
198   CheckPaddedMax(getPadUAccumSema());
199   CheckPaddedMax(getPadULAccumSema());
200   CheckPaddedMax(getPadUSFractSema());
201   CheckPaddedMax(getPadUFractSema());
202   CheckPaddedMax(getPadULFractSema());
203 }
204 
205 TEST(FixedPointTest, getMin) {
206   CheckMin(getSAccumSema());
207   CheckMin(getAccumSema());
208   CheckMin(getLAccumSema());
209   CheckMin(getUSAccumSema());
210   CheckMin(getUAccumSema());
211   CheckMin(getULAccumSema());
212   CheckMin(getSFractSema());
213   CheckMin(getFractSema());
214   CheckMin(getLFractSema());
215   CheckMin(getUSFractSema());
216   CheckMin(getUFractSema());
217   CheckMin(getULFractSema());
218   CheckMin(getU8Neg10());
219   CheckMin(getS16Neg18());
220   CheckMin(getU8Pos4());
221   CheckMin(getS32Pos2());
222 
223   CheckMin(getPadUSAccumSema());
224   CheckMin(getPadUAccumSema());
225   CheckMin(getPadULAccumSema());
226   CheckMin(getPadUSFractSema());
227   CheckMin(getPadUFractSema());
228   CheckMin(getPadULFractSema());
229 }
230 
231 int64_t relativeShr(int64_t Int, int64_t Shift) {
232   return (Shift > 0) ? Int >> Shift : Int << -Shift;
233 }
234 
235 void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
236   int64_t FullFactPart =
237       (Sema.getLsbWeight() > 0) ? 0 : (1ULL << (-Sema.getLsbWeight() - 1));
238 
239   // Value with a fraction
240   APFixedPoint ValWithFract(
241       APInt(Sema.getWidth(),
242             relativeShr(IntPart, Sema.getLsbWeight()) + FullFactPart,
243             Sema.isSigned(), /*implicitTrunc=*/true),
244       Sema);
245   ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
246 
247   // Just fraction
248   APFixedPoint JustFract(APInt(Sema.getWidth(), FullFactPart, Sema.isSigned(),
249                                /*implicitTrunc=*/true),
250                          Sema);
251   ASSERT_EQ(JustFract.getIntPart(), 0);
252 
253   // Whole number
254   APFixedPoint WholeNum(APInt(Sema.getWidth(),
255                               relativeShr(IntPart, Sema.getLsbWeight()),
256                               Sema.isSigned(), /*implicitTrunc=*/true),
257                         Sema);
258   ASSERT_EQ(WholeNum.getIntPart(), IntPart);
259 
260   // Negative
261   if (Sema.isSigned()) {
262     APFixedPoint Negative(APInt(Sema.getWidth(),
263                                 relativeShr(IntPart, Sema.getLsbWeight()),
264                                 Sema.isSigned(), /*implicitTrunc=*/true),
265                           Sema);
266     ASSERT_EQ(Negative.getIntPart(), IntPart);
267   }
268 }
269 
270 void CheckIntPartMin(const FixedPointSemantics &Sema, int64_t Expected) {
271   EXPECT_TRUE(APSInt::compareValues(APFixedPoint::getMin(Sema).getIntPart(),
272                                     APSInt::get(Expected)) == 0);
273 }
274 
275 void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) {
276   EXPECT_TRUE(APSInt::compareValues(APFixedPoint::getMax(Sema).getIntPart(),
277                                     APSInt::getUnsigned(Expected)) == 0);
278 }
279 
280 void CheckIntPartRes(const FixedPointSemantics &Sema, int64_t Representation,
281                      uint64_t Result) {
282   APFixedPoint Val(Representation, Sema);
283   ASSERT_EQ(Val.getIntPart().getZExtValue(), Result) ;
284 }
285 
286 TEST(FixedPoint, getIntPart) {
287   // Normal values
288   CheckIntPart(getSAccumSema(), 2);
289   CheckIntPart(getAccumSema(), 2);
290   CheckIntPart(getLAccumSema(), 2);
291   CheckIntPart(getUSAccumSema(), 2);
292   CheckIntPart(getUAccumSema(), 2);
293   CheckIntPart(getULAccumSema(), 2);
294   CheckIntPart(getU8Pos4(), 32);
295   CheckIntPart(getS32Pos2(), 32);
296 
297   // Zero
298   CheckIntPart(getSAccumSema(), 0);
299   CheckIntPart(getAccumSema(), 0);
300   CheckIntPart(getLAccumSema(), 0);
301   CheckIntPart(getUSAccumSema(), 0);
302   CheckIntPart(getUAccumSema(), 0);
303   CheckIntPart(getULAccumSema(), 0);
304 
305   CheckIntPart(getSFractSema(), 0);
306   CheckIntPart(getFractSema(), 0);
307   CheckIntPart(getLFractSema(), 0);
308   CheckIntPart(getUSFractSema(), 0);
309   CheckIntPart(getUFractSema(), 0);
310   CheckIntPart(getULFractSema(), 0);
311 
312   CheckIntPart(getS16Neg18(), 0);
313   CheckIntPart(getU8Neg10(), 0);
314   CheckIntPart(getU8Pos4(), 0);
315   CheckIntPart(getS32Pos2(), 0);
316 
317   // Min
318   CheckIntPartMin(getSAccumSema(), -256);
319   CheckIntPartMin(getAccumSema(), -65536);
320   CheckIntPartMin(getLAccumSema(), -4294967296);
321 
322   CheckIntPartMin(getSFractSema(), -1);
323   CheckIntPartMin(getFractSema(), -1);
324   CheckIntPartMin(getLFractSema(), -1);
325 
326   CheckIntPartMin(getS32Pos2(), -8589934592);
327 
328   // Max
329   CheckIntPartMax(getSAccumSema(), 255);
330   CheckIntPartMax(getAccumSema(), 65535);
331   CheckIntPartMax(getLAccumSema(), 4294967295);
332   CheckIntPartMax(getUSAccumSema(), 255);
333   CheckIntPartMax(getUAccumSema(), 65535);
334   CheckIntPartMax(getULAccumSema(), 4294967295);
335 
336   CheckIntPartMax(getU8Pos4(), 255 << 4);
337   CheckIntPartMax(getS32Pos2(), 2147483647ull << 2);
338 
339   CheckIntPartMax(getSFractSema(), 0);
340   CheckIntPartMax(getFractSema(), 0);
341   CheckIntPartMax(getLFractSema(), 0);
342   CheckIntPartMax(getUSFractSema(), 0);
343   CheckIntPartMax(getUFractSema(), 0);
344   CheckIntPartMax(getULFractSema(), 0);
345 
346   // Padded
347   // Normal Values
348   CheckIntPart(getPadUSAccumSema(), 2);
349   CheckIntPart(getPadUAccumSema(), 2);
350   CheckIntPart(getPadULAccumSema(), 2);
351 
352   // Zero
353   CheckIntPart(getPadUSAccumSema(), 0);
354   CheckIntPart(getPadUAccumSema(), 0);
355   CheckIntPart(getPadULAccumSema(), 0);
356 
357   CheckIntPart(getPadUSFractSema(), 0);
358   CheckIntPart(getPadUFractSema(), 0);
359   CheckIntPart(getPadULFractSema(), 0);
360 
361   // Max
362   CheckIntPartMax(getPadUSAccumSema(), 255);
363   CheckIntPartMax(getPadUAccumSema(), 65535);
364   CheckIntPartMax(getPadULAccumSema(), 4294967295);
365 
366   CheckIntPartMax(getPadUSFractSema(), 0);
367   CheckIntPartMax(getPadUFractSema(), 0);
368   CheckIntPartMax(getPadULFractSema(), 0);
369 
370   // Rounded Towards Zero
371   CheckIntPartRes(getSFractSema(), -127, 0);
372   CheckIntPartRes(getFractSema(), -32767, 0);
373   CheckIntPartRes(getLFractSema(), -2147483647, 0);
374   CheckIntPartRes(getS16Neg18(), -32768, 0);
375 }
376 
377 TEST(FixedPoint, compare) {
378   // Equality
379   // With fractional part (2.5)
380   // Across sizes
381   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
382             APFixedPoint(81920, getAccumSema()));
383   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
384             APFixedPoint(5368709120, getLAccumSema()));
385   ASSERT_EQ(APFixedPoint(0, getSAccumSema()), APFixedPoint(0, getLAccumSema()));
386 
387   ASSERT_EQ(APFixedPoint(0, getS16Neg18()), APFixedPoint(0, getU8Neg10()));
388   ASSERT_EQ(APFixedPoint(256, getS16Neg18()), APFixedPoint(1, getU8Neg10()));
389   ASSERT_EQ(APFixedPoint(32512, getS16Neg18()),
390             APFixedPoint(127, getU8Neg10()));
391   ASSERT_EQ(APFixedPoint(4, getS32Pos2()), APFixedPoint(1, getU8Pos4()));
392   ASSERT_EQ(APFixedPoint(1020, getS32Pos2()), APFixedPoint(255, getU8Pos4()));
393 
394   // Across types (0.5)
395   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
396             APFixedPoint(64, getSFractSema()));
397   ASSERT_EQ(APFixedPoint(16384, getAccumSema()),
398             APFixedPoint(16384, getFractSema()));
399   ASSERT_EQ(APFixedPoint(1073741824, getLAccumSema()),
400             APFixedPoint(1073741824, getLFractSema()));
401 
402   // Across widths and types (0.5)
403   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
404             APFixedPoint(16384, getFractSema()));
405   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
406             APFixedPoint(1073741824, getLFractSema()));
407 
408   // Across saturation
409   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
410             APFixedPoint(81920, Saturated(getAccumSema())));
411 
412   // Across signs
413   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
414             APFixedPoint(640, getUSAccumSema()));
415   ASSERT_EQ(APFixedPoint(-320, getSAccumSema()),
416             APFixedPoint(-81920, getAccumSema()));
417 
418   // Across padding
419   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
420             APFixedPoint(320, getPadUSAccumSema()));
421   ASSERT_EQ(APFixedPoint(640, getUSAccumSema()),
422             APFixedPoint(320, getPadUSAccumSema()));
423 
424   // Less than
425   ASSERT_LT(APFixedPoint(-1, getSAccumSema()), APFixedPoint(0, getAccumSema()));
426   ASSERT_LT(APFixedPoint(-1, getSAccumSema()),
427             APFixedPoint(0, getUAccumSema()));
428   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getAccumSema()));
429   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getUAccumSema()));
430   ASSERT_LT(APFixedPoint(0, getUSAccumSema()), APFixedPoint(1, getAccumSema()));
431   ASSERT_LT(APFixedPoint(0, getUSAccumSema()),
432             APFixedPoint(1, getUAccumSema()));
433   ASSERT_LT(APFixedPoint(65280, getS16Neg18()),
434             APFixedPoint(255, getU8Neg10()));
435 
436   // Greater than
437   ASSERT_GT(APFixedPoint(0, getAccumSema()), APFixedPoint(-1, getSAccumSema()));
438   ASSERT_GT(APFixedPoint(0, getUAccumSema()),
439             APFixedPoint(-1, getSAccumSema()));
440   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getSAccumSema()));
441   ASSERT_GT(APFixedPoint(1, getUAccumSema()), APFixedPoint(0, getSAccumSema()));
442   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getUSAccumSema()));
443   ASSERT_GT(APFixedPoint(1, getUAccumSema()),
444             APFixedPoint(0, getUSAccumSema()));
445 }
446 
447 // Check that a fixed point value in one sema is the same in another sema
448 void CheckUnsaturatedConversion(FixedPointSemantics Src,
449                                 FixedPointSemantics Dst, int64_t TestVal) {
450   int64_t ScaledVal = TestVal;
451   bool IsNegative = ScaledVal < 0;
452   if (IsNegative)
453     ScaledVal = -ScaledVal;
454 
455   if (Dst.getLsbWeight() < Src.getLsbWeight()) {
456     ScaledVal <<= (Src.getLsbWeight() - Dst.getLsbWeight());
457   } else {
458     ScaledVal >>= (Dst.getLsbWeight() - Src.getLsbWeight());
459   }
460 
461   if (IsNegative)
462     ScaledVal = -ScaledVal;
463 
464   APFixedPoint Fixed(TestVal, Src);
465   APFixedPoint Expected(ScaledVal, Dst);
466   ASSERT_EQ(Fixed.convert(Dst), Expected);
467 }
468 
469 // Check the value in a given fixed point sema overflows to the saturated min
470 // for another sema
471 void CheckSaturatedConversionMin(FixedPointSemantics Src,
472                                  FixedPointSemantics Dst, int64_t TestVal) {
473   APFixedPoint Fixed(TestVal, Src);
474   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMin(Dst));
475 }
476 
477 // Check the value in a given fixed point sema overflows to the saturated max
478 // for another sema
479 void CheckSaturatedConversionMax(FixedPointSemantics Src,
480                                  FixedPointSemantics Dst, int64_t TestVal) {
481   APFixedPoint Fixed(TestVal, Src);
482   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMax(Dst));
483 }
484 
485 // Check one signed _Accum sema converted to other sema for different values.
486 void CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
487                                               int64_t OneVal) {
488   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
489   int64_t HalfVal = (OneVal / 2);                  // 0.5
490 
491   // +Accums to Accums
492   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
493   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
494   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
495   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
496   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
497   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
498   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
499   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
500   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
501 
502   // -Accums to Accums
503   CheckUnsaturatedConversion(Src, getSAccumSema(), -NormalVal);
504   CheckUnsaturatedConversion(Src, getAccumSema(), -NormalVal);
505   CheckUnsaturatedConversion(Src, getLAccumSema(), -NormalVal);
506   CheckSaturatedConversionMin(Src, Saturated(getUSAccumSema()), -NormalVal);
507   CheckSaturatedConversionMin(Src, Saturated(getUAccumSema()), -NormalVal);
508   CheckSaturatedConversionMin(Src, Saturated(getULAccumSema()), -NormalVal);
509   CheckSaturatedConversionMin(Src, Saturated(getPadUSAccumSema()), -NormalVal);
510   CheckSaturatedConversionMin(Src, Saturated(getPadUAccumSema()), -NormalVal);
511   CheckSaturatedConversionMin(Src, Saturated(getPadULAccumSema()), -NormalVal);
512 
513   // +Accums to Fracts
514   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
515   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
516   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
517   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
518   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
519   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
520   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
521   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
522   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
523 
524   // -Accums to Fracts
525   CheckUnsaturatedConversion(Src, getSFractSema(), -HalfVal);
526   CheckUnsaturatedConversion(Src, getFractSema(), -HalfVal);
527   CheckUnsaturatedConversion(Src, getLFractSema(), -HalfVal);
528   CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), -HalfVal);
529   CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), -HalfVal);
530   CheckSaturatedConversionMin(Src, Saturated(getULFractSema()), -HalfVal);
531   CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), -HalfVal);
532   CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), -HalfVal);
533   CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), -HalfVal);
534 
535   // 0 to Accums
536   CheckUnsaturatedConversion(Src, getSAccumSema(), 0);
537   CheckUnsaturatedConversion(Src, getAccumSema(), 0);
538   CheckUnsaturatedConversion(Src, getLAccumSema(), 0);
539   CheckUnsaturatedConversion(Src, getUSAccumSema(), 0);
540   CheckUnsaturatedConversion(Src, getUAccumSema(), 0);
541   CheckUnsaturatedConversion(Src, getULAccumSema(), 0);
542   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), 0);
543   CheckUnsaturatedConversion(Src, getPadUAccumSema(), 0);
544   CheckUnsaturatedConversion(Src, getPadULAccumSema(), 0);
545 
546   // 0 to Fracts
547   CheckUnsaturatedConversion(Src, getSFractSema(), 0);
548   CheckUnsaturatedConversion(Src, getFractSema(), 0);
549   CheckUnsaturatedConversion(Src, getLFractSema(), 0);
550   CheckUnsaturatedConversion(Src, getUSFractSema(), 0);
551   CheckUnsaturatedConversion(Src, getUFractSema(), 0);
552   CheckUnsaturatedConversion(Src, getULFractSema(), 0);
553   CheckUnsaturatedConversion(Src, getPadUSFractSema(), 0);
554   CheckUnsaturatedConversion(Src, getPadUFractSema(), 0);
555   CheckUnsaturatedConversion(Src, getPadULFractSema(), 0);
556 }
557 
558 // Check one unsigned _Accum sema converted to other sema for different
559 // values.
560 void CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
561                                                 int64_t OneVal) {
562   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
563   int64_t HalfVal = (OneVal / 2);                  // 0.5
564 
565   // +UAccums to Accums
566   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
567   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
568   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
569   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
570   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
571   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
572   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
573   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
574   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
575 
576   // +UAccums to Fracts
577   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
578   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
579   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
580   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
581   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
582   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
583   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
584   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
585   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
586 }
587 
588 TEST(FixedPoint, AccumConversions) {
589   // Normal conversions
590   CheckSignedAccumConversionsAgainstOthers(getSAccumSema(), 128);
591   CheckUnsignedAccumConversionsAgainstOthers(getUSAccumSema(), 256);
592   CheckSignedAccumConversionsAgainstOthers(getAccumSema(), 32768);
593   CheckUnsignedAccumConversionsAgainstOthers(getUAccumSema(), 65536);
594   CheckSignedAccumConversionsAgainstOthers(getLAccumSema(), 2147483648);
595   CheckUnsignedAccumConversionsAgainstOthers(getULAccumSema(), 4294967296);
596 
597   CheckUnsignedAccumConversionsAgainstOthers(getPadUSAccumSema(), 128);
598   CheckUnsignedAccumConversionsAgainstOthers(getPadUAccumSema(), 32768);
599   CheckUnsignedAccumConversionsAgainstOthers(getPadULAccumSema(), 2147483648);
600 }
601 
602 TEST(FixedPoint, AccumConversionOverflow) {
603   // To SAccum max limit (65536)
604   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getAccumSema()),
605                               140737488355328);
606   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUAccumSema()),
607                               140737488355328);
608   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUAccumSema()),
609                               140737488355328);
610   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getAccumSema()),
611                               281474976710656);
612   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUAccumSema()),
613                               281474976710656);
614   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUAccumSema()),
615                               281474976710656);
616 
617   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getAccumSema()),
618                               140737488355328);
619   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUAccumSema()),
620                               140737488355328);
621   CheckSaturatedConversionMax(getPadULAccumSema(),
622                               Saturated(getPadUAccumSema()), 140737488355328);
623 
624   // To SAccum min limit (-65536)
625   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getAccumSema()),
626                               -140737488355328);
627   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUAccumSema()),
628                               -140737488355328);
629   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUAccumSema()),
630                               -140737488355328);
631 }
632 
633 TEST(FixedPoint, SAccumConversionOverflow) {
634   // To SAccum max limit (256)
635   CheckSaturatedConversionMax(getAccumSema(), Saturated(getSAccumSema()),
636                               8388608);
637   CheckSaturatedConversionMax(getAccumSema(), Saturated(getUSAccumSema()),
638                               8388608);
639   CheckSaturatedConversionMax(getAccumSema(), Saturated(getPadUSAccumSema()),
640                               8388608);
641   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getSAccumSema()),
642                               16777216);
643   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getUSAccumSema()),
644                               16777216);
645   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getPadUSAccumSema()),
646                               16777216);
647   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getSAccumSema()),
648                               549755813888);
649   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUSAccumSema()),
650                               549755813888);
651   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUSAccumSema()),
652                               549755813888);
653   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getSAccumSema()),
654                               1099511627776);
655   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUSAccumSema()),
656                               1099511627776);
657   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUSAccumSema()),
658                               1099511627776);
659 
660   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getSAccumSema()),
661                               8388608);
662   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getUSAccumSema()),
663                               8388608);
664   CheckSaturatedConversionMax(getPadUAccumSema(),
665                               Saturated(getPadUSAccumSema()), 8388608);
666   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getSAccumSema()),
667                               549755813888);
668   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUSAccumSema()),
669                               549755813888);
670   CheckSaturatedConversionMax(getPadULAccumSema(),
671                               Saturated(getPadUSAccumSema()), 549755813888);
672 
673   // To SAccum min limit (-256)
674   CheckSaturatedConversionMin(getAccumSema(), Saturated(getSAccumSema()),
675                               -8388608);
676   CheckSaturatedConversionMin(getAccumSema(), Saturated(getUSAccumSema()),
677                               -8388608);
678   CheckSaturatedConversionMin(getAccumSema(), Saturated(getPadUSAccumSema()),
679                               -8388608);
680   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getSAccumSema()),
681                               -549755813888);
682   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUSAccumSema()),
683                               -549755813888);
684   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUSAccumSema()),
685                               -549755813888);
686 }
687 
688 TEST(FixedPoint, GetValueSignAfterConversion) {
689   APFixedPoint Fixed(255 << 7, getSAccumSema());
690   ASSERT_TRUE(Fixed.getValue().isSigned());
691   APFixedPoint UFixed = Fixed.convert(getUSAccumSema());
692   ASSERT_TRUE(UFixed.getValue().isUnsigned());
693   ASSERT_EQ(UFixed.getValue(), APSInt::getUnsigned(255 << 8).extOrTrunc(16));
694 }
695 
696 TEST(FixedPoint, ModularWrapAround) {
697   // Positive to negative
698   APFixedPoint Val = APFixedPoint(1ULL << 7, getSAccumSema());
699   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), -(1ULL << 31));
700 
701   Val = APFixedPoint(1ULL << 23, getAccumSema());
702   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), -(1ULL << 15));
703 
704   Val = APFixedPoint(1ULL << 47, getLAccumSema());
705   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), -(1ULL << 31));
706 
707   // Negative to positive
708   Val = APFixedPoint(/*-1.5*/ -192, getSAccumSema());
709   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), 1ULL << 30);
710 
711   Val = APFixedPoint(-(257 << 15), getAccumSema());
712   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), 255 << 7);
713 
714   Val = APFixedPoint(-(65537ULL << 31), getLAccumSema());
715   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), 65535 << 15);
716 
717   // Signed to unsigned
718   Val = APFixedPoint(-(1 << 7), getSAccumSema());
719   ASSERT_EQ(Val.convert(getUSAccumSema()).getValue(), 255 << 8);
720 
721   Val = APFixedPoint(-(1 << 15), getAccumSema());
722   ASSERT_EQ(Val.convert(getUAccumSema()).getValue(), 65535ULL << 16);
723 
724   Val = APFixedPoint(-(1ULL << 31), getLAccumSema());
725   ASSERT_EQ(Val.convert(getULAccumSema()).getValue().getZExtValue(),
726             4294967295ULL << 32);
727 }
728 
729 enum OvfKind { MinSat, MaxSat };
730 
731 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema,
732                                  int64_t ExpectedNonSat) {
733   bool Ovf;
734   ASSERT_EQ(APFixedPoint::getFromFloatValue(Val, Sema, &Ovf).getValue(),
735             ExpectedNonSat);
736   ASSERT_EQ(Ovf, false);
737   ASSERT_EQ(
738       APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(),
739       ExpectedNonSat);
740   ASSERT_EQ(Ovf, false);
741 }
742 
743 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema,
744                                  OvfKind ExpectedOvf) {
745   bool Ovf;
746   (void)APFixedPoint::getFromFloatValue(Val, Sema, &Ovf);
747   ASSERT_EQ(Ovf, true);
748   ASSERT_EQ(
749       APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(),
750       (ExpectedOvf == MinSat ? APFixedPoint::getMin(Sema)
751                              : APFixedPoint::getMax(Sema))
752           .getValue());
753   ASSERT_EQ(Ovf, false);
754 }
755 
756 TEST(FixedPoint, toString) {
757   ASSERT_EQ(APFixedPoint::getMax(getS16Neg18()).toString(),
758             "0.124996185302734375");
759   ASSERT_EQ(APFixedPoint::getMin(getS16Neg18())
760                 .add(APFixedPoint(1, getS16Neg18()))
761                 .toString(),
762             "-0.124996185302734375");
763   ASSERT_EQ(APFixedPoint::getMin(getS16Neg18()).toString(), "-0.125");
764   ASSERT_EQ(APFixedPoint::getMax(getU8Neg10()).toString(), "0.2490234375");
765   ASSERT_EQ(APFixedPoint::getMin(getU8Neg10()).toString(), "0.0");
766   ASSERT_EQ(APFixedPoint::getMax(getS32Pos2()).toString(), "8589934588.0");
767   ASSERT_EQ(APFixedPoint::getMin(getS32Pos2())
768                 .add(APFixedPoint(1, getS32Pos2()))
769                 .toString(),
770             "-8589934588.0");
771   ASSERT_EQ(APFixedPoint::getMin(getS32Pos2()).toString(), "-8589934592.0");
772   ASSERT_EQ(APFixedPoint::getMax(getU8Pos4()).toString(), "4080.0");
773   ASSERT_EQ(APFixedPoint::getMin(getU8Pos4()).toString(), "0.0");
774 }
775 
776 TEST(FixedPoint, FloatToFixed) {
777   APFloat Val(0.0f);
778 
779   // Simple exact fraction
780   Val = APFloat(0.75f);
781   CheckFloatToFixedConversion(Val, getSAccumSema(), 3ULL << 5);
782   CheckFloatToFixedConversion(Val, getAccumSema(),  3ULL << 13);
783   CheckFloatToFixedConversion(Val, getLAccumSema(), 3ULL << 29);
784 
785   CheckFloatToFixedConversion(Val, getUSAccumSema(), 3ULL << 6);
786   CheckFloatToFixedConversion(Val, getUAccumSema(),  3ULL << 14);
787   CheckFloatToFixedConversion(Val, getULAccumSema(), 3ULL << 30);
788 
789   CheckFloatToFixedConversion(Val, getSFractSema(), 3ULL << 5);
790   CheckFloatToFixedConversion(Val, getFractSema(),  3ULL << 13);
791   CheckFloatToFixedConversion(Val, getLFractSema(), 3ULL << 29);
792 
793   CheckFloatToFixedConversion(Val, getUSFractSema(), 3ULL << 6);
794   CheckFloatToFixedConversion(Val, getUFractSema(),  3ULL << 14);
795   CheckFloatToFixedConversion(Val, getULFractSema(), 3ULL << 30);
796 
797   CheckFloatToFixedConversion(Val, getU8Neg10(), MaxSat);
798   CheckFloatToFixedConversion(Val, getU8Pos4(),  0);
799   CheckFloatToFixedConversion(Val, getS16Neg18(), MaxSat);
800   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
801 
802   // Simple negative exact fraction
803   Val = APFloat(-0.75f);
804   CheckFloatToFixedConversion(Val, getSAccumSema(), -3ULL << 5);
805   CheckFloatToFixedConversion(Val, getAccumSema(),  -3ULL << 13);
806   CheckFloatToFixedConversion(Val, getLAccumSema(), -3ULL << 29);
807 
808   CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat);
809   CheckFloatToFixedConversion(Val, getUAccumSema(),  MinSat);
810   CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat);
811 
812   CheckFloatToFixedConversion(Val, getSFractSema(), -3ULL << 5);
813   CheckFloatToFixedConversion(Val, getFractSema(),  -3ULL << 13);
814   CheckFloatToFixedConversion(Val, getLFractSema(), -3ULL << 29);
815 
816   CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat);
817   CheckFloatToFixedConversion(Val, getUFractSema(),  MinSat);
818   CheckFloatToFixedConversion(Val, getULFractSema(), MinSat);
819 
820   CheckFloatToFixedConversion(Val, getU8Neg10(), MinSat);
821   CheckFloatToFixedConversion(Val, getU8Pos4(),  0);
822   CheckFloatToFixedConversion(Val, getS16Neg18(), MinSat);
823   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
824 
825   // Highly precise fraction
826   Val = APFloat(0.999999940395355224609375f);
827   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL);
828   CheckFloatToFixedConversion(Val, getAccumSema(),  0x7FFFULL);
829   CheckFloatToFixedConversion(Val, getLAccumSema(), 0xFFFFFFULL << 7);
830 
831   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL);
832   CheckFloatToFixedConversion(Val, getUAccumSema(),  0xFFFFULL);
833   CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFFFFFULL << 8);
834 
835   CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL);
836   CheckFloatToFixedConversion(Val, getFractSema(),  0x7FFFULL);
837   CheckFloatToFixedConversion(Val, getLFractSema(), 0xFFFFFFULL << 7);
838 
839   CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL);
840   CheckFloatToFixedConversion(Val, getUFractSema(),  0xFFFFULL);
841   CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFFFFFULL << 8);
842 
843   CheckFloatToFixedConversion(Val, getU8Neg10(), MaxSat);
844   CheckFloatToFixedConversion(Val, getU8Pos4(), 0);
845   CheckFloatToFixedConversion(Val, getS16Neg18(), MaxSat);
846   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
847 
848   // Integral and fraction
849   Val = APFloat(17.99609375f);
850   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x11FFULL >> 1);
851   CheckFloatToFixedConversion(Val, getAccumSema(),  0x11FFULL << 7);
852   CheckFloatToFixedConversion(Val, getLAccumSema(), 0x11FFULL << 23);
853 
854   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0x11FFULL);
855   CheckFloatToFixedConversion(Val, getUAccumSema(),  0x11FFULL << 8);
856   CheckFloatToFixedConversion(Val, getULAccumSema(), 0x11FFULL << 24);
857 
858   CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat);
859   CheckFloatToFixedConversion(Val, getFractSema(),  MaxSat);
860   CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat);
861 
862   CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat);
863   CheckFloatToFixedConversion(Val, getUFractSema(),  MaxSat);
864   CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat);
865 
866   CheckFloatToFixedConversion(Val, getU8Neg10(), MaxSat);
867   CheckFloatToFixedConversion(Val, getU8Pos4(), 1);
868   CheckFloatToFixedConversion(Val, getS16Neg18(), MaxSat);
869   CheckFloatToFixedConversion(Val, getS32Pos2(), 1 << 2);
870 
871   // Negative integral and fraction
872   Val = APFloat(-17.99609375f);
873   CheckFloatToFixedConversion(Val, getSAccumSema(), -0x11FELL >> 1);
874   CheckFloatToFixedConversion(Val, getAccumSema(),  -0x11FFULL << 7);
875   CheckFloatToFixedConversion(Val, getLAccumSema(), -0x11FFULL << 23);
876 
877   CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat);
878   CheckFloatToFixedConversion(Val, getUAccumSema(),  MinSat);
879   CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat);
880 
881   CheckFloatToFixedConversion(Val, getSFractSema(), MinSat);
882   CheckFloatToFixedConversion(Val, getFractSema(),  MinSat);
883   CheckFloatToFixedConversion(Val, getLFractSema(), MinSat);
884 
885   CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat);
886   CheckFloatToFixedConversion(Val, getUFractSema(),  MinSat);
887   CheckFloatToFixedConversion(Val, getULFractSema(), MinSat);
888 
889   CheckFloatToFixedConversion(Val, getU8Neg10(), MinSat);
890   CheckFloatToFixedConversion(Val, getU8Pos4(), MinSat);
891   CheckFloatToFixedConversion(Val, getS16Neg18(), MinSat);
892   CheckFloatToFixedConversion(Val, getS32Pos2(), -4);
893 
894   // Very large value
895   Val = APFloat(1.0e38f);
896   CheckFloatToFixedConversion(Val, getSAccumSema(), MaxSat);
897   CheckFloatToFixedConversion(Val, getAccumSema(),  MaxSat);
898   CheckFloatToFixedConversion(Val, getLAccumSema(), MaxSat);
899 
900   CheckFloatToFixedConversion(Val, getUSAccumSema(), MaxSat);
901   CheckFloatToFixedConversion(Val, getUAccumSema(),  MaxSat);
902   CheckFloatToFixedConversion(Val, getULAccumSema(), MaxSat);
903 
904   CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat);
905   CheckFloatToFixedConversion(Val, getFractSema(),  MaxSat);
906   CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat);
907 
908   CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat);
909   CheckFloatToFixedConversion(Val, getUFractSema(),  MaxSat);
910   CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat);
911 
912   CheckFloatToFixedConversion(Val, getU8Neg10(), MaxSat);
913   CheckFloatToFixedConversion(Val, getU8Pos4(), MaxSat);
914   CheckFloatToFixedConversion(Val, getS16Neg18(), MaxSat);
915   CheckFloatToFixedConversion(Val, getS32Pos2(), MaxSat);
916 
917   // Very small value
918   Val = APFloat(1.0e-38f);
919   CheckFloatToFixedConversion(Val, getSAccumSema(), 0);
920   CheckFloatToFixedConversion(Val, getAccumSema(),  0);
921   CheckFloatToFixedConversion(Val, getLAccumSema(), 0);
922 
923   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0);
924   CheckFloatToFixedConversion(Val, getUAccumSema(),  0);
925   CheckFloatToFixedConversion(Val, getULAccumSema(), 0);
926 
927   CheckFloatToFixedConversion(Val, getSFractSema(), 0);
928   CheckFloatToFixedConversion(Val, getFractSema(),  0);
929   CheckFloatToFixedConversion(Val, getLFractSema(), 0);
930 
931   CheckFloatToFixedConversion(Val, getUSFractSema(), 0);
932   CheckFloatToFixedConversion(Val, getUFractSema(),  0);
933   CheckFloatToFixedConversion(Val, getULFractSema(), 0);
934 
935   CheckFloatToFixedConversion(Val, getU8Neg10(), 0);
936   CheckFloatToFixedConversion(Val, getU8Pos4(), 0);
937   CheckFloatToFixedConversion(Val, getS16Neg18(), 0);
938   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
939 
940   // Half conversion
941   Val = APFloat(0.99951171875f);
942   bool Ignored;
943   Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
944 
945   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL);
946   CheckFloatToFixedConversion(Val, getAccumSema(),  0x7FFULL << 4);
947   CheckFloatToFixedConversion(Val, getLAccumSema(), 0x7FFULL << 20);
948 
949   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL);
950   CheckFloatToFixedConversion(Val, getUAccumSema(),  0xFFEULL << 4);
951   CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFEULL << 20);
952 
953   CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL);
954   CheckFloatToFixedConversion(Val, getFractSema(),  0x7FFULL << 4);
955   CheckFloatToFixedConversion(Val, getLFractSema(), 0x7FFULL << 20);
956 
957   CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL);
958   CheckFloatToFixedConversion(Val, getUFractSema(),  0xFFEULL << 4);
959   CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFEULL << 20);
960 
961   CheckFloatToFixedConversion(Val, getU8Neg10(), MaxSat);
962   CheckFloatToFixedConversion(Val, getU8Pos4(), 0);
963   CheckFloatToFixedConversion(Val, getS16Neg18(), MaxSat);
964   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
965 
966   Val = APFloat(0.124996185302734375);
967   CheckFloatToFixedConversion(Val, getU8Neg10(), 0x7f);
968   CheckFloatToFixedConversion(Val, getU8Pos4(), 0);
969   CheckFloatToFixedConversion(Val, getS16Neg18(), 0x7fff);
970   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
971 
972   Val = APFloat(-0.124996185302734375);
973   CheckFloatToFixedConversion(Val, getU8Neg10(), MinSat);
974   CheckFloatToFixedConversion(Val, getU8Pos4(), 0);
975   CheckFloatToFixedConversion(Val, getS16Neg18(), -0x7fff);
976   CheckFloatToFixedConversion(Val, getS32Pos2(), 0);
977 }
978 
979 void CheckFixedToFloatConversion(int64_t Val, const FixedPointSemantics &Sema,
980                                  float Result) {
981   APFixedPoint FXVal(Val, Sema);
982   APFloat APRes(Result);
983   ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEsingle()), APRes);
984 }
985 
986 void CheckFixedToHalfConversion(int64_t Val, const FixedPointSemantics &Sema,
987                                 float Result) {
988   APFixedPoint FXVal(Val, Sema);
989   APFloat APRes(Result);
990   bool Ignored;
991   APRes.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
992   ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEhalf()), APRes);
993 }
994 
995 TEST(FixedPoint, FixedToFloat) {
996   int64_t Val = 0x1ULL;
997   CheckFixedToFloatConversion(Val, getSAccumSema(), 0.0078125f);
998   CheckFixedToFloatConversion(Val, getFractSema(),  0.000030517578125f);
999   CheckFixedToFloatConversion(Val, getAccumSema(),  0.000030517578125f);
1000   CheckFixedToFloatConversion(Val, getLFractSema(),
1001                               0.0000000004656612873077392578125f);
1002 
1003   CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.00390625f);
1004   CheckFixedToFloatConversion(Val, getUFractSema(),  0.0000152587890625f);
1005   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.0000152587890625f);
1006   CheckFixedToFloatConversion(Val, getULFractSema(),
1007                               0.00000000023283064365386962890625f);
1008 
1009   CheckFixedToFloatConversion(Val, getU8Neg10(), 0.0009765625f);
1010   CheckFixedToFloatConversion(Val, getU8Pos4(), 16.0f);
1011   CheckFixedToFloatConversion(Val, getS16Neg18(), 0.000003814697265625f);
1012   CheckFixedToFloatConversion(Val, getS32Pos2(), 4.0f);
1013 
1014   Val = 0x7FULL;
1015   CheckFixedToFloatConversion(Val, getSAccumSema(), 0.9921875f);
1016   CheckFixedToFloatConversion(Val, getFractSema(),  0.003875732421875f);
1017   CheckFixedToFloatConversion(Val, getAccumSema(),  0.003875732421875f);
1018   CheckFixedToFloatConversion(Val, getLFractSema(),
1019                               0.0000000591389834880828857421875f);
1020 
1021   CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.49609375f);
1022   CheckFixedToFloatConversion(Val, getUFractSema(),  0.0019378662109375f);
1023   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.0019378662109375f);
1024   CheckFixedToFloatConversion(Val, getULFractSema(),
1025                               0.00000002956949174404144287109375f);
1026 
1027   CheckFixedToFloatConversion(Val, getU8Neg10(), 0.1240234375f);
1028   CheckFixedToFloatConversion(Val, getU8Pos4(), 2032.0f);
1029   CheckFixedToFloatConversion(Val, getS16Neg18(), 0.000484466552734375f);
1030   CheckFixedToFloatConversion(Val, getS32Pos2(), 508.0f);
1031 
1032   Val = -0x1ULL;
1033   CheckFixedToFloatConversion(Val, getSAccumSema(), -0.0078125f);
1034   CheckFixedToFloatConversion(Val, getFractSema(),  -0.000030517578125f);
1035   CheckFixedToFloatConversion(Val, getAccumSema(),  -0.000030517578125f);
1036   CheckFixedToFloatConversion(Val, getLFractSema(),
1037                               -0.0000000004656612873077392578125f);
1038 
1039   CheckFixedToFloatConversion(Val, getU8Neg10(), 0.249023437f);
1040   CheckFixedToFloatConversion(Val, getU8Pos4(), 4080.0f);
1041   CheckFixedToFloatConversion(Val, getS16Neg18(), -0.000003814697265625f);
1042   CheckFixedToFloatConversion(Val, getS32Pos2(), -4.0f);
1043 
1044   CheckFixedToFloatConversion(-0x80ULL,       getSAccumSema(), -1.0f);
1045   CheckFixedToFloatConversion(-0x8000ULL,     getFractSema(),  -1.0f);
1046   CheckFixedToFloatConversion(-0x8000ULL,     getAccumSema(),  -1.0f);
1047   CheckFixedToFloatConversion(-0x80000000ULL, getLFractSema(), -1.0f);
1048 
1049   Val = 0xAFAULL;
1050   CheckFixedToFloatConversion(Val, getSAccumSema(), 21.953125f);
1051   CheckFixedToFloatConversion(Val, getFractSema(),  0.08575439453125f);
1052   CheckFixedToFloatConversion(Val, getAccumSema(),  0.08575439453125f);
1053   CheckFixedToFloatConversion(Val, getLFractSema(),
1054                               0.000001308508217334747314453125f);
1055 
1056   CheckFixedToFloatConversion(Val, getUSAccumSema(), 10.9765625f);
1057   CheckFixedToFloatConversion(Val, getUFractSema(),  0.042877197265625f);
1058   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.042877197265625f);
1059   CheckFixedToFloatConversion(Val, getULFractSema(),
1060                               0.0000006542541086673736572265625f);
1061 
1062   CheckFixedToFloatConversion(Val, getS16Neg18(), 0.01071929931640625f);
1063   CheckFixedToFloatConversion(Val, getS32Pos2(), 11240.0f);
1064 
1065   Val = -0xAFAULL;
1066   CheckFixedToFloatConversion(Val, getSAccumSema(), -21.953125f);
1067   CheckFixedToFloatConversion(Val, getFractSema(),  -0.08575439453125f);
1068   CheckFixedToFloatConversion(Val, getAccumSema(),  -0.08575439453125f);
1069   CheckFixedToFloatConversion(Val, getLFractSema(),
1070                               -0.000001308508217334747314453125f);
1071 
1072   CheckFixedToFloatConversion(Val, getS16Neg18(), -0.01071929931640625f);
1073   CheckFixedToFloatConversion(Val, getS32Pos2(), -11240.0f);
1074 
1075   Val = 0x40000080ULL;
1076   CheckFixedToFloatConversion(Val, getAccumSema(),  32768.00390625f);
1077   CheckFixedToFloatConversion(Val, getLFractSema(),
1078                               0.500000059604644775390625f);
1079 
1080   CheckFixedToFloatConversion(Val, getUAccumSema(),  16384.001953125f);
1081   CheckFixedToFloatConversion(Val, getULFractSema(),
1082                               0.2500000298023223876953125f);
1083 
1084   CheckFixedToFloatConversion(Val, getS32Pos2(), 4294967808.0f);
1085 
1086   Val = 0x40000040ULL;
1087   CheckFixedToFloatConversion(Val, getAccumSema(),  32768.0f);
1088   CheckFixedToFloatConversion(Val, getLFractSema(), 0.5f);
1089 
1090   CheckFixedToFloatConversion(Val, getUAccumSema(),  16384.0f);
1091   CheckFixedToFloatConversion(Val, getULFractSema(), 0.25f);
1092 
1093   CheckFixedToFloatConversion(Val, getS32Pos2(), 4294967552.0f);
1094 
1095   Val = 0x7FF0ULL;
1096   CheckFixedToHalfConversion(Val, getAccumSema(), 0.99951171875f);
1097   CheckFixedToHalfConversion(Val, getLFractSema(), 0.000015251338481903076171875f);
1098 
1099   CheckFixedToHalfConversion(Val, getUAccumSema(), 0.499755859375f);
1100   CheckFixedToHalfConversion(Val, getULFractSema(), 0.0000076256692409515380859375f);
1101 
1102   CheckFixedToFloatConversion(Val, getS32Pos2(), 131008.0f);
1103 }
1104 
1105 void CheckAdd(const APFixedPoint &Lhs, const APFixedPoint &Rhs,
1106               const APFixedPoint &Res) {
1107   bool Overflow = false;
1108   APFixedPoint Result = Lhs.add(Rhs, &Overflow);
1109   ASSERT_FALSE(Overflow);
1110   ASSERT_EQ(Result.getSemantics(), Res.getSemantics());
1111   ASSERT_EQ(Result, Res);
1112 }
1113 
1114 void CheckAddOverflow(const APFixedPoint &Lhs, const APFixedPoint &Rhs) {
1115   bool Overflow = false;
1116   APFixedPoint Result = Lhs.add(Rhs, &Overflow);
1117   ASSERT_TRUE(Overflow);
1118 }
1119 
1120 TEST(FixedPoint, add) {
1121   CheckAdd(APFixedPoint(1, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1122            APFixedPoint(2, getS32Pos2()));
1123   CheckAdd(APFixedPoint(1, getS16Neg18()), APFixedPoint(1, getS16Neg18()),
1124            APFixedPoint(2, getS16Neg18()));
1125   CheckAdd(APFixedPoint(1, getU8Neg10()), APFixedPoint(1, getU8Neg10()),
1126            APFixedPoint(2, getU8Neg10()));
1127   CheckAdd(APFixedPoint(1, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1128            APFixedPoint(2, getU8Pos4()));
1129 
1130   CheckAdd(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1131            APFixedPoint(12, getS32Pos2()));
1132   CheckAdd(APFixedPoint(11, getS16Neg18()), APFixedPoint(1, getS16Neg18()),
1133            APFixedPoint(12, getS16Neg18()));
1134   CheckAdd(APFixedPoint(11, getU8Neg10()), APFixedPoint(1, getU8Neg10()),
1135            APFixedPoint(12, getU8Neg10()));
1136   CheckAdd(APFixedPoint(11, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1137            APFixedPoint(12, getU8Pos4()));
1138 
1139   CheckAdd(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS16Neg18()),
1140            APFixedPoint(11534337,
1141                         FixedPointSemantics(52, FixedPointSemantics::Lsb{-18},
1142                                             true, false, false)));
1143   CheckAdd(
1144       APFixedPoint(11, getU8Neg10()), APFixedPoint(-9472, getS16Neg18()),
1145       APFixedPoint(-6656, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1146                                               true, false, false)));
1147   CheckAddOverflow(
1148       APFixedPoint::getMax(getU8Neg10()), APFixedPoint::getMax(getS16Neg18()));
1149   CheckAdd(APFixedPoint::getMin(getU8Neg10()),
1150            APFixedPoint::getMin(getS16Neg18()),
1151            APFixedPoint::getMin(getS16Neg18())
1152                .convert(FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1153                                             true, false, false)));
1154   CheckAddOverflow(APFixedPoint::getMin(getS32Pos2()),
1155                    APFixedPoint::getMin(getS16Neg18()));
1156 }
1157 
1158 void CheckMul(const APFixedPoint &Lhs, const APFixedPoint &Rhs,
1159               const APFixedPoint &Res) {
1160   bool Overflow = false;
1161   APFixedPoint Result = Lhs.mul(Rhs, &Overflow);
1162   ASSERT_FALSE(Overflow);
1163   ASSERT_EQ(Result.getSemantics(), Res.getSemantics());
1164   ASSERT_EQ(Result, Res);
1165 }
1166 
1167 void CheckMulOverflow(const APFixedPoint &Lhs, const APFixedPoint &Rhs) {
1168   bool Overflow = false;
1169   APFixedPoint Result = Lhs.mul(Rhs, &Overflow);
1170   ASSERT_TRUE(Overflow);
1171 }
1172 
1173 TEST(FixedPoint, mul) {
1174   CheckMul(APFixedPoint(1, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1175            APFixedPoint(4, getS32Pos2()));
1176   CheckMul(APFixedPoint(1, getS16Neg18()), APFixedPoint(1, getS16Neg18()),
1177            APFixedPoint(0, getS16Neg18()));
1178   CheckMul(APFixedPoint(1, getU8Neg10()), APFixedPoint(1, getU8Neg10()),
1179            APFixedPoint(0, getU8Neg10()));
1180   CheckMul(APFixedPoint(1, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1181            APFixedPoint(16, getU8Pos4()));
1182 
1183   CheckMul(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1184            APFixedPoint(44, getS32Pos2()));
1185   CheckMul(APFixedPoint(11, getS16Neg18()), APFixedPoint(1, getS16Neg18()),
1186            APFixedPoint(0, getS16Neg18()));
1187   CheckMul(APFixedPoint(11, getU8Neg10()), APFixedPoint(1, getU8Neg10()),
1188            APFixedPoint(0, getU8Neg10()));
1189   CheckMul(APFixedPoint(11, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1190            APFixedPoint(176, getU8Pos4()));
1191 
1192   CheckMul(APFixedPoint(512, getS16Neg18()), APFixedPoint(512, getS16Neg18()),
1193            APFixedPoint(1, getS16Neg18()));
1194   CheckMul(APFixedPoint(32, getU8Neg10()), APFixedPoint(32, getU8Neg10()),
1195            APFixedPoint(1, getU8Neg10()));
1196 
1197   CheckMul(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS16Neg18()),
1198            APFixedPoint(44,
1199                         FixedPointSemantics(52, FixedPointSemantics::Lsb{-18},
1200                                             true, false, false)));
1201   CheckMul(
1202       APFixedPoint(11, getU8Neg10()), APFixedPoint(-9472, getS16Neg18()),
1203       APFixedPoint(-102, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1204                                              true, false, false)));
1205   CheckMul(
1206       APFixedPoint::getMax(getU8Neg10()), APFixedPoint::getMax(getS16Neg18()),
1207       APFixedPoint(8159, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1208                                              true, false, false)));
1209   CheckMul(
1210       APFixedPoint::getMin(getU8Neg10()), APFixedPoint::getMin(getS16Neg18()),
1211       APFixedPoint(0, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1212                                           true, false, false)));
1213   CheckMul(APFixedPoint::getMin(getS32Pos2()),
1214            APFixedPoint::getMin(getS16Neg18()),
1215            APFixedPoint(281474976710656,
1216                         FixedPointSemantics(52, FixedPointSemantics::Lsb{-18},
1217                                             true, false, false)));
1218   CheckMulOverflow(APFixedPoint::getMax(getS32Pos2()), APFixedPoint::getMax(getU8Pos4()));
1219   CheckMulOverflow(APFixedPoint::getMin(getS32Pos2()), APFixedPoint::getMax(getU8Pos4()));
1220 }
1221 
1222 void CheckDiv(const APFixedPoint &Lhs, const APFixedPoint &Rhs,
1223               const APFixedPoint &Expected) {
1224   bool Overflow = false;
1225   APFixedPoint Result = Lhs.div(Rhs, &Overflow);
1226   ASSERT_FALSE(Overflow);
1227   ASSERT_EQ(Result.getSemantics(), Expected.getSemantics());
1228   ASSERT_EQ(Result, Expected);
1229 }
1230 
1231 void CheckDivOverflow(const APFixedPoint &Lhs, const APFixedPoint &Rhs) {
1232   bool Overflow = false;
1233   APFixedPoint Result = Lhs.div(Rhs, &Overflow);
1234   ASSERT_TRUE(Overflow);
1235 }
1236 
1237 TEST(FixedPoint, div) {
1238   CheckDiv(APFixedPoint(1, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1239            APFixedPoint(0, getS32Pos2()));
1240   CheckDivOverflow(APFixedPoint(1, getS16Neg18()), APFixedPoint(1, getS16Neg18()));
1241   CheckDivOverflow(APFixedPoint(1, getU8Neg10()), APFixedPoint(1, getU8Neg10()));
1242   CheckDiv(APFixedPoint(1, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1243            APFixedPoint(0, getU8Pos4()));
1244 
1245   CheckDiv(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS32Pos2()),
1246            APFixedPoint(2, getS32Pos2()));
1247   CheckDiv(APFixedPoint(11, getU8Pos4()), APFixedPoint(1, getU8Pos4()),
1248            APFixedPoint(0, getU8Pos4()));
1249 
1250   CheckDiv(APFixedPoint(11, getS32Pos2()), APFixedPoint(1, getS16Neg18()),
1251            APFixedPoint(3023656976384,
1252                         FixedPointSemantics(52, FixedPointSemantics::Lsb{-18},
1253                                             true, false, false)));
1254   CheckDiv(APFixedPoint(11, getU8Neg10()), APFixedPoint(-11264, getS16Neg18()),
1255            APFixedPoint::getMin(FixedPointSemantics(
1256                17, FixedPointSemantics::Lsb{-18}, true, false, false)));
1257   CheckDiv(APFixedPoint(11, getU8Neg10()), APFixedPoint(11265, getS16Neg18()),
1258            APFixedPoint(0xfffa,
1259                         FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1260                                             true, false, false)));
1261   CheckDivOverflow(APFixedPoint(11, getU8Neg10()),
1262                    APFixedPoint(11264, getS16Neg18()));
1263 
1264   CheckDivOverflow(APFixedPoint(11, getU8Neg10()),
1265                    APFixedPoint(-9472, getS16Neg18()));
1266   CheckDivOverflow(APFixedPoint::getMax(getU8Neg10()),
1267                    APFixedPoint::getMax(getS16Neg18()));
1268   CheckDiv(
1269       APFixedPoint::getMin(getU8Neg10()), APFixedPoint::getMin(getS16Neg18()),
1270       APFixedPoint(0, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1271                                           true, false, false)));
1272   CheckDiv(
1273       APFixedPoint(1, getU8Neg10()), APFixedPoint::getMin(getS16Neg18()),
1274       APFixedPoint(-2048, FixedPointSemantics(17, FixedPointSemantics::Lsb{-18},
1275                                               true, false, false)));
1276 }
1277 
1278 TEST(FixedPoint, semanticsSerialization) {
1279   auto roundTrip = [](FixedPointSemantics FPS) -> bool {
1280     uint32_t I = FPS.toOpaqueInt();
1281     FixedPointSemantics FPS2 = FixedPointSemantics::getFromOpaqueInt(I);
1282     return FPS == FPS2;
1283   };
1284 
1285   ASSERT_TRUE(roundTrip(getS32Pos2()));
1286   ASSERT_TRUE(roundTrip(getU8Pos4()));
1287   ASSERT_TRUE(roundTrip(getS16Neg18()));
1288   ASSERT_TRUE(roundTrip(getU8Neg10()));
1289   ASSERT_TRUE(roundTrip(getPadULFractSema()));
1290   ASSERT_TRUE(roundTrip(getPadUFractSema()));
1291   ASSERT_TRUE(roundTrip(getPadUSFractSema()));
1292   ASSERT_TRUE(roundTrip(getPadULAccumSema()));
1293   ASSERT_TRUE(roundTrip(getPadUAccumSema()));
1294   ASSERT_TRUE(roundTrip(getPadUSAccumSema()));
1295   ASSERT_TRUE(roundTrip(getULFractSema()));
1296   ASSERT_TRUE(roundTrip(getUFractSema()));
1297   ASSERT_TRUE(roundTrip(getUSFractSema()));
1298   ASSERT_TRUE(roundTrip(getULAccumSema()));
1299   ASSERT_TRUE(roundTrip(getUAccumSema()));
1300   ASSERT_TRUE(roundTrip(getUSAccumSema()));
1301   ASSERT_TRUE(roundTrip(getLFractSema()));
1302   ASSERT_TRUE(roundTrip(getFractSema()));
1303   ASSERT_TRUE(roundTrip(getSFractSema()));
1304   ASSERT_TRUE(roundTrip(getLAccumSema()));
1305   ASSERT_TRUE(roundTrip(getAccumSema()));
1306   ASSERT_TRUE(roundTrip(getSAccumSema()));
1307 }
1308 
1309 } // namespace
1310