quinnp created this revision.
Herald added subscribers: shchenz, kbarton, nemanjai.
quinnp requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds range checking for some Power10 altivec builtins and
changes the signature of a builtin to match documentation. For `vec_cntm`,
range checking is done via SemaChecking. For `vec_splati_ins`, the second
argument is masked to extract the 0th bit so that we always receive either a `0`
or a `1`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D109710

Files:
  clang/lib/Headers/altivec.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-ppc-p10vector-error.c
  clang/test/CodeGen/builtins-ppc-p10vector.c

Index: clang/test/CodeGen/builtins-ppc-p10vector.c
===================================================================
--- clang/test/CodeGen/builtins-ppc-p10vector.c
+++ clang/test/CodeGen/builtins-ppc-p10vector.c
@@ -1370,10 +1370,12 @@
 }
 
 vector signed int test_vec_vec_splati_ins_si(void) {
+  // CHECK-BE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 %{{.+}}
   // CHECK-BE:  [[T1:%.+]] = add i32 2, %{{.+}}
   // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
   // CHECK-BE: ret <4 x i32>
+  // CHECK-LE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-LE:  [[T1:%.+]] = sub i32 1, %{{.+}}
   // CHECK-LE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
   // CHECK-LE:  [[T2:%.+]] = sub i32 3, %{{.+}}
@@ -1383,10 +1385,12 @@
 }
 
 vector unsigned int test_vec_vec_splati_ins_ui(void) {
+  // CHECK-BE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 %{{.+}}
   // CHECK-BE:  [[T1:%.+]] = add i32 2, %{{.+}}
   // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
   // CHECK-BE: ret <4 x i32>
+  // CHECK-LE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-LE:  [[T1:%.+]] = sub i32 1, %{{.+}}
   // CHECK-LE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
   // CHECK-LE:  [[T2:%.+]] = sub i32 3, %{{.+}}
@@ -1396,10 +1400,12 @@
 }
 
 vector float test_vec_vec_splati_ins_f(void) {
+  // CHECK-BE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-BE: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 %{{.+}}
   // CHECK-BE:  [[T1:%.+]] = add i32 2, %{{.+}}
   // CHECK-BE: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T1]]
   // CHECK-BE: ret <4 x float>
+  // CHECK-LE: [[T0:%.+]]] = and %{{.+}}, i32 1
   // CHECK-LE:  [[T1:%.+]] = sub i32 1, %{{.+}}
   // CHECK-LE: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T1]]
   // CHECK-LE:  [[T2:%.+]] = sub i32 3, %{{.+}}
Index: clang/test/CodeGen/builtins-ppc-p10vector-error.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/builtins-ppc-p10vector-error.c
@@ -0,0 +1,32 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr10 \
+// RUN:   -fsyntax-only -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 \
+// RUN:   -fsyntax-only -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-cpu pwr10 \
+// RUN:   -fsyntax-only -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -target-cpu pwr10 \
+// RUN:   -fsyntax-only -Wall -Werror -verify %s
+
+#include <altivec.h>
+
+vector unsigned char vuca;
+vector unsigned short vusa;
+vector unsigned int vuia;
+vector unsigned long long vulla;
+
+unsigned long long test_vec_cntm_uc(void) {
+  return vec_cntm(vuca, -1); // expected-error 1+ {{argument value 255 is outside the valid range [0, 1]}}
+}
+
+unsigned long long test_vec_cntm_us(void) {
+  return vec_cntm(vusa, -1); // expected-error 1+ {{argument value 255 is outside the valid range [0, 1]}}
+}
+
+unsigned long long test_vec_cntm_ui(void) {
+  return vec_cntm(vuia, 2); // expected-error 1+ {{argument value 2 is outside the valid range [0, 1]}}
+}
+
+unsigned long long test_vec_cntm_ull(void) {
+  return vec_cntm(vulla, 2); // expected-error 1+  {{argument value 2 is outside the valid range [0, 1]}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -3473,6 +3473,11 @@
     return SemaFeatureCheck(*this, TheCall, "isa-v207-instructions",
                             diag::err_ppc_builtin_only_on_arch, "8") ||
            SemaBuiltinConstantArgRange(TheCall, 1, 1, 16);
+  case PPC::BI__builtin_altivec_vcntmbb:
+  case PPC::BI__builtin_altivec_vcntmbh:
+  case PPC::BI__builtin_altivec_vcntmbw:
+  case PPC::BI__builtin_altivec_vcntmbd:
+    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1);
 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
   case PPC::BI__builtin_##Name: \
     return SemaBuiltinPPCMMACall(TheCall, Types);
Index: clang/lib/Headers/altivec.h
===================================================================
--- clang/lib/Headers/altivec.h
+++ clang/lib/Headers/altivec.h
@@ -18191,13 +18191,13 @@
 
 #define vec_cntm(__a, __mp)                                                    \
   _Generic((__a), vector unsigned char                                         \
-           : __builtin_altivec_vcntmbb((__a), (unsigned int)(__mp)),           \
+           : __builtin_altivec_vcntmbb((__a), (unsigned char)(__mp)),          \
              vector unsigned short                                             \
-           : __builtin_altivec_vcntmbh((__a), (unsigned int)(__mp)),           \
+           : __builtin_altivec_vcntmbh((__a), (unsigned char)(__mp)),          \
              vector unsigned int                                               \
-           : __builtin_altivec_vcntmbw((__a), (unsigned int)(__mp)),           \
+           : __builtin_altivec_vcntmbw((__a), (unsigned char)(__mp)),          \
              vector unsigned long long                                         \
-           : __builtin_altivec_vcntmbd((__a), (unsigned int)(__mp)))
+           : __builtin_altivec_vcntmbd((__a), (unsigned char)(__mp)))
 
 /* vec_gen[b|h|w|d|q]m */
 
@@ -18726,36 +18726,39 @@
 
 static __inline__ vector signed int __ATTRS_o_ai vec_splati_ins(
     vector signed int __a, const unsigned int __b, const signed int __c) {
+  const unsigned int __d = __b & 0x01;
 #ifdef __LITTLE_ENDIAN__
-  __a[1 - __b] = __c;
-  __a[3 - __b] = __c;
+  __a[1 - __d] = __c;
+  __a[3 - __d] = __c;
 #else
-  __a[__b] = __c;
-  __a[2 + __b] = __c;
+  __a[__d] = __c;
+  __a[2 + __d] = __c;
 #endif
   return __a;
 }
 
 static __inline__ vector unsigned int __ATTRS_o_ai vec_splati_ins(
     vector unsigned int __a, const unsigned int __b, const unsigned int __c) {
+  const unsigned int __d = __b & 0x01;
 #ifdef __LITTLE_ENDIAN__
-  __a[1 - __b] = __c;
-  __a[3 - __b] = __c;
+  __a[1 - __d] = __c;
+  __a[3 - __d] = __c;
 #else
-  __a[__b] = __c;
-  __a[2 + __b] = __c;
+  __a[__d] = __c;
+  __a[2 + __d] = __c;
 #endif
   return __a;
 }
 
 static __inline__ vector float __ATTRS_o_ai
 vec_splati_ins(vector float __a, const unsigned int __b, const float __c) {
+  const unsigned int __d = __b & 0x01;
 #ifdef __LITTLE_ENDIAN__
-  __a[1 - __b] = __c;
-  __a[3 - __b] = __c;
+  __a[1 - __d] = __c;
+  __a[3 - __d] = __c;
 #else
-  __a[__b] = __c;
-  __a[2 + __b] = __c;
+  __a[__d] = __c;
+  __a[2 + __d] = __c;
 #endif
   return __a;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to