diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 66c35a9a82bed..730c2ea93fbde 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -546,6 +546,8 @@ BUILTIN(__builtin_vsx_xvxsigsp, "V4UiV4f", "") // Conversion builtins BUILTIN(__builtin_vsx_xvcvdpsxws, "V4SiV2d", "") BUILTIN(__builtin_vsx_xvcvdpuxws, "V4UiV2d", "") +BUILTIN(__builtin_vsx_xvcvspsxds, "V2SLLiV4f", "") +BUILTIN(__builtin_vsx_xvcvspuxds, "V2ULLiV4f", "") BUILTIN(__builtin_vsx_xvcvsxwdp, "V2dV4Si", "") BUILTIN(__builtin_vsx_xvcvuxwdp, "V2dV4Ui", "") BUILTIN(__builtin_vsx_xvcvspdp, "V2dV4f", "") diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 57d7828f5285f..422e4ba48b0d6 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -3150,6 +3150,90 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a, #define vec_ctu __builtin_altivec_vctuxs #endif +#ifdef __LITTLE_ENDIAN__ +/* vec_ctsl */ + +#ifdef __VSX__ +#define vec_ctsl(__a, __b) \ + _Generic((__a), vector float \ + : __extension__({ \ + vector float __ret = \ + (vector float)(__a) * \ + (vector float)(vector unsigned)((0x7f + (__b)) << 23); \ + __builtin_vsx_xvcvspsxds( \ + __builtin_vsx_xxsldwi(__ret, __ret, 1)); \ + }), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + __b) \ + << 52); \ + __builtin_convertvector(__ret, vector signed long long); \ + })) + +/* vec_ctul */ + +#define vec_ctul(__a, __b) \ + _Generic((__a), vector float \ + : __extension__({ \ + vector float __ret = \ + (vector float)(__a) * \ + (vector float)(vector unsigned)((0x7f + (__b)) << 23); \ + __builtin_vsx_xvcvspuxds( \ + __builtin_vsx_xxsldwi(__ret, __ret, 1)); \ + }), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + __b) \ + << 52); \ + __builtin_convertvector(__ret, vector unsigned long long); \ + })) +#endif +#else // __LITTLE_ENDIAN__ +/* vec_ctsl */ + +#ifdef __VSX__ +#define vec_ctsl(__a, __b) \ + _Generic((__a), vector float \ + : __extension__({ \ + vector float __ret = \ + (vector float)(__a) * \ + (vector float)(vector unsigned)((0x7f + (__b)) << 23); \ + __builtin_vsx_xvcvspsxds(__ret); \ + }), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + __b) \ + << 52); \ + __builtin_convertvector(__ret, vector signed long long); \ + })) + +/* vec_ctul */ + +#define vec_ctul(__a, __b) \ + _Generic((__a), vector float \ + : __extension__({ \ + vector float __ret = \ + (vector float)(__a) * \ + (vector float)(vector unsigned)((0x7f + (__b)) << 23); \ + __builtin_vsx_xvcvspuxds(__ret); \ + }), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + __b) \ + << 52); \ + __builtin_convertvector(__ret, vector unsigned long long); \ + })) +#endif +#endif // __LITTLE_ENDIAN__ + /* vec_vctuxs */ #define vec_vctuxs __builtin_altivec_vctuxs diff --git a/clang/test/CodeGen/builtins-ppc-vsx.c b/clang/test/CodeGen/builtins-ppc-vsx.c index a8eaf341e8fcf..c78218effaee8 100644 --- a/clang/test/CodeGen/builtins-ppc-vsx.c +++ b/clang/test/CodeGen/builtins-ppc-vsx.c @@ -1290,6 +1290,19 @@ void test1() { // CHECK-LE: fmul <2 x double> // CHECK-LE: fptosi <2 x double> %{{.*}} to <2 x i64> + res_vsll = vec_ctsl(vf, 3); + // CHECK: fmul <4 x float> {{%.*}}, + // CHECK: call <2 x i64> @llvm.ppc.vsx.xvcvspsxds(<4 x float> + // CHECK-LE: fmul <4 x float> {{%.*}}, + // CHECK-LE: shufflevector <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> + // CHECK-LE: call <2 x i64> @llvm.ppc.vsx.xvcvspsxds(<4 x float> + + res_vsll = vec_ctsl(vd, 3); + // CHECK: fmul <2 x double> {{%.*}}, + // CHECK: fptosi <2 x double> {{%.*}} to <2 x i64> + // CHECK-LE: fmul <2 x double> {{%.*}}, + // CHECK-LE: fptosi <2 x double> {{%.*}} to <2 x i64> + res_vsll = vec_ctu(vd, 0); // CHECK: fmul <2 x double> // CHECK: fptoui <2 x double> %{{.*}} to <2 x i64> @@ -1302,6 +1315,19 @@ void test1() { // CHECK-LE: fmul <2 x double> // CHECK-LE: fptoui <2 x double> %{{.*}} to <2 x i64> + res_vull = vec_ctul(vf, 3); + // CHECK: fmul <4 x float> {{%.*}}, + // CHECK: call <2 x i64> @llvm.ppc.vsx.xvcvspuxds(<4 x float> + // CHECK-LE: fmul <4 x float> {{%.*}}, + // CHECK-LE: shufflevector <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> + // CHECK-LE: call <2 x i64> @llvm.ppc.vsx.xvcvspuxds(<4 x float> + + res_vull = vec_ctul(vd, 3); + // CHECK: fmul <2 x double> {{%.*}}, + // CHECK: fptoui <2 x double> {{%.*}} to <2 x i64> + // CHECK-LE: fmul <2 x double> {{%.*}}, + // CHECK-LE: fptoui <2 x double> {{%.*}} to <2 x i64> + res_vd = vec_ctf(vsll, 0); // CHECK: sitofp <2 x i64> %{{.*}} to <2 x double> // CHECK: fmul <2 x double> diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index 075b6252d9a5d..883d9e656990c 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1239,6 +1239,12 @@ def int_ppc_vsx_xvcvdpsxws : def int_ppc_vsx_xvcvdpuxws : PowerPC_VSX_Intrinsic<"xvcvdpuxws", [llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcvspsxds : + PowerPC_VSX_Intrinsic<"xvcvspsxds", [llvm_v2i64_ty], + [llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcvspuxds : + PowerPC_VSX_Intrinsic<"xvcvspuxds", [llvm_v2i64_ty], + [llvm_v4f32_ty], [IntrNoMem]>; def int_ppc_vsx_xvcvsxwdp : PowerPC_VSX_Intrinsic<"xvcvsxwdp", [llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td index 0347a191856d8..16f5bac501033 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -849,14 +849,16 @@ let hasSideEffects = 0 in { [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>; def XVCVSPSXDS : XX2Form<60, 408, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvspsxds $XT, $XB", IIC_VecFP, []>; + "xvcvspsxds $XT, $XB", IIC_VecFP, + [(set v2i64:$XT, (int_ppc_vsx_xvcvspsxds v4f32:$XB))]>; def XVCVSPSXWS : XX2Form<60, 152, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvspsxws $XT, $XB", IIC_VecFP, [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>; def XVCVSPUXDS : XX2Form<60, 392, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvspuxds $XT, $XB", IIC_VecFP, []>; + "xvcvspuxds $XT, $XB", IIC_VecFP, + [(set v2i64:$XT, (int_ppc_vsx_xvcvspuxds v4f32:$XB))]>; def XVCVSPUXWS : XX2Form<60, 136, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvspuxws $XT, $XB", IIC_VecFP, diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll index bc2336fa23899..10a705050cd9c 100644 --- a/llvm/test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll @@ -230,7 +230,21 @@ entry: ; CHECK: xvcvdpsp 34, 34 } -; Function Attrs: nounwind readnone +define dso_local <2 x i64> @emit_xvcvspsxds(<4 x float> %a) local_unnamed_addr #0 { +entry: + %0 = tail call <2 x i64> @llvm.ppc.vsx.xvcvspsxds(<4 x float> %a) + ret <2 x i64> %0 +; CHECK-LABEL: @emit_xvcvspsxds +; CHECK: xvcvspsxds 34, 34 +} + +define dso_local <2 x i64> @emit_xvcvspuxds(<4 x float> %a) local_unnamed_addr #0 { +entry: + %0 = tail call <2 x i64> @llvm.ppc.vsx.xvcvspuxds(<4 x float> %a) + ret <2 x i64> %0 +; CHECK-LABEL: @emit_xvcvspuxds +; CHECK: xvcvspuxds 34, 34 +} ; Function Attrs: nounwind readnone declare <4 x float> @llvm.ppc.vsx.xvresp(<4 x float>) @@ -275,3 +289,5 @@ declare <2 x double> @llvm.ppc.vsx.xvcvuxwdp(<4 x i32>) #1 declare <2 x double> @llvm.ppc.vsx.xvcvspdp(<4 x float>) #1 declare <4 x float> @llvm.ppc.vsx.xvcvsxdsp(<2 x i64>) #1 declare <4 x float> @llvm.ppc.vsx.xvcvuxdsp(<2 x i64>) #1 +declare <2 x i64> @llvm.ppc.vsx.xvcvspsxds(<4 x float>) #1 +declare <2 x i64> @llvm.ppc.vsx.xvcvspuxds(<4 x float>) #1