summaryrefslogtreecommitdiff
path: root/test/Sema
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2017-09-23 05:02:02 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2017-09-23 05:02:02 +0000
commitd0d150d7131ee1804fff040bcf9794b4da08a856 (patch)
tree5dd1ee043f47b4c3b45a50f3b574d029c84849b8 /test/Sema
parent2e4086bb2d8b007a7232fae27e6068a83c2433fd (diff)
downloadclang-d0d150d7131ee1804fff040bcf9794b4da08a856.tar.gz
Promote storage-only __fp16 vector operands to float vectors.
This commit fixes a bug in the handling of storage-only __fp16 vectors where clang didn't promote __fp16 vector operands to float vectors. Conceptually, it performs the following transformation on the AST in CreateBuiltinBinOp and CreateBuiltinUnaryOp: (Before) typedef __fp16 half4 __attribute__ ((vector_size (8))); typedef float float4 __attribute__ ((vector_size (16))); half4 hv0, hv1, hv2, hv3; hv0 = hv1 + hv2 + hv3; (After) float4 t0 = (float4)hv1 + (float4)hv2; float4 t1 = t0 + (float4)hv3; hv0 = (half4)t1; Note that this commit fixes the bug for targets that set HalfArgsAndReturns to true (ARM and ARM64). Targets using intrinsics such as llvm.convert.to.fp16 to handle __fp16 are still broken. rdar://problem/20625184 Differential Revision: https://reviews.llvm.org/D32520 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314056 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Sema')
-rw-r--r--test/Sema/fp16vec-sema.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/test/Sema/fp16vec-sema.c b/test/Sema/fp16vec-sema.c
new file mode 100644
index 0000000000..aefb5f86a1
--- /dev/null
+++ b/test/Sema/fp16vec-sema.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __fp16 half4 __attribute__ ((vector_size (8)));
+typedef float float4 __attribute__ ((vector_size (16)));
+typedef short short4 __attribute__ ((vector_size (8)));
+typedef int int4 __attribute__ ((vector_size (16)));
+
+half4 hv0, hv1;
+float4 fv0, fv1;
+short4 sv0;
+int4 iv0;
+
+void testFP16Vec(int c) {
+ hv0 = hv0 + hv1;
+ hv0 = hv0 - hv1;
+ hv0 = hv0 * hv1;
+ hv0 = hv0 / hv1;
+ hv0 = c ? hv0 : hv1;
+ hv0 += hv1;
+ hv0 -= hv1;
+ hv0 *= hv1;
+ hv0 /= hv1;
+ sv0 = hv0 == hv1;
+ sv0 = hv0 != hv1;
+ sv0 = hv0 < hv1;
+ sv0 = hv0 > hv1;
+ sv0 = hv0 <= hv1;
+ sv0 = hv0 >= hv1;
+ sv0 = hv0 || hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+ sv0 = hv0 && hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+
+ // Implicit conversion between half vectors and float vectors are not allowed.
+ hv0 = fv0; // expected-error{{assigning to}}
+ fv0 = hv0; // expected-error{{assigning to}}
+ hv0 = (half4)fv0; // expected-error{{invalid conversion between}}
+ fv0 = (float4)hv0; // expected-error{{invalid conversion between}}
+ hv0 = fv0 + fv1; // expected-error{{assigning to}}
+ fv0 = hv0 + hv1; // expected-error{{assigning to}}
+ hv0 = hv0 + fv1; // expected-error{{cannot convert between vector}}
+ hv0 = c ? hv0 : fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 == fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 < fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} expected-error{{invalid operands to binary expression}}
+ iv0 = hv0 == hv1; // expected-error{{assigning to}}
+
+ // FIXME: clang currently disallows using these operators on vectors, which is
+ // allowed by gcc.
+ sv0 = !hv0; // expected-error{{invalid argument type}}
+ hv0++; // expected-error{{cannot increment value of type}}
+ ++hv0; // expected-error{{cannot increment value of type}}
+}