sfertile updated this revision to Diff 79860.
sfertile marked an inline comment as done.
sfertile added a comment.
Changed all variable names to start with capitals, added description strings to
the assertions, changed uses of '12' to MaxIndex and initialized the arrays in
their definition.
Repository:
rL LLVM
https://reviews.llvm.org/D26546
Files:
include/clang/Basic/BuiltinsPPC.def
lib/CodeGen/CGBuiltin.cpp
lib/Headers/altivec.h
test/CodeGen/builtins-ppc-error.c
test/CodeGen/builtins-ppc-extractword-error.c
test/CodeGen/builtins-ppc-insertword-error.c
test/CodeGen/builtins-ppc-p9vector.c
Index: test/CodeGen/builtins-ppc-p9vector.c
===================================================================
--- test/CodeGen/builtins-ppc-p9vector.c
+++ test/CodeGen/builtins-ppc-p9vector.c
@@ -1166,17 +1166,41 @@
// CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3>
// CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
// CHECK-BE-NEXT: ret <4 x float>
-// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3, i32 undef>
-// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
-// CHECK-LE-NEXT: ret <4 x float>
+// CHECK: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3, i32 undef>
+// CHECK: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-NEXT: ret <4 x float>
return vec_extract_fp32_from_shorth(vusa);
}
vector float test115(void) {
// CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7>
// CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
// CHECK-BE-NEXT: ret <4 x float>
-// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7, i32 undef>
-// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
-// CHECK-LE-NEXT: ret <4 x float>
+// CHECK: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7, i32 undef>
+// CHECK: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-NEXT: ret <4 x float>
return vec_extract_fp32_from_shortl(vusa);
}
+vector unsigned char test116(void) {
+// CHECK-BE: [[T1:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> {{.+}}, i32 7)
+// CHECK-BE-NEXT: bitcast <4 x i32> [[T1]] to <16 x i8>
+// CHECK: [[T1:%.+]] = shufflevector <2 x i64> {{.+}}, <2 x i64> {{.+}}, <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: [[T2:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> [[T1]], i32 5)
+// CHECK-NEXT: bitcast <4 x i32> [[T2]] to <16 x i8>
+ return vec_insert4b(vuia, vuca, 7);
+}
+vector unsigned char test117(void) {
+// CHECK-BE: [[T1:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> {{.+}}, i32 5)
+// CHECK-BE-NEXT: bitcast <4 x i32> [[T1]] to <16 x i8>
+// CHECK: [[T1:%.+]] = shufflevector <2 x i64> {{.+}}, <2 x i64> {{.+}}, <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: [[T2:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> [[T1]], i32 7)
+// CHECK-NEXT: bitcast <4 x i32> [[T2]] to <16 x i8>
+ return vec_insert4b(vsia, vuca, 5);
+}
+vector unsigned long long test118(void) {
+// CHECK-BE: call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 11)
+// CHECK-BE-NEXT: ret <2 x i64>
+// CHECK: [[T1:%.+]] = call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 1)
+// CHECK-NEXT: shufflevector <2 x i64> [[T1]], <2 x i64> [[T1]], <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: ret <2 x i64>
+ return vec_extract4b(vuca, 11);
+}
Index: test/CodeGen/builtins-ppc-insertword-error.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-ppc-insertword-error.c
@@ -0,0 +1,16 @@
+// REQUIRES: powerpc-registered-target
+// XFAIL: powerpc
+
+// RUN: %clang -faltivec -target powerpc64le-unknown-unknown -mcpu=power8 \
+// RUN: -Wall -Werror -c %s
+
+// RUN: %clang -faltivec -target powerpc64-unknown-unknown -mcpu=power8 \
+// RUN: -Wall -Werror -c %s
+
+// expect to fail with diagnostic: "cannot compile this builtin function yet"
+extern vector signed int vsi;
+extern vector unsigned char vuc;
+
+vector unsigned char testInsertWord(void) {
+ return __builtin_vsx_insertword(vsi, vuc, 0);
+}
Index: test/CodeGen/builtins-ppc-extractword-error.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-ppc-extractword-error.c
@@ -0,0 +1,15 @@
+// REQUIRES: powerpc-registered-target
+// XFAIL: powerpc
+
+// RUN: %clang -faltivec -target powerpc64le-unknown-unknown -mcpu=power8 \
+// RUN: -Wall -Wextra -c %s
+// RUN: %clang -faltivec -target powerpc64-unknown-unknown -mcpu=power8 \
+// RUN: -Wall -Wextra -c %s
+
+// Expect the compile to fail ith "cannot compile this builtin function yet"
+extern vector signed int vsi;
+extern vector unsigned char vuc;
+
+vector unsigned long long testExtractWord(void) {
+ return __builtin_vsx_extractuword(vuc, 12);
+}
Index: test/CodeGen/builtins-ppc-error.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-ppc-error.c
@@ -0,0 +1,20 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang_cc1 -faltivec -target-feature +power9-vector \
+// RUN: -triple powerpc64-unknown-unknown -fsyntax-only \
+// RUN: -Wall -Werror -verify %s
+
+// RUN: %clang_cc1 -faltivec -target-feature +power9-vector \
+// RUN: -triple powerpc64le-unknown-unknown -fsyntax-only \
+// RUN: -Wall -Werror -verify %s
+
+#include <altivec.h>
+
+extern vector signed int vsi;
+extern vector unsigned char vuc;
+
+void testInsertWord1(void) {
+ int index = 5;
+ vector unsigned char v1 = vec_insert4b(vsi, vuc, index); // expected-error {{argument to '__builtin_vsx_insertword' must be a constant integer}}
+ vector unsigned long long v2 = vec_extract4b(vuc, index); // expected-error {{argument to '__builtin_vsx_extractuword' must be a constant integer}}
+}
Index: lib/Headers/altivec.h
===================================================================
--- lib/Headers/altivec.h
+++ lib/Headers/altivec.h
@@ -12456,6 +12456,9 @@
#ifdef __POWER9_VECTOR__
+#define vec_insert4b __builtin_vsx_insertword
+#define vec_extract4b __builtin_vsx_extractuword
+
/* vec_extract_exp */
static __inline__ vector unsigned int __ATTRS_o_ai
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -35,6 +35,11 @@
using namespace CodeGen;
using namespace llvm;
+static
+int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
+ return std::min(High, std::max(Low, Value));
+}
+
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
@@ -8168,6 +8173,73 @@
llvm_unreachable("Unknown FMA operation");
return nullptr; // Suppress no-return warning
}
+
+ case PPC::BI__builtin_vsx_insertword: {
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
+
+ // Third argument is a compile time constant int. It must be clamped to
+ // to the range [0, 12].
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+ assert(ArgCI &&
+ "Third arg to xxinsertw intrinsic must be constant integer");
+ const int64_t MaxIndex = 12;
+ int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
+
+ // Need to cast the second argument from a vector of char to a vector
+ // of long long.
+ Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
+
+ if (getTarget().isLittleEndian()) {
+ // Create a shuffle mask of (1, 0)
+ Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
+ ConstantInt::get(Int32Ty, 0)
+ };
+ Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
+ // Reverse the double words in the second argument.
+ Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], ShuffleMask);
+
+ // Reverse the index.
+ Index = MaxIndex - Index;
+ }
+
+ Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
+ return Builder.CreateCall(F, Ops);
+ }
+
+ case PPC::BI__builtin_vsx_extractuword: {
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
+
+ Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
+
+ // The second argument is a compile time constant int that needs to
+ // be clamped to the range [0, 12].
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
+ assert(ArgCI &&
+ "Second Arg to xxextractuw intrinsic must be a constant integer!");
+ const int64_t MaxIndex = 12;
+ int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
+
+ if (getTarget().isLittleEndian()) {
+ // Reverse the index.
+ Index = MaxIndex - Index;
+ Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
+
+ // Emit the call, then reverse the double words of the results vector.
+ Value *Call = Builder.CreateCall(F, Ops);
+
+ // Create a shuffle mask of (1, 0)
+ Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
+ ConstantInt::get(Int32Ty, 0)
+ };
+ Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
+
+ Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
+ return ShuffleCall;
+ } else {
+ Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
+ return Builder.CreateCall(F, Ops);
+ }
+ }
}
}
Index: include/clang/Basic/BuiltinsPPC.def
===================================================================
--- include/clang/Basic/BuiltinsPPC.def
+++ include/clang/Basic/BuiltinsPPC.def
@@ -417,6 +417,9 @@
BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
+BUILTIN(__builtin_vsx_insertword, "V16UcV4UiV16UcIi", "")
+BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "")
+
// HTM builtins
BUILTIN(__builtin_tbegin, "UiUIi", "")
BUILTIN(__builtin_tend, "UiUIi", "")
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits