1 // RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s  --check-prefix=CHECK --check-prefix=CHECK-AARCH64
2 // RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s  --check-prefix=CHECK --check-prefix=CHECK-X86
3 
4 /*  Various contexts where type _Float16 can appear. */
5 
6 
7 /*  Namespace */
8 
9 namespace {
10   _Float16 f1n;
11 // CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global half 0xH0000, align 2
12 
13   _Float16 f2n = 33.f16;
14 // CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global half 0xH5020, align 2
15 
16   _Float16 arr1n[10];
17 // CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
18 // CHECK-X86-DAG:     @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
19 
20   _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
21 // CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
22 
23   const volatile _Float16 func1n(const _Float16 &arg) {
24     return arg + f2n + arr1n[4] - arr2n[1];
25   }
26 }
27 
28 
29 /* File */
30 
31 _Float16 f1f;
32 // CHECK-AARCH64-DAG: @f1f = global half 0xH0000, align 2
33 // CHECK-X86-DAG: @f1f = global half 0xH0000, align 2
34 
35 _Float16 f2f = 32.4;
36 // CHECK-DAG: @f2f = global half 0xH500D, align 2
37 
38 _Float16 arr1f[10];
39 // CHECK-AARCH64-DAG: @arr1f = global [10 x half] zeroinitializer, align 2
40 // CHECK-X86-DAG: @arr1f = global [10 x half] zeroinitializer, align 16
41 
42 _Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
43 // CHECK-DAG: @arr2f = global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
44 
45 _Float16 func1f(_Float16 arg);
46 
47 
48 /* Class */
49 
50 class C1 {
51   _Float16 f1c;
52 
53   static const _Float16 f2c;
54 // CHECK-DAG: @_ZN2C13f2cE = external constant half, align 2
55 
56   volatile _Float16 f3c;
57 
58 public:
59   C1(_Float16 arg) : f1c(arg), f3c(arg) { }
60 // Check that we mangle _Float16 to DF16_
61 // CHECK-DAG: define linkonce_odr void @_ZN2C1C2EDF16_(%class.C1*{{.*}}, half{{.*}})
62 
63   _Float16 func1c(_Float16 arg ) {
64     return f1c + arg;
65   }
66 // CHECK-DAG: define linkonce_odr half @_ZN2C16func1cEDF16_(%class.C1*{{.*}}, half{{.*}})
67 
68   static _Float16 func2c(_Float16 arg) {
69     return arg * C1::f2c;
70   }
71 // CHECK-DAG: define linkonce_odr half @_ZN2C16func2cEDF16_(half{{.*}})
72 };
73 
74 /*  Template */
75 
76 template <class C> C func1t(C arg) {
77   return arg * 2.f16;
78 }
79 // CHECK-DAG: define linkonce_odr half @_Z6func1tIDF16_ET_S0_(half{{.*}})
80 
81 template <class C> struct S1 {
82   C mem1;
83 };
84 
85 template <> struct S1<_Float16> {
86   _Float16 mem2;
87 };
88 
89 
90 /* Local */
91 
92 extern int printf (const char *__restrict __format, ...);
93 
94 int main(void) {
95   _Float16 f1l = 1e3f16;
96 // CHECK-DAG: store half 0xH63D0, half* %{{.*}}, align 2
97 
98   _Float16 f2l = -0.f16;
99 // CHECK-DAG: store half 0xH8000, half* %{{.*}}, align 2
100 
101   _Float16 f3l = 1.000976562;
102 // CHECK-DAG: store half 0xH3C01, half* %{{.*}}, align 2
103 
104   C1 c1(f1l);
105 // CHECK-DAG:  [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
106 // CHECK-DAG:  call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
107 
108   S1<_Float16> s1 = { 132.f16 };
109 // CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
110 // CHECK-DAG:  [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
111 // CHECK-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 2 [[S1]], i8* align 2 bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i1 false)
112 
113   _Float16 f4l = func1n(f1l)  + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
114     func1t(f1l) + s1.mem2 - f1n + f2n;
115 
116   auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
117 // CHECK-DAG:  store half 0xHBC00, half* %{{.*}}, align 2
118 // CHECK-DAG:  store half* %{{.*}}, half** %{{.*}}, align 8
119 
120   _Float16 f8l = f4l++;
121 // CHECK-DAG:  %{{.*}} = load half, half* %{{.*}}, align 2
122 // CHECK-DAG:  [[INC:%[a-z0-9]+]] = fadd half {{.*}}, 0xH3C00
123 // CHECK-DAG:  store half [[INC]], half* %{{.*}}, align 2
124 
125   _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
126 // CHECK-DAG: @_ZZ4mainE5arr1l = private unnamed_addr constant [3 x half] [half 0xHBC00, half 0xH8000, half 0xHC980], align 2
127 
128   float cvtf = f2n;
129 //CHECK-DAG: [[H2F:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to float
130 //CHECK-DAG:  store float [[H2F]], float* %{{.*}}, align 4
131 
132   double cvtd = f2n;
133 //CHECK-DAG: [[H2D:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to double
134 //CHECK-DAG: store double [[H2D]], double* %{{.*}}, align 8
135 
136 
137   long double cvtld = f2n;
138 //CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
139 //CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
140 //CHECK-X86-DAG:     [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
141 //CHECK-X86-DAG:     store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
142 
143   _Float16 f2h = 42.0f;
144 //CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
145   _Float16 d2h = 42.0;
146 //CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
147   _Float16 ld2h = 42.0l;
148 //CHECK-DAG:store half 0xH5140, half* %{{.*}}, align 2
149 }
150