Skip to content

Commit

Permalink
[PowerPC] Implement Vector Insert Builtins in LLVM/Clang
Browse files Browse the repository at this point in the history
Implements vec_insertl() and vec_inserth().

Differential Revision: https://reviews.llvm.org/D82365
  • Loading branch information
biplmish authored and lei137 committed Jul 3, 2020
1 parent 551092b commit 0939e04
Show file tree
Hide file tree
Showing 6 changed files with 549 additions and 15 deletions.
16 changes: 16 additions & 0 deletions clang/include/clang/Basic/BuiltinsPPC.def
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,22 @@ BUILTIN(__builtin_altivec_vctzdm, "V2ULLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "")
BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "")

// P10 Vector Insert built-ins.
BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcULLiULLi", "")
BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcULLiULLi", "")
BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsULLiULLi", "")
BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsULLiULLi", "")
BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiULLiULLi", "")
BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcULLiV16Uc", "")
BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcULLiV16Uc", "")
BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsULLiV8Us", "")
BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsULLiV8Us", "")
BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiULLiV4Ui", "")
BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiULLiV4Ui", "")

// VSX built-ins.

BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
Expand Down
130 changes: 130 additions & 0 deletions clang/lib/Headers/altivec.h
Original file line number Diff line number Diff line change
Expand Up @@ -16889,6 +16889,136 @@ vec_cnttzm(vector unsigned long long __a, vector unsigned long long __b) {

#define vec_srdb(__a, __b, __c) __builtin_altivec_vsrdbi(__a, __b, (__c & 0x7))

/* vec_insertl */

static __inline__ vector unsigned char __ATTRS_o_ai
vec_insertl(unsigned char __a, vector unsigned char __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsbrx(__b, __c, __a);
#else
return __builtin_altivec_vinsblx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned short __ATTRS_o_ai
vec_insertl(unsigned short __a, vector unsigned short __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinshrx(__b, __c, __a);
#else
return __builtin_altivec_vinshlx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned int __ATTRS_o_ai
vec_insertl(unsigned int __a, vector unsigned int __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinswrx(__b, __c, __a);
#else
return __builtin_altivec_vinswlx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned long long __ATTRS_o_ai vec_insertl(
unsigned long long __a, vector unsigned long long __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsdrx(__b, __c, __a);
#else
return __builtin_altivec_vinsdlx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned char __ATTRS_o_ai vec_insertl(
vector unsigned char __a, vector unsigned char __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsbvrx(__b, __c, __a);
#else
return __builtin_altivec_vinsbvlx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned short __ATTRS_o_ai vec_insertl(
vector unsigned short __a, vector unsigned short __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinshvrx(__b, __c, __a);
#else
return __builtin_altivec_vinshvlx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned int __ATTRS_o_ai vec_insertl(
vector unsigned int __a, vector unsigned int __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinswvrx(__b, __c, __a);
#else
return __builtin_altivec_vinswvlx(__b, __c, __a);
#endif
}

/* vec_inserth */

static __inline__ vector unsigned char __ATTRS_o_ai
vec_inserth(unsigned char __a, vector unsigned char __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsblx(__b, __c, __a);
#else
return __builtin_altivec_vinsbrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned short __ATTRS_o_ai
vec_inserth(unsigned short __a, vector unsigned short __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinshlx(__b, __c, __a);
#else
return __builtin_altivec_vinshrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned int __ATTRS_o_ai
vec_inserth(unsigned int __a, vector unsigned int __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinswlx(__b, __c, __a);
#else
return __builtin_altivec_vinswrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned long long __ATTRS_o_ai vec_inserth(
unsigned long long __a, vector unsigned long long __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsdlx(__b, __c, __a);
#else
return __builtin_altivec_vinsdrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned char __ATTRS_o_ai vec_inserth(
vector unsigned char __a, vector unsigned char __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinsbvlx(__b, __c, __a);
#else
return __builtin_altivec_vinsbvrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned short __ATTRS_o_ai vec_inserth(
vector unsigned short __a, vector unsigned short __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinshvlx(__b, __c, __a);
#else
return __builtin_altivec_vinshvrx(__b, __c, __a);
#endif
}

static __inline__ vector unsigned int __ATTRS_o_ai vec_inserth(
vector unsigned int __a, vector unsigned int __b, unsigned int __c) {
#ifdef __LITTLE_ENDIAN__
return __builtin_altivec_vinswvlx(__b, __c, __a);
#else
return __builtin_altivec_vinswvrx(__b, __c, __a);
#endif
}

#ifdef __VSX__

/* vec_permx */
Expand Down
125 changes: 124 additions & 1 deletion clang/test/CodeGen/builtins-ppc-p10vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
// RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \
// RUN: -o - | FileCheck %s

// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \
// RUN: -target-cpu pwr10 -triple powerpc64-unknown-unknown -emit-llvm %s \
// RUN: -o - | FileCheck %s -check-prefix=CHECK-BE

// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \
// RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \
// RUN: -o - | FileCheck %s -check-prefix=CHECK-LE

#include <altivec.h>

vector signed char vsca, vscb;
Expand All @@ -16,7 +24,10 @@ vector unsigned long long vulla, vullb, vullc;
vector unsigned __int128 vui128a, vui128b, vui128c;
vector float vfa, vfb;
vector double vda, vdb;
unsigned int uia;
unsigned int uia, uib;
unsigned char uca;
unsigned short usa;
unsigned long long ulla;

vector unsigned long long test_vpdepd(void) {
// CHECK: @llvm.ppc.altivec.vpdepd(<2 x i64>
Expand Down Expand Up @@ -389,3 +400,115 @@ vector double test_vec_blend_d(void) {
// CHECK-NEXT: ret <2 x double>
return vec_blendv(vda, vdb, vullc);
}

vector unsigned char test_vec_insertl_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsblx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vinsbrx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <16 x i8>
return vec_insertl(uca, vuca, uia);
}

vector unsigned short test_vec_insertl_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vinshlx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vinshrx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <8 x i16>
return vec_insertl(usa, vusa, uia);
}

vector unsigned int test_vec_insertl_ui(void) {
// CHECK-BE: @llvm.ppc.altivec.vinswlx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK-LE: @llvm.ppc.altivec.vinswrx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <4 x i32>
return vec_insertl(uib, vuia, uia);
}

vector unsigned long long test_vec_insertl_ul(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsdlx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK-LE: @llvm.ppc.altivec.vinsdrx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <2 x i64>
return vec_insertl(ulla, vulla, uia);
}

vector unsigned char test_vec_insertl_ucv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsbvlx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vinsbvrx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8>
// CHECK-LE-NEXT: ret <16 x i8>
return vec_insertl(vuca, vucb, uia);
}

vector unsigned short test_vec_insertl_usv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinshvlx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vinshvrx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16>
// CHECK-LE-NEXT: ret <8 x i16>
return vec_insertl(vusa, vusb, uia);
}

vector unsigned int test_vec_insertl_uiv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinswvlx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK-LE: @llvm.ppc.altivec.vinswvrx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32>
// CHECK-LE-NEXT: ret <4 x i32>
return vec_insertl(vuia, vuib, uia);
}

vector unsigned char test_vec_inserth_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsbrx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vinsblx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <16 x i8>
return vec_inserth(uca, vuca, uia);
}

vector unsigned short test_vec_inserth_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vinshrx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vinshlx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <8 x i16>
return vec_inserth(usa, vusa, uia);
}

vector unsigned int test_vec_inserth_ui(void) {
// CHECK-BE: @llvm.ppc.altivec.vinswrx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK-LE: @llvm.ppc.altivec.vinswlx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <4 x i32>
return vec_inserth(uib, vuia, uia);
}

vector unsigned long long test_vec_inserth_ul(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsdrx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK-LE: @llvm.ppc.altivec.vinsdlx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64
// CHECK-LE-NEXT: ret <2 x i64>
return vec_inserth(ulla, vulla, uia);
}

vector unsigned char test_vec_inserth_ucv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinsbvrx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vinsbvlx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8>
// CHECK-LE-NEXT: ret <16 x i8>
return vec_inserth(vuca, vucb, uia);
}

vector unsigned short test_vec_inserth_usv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinshvrx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vinshvlx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16>
// CHECK-LE-NEXT: ret <8 x i16>
return vec_inserth(vusa, vusb, uia);
}

vector unsigned int test_vec_inserth_uiv(void) {
// CHECK-BE: @llvm.ppc.altivec.vinswvrx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK-LE: @llvm.ppc.altivec.vinswvlx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32>
// CHECK-LE-NEXT: ret <4 x i32>
return vec_inserth(vuia, vuib, uia);
}
58 changes: 58 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,64 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;

// P10 Vector Insert.
def int_ppc_altivec_vinsblx : GCCBuiltin<"__builtin_altivec_vinsblx">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsbrx : GCCBuiltin<"__builtin_altivec_vinsbrx">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshlx : GCCBuiltin<"__builtin_altivec_vinshlx">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshrx : GCCBuiltin<"__builtin_altivec_vinshrx">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswlx : GCCBuiltin<"__builtin_altivec_vinswlx">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswrx : GCCBuiltin<"__builtin_altivec_vinswrx">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsdlx : GCCBuiltin<"__builtin_altivec_vinsdlx">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsdrx : GCCBuiltin<"__builtin_altivec_vinsdrx">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsbvlx : GCCBuiltin<"__builtin_altivec_vinsbvlx">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i64_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsbvrx : GCCBuiltin<"__builtin_altivec_vinsbvrx">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i64_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshvlx : GCCBuiltin<"__builtin_altivec_vinshvlx">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_i64_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshvrx : GCCBuiltin<"__builtin_altivec_vinshvrx">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_i64_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswvlx : GCCBuiltin<"__builtin_altivec_vinswvlx">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_i64_ty, llvm_v4i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswvrx : GCCBuiltin<"__builtin_altivec_vinswvrx">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_i64_ty, llvm_v4i32_ty],
[IntrNoMem]>;
}

// Vector average.
Expand Down
Loading

0 comments on commit 0939e04

Please sign in to comment.