diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 5681c1f2ae1a..365dcc02a46d 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -336,6 +336,9 @@ BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "") BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "") +BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "") + // HTM builtins BUILTIN(__builtin_tbegin, "UiUIi", "") BUILTIN(__builtin_tend, "UiUIi", "") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fbba561f7ccd..fc3d1266146d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -6992,6 +6992,16 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, llvm::Function *F = CGM.getIntrinsic(ID, ResultType); return Builder.CreateCall(F, X); } + + // Absolute value + case PPC::BI__builtin_vsx_xvabsdp: + case PPC::BI__builtin_vsx_xvabssp: { + llvm::Type *ResultType = ConvertType(E->getType()); + Value *X = EmitScalarExpr(E->getArg(0)); + llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); + return Builder.CreateCall(F, X); + } + // FMA variations case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 5973326fe4ee..017f69678ecd 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -124,16 +124,18 @@ vec_abs(vector signed long long __a) { #endif static vector float __ATTRS_o_ai vec_abs(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvabssp(__a); +#else vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)(0x7FFFFFFF); return (vector float)__res; +#endif } #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) static vector double __ATTRS_o_ai vec_abs(vector double __a) { - vector unsigned long long __res = { 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF }; - __res &= (vector unsigned int)__a; - return (vector double)__res; + return __builtin_vsx_xvabsdp(__a); } #endif diff --git a/clang/test/CodeGen/builtins-ppc-altivec.c b/clang/test/CodeGen/builtins-ppc-altivec.c index 9539d6ca7afc..f9e0584ad055 100644 --- a/clang/test/CodeGen/builtins-ppc-altivec.c +++ b/clang/test/CodeGen/builtins-ppc-altivec.c @@ -1,7 +1,13 @@ // REQUIRES: powerpc-registered-target -// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-LE +// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s +// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s +// RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s -check-prefix=CHECK-LE +// RUN: not %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: -ferror-limit 0 -o - 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOALTIVEC vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 }; @@ -27,6 +33,8 @@ vector int res_vi; vector unsigned int res_vui; vector float res_vf; +// CHECK-NOALTIVEC: error: unknown type name 'vector' + signed char param_sc; unsigned char param_uc; short param_s; @@ -66,8 +74,16 @@ void test1() { // CHECK-LE: @llvm.ppc.altivec.vmaxsw vf = vec_abs(vf); -// CHECK: and <4 x i32> -// CHECK-LE: and <4 x i32> +// CHECK: bitcast <4 x float> %{{.*}} to <4 x i32> +// CHECK: and <4 x i32> {{.*}}, +// CHECK: bitcast <4 x i32> %{{.*}} to <4 x float> +// CHECK: store <4 x float> %{{.*}}, <4 x float>* @vf +// CHECK-LE: bitcast <4 x float> %{{.*}} to <4 x i32> +// CHECK-LE: and <4 x i32> {{.*}}, +// CHECK-LE: bitcast <4 x i32> %{{.*}} to <4 x float> +// CHECK-LE: store <4 x float> %{{.*}}, <4 x float>* @vf +// CHECK-NOALTIVEC: error: use of undeclared identifier 'vf' +// CHECK-NOALTIVEC: vf = vec_abs(vf) /* vec_abs */ vsc = vec_abss(vsc); diff --git a/clang/test/CodeGen/builtins-ppc-p8vector.c b/clang/test/CodeGen/builtins-ppc-p8vector.c index 29503f0134be..594ed335c85f 100644 --- a/clang/test/CodeGen/builtins-ppc-p8vector.c +++ b/clang/test/CodeGen/builtins-ppc-p8vector.c @@ -73,10 +73,10 @@ void test1() { // CHECK-PPC: error: call to 'vec_abs' is ambiguous res_vd = vec_abs(vda); -// CHECK: store <2 x i64> , <2 x i64>* -// CHECK: and <2 x i64> -// CHECK-LE: store <2 x i64> , <2 x i64>* -// CHECK-LE: and <2 x i64> +// CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) +// CHECK: store <2 x double> %{{.*}}, <2 x double>* @res_vd +// CHECK-LE: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) +// CHECK-LE: store <2 x double> %{{.*}}, <2 x double>* @res_vd // CHECK-PPC: error: call to 'vec_abs' is ambiguous /* vec_add */ diff --git a/clang/test/CodeGen/builtins-ppc-vsx.c b/clang/test/CodeGen/builtins-ppc-vsx.c index 96d0ad8433b2..27f160586d9c 100644 --- a/clang/test/CodeGen/builtins-ppc-vsx.c +++ b/clang/test/CodeGen/builtins-ppc-vsx.c @@ -51,6 +51,14 @@ void test1() { // CHECK-LABEL: define void @test1 // CHECK-LE-LABEL: define void @test1 + res_vf = vec_abs(vf); +// CHECK: call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{[0-9]*}}) +// CHECK-LE: call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{[0-9]*}}) + + dummy(); +// CHECK: call void @dummy() +// CHECK-LE: call void @dummy() + res_vd = vec_add(vd, vd); // CHECK: fadd <2 x double> // CHECK-LE: fadd <2 x double>