LukeGeeson created this revision.
LukeGeeson added a reviewer: SjoerdMeijer.
Herald added a reviewer: javed.absar.
Herald added a subscriber: kristof.beyls.

This fixes the ranges for the vcvth family of FP16 intrinsics in the clang 
front end. Previously it was accepting incorrect ranges
-Changed builtin range checking in SemaChecking
-added tests SemaCheck changes - included in  their own file since no similar 
one exists
-modified existing tests to reflect new ranges


https://reviews.llvm.org/D47592

Files:
  lib/Sema/SemaChecking.cpp
  test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c
  test/Sema/aarch64-neon-fp16-ranges.c

Index: test/Sema/aarch64-neon-fp16-ranges.c
===================================================================
--- /dev/null
+++ test/Sema/aarch64-neon-fp16-ranges.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -fallow-half-arguments-and-returns -target-feature +fullfp16 -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fallow-half-arguments-and-returns -target-feature +fullfp16 -ffreestanding -fsyntax-only -verify %s
+
+#include <arm_neon.h>
+#include <arm_fp16.h>
+
+void test_vcvt_f16_16(int16_t a){
+  vcvth_n_f16_s16(a, 1);
+  vcvth_n_f16_s16(a, 16);
+  vcvth_n_f16_s16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_f16_s16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+  vcvth_n_f16_u16(a, 1);
+  vcvth_n_f16_u16(a, 16);
+  vcvth_n_f16_u16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_f16_u16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+}
+
+void test_vcvt_f16_32(int32_t a){
+  vcvth_n_f16_u32(a, 1);
+  vcvth_n_f16_u32(a, 16);
+  vcvth_n_f16_u32(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_f16_u32(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+  vcvth_n_f16_s32(a, 1);
+  vcvth_n_f16_s32(a, 16);
+  vcvth_n_f16_s32(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_f16_s32(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+}
+
+void test_vcvt_f16_64(int64_t a){
+  vcvth_n_f16_s64(a, 1);
+  vcvth_n_f16_s64(a, 16);
+  vcvth_n_f16_s64(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_f16_s64(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+}
+
+
+void test_vcvt_su_f(int64_t a){
+  vcvth_n_s16_f16(a, 1);
+  vcvth_n_s16_f16(a, 16);
+  vcvth_n_s16_f16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_s16_f16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+  vcvth_n_s32_f16(a, 1);
+  vcvth_n_s32_f16(a, 16);
+  vcvth_n_s32_f16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_s32_f16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+  vcvth_n_s64_f16(a, 1);
+  vcvth_n_s64_f16(a, 32);
+  vcvth_n_s64_f16(a, 0);  // expected-error {{argument should be a value from 1 to 32}}
+  vcvth_n_s64_f16(a, 33); // expected-error {{argument should be a value from 1 to 32}}
+
+  vcvth_n_u16_f16(a, 1);
+  vcvth_n_u16_f16(a, 16);
+  vcvth_n_u16_f16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_u16_f16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+  vcvth_n_u32_f16(a, 1);
+  vcvth_n_u32_f16(a, 16);
+  vcvth_n_u32_f16(a, 0);  // expected-error {{argument should be a value from 1 to 16}}
+  vcvth_n_u32_f16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+}
Index: test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c
===================================================================
--- test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c
+++ test/CodeGen/aarch64-v8.2a-fp16-intrinsics.c
@@ -486,90 +486,90 @@
 
 // CHECK-LABEL: test_vcvth_n_f16_s16
 // CHECK: [[SEXT:%.*]] = sext i16 %a to i32
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 [[SEXT]], i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 [[SEXT]], i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_s16(int16_t a) {
-  return vcvth_n_f16_s16(a, 0);
+  return vcvth_n_f16_s16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_f16_s32
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_s32(int32_t a) {
-  return vcvth_n_f16_s32(a, 0);
+  return vcvth_n_f16_s32(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_f16_s64
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_s64(int64_t a) {
-  return vcvth_n_f16_s64(a, 0);
+  return vcvth_n_f16_s64(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_s16_f16
-// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
 // CHECK: [[RET:%.*]] = trunc i32 [[CVT]] to i16
 // CHECK: ret i16 [[RET]]
 int16_t test_vcvth_n_s16_f16(float16_t a) {
-  return vcvth_n_s16_f16(a, 0);
+  return vcvth_n_s16_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_s32_f16
-// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
 // CHECK:  ret i32 [[CVT]]
 int32_t test_vcvth_n_s32_f16(float16_t a) {
-  return vcvth_n_s32_f16(a, 0);
+  return vcvth_n_s32_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_s64_f16
-// CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1)
 // CHECK:  ret i64 [[CVT]]
 int64_t test_vcvth_n_s64_f16(float16_t a) {
-  return vcvth_n_s64_f16(a, 0);
+  return vcvth_n_s64_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_f16_u16
 // CHECK: [[SEXT:%.*]] = zext i16 %a to i32
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 [[SEXT]], i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 [[SEXT]], i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_u16(int16_t a) {
-  return vcvth_n_f16_u16(a, 0);
+  return vcvth_n_f16_u16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_f16_u32
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_u32(int32_t a) {
-  return vcvth_n_f16_u32(a, 0);
+  return vcvth_n_f16_u32(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_f16_u64
-// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i64(i64 %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i64(i64 %a, i32 1)
 // CHECK:  ret half [[CVT]]
 float16_t test_vcvth_n_f16_u64(int64_t a) {
-  return vcvth_n_f16_u64(a, 0);
+  return vcvth_n_f16_u64(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_u16_f16
-// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
 // CHECK: [[RET:%.*]] = trunc i32 [[CVT]] to i16
 // CHECK: ret i16 [[RET]]
 int16_t test_vcvth_n_u16_f16(float16_t a) {
-  return vcvth_n_u16_f16(a, 0);
+  return vcvth_n_u16_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_u32_f16
-// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
 // CHECK:  ret i32 [[CVT]]
 int32_t test_vcvth_n_u32_f16(float16_t a) {
-  return vcvth_n_u32_f16(a, 0);
+  return vcvth_n_u32_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vcvth_n_u64_f16
-// CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxu.i64.f16(half %a, i32 0)
+// CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxu.i64.f16(half %a, i32 1)
 // CHECK:  ret i64 [[CVT]]
 int64_t test_vcvth_n_u64_f16(float16_t a) {
-  return vcvth_n_u64_f16(a, 0);
+  return vcvth_n_u64_f16(a, 1);
 }
 
 // CHECK-LABEL: test_vdivh_f16
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -1405,12 +1405,6 @@
   unsigned TV = 0;
   int PtrArgNum = -1;
   bool HasConstPtr = false;
-  switch (BuiltinID) {
-#define GET_NEON_OVERLOAD_CHECK
-#include "clang/Basic/arm_neon.inc"
-#include "clang/Basic/arm_fp16.inc"
-#undef GET_NEON_OVERLOAD_CHECK
-  }
 
   // For NEON intrinsics which are overloaded on vector element type, validate
   // the immediate which specifies which variant to emit.
@@ -1458,10 +1452,20 @@
   switch (BuiltinID) {
   default:
     return false;
-#define GET_NEON_IMMEDIATE_CHECK
-#include "clang/Basic/arm_neon.inc"
-#include "clang/Basic/arm_fp16.inc"
-#undef GET_NEON_IMMEDIATE_CHECK
+  case NEON::BI__builtin_neon_vcvth_n_f16_s16:
+  case NEON::BI__builtin_neon_vcvth_n_f16_s32:
+  case NEON::BI__builtin_neon_vcvth_n_f16_s64:
+  case NEON::BI__builtin_neon_vcvth_n_s16_f16:
+  case NEON::BI__builtin_neon_vcvth_n_s32_f16:
+  case NEON::BI__builtin_neon_vcvth_n_f16_u16:
+  case NEON::BI__builtin_neon_vcvth_n_f16_u32:
+  case NEON::BI__builtin_neon_vcvth_n_u16_f16:
+  case NEON::BI__builtin_neon_vcvth_n_u32_f16:
+  case NEON::BI__builtin_neon_vcvth_n_u64_f16:
+  case NEON::BI__builtin_neon_vcvth_n_f16_u64:
+    return SemaBuiltinConstantArgRange(TheCall, 1, 1, 16);
+  case NEON::BI__builtin_neon_vcvth_n_s64_f16:
+    return SemaBuiltinConstantArgRange(TheCall, 1, 1, 32);
   }
 
   return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to