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 @@ -3288,6 +3288,18 @@ } #endif +#ifdef __POWER10_VECTOR__ +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_div(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __a / __b; +} + +static __inline__ vector signed __int128 __ATTRS_o_ai +vec_div(vector signed __int128 __a, vector signed __int128 __b) { + return __a / __b; +} +#endif __POWER10_VECTOR__ + /* vec_dss */ #define vec_dss __builtin_altivec_dss 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 @@ -17,6 +17,7 @@ vector unsigned int vuia, vuib, vuic; vector signed long long vslla, vsllb; vector unsigned long long vulla, vullb, vullc; +vector signed __int128 vsi128a, vsi128b; vector unsigned __int128 vui128a, vui128b, vui128c; vector float vfa, vfb; vector double vda, vdb; @@ -61,6 +62,18 @@ return vec_div(vulla, vullb); } +vector unsigned __int128 test_vec_div_u128(void) { + // CHECK: udiv <1 x i128> + // CHECK-NEXT: ret <1 x i128> + return vec_div(vui128a, vui128b); +} + +vector signed __int128 test_vec_div_s128(void) { + // CHECK: sdiv <1 x i128> + // CHECK-NEXT: ret <1 x i128> + return vec_div(vsi128a, vsi128b); +} + vector signed int test_vec_mod_si(void) { // CHECK: srem <4 x i32> // CHECK-NEXT: ret <4 x i32> diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -836,6 +836,8 @@ setOperationAction(ISD::SREM, MVT::v2i64, Legal); setOperationAction(ISD::UREM, MVT::v4i32, Legal); setOperationAction(ISD::SREM, MVT::v4i32, Legal); + setOperationAction(ISD::UDIV, MVT::v1i128, Legal); + setOperationAction(ISD::SDIV, MVT::v1i128, Legal); } setOperationAction(ISD::MUL, MVT::v8i16, Legal); 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 @@ -1124,9 +1124,11 @@ (ins vrrc:$vA, vrrc:$vB, vrrc:$vC), "vmsumcud $vD, $vA, $vB, $vC", IIC_VecGeneral, []>; def VDIVSQ : VXForm_1<267, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), - "vdivsq $vD, $vA, $vB", IIC_VecGeneral, []>; + "vdivsq $vD, $vA, $vB", IIC_VecGeneral, + [(set v1i128:$vD, (sdiv v1i128:$vA, v1i128:$vB))]>; def VDIVUQ : VXForm_1<11, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), - "vdivuq $vD, $vA, $vB", IIC_VecGeneral, []>; + "vdivuq $vD, $vA, $vB", IIC_VecGeneral, + [(set v1i128:$vD, (udiv v1i128:$vA, v1i128:$vB))]>; def VDIVESQ : VXForm_1<779, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), "vdivesq $vD, $vA, $vB", IIC_VecGeneral, []>; def VDIVEUQ : VXForm_1<523, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), diff --git a/llvm/test/CodeGen/PowerPC/p10-vector-divide.ll b/llvm/test/CodeGen/PowerPC/p10-vector-divide.ll --- a/llvm/test/CodeGen/PowerPC/p10-vector-divide.ll +++ b/llvm/test/CodeGen/PowerPC/p10-vector-divide.ll @@ -49,3 +49,21 @@ %div = sdiv <4 x i32> %a, %b ret <4 x i32> %div } + +define <1 x i128> @test_vdivsq(<1 x i128> %x, <1 x i128> %y) nounwind readnone { +; CHECK-LABEL: test_vdivsq: +; CHECK: # %bb.0: +; CHECK-NEXT: vdivsq v2, v2, v3 +; CHECK-NEXT: blr + %tmp = sdiv <1 x i128> %x, %y + ret <1 x i128> %tmp +} + +define <1 x i128> @test_vdivuq(<1 x i128> %x, <1 x i128> %y) nounwind readnone { +; CHECK-LABEL: test_vdivuq: +; CHECK: # %bb.0: +; CHECK-NEXT: vdivuq v2, v2, v3 +; CHECK-NEXT: blr + %tmp = udiv <1 x i128> %x, %y + ret <1 x i128> %tmp +}