HsiangKai updated this revision to Diff 382529.
HsiangKai added a comment.

Address @craig.topper's comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112534/new/

https://reviews.llvm.org/D112534

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-policy.c
  clang/utils/TableGen/RISCVVEmitter.cpp

Index: clang/utils/TableGen/RISCVVEmitter.cpp
===================================================================
--- clang/utils/TableGen/RISCVVEmitter.cpp
+++ clang/utils/TableGen/RISCVVEmitter.cpp
@@ -204,6 +204,10 @@
   // Emit the macros for mapping C/C++ intrinsic function to builtin functions.
   void emitIntrinsicFuncDef(raw_ostream &o) const;
 
+  // Emit the declarations for mapping C/C++ intrinsic function to builtin
+  // functions.
+  void emitIntrinsicWithPolicyFuncDef(raw_ostream &o) const;
+
   // Emit the mangled function definition.
   void emitMangledFuncDef(raw_ostream &o) const;
 };
@@ -835,9 +839,10 @@
   if (isMask()) {
     if (hasVL()) {
       OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);\n";
-      if (hasPolicy())
-        OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(),"
-                               " TAIL_UNDISTURBED));\n";
+      if (hasPolicy()) {
+        OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(), "
+              "PolicyValue));\n";
+      }
     } else {
       OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());\n";
     }
@@ -865,12 +870,32 @@
   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
   OS << OutputType->getTypeStr() << " " << getName() << "(";
   // Emit function arguments
-  if (!InputTypes.empty()) {
+  ListSeparator LS;
+  for (unsigned i = 0; i < InputTypes.size(); ++i)
+    OS << LS << InputTypes[i]->getTypeStr();
+  OS << ");\n";
+}
+
+void RVVIntrinsic::emitIntrinsicWithPolicyFuncDef(raw_ostream &OS) const {
+  if (!isMask())
+    return;
+
+  const char *policySuffix[] = {"tumu", "tamu", "tuma", "tama"};
+
+  for (unsigned i = 0; i < 4; ++i) {
+    OS << "__rvv_ai ";
+    OS << "__attribute__((__clang_builtin_alias__(";
+    OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
+    OS << "__attribute__((rvv_policy(" << policySuffix[i] << ")))\n";
+    StringRef IntrinsicName = getName().substr(0, getName().size() - 2);
+    OS << OutputType->getTypeStr() << " " << IntrinsicName << "_"
+       << policySuffix[i] << "(";
+    // Emit function arguments
     ListSeparator LS;
     for (unsigned i = 0; i < InputTypes.size(); ++i)
       OS << LS << InputTypes[i]->getTypeStr();
+    OS << ");\n";
   }
-  OS << ");\n";
 }
 
 void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
@@ -878,11 +903,9 @@
   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
   OS << OutputType->getTypeStr() << " " << getMangledName() << "(";
   // Emit function arguments
-  if (!InputTypes.empty()) {
-    ListSeparator LS;
-    for (unsigned i = 0; i < InputTypes.size(); ++i)
-      OS << LS << InputTypes[i]->getTypeStr();
-  }
+  ListSeparator LS;
+  for (unsigned i = 0; i < InputTypes.size(); ++i)
+    OS << LS << InputTypes[i]->getTypeStr();
   OS << ");\n";
 }
 
@@ -989,6 +1012,10 @@
     Inst.emitIntrinsicFuncDef(OS);
   });
 
+  emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
+    Inst.emitIntrinsicWithPolicyFuncDef(OS);
+  });
+
   OS << "#undef __rvv_ai\n\n";
 
   OS << "#define __riscv_v_intrinsic_overloading 1\n";
Index: clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-policy.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-policy.c
@@ -0,0 +1,42 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \
+// RUN:   -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
+
+#include <riscv_vector.h>
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tama(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[MASKEDOFF:%.*]], <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
+// CHECK-RV64-NEXT:    ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_vadd_vv_i8m1_tama(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) {
+  return vadd_vv_i8m1_tama(mask, maskedoff, op1, op2, vl);
+}
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tamu(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[MASKEDOFF:%.*]], <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
+// CHECK-RV64-NEXT:    ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_vadd_vv_i8m1_tamu(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) {
+  return vadd_vv_i8m1_tamu(mask, maskedoff, op1, op2, vl);
+}
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tuma(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[MASKEDOFF:%.*]], <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 2)
+// CHECK-RV64-NEXT:    ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_vadd_vv_i8m1_tuma(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) {
+  return vadd_vv_i8m1_tuma(mask, maskedoff, op1, op2, vl);
+}
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tumu(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[MASKEDOFF:%.*]], <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 [[VL:%.*]], i64 0)
+// CHECK-RV64-NEXT:    ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_vadd_vv_i8m1_tumu(vbool8_t mask, vint8m1_t maskedoff, vint8m1_t op1, vint8m1_t op2, size_t vl) {
+  return vadd_vv_i8m1_tumu(mask, maskedoff, op1, op2, vl);
+}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5369,6 +5369,23 @@
   D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
 }
 
+static void handleRISCVVPolicyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!AL.isArgIdent(0)) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
+        << AL << 0 << AANT_ArgumentIdentifier;
+    return;
+  }
+
+  RISCVVPolicyAttr::PolicyType Policy;
+  IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
+  if (!RISCVVPolicyAttr::ConvertStrToPolicyType(II->getName(), Policy)) {
+    S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) RISCVVPolicyAttr(S.Context, AL, Policy));
+}
+
 //===----------------------------------------------------------------------===//
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -8520,6 +8537,10 @@
   case ParsedAttr::AT_UsingIfExists:
     handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
     break;
+
+  case ParsedAttr::AT_RISCVVPolicy:
+    handleRISCVVPolicyAttr(S, D, AL);
+    break;
   }
 }
 
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -18608,6 +18608,26 @@
   Intrinsic::ID ID = Intrinsic::not_intrinsic;
   unsigned NF = 1;
   constexpr unsigned TAIL_UNDISTURBED = 0;
+  constexpr unsigned TAIL_AGNOSTIC = 0b01;
+  constexpr unsigned MASK_AGNOSTIC = 0b10;
+  auto *PolicyAttr = E->getCalleeDecl()->getAttr<RISCVVPolicyAttr>();
+  uint64_t PolicyValue = 0;
+
+  if (PolicyAttr) {
+    switch (PolicyAttr->getPolicy()) {
+    default:
+      break;
+    case RISCVVPolicyAttr::TAMU:
+      PolicyValue = TAIL_AGNOSTIC;
+      break;
+    case RISCVVPolicyAttr::TUMA:
+      PolicyValue = MASK_AGNOSTIC;
+      break;
+    case RISCVVPolicyAttr::TAMA:
+      PolicyValue = MASK_AGNOSTIC | TAIL_AGNOSTIC;
+      break;
+    }
+  }
 
   // Required for overloaded intrinsics.
   llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -2143,6 +2143,19 @@
   }];
 }
 
+def RISCVVPolicyDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "RISC-V vector tail/mask policy";
+  let Content = [{
+Users could use the attribute to specify the policy of destination tail and
+destination inactive masked-off elements in the vector operations. There are
+two kinds of policies described in the vector specification. One is undisturbed.
+It will retain the value they previously held. Another is agnostic. It will
+retain the value they previously held or are overwritten with 1s. It is intended
+for use only inside ``riscv_*.h``.
+  }];
+}
+
 def AVRInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (AVR)";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1783,6 +1783,15 @@
   let Documentation = [RISCVInterruptDocs];
 }
 
+def RISCVVPolicy : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
+  let Spellings = [Clang<"rvv_policy">];
+  let Subjects = SubjectList<[Function]>;
+  let Args = [EnumArgument<"Policy", "PolicyType",
+              ["tumu", "tamu", "tuma", "tama"],
+              ["TUMU", "TAMU", "TUMA", "TAMA"]>];
+  let Documentation = [RISCVVPolicyDocs];
+}
+
 // This is not a TargetSpecificAttr so that is silently accepted and
 // ignored on other targets as encouraged by the OpenCL spec.
 //
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to