[clang] f9912fe - [PowerPC] Add range checks for P10 Vector Builtins
Quinn Pham via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 23 09:05:55 PDT 2021
Author: Quinn Pham
Date: 2021-09-23T11:05:49-05:00
New Revision: f9912fe4eac91f27965c22d015b3109c5158d050
URL: https://github.com/llvm/llvm-project/commit/f9912fe4eac91f27965c22d015b3109c5158d050
DIFF: https://github.com/llvm/llvm-project/commit/f9912fe4eac91f27965c22d015b3109c5158d050.diff
LOG: [PowerPC] Add range checks for P10 Vector Builtins
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`.
Reviewed By: lei, amyk
Differential Revision: https://reviews.llvm.org/D109710
Added:
clang/test/CodeGen/builtins-ppc-p10vector-error.c
Modified:
clang/lib/Headers/altivec.h
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/builtins-ppc-p10vector.c
Removed:
################################################################################
diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h
index 239c93d5b115c..6cfe9815228fa 100644
--- a/clang/lib/Headers/altivec.h
+++ b/clang/lib/Headers/altivec.h
@@ -18221,13 +18221,13 @@ vec_expandm(vector unsigned __int128 __a) {
#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 */
@@ -18756,36 +18756,39 @@ static __inline__ vector double __ATTRS_o_ai vec_splatid(const float __a) {
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;
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9862306325322..5cc968c133ce3 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3473,6 +3473,11 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
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);
diff --git a/clang/test/CodeGen/builtins-ppc-p10vector-error.c b/clang/test/CodeGen/builtins-ppc-p10vector-error.c
new file mode 100644
index 0000000000000..e509c5a82c5b0
--- /dev/null
+++ b/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]}}
+}
diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c
index 8816ae8028ebf..48a95bf4ab876 100644
--- a/clang/test/CodeGen/builtins-ppc-p10vector.c
+++ b/clang/test/CodeGen/builtins-ppc-p10vector.c
@@ -1371,10 +1371,12 @@ vector double test_vec_vec_splatid(void) {
}
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, %{{.+}}
@@ -1384,10 +1386,12 @@ vector signed int test_vec_vec_splati_ins_si(void) {
}
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, %{{.+}}
@@ -1397,10 +1401,12 @@ vector unsigned int test_vec_vec_splati_ins_ui(void) {
}
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, %{{.+}}
@@ -1409,6 +1415,24 @@ vector float test_vec_vec_splati_ins_f(void) {
return vec_splati_ins(vfa, 0, 1.0f);
}
+// In this test case, the second argument of vec_splati_ins is outside of the
+// expected range [0,1]. A mask of 0x01 is applied to obtain an in-range value
+// for the second argument.
+vector signed int test_vec_vec_splati_ins_range(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, %{{.+}}
+ // CHECK-LE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T2]]
+ // CHECK-LE: ret <4 x i32>
+ return vec_splati_ins(vsia, 2, -17);
+}
+
void test_vec_xst_trunc_sc(vector signed __int128 __a, signed long long __b,
signed char *__c) {
// CHECK: store i8 %{{.+}}, i8* %{{.+}}, align 1
More information about the cfe-commits
mailing list