Skip to content

Commit

Permalink
[RISCV][Clang] Support policy functions for vneg, vnot, vncvt, vwcvt,
Browse files Browse the repository at this point in the history
vwcvtu, vfabs and vfneg.

We will switch all UndefValue to PoisonValue in follow up patches.

Reviewed By: kito-cheng

Differential Revision: https://reviews.llvm.org/D126744
  • Loading branch information
zakk0610 committed Aug 2, 2022
1 parent d884eb2 commit b1b22b4
Show file tree
Hide file tree
Showing 13 changed files with 1,155 additions and 180 deletions.
131 changes: 71 additions & 60 deletions clang/include/clang/Basic/riscv_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -1282,27 +1282,28 @@ multiclass RVVPseudoUnaryBuiltin<string IR, string type_range> {
let Name = NAME,
IRName = IR,
MaskedIRName = IR # "_mask",
UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
// op1, vl
IntrinsicTypes = {ResultType,
cast<llvm::VectorType>(ResultType)->getElementType(),
Ops[1]->getType()};
Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[1]));
// insert undef passthru
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
if (DefaultPolicy == TAIL_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
// passthru, op1, op2, vl
IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
break;
}
}],
MaskedManualCodegen = [{
{
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), TAIL_UNDISTURBED));
// maskedoff, op1, mask, vl
IntrinsicTypes = {ResultType,
cast<llvm::VectorType>(ResultType)->getElementType(),
Ops[3]->getType()};
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[1]));
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, op2, mask, vl, policy
IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
break;
}
}] in {
Expand All @@ -1314,29 +1315,34 @@ multiclass RVVPseudoVNotBuiltin<string IR, string type_range> {
let Name = NAME,
IRName = IR,
MaskedIRName = IR # "_mask",
UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
// op1, vl
if (DefaultPolicy == TAIL_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2,
llvm::Constant::getAllOnesValue(ElemTy));
// passthru, op1, op2, vl
IntrinsicTypes = {ResultType,
cast<llvm::VectorType>(ResultType)->getElementType(),
Ops[1]->getType()};
Ops.insert(Ops.begin() + 1,
llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
// insert undef passthru
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
ElemTy,
Ops[3]->getType()};
break;
}
}],
MaskedManualCodegen = [{
{
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), TAIL_UNDISTURBED));
// maskedoff, op1, mask, vl
IntrinsicTypes = {ResultType,
cast<llvm::VectorType>(ResultType)->getElementType(),
Ops[3]->getType()};
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2,
llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
llvm::Constant::getAllOnesValue(ElemTy));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, po2, mask, vl, policy
IntrinsicTypes = {ResultType,
ElemTy,
Ops[4]->getType()};
break;
}
}] in {
Expand Down Expand Up @@ -1366,28 +1372,29 @@ multiclass RVVPseudoVFUnaryBuiltin<string IR, string type_range> {
let Name = NAME,
IRName = IR,
MaskedIRName = IR # "_mask",
UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
// op1, vl
IntrinsicTypes = {ResultType,
Ops[0]->getType(), Ops[1]->getType()};
Ops.insert(Ops.begin() + 1, Ops[0]);
if (DefaultPolicy == TAIL_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
// op1, po2, vl
IntrinsicTypes = {ResultType,
Ops[1]->getType(), Ops[2]->getType()};
Ops.insert(Ops.begin() + 2, Ops[1]);
break;
}
}],
MaskedManualCodegen = [{
{
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, mask, vl
IntrinsicTypes = {ResultType,
Ops[1]->getType(),
Ops[3]->getType()};
Ops.insert(Ops.begin() + 2, Ops[1]);
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
Ops.insert(Ops.begin() + 2, Ops[1]);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, op2, mask, vl
IntrinsicTypes = {ResultType,
Ops[2]->getType(),
Ops.back()->getType()};
break;
}
}] in {
Expand All @@ -1401,31 +1408,34 @@ multiclass RVVPseudoVWCVTBuiltin<string IR, string MName, string type_range,
OverloadedName = MName,
IRName = IR,
MaskedIRName = IR # "_mask",
UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
// op1, vl
IntrinsicTypes = {ResultType,
Ops[0]->getType(),
cast<llvm::VectorType>(Ops[0]->getType())->getElementType(),
Ops[1]->getType()};
Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
if (DefaultPolicy == TAIL_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
// passtru, op1, op2, vl
IntrinsicTypes = {ResultType,
Ops[1]->getType(),
ElemTy,
Ops[3]->getType()};
break;
}
}],
MaskedManualCodegen = [{
{
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, mask, vl
// maskedoff, op1, op2, mask, vl, policy
IntrinsicTypes = {ResultType,
Ops[1]->getType(),
cast<llvm::VectorType>(Ops[1]->getType())->getElementType(),
Ops[3]->getType()};
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
ElemTy,
Ops[4]->getType()};
break;
}
}] in {
Expand All @@ -1441,31 +1451,32 @@ multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range,
OverloadedName = MName,
IRName = IR,
MaskedIRName = IR # "_mask",
UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
// op1, vl
IntrinsicTypes = {ResultType,
Ops[0]->getType(),
Ops[1]->getType(),
Ops[1]->getType()};
Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
if (DefaultPolicy == TAIL_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(Ops.back()->getType()));
// passthru, op1, xlen, vl
IntrinsicTypes = {ResultType,
Ops[1]->getType(),
Ops[3]->getType(),
Ops[3]->getType()};
break;
}
}],
MaskedManualCodegen = [{
{
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(Ops.back()->getType()));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), DefaultPolicy));
// maskedoff, op1, mask, vl
// maskedoff, op1, xlen, mask, vl
IntrinsicTypes = {ResultType,
Ops[1]->getType(),
Ops[3]->getType(),
Ops[3]->getType()};
Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
if (DefaultPolicy == TAIL_AGNOSTIC_MASK_AGNOSTIC)
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
Ops[4]->getType(),
Ops[4]->getType()};
break;
}
}] in {
Expand Down
53 changes: 53 additions & 0 deletions clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vfabs.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,56 @@ vfloat64m8_t test_vfabs_v_f64m8_m (vbool8_t mask, vfloat64m8_t maskedoff, vfloat
return vfabs(mask, maskedoff, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_tu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], i64 [[VL:%.*]])
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_tu(vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfabs_tu(merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_ta(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.nxv1f32.nxv1f32.i64(<vscale x 1 x float> undef, <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], i64 [[VL:%.*]])
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_ta(vfloat32mf2_t op1, size_t vl) {
return vfabs_ta(op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_tuma(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 2)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_tuma(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfabs_tuma(mask, merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_tumu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 0)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfabs_tumu(mask, merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_tama(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> undef, <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_tama(vbool64_t mask, vfloat32mf2_t op1, size_t vl) {
return vfabs_tama(mask, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfabs_v_f32mf2_tamu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjx.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfabs_v_f32mf2_tamu(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfabs_tamu(mask, merge, op1, vl);
}
53 changes: 53 additions & 0 deletions clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vfneg.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,56 @@ vfloat64m8_t test_vfneg_v_f64m8_m (vbool8_t mask, vfloat64m8_t maskedoff, vfloat
return vfneg(mask, maskedoff, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_tu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], i64 [[VL:%.*]])
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_tu(vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfneg_tu(merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_ta(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.nxv1f32.nxv1f32.i64(<vscale x 1 x float> undef, <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], i64 [[VL:%.*]])
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_ta(vfloat32mf2_t op1, size_t vl) {
return vfneg_ta(op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_tuma(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 2)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_tuma(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfneg_tuma(mask, merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_tumu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 0)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_tumu(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfneg_tumu(mask, merge, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_tama(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> undef, <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_tama(vbool64_t mask, vfloat32mf2_t op1, size_t vl) {
return vfneg_tama(mask, op1, vl);
}

// CHECK-RV64-LABEL: @test_vfneg_v_f32mf2_tamu(
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x float> @llvm.riscv.vfsgnjn.mask.nxv1f32.nxv1f32.i64(<vscale x 1 x float> [[MERGE:%.*]], <vscale x 1 x float> [[OP1:%.*]], <vscale x 1 x float> [[OP1]], <vscale x 1 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
// CHECK-RV64-NEXT: ret <vscale x 1 x float> [[TMP0]]
//
vfloat32mf2_t test_vfneg_v_f32mf2_tamu(vbool64_t mask, vfloat32mf2_t merge, vfloat32mf2_t op1, size_t vl) {
return vfneg_tamu(mask, merge, op1, vl);
}
Loading

0 comments on commit b1b22b4

Please sign in to comment.