Index: include/clang/Basic/BuiltinsPPC.def =================================================================== --- include/clang/Basic/BuiltinsPPC.def +++ include/clang/Basic/BuiltinsPPC.def @@ -301,6 +301,11 @@ BUILTIN(__builtin_vsx_stxvd2x, "vV2div*", "") BUILTIN(__builtin_vsx_stxvw4x, "vV4iiv*", "") +BUILTIN(__builtin_vsx_lxvl, "V4ivC*ULLi", "") +BUILTIN(__builtin_vsx_lxvll, "V4ivC*ULLi", "") +BUILTIN(__builtin_vsx_stxvl, "vV4iv*ULLi", "") +BUILTIN(__builtin_vsx_stxvll, "vV4iv*ULLi", "") + BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "") BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "") BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "") Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7935,11 +7935,17 @@ case PPC::BI__builtin_altivec_lvsr: case PPC::BI__builtin_vsx_lxvd2x: case PPC::BI__builtin_vsx_lxvw4x: + case PPC::BI__builtin_vsx_lxvl: + case PPC::BI__builtin_vsx_lxvll: { - Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); - - Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); - Ops.pop_back(); + if(BuiltinID == PPC::BI__builtin_vsx_lxvl || + BuiltinID == PPC::BI__builtin_vsx_lxvll){ + Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); + }else { + Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); + Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); + Ops.pop_back(); + } switch (BuiltinID) { default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); @@ -7970,6 +7976,12 @@ case PPC::BI__builtin_vsx_lxvw4x: ID = Intrinsic::ppc_vsx_lxvw4x; break; + case PPC::BI__builtin_vsx_lxvl: + ID = Intrinsic::ppc_vsx_lxvl; + break; + case PPC::BI__builtin_vsx_lxvll: + ID = Intrinsic::ppc_vsx_lxvll; + break; } llvm::Function *F = CGM.getIntrinsic(ID); return Builder.CreateCall(F, Ops, ""); @@ -7983,10 +7995,17 @@ case PPC::BI__builtin_altivec_stvewx: case PPC::BI__builtin_vsx_stxvd2x: case PPC::BI__builtin_vsx_stxvw4x: + case PPC::BI__builtin_vsx_stxvl: + case PPC::BI__builtin_vsx_stxvll: { - Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); - Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); - Ops.pop_back(); + if(BuiltinID == PPC::BI__builtin_vsx_stxvl || + BuiltinID == PPC::BI__builtin_vsx_stxvll ){ + Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); + }else { + Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); + Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); + Ops.pop_back(); + } switch (BuiltinID) { default: llvm_unreachable("Unsupported st intrinsic!"); @@ -8011,6 +8030,12 @@ case PPC::BI__builtin_vsx_stxvw4x: ID = Intrinsic::ppc_vsx_stxvw4x; break; + case PPC::BI__builtin_vsx_stxvl: + ID = Intrinsic::ppc_vsx_stxvl; + break; + case PPC::BI__builtin_vsx_stxvll: + ID = Intrinsic::ppc_vsx_stxvll; + break; } llvm::Function *F = CGM.getIntrinsic(ID); return Builder.CreateCall(F, Ops, ""); Index: lib/Headers/altivec.h =================================================================== --- lib/Headers/altivec.h +++ lib/Headers/altivec.h @@ -36,6 +36,10 @@ #define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__)) +#ifdef __POWER9_VECTOR__ +#include +#endif + static __inline__ vector signed char __ATTRS_o_ai vec_perm( vector signed char __a, vector signed char __b, vector unsigned char __c); @@ -2632,6 +2636,160 @@ return __builtin_vsx_xviexpsp(__a,__b); } +#if defined(__powerpc64__) +static __inline__ vector signed char __ATTRS_o_ai vec_xl_len(signed char *__a, + size_t __b) { + return (vector signed char)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_xl_len(unsigned char *__a, size_t __b) { + return (vector unsigned char)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector signed short __ATTRS_o_ai vec_xl_len(signed short *__a, + size_t __b) { + return (vector signed short)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_xl_len(unsigned short *__a, size_t __b) { + return (vector unsigned short)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector signed int __ATTRS_o_ai vec_xl_len(signed int *__a, + size_t __b) { + return (vector signed int)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector unsigned int __ATTRS_o_ai vec_xl_len(unsigned int *__a, + size_t __b) { + return (vector unsigned int)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector float __ATTRS_o_ai vec_xl_len(float *__a, size_t __b) { + return (vector float)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector signed __int128 __ATTRS_o_ai +vec_xl_len(signed __int128 *__a, size_t __b) { + return (vector signed __int128)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_xl_len(unsigned __int128 *__a, size_t __b) { + return (vector unsigned __int128)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector signed long long __ATTRS_o_ai +vec_xl_len(signed long long *__a, size_t __b) { + return (vector signed long long)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_xl_len(unsigned long long *__a, size_t __b) { + return (vector unsigned long long)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector double __ATTRS_o_ai vec_xl_len(double *__a, + size_t __b) { + return (vector double)__builtin_vsx_lxvl(__a, (__b << 56)); +} + +static __inline__ vector double __ATTRS_o_ai vec_xl_len_r(unsigned char *__a, + size_t __b) { + vector unsigned char __res = + (vector unsigned char)__builtin_vsx_lxvll(__a, (__b << 56)); +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __mask = + (vector unsigned char)__builtin_altivec_lvsr(16 - __b, (int *)NULL); + __res = (vector unsigned char)__builtin_altivec_vperm_4si( + (vector int)__res, (vector int)__res, __mask); +#endif + return __res; +} + +// vec_xst_len +static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned char __a, + unsigned char *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed char __a, + signed char *__b, size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed short __a, + signed short *__b, size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned short __a, + unsigned short *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed int __a, + signed int *__b, size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned int __a, + unsigned int *__b, size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector float __a, float *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed __int128 __a, + signed __int128 *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned __int128 __a, + unsigned __int128 *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector signed long long __a, + signed long long *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector unsigned long long __a, + unsigned long long *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len(vector double __a, double *__b, + size_t __c) { + return __builtin_vsx_stxvl((vector int)__a, __b, (__c << 56)); +} + +static __inline__ void __ATTRS_o_ai vec_xst_len_r(vector unsigned char __a, + unsigned char *__b, + size_t __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __mask = + (vector unsigned char)__builtin_altivec_lvsl(16 - __c, (int *)NULL); + vector unsigned char __res = + __builtin_altivec_vperm_4si((vector int)__a, (vector int)__a, __mask); + return __builtin_vsx_stxvll((vector int)__res, __b, (__c << 56)); +#else + return __builtin_vsx_stxvll((vector int)__a, __b, (__c << 56)); +#endif +} +#endif #endif /* vec_cpsgn */ Index: test/CodeGen/builtins-ppc-p9vector.c =================================================================== --- test/CodeGen/builtins-ppc-p9vector.c +++ test/CodeGen/builtins-ppc-p9vector.c @@ -26,6 +26,23 @@ vector unsigned __int128 vui128a, vui128b; vector signed __int128 vsi128a, vsi128b; +float f[4] = { 23.4f, 56.7f, 89.0f, 12.3f }; +double d[2] = { 23.4, 56.7 }; +signed char sc[16] = { -8, 9, -10, 11, -12, 13, -14, 15, + -0, 1, -2, 3, -4, 5, -6, 7 }; +unsigned char uc[16] = { 8, 9, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7 }; +signed short ss[8] = { -1, 2, -3, 4, -5, 6, -7, 8 }; +unsigned short us[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +signed int si[4] = { -1, 2, -3, 4 }; +unsigned int ui[4] = { 0, 1, 2, 3 }; +signed long sl[2] = { -1L, 2L }; +unsigned long ul[2] = { 1L, 2L }; +signed long long sll[2] = { 1LL, 1LL }; +unsigned long long ull[2] = { -1LL, 1LL }; +signed __int128 sint128[1] = { -1 }; +unsigned __int128 uint128[1] = { 1 }; + unsigned test1(void) { // CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8> // CHECK-BE: @llvm.ctlz.v2i64(<2 x i64> @@ -827,4 +844,181 @@ // CHECK-NEXT: ret <16 x i8> return vec_srv (vuca, vucb); } +vector unsigned char test74(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <16 x i8> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <16 x i8> + return vec_xl_len(uc,0); +} +vector signed char test75(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <16 x i8> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <16 x i8> + return vec_xl_len(sc,0); +} +vector unsigned short test76(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <8 x i16> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <8 x i16> + return vec_xl_len(us,0); +} +vector signed short test77(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <8 x i16> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <8 x i16> + return vec_xl_len(ss,0); +} +vector unsigned int test78(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT: ret <4 x i32> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT: ret <4 x i32> + return vec_xl_len(ui,0); +} + +vector signed int test79(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT: ret <4 x i32> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT: ret <4 x i32> + return vec_xl_len(si,0); +} + +vector float test80(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <4 x i32> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <4 x i32> + return vec_xl_len(f,0); +} + +vector unsigned long long test81(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <2 x i64> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <2 x i64> + return vec_xl_len(ull,0); +} +vector signed long long test82(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <2 x i64> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <2 x i64> + return vec_xl_len(sll,0); +} + +vector double test83(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <2 x i64> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <2 x i64> + return vec_xl_len(d,0); +} + +vector unsigned __int128 test84(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <1 x i128> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <1 x i128> + return vec_xl_len(uint128,0); +} + +vector signed __int128 test85(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-BE-NEXT-NEXT: ret <1 x i128> +// CHECK: @llvm.ppc.vsx.lxvl(i8* %{{.+}}, i64 +// CHECK-NEXT-NEXT: ret <1 x i128> + return vec_xl_len(sint128,0); +} + +void test86(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vuca,uc,0); +} + +void test87(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vsca,sc,0); +} + +void test88(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vusa,us,0); +} + +void test89(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vssa,ss,0); +} + +void test90(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vuia,ui,0); +} + +void test91(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vsia,si,0); +} + +void test92(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vfa,f,0); +} + +void test93(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vula,ull,0); +} + +void test94(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vsla,sll,0); +} + +void test95(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vda,d,0); +} + +void test96(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vui128a,uint128,0); +} + +void test97(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.stxvl(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len(vsi128a,sint128,0); +} + +vector unsigned char test98(void) { +// CHECK-BE: @llvm.ppc.vsx.lxvll(i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.vsx.lxvll(i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.altivec.lvsr(i8* %{{.+}} +// CHECK: @llvm.ppc.altivec.vperm + return vec_xl_len_r(uc,0); +} +void test99(void) { +// CHECK-BE: @llvm.ppc.vsx.stxvll(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 +// CHECK: @llvm.ppc.altivec.lvsl(i8* %{{.+}} +// CHECK: @llvm.ppc.altivec.vperm +// CHECK: @llvm.ppc.vsx.stxvll(<4 x i32> %{{.+}}, i8* %{{.+}}, i64 + return vec_xst_len_r(vuca,uc,0); +}