]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/spir-half-type.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / CodeGen / spir-half-type.cpp
1 // RUN: %clang_cc1 -O0 -triple spir -emit-llvm %s -o - | FileCheck %s
2 // RUN: %clang_cc1 -O0 -triple spir64 -emit-llvm %s -o - | FileCheck %s
3
4 // This file tests that using the _Float16 type with the spir target will not
5 // use the llvm intrinsics but instead will use the half arithmetic
6 // instructions directly.
7
8 // Previously attempting to use a constant _Float16 with a comparison
9 // instruction when the target is spir or spir64 lead to an assert being hit.
10 bool fcmp_const() {
11   _Float16 a = 0.0f16;
12   const _Float16 b = 1.0f16;
13
14   // CHECK-NOT: llvm.convert.to.fp16
15   // CHECK-NOT: llvm.convert.from.fp16
16
17   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
18   // CHECK-NEXT: fcmp olt half [[REG1]], 0xH3C00
19
20   // CHECK: [[REG2:%.*]] = load half, half* %a, align 2
21   // CHECK-NEXT: fcmp olt half [[REG2]], 0xH4000
22
23   // CHECK: [[REG3:%.*]] = load half, half* %a, align 2
24   // CHECK-NEXT: fcmp ogt half [[REG3]], 0xH3C00
25
26   // CHECK: [[REG4:%.*]] = load half, half* %a, align 2
27   // CHECK-NEXT: fcmp ogt half [[REG4]], 0xH4200
28
29   // CHECK: [[REG5:%.*]] = load half, half* %a, align 2
30   // CHECK-NEXT: fcmp oeq half [[REG5]], 0xH3C00
31
32   // CHECK: [[REG7:%.*]] = load half, half* %a, align 2
33   // CHECK-NEXT: fcmp oeq half [[REG7]], 0xH4400
34
35   // CHECK: [[REG8:%.*]] = load half, half* %a, align 2
36   // CHECK-NEXT: fcmp une half [[REG8]], 0xH3C00
37
38   // CHECK: [[REG9:%.*]] = load half, half* %a, align 2
39   // CHECK-NEXT: fcmp une half [[REG9]], 0xH4500
40
41   // CHECK: [[REG10:%.*]] = load half, half* %a, align 2
42   // CHECK-NEXT: fcmp ole half [[REG10]], 0xH3C00
43
44   // CHECK: [[REG11:%.*]] = load half, half* %a, align 2
45   // CHECK-NEXT: fcmp ole half [[REG11]], 0xH4600
46
47   // CHECK: [[REG12:%.*]] = load half, half* %a, align 2
48   // CHECK-NEXT: fcmp oge half [[REG12]], 0xH3C00
49
50   // CHECK: [[REG13:%.*]] = load half, half* %a, align 2
51   // CHECK-NEXT: fcmp oge half [[REG13]], 0xH4700
52   return a < b || a < 2.0f16 || a > b || a > 3.0f16 || a == b || a == 4.0f16 ||
53          a != b || a != 5.0f16 || a <= b || a <= 6.0f16 || a >= b ||
54          a >= 7.0f16;
55 }
56
57 bool fcmp() {
58   _Float16 a = 0.0f16;
59   _Float16 b = 1.0f16;
60
61   // CHECK-NOT: llvm.convert.to.fp16
62   // CHECK-NOT: llvm.convert.from.fp16
63   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
64   // CHECK-NEXT: [[REG2:%.*]] = load half, half* %b, align 2
65   // CHECK-NEXT: fcmp olt half [[REG1]], [[REG2]]
66
67   // CHECK: [[REG3:%.*]] = load half, half* %a, align 2
68   // CHECK-NEXT: [[REG4:%.*]] = load half, half* %b, align 2
69   // CHECK-NEXT: fcmp ogt half [[REG3]], [[REG4]]
70
71   // CHECK: [[REG5:%.*]] = load half, half* %a, align 2
72   // CHECK-NEXT: [[REG6:%.*]] = load half, half* %b, align 2
73   // CHECK-NEXT: fcmp oeq half [[REG5]], [[REG6]]
74
75   // CHECK: [[REG7:%.*]] = load half, half* %a, align 2
76   // CHECK-NEXT: [[REG8:%.*]] = load half, half* %b, align 2
77   // CHECK-NEXT: fcmp une half [[REG7]], [[REG8]]
78
79   // CHECK: [[REG7:%.*]] = load half, half* %a, align 2
80   // CHECK-NEXT: [[REG8:%.*]] = load half, half* %b, align 2
81   // CHECK-NEXT: fcmp ole half [[REG7]], [[REG8]]
82
83   // CHECK: [[REG7:%.*]] = load half, half* %a, align 2
84   // CHECK-NEXT: [[REG8:%.*]] = load half, half* %b, align 2
85   // CHECK-NEXT: fcmp oge half [[REG7]], [[REG8]]
86   return a < b || a > b || a == b || a != b || a <= b || a >= b;
87 }
88
89 _Float16 fadd() {
90   _Float16 a = 1.0f16;
91   const _Float16 b = 2.0f16;
92
93   // CHECK-NOT: llvm.convert.to.fp16
94   // CHECK-NOT: llvm.convert.from.fp16
95
96   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
97   // CHECK-NEXT: [[REG2:%.*]] = fadd half [[REG1]], 0xH4000
98   // CHECK-NEXT: [[REG3:%.*]] = fadd half [[REG2]], 0xH4200
99   // CHECK-NEXT: ret half [[REG3]]
100   return a + b + 3.0f16;
101 }
102
103 _Float16 fsub() {
104   _Float16 a = 1.0f16;
105   const _Float16 b = 2.0f16;
106
107   // CHECK-NOT: llvm.convert.to.fp16
108   // CHECK-NOT: llvm.convert.from.fp16
109
110   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
111   // CHECK-NEXT: [[REG2:%.*]] = fsub half [[REG1]], 0xH4000
112   // CHECK-NEXT: [[REG3:%.*]] = fsub half [[REG2]], 0xH4200
113   // CHECK-NEXT: ret half [[REG3]]
114   return a - b - 3.0f16;
115 }
116
117 // CHECK: define spir_func half @_Z4fmulDF16_(half %arg)
118 _Float16 fmul(_Float16 arg) {
119   _Float16 a = 1.0f16;
120   const _Float16 b = 2.0f16;
121
122   // CHECK-NOT: llvm.convert.to.fp16
123   // CHECK-NOT: llvm.convert.from.fp16
124
125   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
126   // CHECK-NEXT: [[REG2:%.*]] = load half, half* %arg.addr, align 2
127   // CHECK-NEXT: [[REG3:%.*]] = fmul half [[REG1]], [[REG2]]
128   // CHECK-NEXT: [[REG4:%.*]] = fmul half [[REG3]], 0xH4000
129   // CHECK-NEXT: [[REG5:%.*]] = fmul half [[REG4]], 0xH4200
130   // CHECK-NEXT: ret half [[REG5]]
131   return a * arg * b * 3.0f16;
132 }
133
134 _Float16 fdiv() {
135   _Float16 a = 1.0f16;
136   const _Float16 b = 2.0f16;
137
138   // CHECK-NOT: llvm.convert.to.fp16
139   // CHECK-NOT: llvm.convert.from.fp16
140
141   // CHECK: [[REG1:%.*]] = load half, half* %a, align 2
142   // CHECK-NEXT: [[REG2:%.*]] = fdiv half [[REG1]], 0xH4000
143   // CHECK-NEXT: [[REG3:%.*]] = fdiv half [[REG2]], 0xH4200
144   // CHECK-NEXT: ret half [[REG3]]
145   return a / b / 3.0f16;
146 }