diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -186,13 +186,16 @@ BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "") BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "") +BUILTIN(__builtin_altivec_vslq, "V1ULLLiV1ULLLiV1ULLLi", "") BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "") BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "") BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "") +BUILTIN(__builtin_altivec_vsraq, "V1ULLLiV1ULLLiV1ULLLi", "") BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "") BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "") +BUILTIN(__builtin_altivec_vsrq, "V1ULLLiV1ULLLiV1ULLLi", "") BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "") diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -17147,6 +17147,38 @@ return __a; } #endif /* __VSX__ */ + +/* vector shifts for quadwords */ +/* vs[l | r | raq] */ +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_slq(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vslq(__a, __b); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_sl(vector unsigned __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vslq(__a, (vector unsigned __int128) __b); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_srq(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vsrq(__a, __b); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_srq(vector unsigned __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vsrq(__a, (vector unsigned __int128) __b); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_sraq(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vsraq(__a, __b); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_sraq(vector unsigned __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vsraq(__a, (vector unsigned __int128) __b); +} #endif /* __POWER10_VECTOR__ */ #undef __ATTRS_o_ai diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c --- a/clang/test/CodeGen/builtins-ppc-p10vector.c +++ b/clang/test/CodeGen/builtins-ppc-p10vector.c @@ -21,6 +21,7 @@ vector unsigned int vuia, vuib, vuic; vector signed long long vslla, vsllb; vector unsigned long long vulla, vullb, vullc; +vector signed __int128 vi128a; vector unsigned __int128 vui128a, vui128b, vui128c; vector float vfa, vfb; vector double vda, vdb; @@ -581,3 +582,45 @@ // CHECK: ret <4 x float> return vec_splati_ins(vfa, 0, 1.0f); } + +vector signed __int128 test_vec_slq_unsigned (void) { + // CHECK-LABEL: test_vec_slq_unsigned + // CHECK: call <1 x i128> @llvm.ppc.altivec.vslq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> %{{.+}} + return vec_slq(vui128a, vui128b); +} + +vector signed __int128 test_vec_slq_signed (void) { + // CHECK-LABEL: test_vec_slq_signed + // CHECK: call <1 x i128> @llvm.ppc.altivec.vslq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> + return vec_slq(vui128a, vi128a); +} + +vector signed __int128 test_vec_srq_unsigned (void) { + // CHECK-LABEL: test_vec_srq_unsigned + // CHECK: call <1 x i128> @llvm.ppc.altivec.vsrq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> + return vec_srq(vui128a, vui128b); +} + +vector signed __int128 test_vec_srq_signed (void) { + // CHECK-LABEL: test_vec_srq_signed + // CHECK: call <1 x i128> @llvm.ppc.altivec.vsrq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> + return vec_srq(vui128a, vi128a); +} + +vector signed __int128 test_vec_sraq_unsigned (void) { + // CHECK-LABEL: test_vec_sraq_unsigned + // CHECK: call <1 x i128> @llvm.ppc.altivec.vsraq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> + return vec_sraq(vui128a, vui128b); +} + +vector signed __int128 test_vec_sraq_signed (void) { + // CHECK-LABEL: test_vec_sraq_signed + // CHECK: call <1 x i128> @llvm.ppc.altivec.vsraq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}}) + // CHECK: ret <1 x i128> + return vec_sraq(vui128a, vi128a); +} diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -797,6 +797,7 @@ def int_ppc_altivec_vsrv : PowerPC_Vec_BBB_Intrinsic<"vsrv">; def int_ppc_altivec_vslh : PowerPC_Vec_HHH_Intrinsic<"vslh">; def int_ppc_altivec_vslw : PowerPC_Vec_WWW_Intrinsic<"vslw">; +def int_ppc_altivec_vslq : PowerPC_Vec_QQQ_Intrinsic<"vslq">; // Right Shifts. def int_ppc_altivec_vsr : PowerPC_Vec_WWW_Intrinsic<"vsr">; @@ -805,9 +806,11 @@ def int_ppc_altivec_vsrb : PowerPC_Vec_BBB_Intrinsic<"vsrb">; def int_ppc_altivec_vsrh : PowerPC_Vec_HHH_Intrinsic<"vsrh">; def int_ppc_altivec_vsrw : PowerPC_Vec_WWW_Intrinsic<"vsrw">; +def int_ppc_altivec_vsrq : PowerPC_Vec_QQQ_Intrinsic<"vsrq">; def int_ppc_altivec_vsrab : PowerPC_Vec_BBB_Intrinsic<"vsrab">; def int_ppc_altivec_vsrah : PowerPC_Vec_HHH_Intrinsic<"vsrah">; def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">; +def int_ppc_altivec_vsraq : PowerPC_Vec_QQQ_Intrinsic<"vsraq">; // Rotates. def int_ppc_altivec_vrlb : PowerPC_Vec_BBB_Intrinsic<"vrlb">; diff --git a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td --- a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td +++ b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td @@ -1027,15 +1027,16 @@ (ins vrrc:$vA, vrrc:$vB, vrrc:$vDi), "vrlqmi $vD, $vA, $vB", IIC_VecFP, []>, RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">; - def VSLQ : VX1_VT5_VA5_VB5<261, "vslq", []>; - def VSRAQ : VX1_VT5_VA5_VB5<773, "vsraq", []>; - def VSRQ : VX1_VT5_VA5_VB5<517, "vsrq", []>; + def VSLQ : VX1_Int_Ty< 261, "vslq", int_ppc_altivec_vslq, v1i128>; + def VSRAQ : VX1_Int_Ty< 773, "vsraq", int_ppc_altivec_vsraq, v1i128>; + def VSRQ : VX1_Int_Ty< 517, "vsrq" , int_ppc_altivec_vsrq, v1i128>; def VRLQ : VX1_VT5_VA5_VB5<5, "vrlq", []>; def XSCVQPUQZ : X_VT5_XO5_VB5<63, 0, 836, "xscvqpuqz", []>; def XSCVQPSQZ : X_VT5_XO5_VB5<63, 8, 836, "xscvqpsqz", []>; def XSCVUQQP : X_VT5_XO5_VB5<63, 3, 836, "xscvuqqp", []>; def XSCVSQQP : X_VT5_XO5_VB5<63, 11, 836, "xscvsqqp", []>; + } //---------------------------- Anonymous Patterns ----------------------------// diff --git a/llvm/test/CodeGen/PowerPC/p10-vector-shift.ll b/llvm/test/CodeGen/PowerPC/p10-vector-shift.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/p10-vector-shift.ll @@ -0,0 +1,50 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \ +; RUN: FileCheck %s + +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \ +; RUN: FileCheck %s + +@vui128a = dso_local global <1 x i128> zeroinitializer, align 16 +@vui128b = dso_local global <1 x i128> zeroinitializer, align 16 + +define dso_local <1 x i128> @test_vec_slq(<1 x i128> %a, <1 x i128> %b) #0 { +; CHECK-LABEL: test_vec_slq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vslq v2, v2, v3 +; CHECK-NEXT: blr +entry: + %slq = call <1 x i128> @llvm.ppc.altivec.vslq(<1 x i128> %a, <1 x i128> %b) + ret <1 x i128> %slq +} + +define dso_local <1 x i128> @test_vec_vsrq(<1 x i128> %a, <1 x i128> %b) #0 { +; CHECK-LABEL: test_vec_vsrq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsrq v2, v2, v3 +; CHECK-NEXT: blr +entry: + %slq = call <1 x i128> @llvm.ppc.altivec.vsrq(<1 x i128> %a, <1 x i128> %b) + ret <1 x i128> %slq +} + +define dso_local <1 x i128> @test_vec_vsraq(<1 x i128> %a, <1 x i128> %b) #0 { +; CHECK-LABEL: test_vec_vsraq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsraq v2, v2, v3 +; CHECK-NEXT: blr +entry: + %slq = call <1 x i128> @llvm.ppc.altivec.vsraq(<1 x i128> %a, <1 x i128> %b) + ret <1 x i128> %slq +} + +; Function Attrs: nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vslq(<1 x i128>, <1 x i128>) #1 + +; Function Attrs: nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vsrq(<1 x i128>, <1 x i128>) #1 + +; Function Attrs: nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vsraq(<1 x i128>, <1 x i128>) #1