forked from OSchip/llvm-project
[PowerPC] Implement Vector Splat Immediate Builtins in Clang
Implements builtins for the following prototypes: vector signed int vec_splati (const signed int); vector float vec_splati (const float); vector double vec_splatid (const float); vector signed int vec_splati_ins (vector signed int, const unsigned int, const signed int); vector unsigned int vec_splati_ins (vector unsigned int, const unsigned int, const unsigned int); vector float vec_splati_ins (vector float, const unsigned int, const float); Differential Revision: https://reviews.llvm.org/D82520
This commit is contained in:
parent
c13e3e2c2e
commit
0c6b6e28e7
|
@ -17094,6 +17094,58 @@ vec_blendv(vector double __a, vector double __b,
|
|||
vector unsigned long long __c) {
|
||||
return __builtin_vsx_xxblendvd(__a, __b, __c);
|
||||
}
|
||||
|
||||
/* vec_splati */
|
||||
|
||||
#define vec_splati(__a) \
|
||||
_Generic((__a), signed int \
|
||||
: ((vector signed int)__a), unsigned int \
|
||||
: ((vector unsigned int)__a), float \
|
||||
: ((vector float)__a))
|
||||
|
||||
/* vec_spatid */
|
||||
|
||||
static __inline__ vector double __ATTRS_o_ai vec_splatid(const float __a) {
|
||||
return ((vector double)((double)__a));
|
||||
}
|
||||
|
||||
/* vec_splati_ins */
|
||||
|
||||
static __inline__ vector signed int __ATTRS_o_ai vec_splati_ins(
|
||||
vector signed int __a, const unsigned int __b, const signed int __c) {
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
__a[1 - __b] = __c;
|
||||
__a[3 - __b] = __c;
|
||||
#else
|
||||
__a[__b] = __c;
|
||||
__a[2 + __b] = __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) {
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
__a[1 - __b] = __c;
|
||||
__a[3 - __b] = __c;
|
||||
#else
|
||||
__a[__b] = __c;
|
||||
__a[2 + __b] = __c;
|
||||
#endif
|
||||
return __a;
|
||||
}
|
||||
|
||||
static __inline__ vector float __ATTRS_o_ai
|
||||
vec_splati_ins(vector float __a, const unsigned int __b, const float __c) {
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
__a[1 - __b] = __c;
|
||||
__a[3 - __b] = __c;
|
||||
#else
|
||||
__a[__b] = __c;
|
||||
__a[2 + __b] = __c;
|
||||
#endif
|
||||
return __a;
|
||||
}
|
||||
#endif /* __VSX__ */
|
||||
#endif /* __POWER10_VECTOR__ */
|
||||
|
||||
|
|
|
@ -512,3 +512,72 @@ vector unsigned int test_vec_inserth_uiv(void) {
|
|||
// CHECK-LE-NEXT: ret <4 x i32>
|
||||
return vec_inserth(vuia, vuib, uia);
|
||||
}
|
||||
|
||||
vector signed int test_vec_vec_splati_si(void) {
|
||||
// CHECK-BE: ret <4 x i32> <i32 -17, i32 -17, i32 -17, i32 -17>
|
||||
// CHECK: ret <4 x i32> <i32 -17, i32 -17, i32 -17, i32 -17>
|
||||
return vec_splati(-17);
|
||||
}
|
||||
|
||||
vector unsigned int test_vec_vec_splati_ui(void) {
|
||||
// CHECK-BE: ret <4 x i32> <i32 16, i32 16, i32 16, i32 16>
|
||||
// CHECK: ret <4 x i32> <i32 16, i32 16, i32 16, i32 16>
|
||||
return vec_splati(16U);
|
||||
}
|
||||
|
||||
vector float test_vec_vec_splati_f(void) {
|
||||
// CHECK-BE: ret <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
|
||||
// CHECK: ret <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
|
||||
return vec_splati(1.0f);
|
||||
}
|
||||
|
||||
vector double test_vec_vec_splatid(void) {
|
||||
// CHECK-BE: [[T1:%.+]] = fpext float %{{.+}} to double
|
||||
// CHECK-BE-NEXT: [[T2:%.+]] = insertelement <2 x double> undef, double [[T1:%.+]], i32 0
|
||||
// CHECK-BE-NEXT: [[T3:%.+]] = shufflevector <2 x double> [[T2:%.+]], <2 x double> undef, <2 x i32> zeroinitialize
|
||||
// CHECK-BE-NEXT: ret <2 x double> [[T3:%.+]]
|
||||
// CHECK: [[T1:%.+]] = fpext float %{{.+}} to double
|
||||
// CHECK-NEXT: [[T2:%.+]] = insertelement <2 x double> undef, double [[T1:%.+]], i32 0
|
||||
// CHECK-NEXT: [[T3:%.+]] = shufflevector <2 x double> [[T2:%.+]], <2 x double> undef, <2 x i32> zeroinitialize
|
||||
// CHECK-NEXT: ret <2 x double> [[T3:%.+]]
|
||||
return vec_splatid(1.0);
|
||||
}
|
||||
|
||||
vector signed int test_vec_vec_splati_ins_si(void) {
|
||||
// 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: [[T1:%.+]] = sub i32 1, %{{.+}}
|
||||
// CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
|
||||
// CHECK: [[T2:%.+]] = sub i32 3, %{{.+}}
|
||||
// CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T2]]
|
||||
// CHECK: ret <4 x i32>
|
||||
return vec_splati_ins(vsia, 0, -17);
|
||||
}
|
||||
|
||||
vector unsigned int test_vec_vec_splati_ins_ui(void) {
|
||||
// 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: [[T1:%.+]] = sub i32 1, %{{.+}}
|
||||
// CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]]
|
||||
// CHECK: [[T2:%.+]] = sub i32 3, %{{.+}}
|
||||
// CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T2]]
|
||||
// CHECK: ret <4 x i32>
|
||||
return vec_splati_ins(vuia, 1, 16U);
|
||||
}
|
||||
|
||||
vector float test_vec_vec_splati_ins_f(void) {
|
||||
// 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: [[T1:%.+]] = sub i32 1, %{{.+}}
|
||||
// CHECK: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T1]]
|
||||
// CHECK: [[T2:%.+]] = sub i32 3, %{{.+}}
|
||||
// CHECK: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T2]]
|
||||
// CHECK: ret <4 x float>
|
||||
return vec_splati_ins(vfa, 0, 1.0f);
|
||||
}
|
||||
|
|
|
@ -286,3 +286,21 @@ define dso_local double @testDoubleZeroScalar() local_unnamed_addr {
|
|||
entry:
|
||||
ret double 0.000000e+00
|
||||
}
|
||||
|
||||
define dso_local <4 x i32> @vec_splati() local_unnamed_addr {
|
||||
; CHECK-LABEL: vec_splati:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: xxspltiw vs34, -17
|
||||
; CHECK-NEXT: blr
|
||||
entry:
|
||||
ret <4 x i32> <i32 -17, i32 -17, i32 -17, i32 -17>
|
||||
}
|
||||
|
||||
define dso_local <2 x double> @vec_splatid() local_unnamed_addr {
|
||||
; CHECK-LABEL: vec_splatid:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: xxspltidp vs34, 1065353216
|
||||
; CHECK-NEXT: blr
|
||||
entry:
|
||||
ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue