324 changes: 324 additions & 0 deletions clang/test/CodeGen/builtins-ppc-p10vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ vector unsigned long long test_vec_dive_ull(void) {
return vec_dive(vulla, vullb);
}

vector unsigned __int128 test_vec_dive_u128(void) {
// CHECK: @llvm.ppc.altivec.vdiveuq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}})
// CHECK-NEXT: ret <1 x i128>
return vec_dive(vui128a, vui128b);
}

vector signed __int128 test_vec_dive_s128(void) {
// CHECK: @llvm.ppc.altivec.vdivesq(<1 x i128> %{{.+}}, <1 x i128> %{{.+}})
// CHECK-NEXT: ret <1 x i128>
return vec_dive(vsi128a, vsi128b);
}

vector signed int test_vec_mulh_si(void) {
// CHECK: @llvm.ppc.altivec.vmulhsw(<4 x i32> %{{.+}}, <4 x i32> %{{.+}})
// CHECK-NEXT: ret <4 x i32>
Expand Down Expand Up @@ -178,6 +190,318 @@ vector unsigned long long test_vpextd(void) {
return vec_pext(vulla, vullb);
}

vector unsigned char test_vec_stril_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret <16 x i8>
return vec_stril(vuca);
}

vector signed char test_vec_stril_sc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret <16 x i8>
return vec_stril(vsca);
}

vector unsigned short test_vec_stril_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret <8 x i16>
return vec_stril(vusa);
}

vector signed short test_vec_stril_ss(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret <8 x i16>
return vec_stril(vssa);
}

int test_vec_stril_p_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_stril_p(vuca);
}

int test_vec_stril_p_sc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_stril_p(vsca);
}

int test_vec_stril_p_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_stril_p(vusa);
}

int test_vec_stril_p_ss(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_stril_p(vssa);
}

vector unsigned char test_vec_stril_p_uc_2(vector unsigned char *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-BE: ret <16 x i8>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-LE: ret <16 x i8>
for (int i = 0; i < len; i++) {
if (vec_stril_p(*(ptr + i))) {
return vec_stril(*(ptr + i));
}
}
return vec_stril(*(ptr));
}

vector signed char test_vec_stril_p_sc_2(vector signed char *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-BE: ret <16 x i8>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-LE: ret <16 x i8>
for (int i = 0; i < len; i++) {
if (vec_stril_p(*(ptr + i))) {
return vec_stril(*(ptr + i));
}
}
return vec_stril(*(ptr));
}

vector unsigned short test_vec_stril_p_us_2(vector unsigned short *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-BE: ret <8 x i16>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-LE: ret <8 x i16>
for (int i = 0; i < len; i++) {
if (vec_stril_p(*(ptr + i))) {
return vec_stril(*(ptr + i));
}
}
return vec_stril(*(ptr));
}

vector signed short test_vec_stril_p_ss_2(vector signed short *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-BE: ret <8 x i16>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-LE: ret <8 x i16>
for (int i = 0; i < len; i++) {
if (vec_stril_p(*(ptr + i))) {
return vec_stril(*(ptr + i));
}
}
return vec_stril(*(ptr));
}

vector unsigned char test_vec_strir_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret <16 x i8>
return vec_strir(vuca);
}

vector signed char test_vec_strir_sc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret <16 x i8>
return vec_strir(vsca);
}

vector unsigned short test_vec_strir_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret <8 x i16>
return vec_strir(vusa);
}

vector signed short test_vec_strir_ss(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret <8 x i16>
return vec_strir(vssa);
}

int test_vec_strir_p_uc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_strir_p(vuca);
}

int test_vec_strir_p_sc(void) {
// CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_strir_p(vsca);
}

int test_vec_strir_p_us(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_strir_p(vusa);
}

int test_vec_strir_p_ss(void) {
// CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE-NEXT: ret i32
// CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE-NEXT: ret i32
return vec_strir_p(vssa);
}

vector unsigned char test_vec_strir_p_uc_2(vector unsigned char *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-BE: ret <16 x i8>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-LE: ret <16 x i8>
for (int i = 0; i < len; i++) {
if (vec_strir_p(*(ptr + i))) {
return vec_strir(*(ptr + i));
}
}
return vec_strir(*(ptr));
}

vector signed char test_vec_strir_p_sc_2(vector signed char *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
// CHECK-BE: ret <16 x i8>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
// CHECK-LE: ret <16 x i8>
for (int i = 0; i < len; i++) {
if (vec_strir_p(*(ptr + i))) {
return vec_strir(*(ptr + i));
}
}
return vec_strir(*(ptr));
}

vector unsigned short test_vec_strir_p_us_2(vector unsigned short *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-BE: ret <8 x i16>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-LE: ret <8 x i16>
for (int i = 0; i < len; i++) {
if (vec_strir_p(*(ptr + i))) {
return vec_strir(*(ptr + i));
}
}
return vec_strir(*(ptr));
}

vector signed short test_vec_strir_p_ss_2(vector signed short *ptr, int len) {
// CHECK-BE: icmp slt i32
// CHECK-BE: br i1
// CHECK-BE: for.body:
// CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
// CHECK-BE: if.then:
// CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
// CHECK-BE: ret <8 x i16>
// CHECK-LE: icmp slt i32
// CHECK-LE: br i1
// CHECK-LE: for.body:
// CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
// CHECK-LE: if.then:
// CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
// CHECK-LE: ret <8 x i16>
for (int i = 0; i < len; i++) {
if (vec_strir_p(*(ptr + i))) {
return vec_strir(*(ptr + i));
}
}
return vec_strir(*(ptr));
}

unsigned int test_vec_extractm_uc(void) {
// CHECK: @llvm.ppc.altivec.vextractbm(<16 x i8> %{{.+}})
// CHECK-NEXT: ret i32
Expand Down
21 changes: 21 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;

// P10 Vector String Isolate Intrinsics.
def int_ppc_altivec_vstribr : GCCBuiltin<"__builtin_altivec_vstribr">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vstribl : GCCBuiltin<"__builtin_altivec_vstribl">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vstrihr : GCCBuiltin<"__builtin_altivec_vstrihr">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
def int_ppc_altivec_vstrihl : GCCBuiltin<"__builtin_altivec_vstrihl">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
// Predicate Intrinsics: The first operand specifies interpretation of CR6.
def int_ppc_altivec_vstribr_p : GCCBuiltin<"__builtin_altivec_vstribr_p">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vstribl_p : GCCBuiltin<"__builtin_altivec_vstribl_p">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vstrihr_p : GCCBuiltin<"__builtin_altivec_vstrihr_p">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
def int_ppc_altivec_vstrihl_p : GCCBuiltin<"__builtin_altivec_vstrihl_p">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;

// P10 Vector Centrifuge Builtin.
def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
Expand Down Expand Up @@ -1007,6 +1026,8 @@ def int_ppc_altivec_vdivesw : PowerPC_Vec_WWW_Intrinsic<"vdivesw">;
def int_ppc_altivec_vdiveuw : PowerPC_Vec_WWW_Intrinsic<"vdiveuw">;
def int_ppc_altivec_vdivesd : PowerPC_Vec_DDD_Intrinsic<"vdivesd">;
def int_ppc_altivec_vdiveud : PowerPC_Vec_DDD_Intrinsic<"vdiveud">;
def int_ppc_altivec_vdivesq : PowerPC_Vec_QQQ_Intrinsic<"vdivesq">;
def int_ppc_altivec_vdiveuq : PowerPC_Vec_QQQ_Intrinsic<"vdiveuq">;

// Vector Multiply High Intrinsics.
def int_ppc_altivec_vmulhsw : PowerPC_Vec_WWW_Intrinsic<"vmulhsw">;
Expand Down
40 changes: 40 additions & 0 deletions llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
Expand Down Expand Up @@ -4677,6 +4678,45 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
}
break;

case ISD::INTRINSIC_WO_CHAIN: {
if (!PPCSubTarget->isISA3_1())
break;
unsigned Opcode = 0;
switch (N->getConstantOperandVal(0)) {
default:
break;
case Intrinsic::ppc_altivec_vstribr_p:
Opcode = PPC::VSTRIBR_rec;
break;
case Intrinsic::ppc_altivec_vstribl_p:
Opcode = PPC::VSTRIBL_rec;
break;
case Intrinsic::ppc_altivec_vstrihr_p:
Opcode = PPC::VSTRIHR_rec;
break;
case Intrinsic::ppc_altivec_vstrihl_p:
Opcode = PPC::VSTRIHL_rec;
break;
}
if (!Opcode)
break;

// Generate the appropriate vector string isolate intrinsic to match.
EVT VTs[] = {MVT::v16i8, MVT::Glue};
SDValue VecStrOp =
SDValue(CurDAG->getMachineNode(Opcode, dl, VTs, N->getOperand(2)), 0);
// Vector string isolate instructions update the EQ bit of CR6.
// Generate a SETBC instruction to extract the bit and place it in a GPR.
SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_eq, dl, MVT::i32);
SDValue CR6Reg = CurDAG->getRegister(PPC::CR6, MVT::i32);
SDValue CRBit = SDValue(
CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
CR6Reg, SubRegIdx, VecStrOp.getValue(1)),
0);
CurDAG->SelectNodeTo(N, PPC::SETBC, MVT::i32, CRBit);
return;
}

case ISD::SETCC:
case ISD::STRICT_FSETCC:
case ISD::STRICT_FSETCCS:
Expand Down
24 changes: 18 additions & 6 deletions llvm/lib/Target/PowerPC/PPCInstrPrefix.td
Original file line number Diff line number Diff line change
Expand Up @@ -1020,13 +1020,21 @@ let Predicates = [IsISA3_1] in {
v16i8:$VRB,
i32:$SH))]>;
defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
"vstribr", "$vT, $vB", IIC_VecGeneral, []>;
"vstribr", "$vT, $vB", IIC_VecGeneral,
[(set v16i8:$vT,
(int_ppc_altivec_vstribr v16i8:$vB))]>;
defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
"vstribl", "$vT, $vB", IIC_VecGeneral, []>;
"vstribl", "$vT, $vB", IIC_VecGeneral,
[(set v16i8:$vT,
(int_ppc_altivec_vstribl v16i8:$vB))]>;
defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
"vstrihr", "$vT, $vB", IIC_VecGeneral, []>;
"vstrihr", "$vT, $vB", IIC_VecGeneral,
[(set v8i16:$vT,
(int_ppc_altivec_vstrihr v8i16:$vB))]>;
defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
"vstrihl", "$vT, $vB", IIC_VecGeneral, []>;
"vstrihl", "$vT, $vB", IIC_VecGeneral,
[(set v8i16:$vT,
(int_ppc_altivec_vstrihl v8i16:$vB))]>;
def VINSW :
VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
"vinsw $vD, $rB, $UIM", IIC_VecGeneral,
Expand Down Expand Up @@ -1427,9 +1435,13 @@ let Predicates = [IsISA3_1] in {
"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, []>;
"vdivesq $vD, $vA, $vB", IIC_VecGeneral,
[(set v1i128:$vD, (int_ppc_altivec_vdivesq v1i128:$vA,
v1i128:$vB))]>;
def VDIVEUQ : VXForm_1<523, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
"vdiveuq $vD, $vA, $vB", IIC_VecGeneral, []>;
"vdiveuq $vD, $vA, $vB", IIC_VecGeneral,
[(set v1i128:$vD, (int_ppc_altivec_vdiveuq v1i128:$vA,
v1i128:$vB))]>;
def VCMPEQUQ : VCMP <455, "vcmpequq $vD, $vA, $vB" , v1i128>;
def VCMPGTSQ : VCMP <903, "vcmpgtsq $vD, $vA, $vB" , v1i128>;
def VCMPGTUQ : VCMP <647, "vcmpgtuq $vD, $vA, $vB" , v1i128>;
Expand Down
97 changes: 97 additions & 0 deletions llvm/test/CodeGen/PowerPC/p10-string-ops.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
; 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

; These test cases aim to test the vector string isolate builtins on Power10.

Expand All @@ -27,3 +30,97 @@ entry:
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8> %a, i32 %n)
ret <16 x i8> %tmp
}

declare <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8>)
declare <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>)
declare <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16>)
declare <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16>)

declare i32 @llvm.ppc.altivec.vstribr.p(i32, <16 x i8>)
declare i32 @llvm.ppc.altivec.vstribl.p(i32, <16 x i8>)
declare i32 @llvm.ppc.altivec.vstrihr.p(i32, <8 x i16>)
declare i32 @llvm.ppc.altivec.vstrihl.p(i32, <8 x i16>)

define <16 x i8> @test_vstribr(<16 x i8> %a) {
; CHECK-LABEL: test_vstribr:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstribr v2, v2
; CHECK-NEXT: blr
entry:
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8> %a)
ret <16 x i8> %tmp
}

define <16 x i8> @test_vstribl(<16 x i8> %a) {
; CHECK-LABEL: test_vstribl:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstribl v2, v2
; CHECK-NEXT: blr
entry:
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>%a)
ret <16 x i8> %tmp
}

define <8 x i16> @test_vstrihr(<8 x i16> %a) {
; CHECK-LABEL: test_vstrihr:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstrihr v2, v2
; CHECK-NEXT: blr
entry:
%tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16> %a)
ret <8 x i16> %tmp
}

define <8 x i16> @test_vstrihl(<8 x i16> %a) {
; CHECK-LABEL: test_vstrihl:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstrihl v2, v2
; CHECK-NEXT: blr
entry:
%tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16> %a)
ret <8 x i16> %tmp
}

define i32 @test_vstribr_p(<16 x i8> %a) {
; CHECK-LABEL: test_vstribr_p:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstribr. v2, v2
; CHECK-NEXT: setbc r3, 4*cr6+eq
; CHECK-NEXT: blr
entry:
%tmp = tail call i32 @llvm.ppc.altivec.vstribr.p(i32 1, <16 x i8> %a)
ret i32 %tmp
}

define i32 @test_vstribl_p(<16 x i8> %a) {
; CHECK-LABEL: test_vstribl_p:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstribl. v2, v2
; CHECK-NEXT: setbc r3, 4*cr6+eq
; CHECK-NEXT: blr
entry:
%tmp = tail call i32 @llvm.ppc.altivec.vstribl.p(i32 1, <16 x i8> %a)
ret i32 %tmp
}

define i32 @test_vstrihr_p(<8 x i16> %a) {
; CHECK-LABEL: test_vstrihr_p:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstrihr. v2, v2
; CHECK-NEXT: setbc r3, 4*cr6+eq
; CHECK-NEXT: blr
entry:
%tmp = tail call i32 @llvm.ppc.altivec.vstrihr.p(i32 1, <8 x i16> %a)
ret i32 %tmp
}

define i32 @test_vstrihl_p(<8 x i16> %a) {
; CHECK-LABEL: test_vstrihl_p:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vstrihl. v2, v2
; CHECK-NEXT: setbc r3, 4*cr6+eq
; CHECK-NEXT: blr
entry:
%tmp = tail call i32 @llvm.ppc.altivec.vstrihl.p(i32 1, <8 x i16> %a)
ret i32 %tmp
}
23 changes: 23 additions & 0 deletions llvm/test/CodeGen/PowerPC/p10-vector-divide.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
; This test case aims to test the vector divide instructions on Power10.
; This includes the low order and extended versions of vector divide,
; that operate on signed and unsigned words and doublewords.
; This also includes 128 bit vector divide instructions.

define <2 x i64> @test_vdivud(<2 x i64> %a, <2 x i64> %b) {
; CHECK-LABEL: test_vdivud:
Expand Down Expand Up @@ -113,3 +114,25 @@ entry:
%div = tail call <2 x i64> @llvm.ppc.altivec.vdiveud(<2 x i64> %a, <2 x i64> %b)
ret <2 x i64> %div
}

declare <1 x i128> @llvm.ppc.altivec.vdivesq(<1 x i128>, <1 x i128>) nounwind readnone
declare <1 x i128> @llvm.ppc.altivec.vdiveuq(<1 x i128>, <1 x i128>) nounwind readnone

define <1 x i128> @test_vdivesq(<1 x i128> %x, <1 x i128> %y) nounwind readnone {
; CHECK-LABEL: test_vdivesq:
; CHECK: # %bb.0:
; CHECK-NEXT: vdivesq v2, v2, v3
; CHECK-NEXT: blr
%tmp = tail call <1 x i128> @llvm.ppc.altivec.vdivesq(<1 x i128> %x, <1 x i128> %y)
ret <1 x i128> %tmp
}


define <1 x i128> @test_vdiveuq(<1 x i128> %x, <1 x i128> %y) nounwind readnone {
; CHECK-LABEL: test_vdiveuq:
; CHECK: # %bb.0:
; CHECK-NEXT: vdiveuq v2, v2, v3
; CHECK-NEXT: blr
%tmp = call <1 x i128> @llvm.ppc.altivec.vdiveuq(<1 x i128> %x, <1 x i128> %y)
ret <1 x i128> %tmp
}