[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-19 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai updated this revision to Diff 395365.
HsiangKai added a comment.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

In riscv-insert-vsetvli, use the policy argument. No use implicit-def maskedoff 
to adjust the setting.


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/include/clang/Basic/riscv_vector.td
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-policy.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/utils/TableGen/RISCVVEmitter.cpp
  llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Index: llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
===
--- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -401,49 +401,18 @@
 INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME,
 false, false)
 
-static MachineInstr *elideCopies(MachineInstr *MI,
- const MachineRegisterInfo *MRI) {
-  while (true) {
-if (!MI->isFullCopy())
-  return MI;
-if (!Register::isVirtualRegister(MI->getOperand(1).getReg()))
-  return nullptr;
-MI = MRI->getVRegDef(MI->getOperand(1).getReg());
-if (!MI)
-  return nullptr;
-  }
-}
-
 static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
const MachineRegisterInfo *MRI) {
   VSETVLIInfo InstrInfo;
   unsigned NumOperands = MI.getNumExplicitOperands();
   bool HasPolicy = RISCVII::hasVecPolicyOp(TSFlags);
-
-  // Default to tail agnostic unless the destination is tied to a source.
-  // Unless the source is undef. In that case the user would have some control
-  // over the tail values. Some pseudo instructions force a tail agnostic policy
-  // despite having a tied def.
-  bool ForceTailAgnostic = RISCVII::doesForceTailAgnostic(TSFlags);
   bool TailAgnostic = true;
+  bool MaskAgnostic = false;
   // If the instruction has policy argument, use the argument.
   if (HasPolicy) {
 const MachineOperand &Op = MI.getOperand(MI.getNumExplicitOperands() - 1);
 TailAgnostic = Op.getImm() & 0x1;
-  }
-
-  unsigned UseOpIdx;
-  if (!(ForceTailAgnostic || (HasPolicy && TailAgnostic)) &&
-  MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
-TailAgnostic = false;
-// If the tied operand is an IMPLICIT_DEF we can keep TailAgnostic.
-const MachineOperand &UseMO = MI.getOperand(UseOpIdx);
-MachineInstr *UseMI = MRI->getVRegDef(UseMO.getReg());
-if (UseMI) {
-  UseMI = elideCopies(UseMI, MRI);
-  if (UseMI && UseMI->isImplicitDef())
-TailAgnostic = true;
-}
+MaskAgnostic = Op.getImm() & 0x2;
   }
 
   // Remove the tail policy so we can find the SEW and VL.
@@ -476,8 +445,8 @@
 }
   } else
 InstrInfo.setAVLReg(RISCV::NoRegister);
-  InstrInfo.setVTYPE(VLMul, SEW, /*TailAgnostic*/ TailAgnostic,
- /*MaskAgnostic*/ false, MaskRegOp, StoreOp);
+  InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, MaskRegOp,
+ StoreOp);
 
   return InstrInfo;
 }
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;
+
+  static const char *cons

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-16 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai updated this revision to Diff 394782.
HsiangKai added a comment.
Herald added a subscriber: jdoerfert.

Update attribute test cases.


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/include/clang/Basic/riscv_vector.td
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-policy.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  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;
+
+  static const char *const PolicySuffix[] = {"tumu", "tamu", "tuma", "tama"};
+
+  for (auto Suffix : PolicySuffix) {
+OS << "__rvv_ai ";
+OS << "__attribute__((__clang_builtin_alias__(";
+OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
+OS << "__attribute__((rvv_policy(" << Suffix << ")))\n";
+StringRef IntrinsicName = getName().substr(0, getName().size() - 2);
+OS << OutputType->getTypeStr() << " " << IntrinsicName << "_" << Suffix
+   << "(";
+// 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/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -148,6 +148,7 @@
 // CHECK-NEXT: PassObjectSize (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: PatchableFunctionEntry (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: Pointer (SubjectMatchRule_record_not_is_union)
+// CHECK-NEXT: RISCVVPolicy (SubjectMatchRule_function)
 // CHECK-NEXT: ReleaseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: RenderScriptKernel (SubjectMatchRule_function)
 // CHECK-NEXT: ReqdWorkGroupSize (SubjectMatchRule_function)
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:   

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-16 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai updated this revision to Diff 394766.
HsiangKai added a comment.

Fix build errors.


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/include/clang/Basic/riscv_vector.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;
+
+  static const char *const PolicySuffix[] = {"tumu", "tamu", "tuma", "tama"};
+
+  for (auto Suffix : PolicySuffix) {
+OS << "__rvv_ai ";
+OS << "__attribute__((__clang_builtin_alias__(";
+OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
+OS << "__attribute__((rvv_policy(" << Suffix << ")))\n";
+StringRef IntrinsicName = getName().substr(0, getName().size() - 2);
+OS << OutputType->getTypeStr() << " " << IntrinsicName << "_" << Suffix
+   << "(";
+// 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 
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tama(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:[[TMP0:%.*]] = call  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
+// CHECK-RV64-NEXT:ret  [[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  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
+// CHECK-RV64-NEXT:ret  [[TMP

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-15 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai updated this revision to Diff 394751.
HsiangKai added a comment.

Address @craig.topper and @frasercrmck'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/include/clang/Basic/riscv_vector.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;
+
+  static const char *const PolicySuffix[] = {"tumu", "tamu", "tuma", "tama"};
+
+  for (auto Suffix : PolicySuffix) {
+OS << "__rvv_ai ";
+OS << "__attribute__((__clang_builtin_alias__(";
+OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
+OS << "__attribute__((rvv_policy(" << Suffix << ")))\n";
+StringRef IntrinsicName = getName().substr(0, getName().size() - 2);
+OS << OutputType->getTypeStr() << " " << IntrinsicName << "_" << Suffix
+   << "(";
+// 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 
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tama(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:[[TMP0:%.*]] = call  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
+// CHECK-RV64-NEXT:ret  [[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  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
+

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-15 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:18610
   unsigned NF = 1;
   constexpr unsigned TAIL_UNDISTURBED = 0;
+  constexpr unsigned TAIL_AGNOSTIC = 0b01;

HsiangKai wrote:
> craig.topper wrote:
> > Is constant still used?
> Yes, it is still used in `ManualCodegenMask` in 
> `clang/include/clang/Basic/riscv_vector.td`.
Sorry, after reviewing these usage, I think I could remove it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-12-15 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai added inline comments.
Herald added subscribers: VincentWu, luke957.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:18610
   unsigned NF = 1;
   constexpr unsigned TAIL_UNDISTURBED = 0;
+  constexpr unsigned TAIL_AGNOSTIC = 0b01;

craig.topper wrote:
> Is constant still used?
Yes, it is still used in `ManualCodegenMask` in 
`clang/include/clang/Basic/riscv_vector.td`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-28 Thread Luke via Phabricator via cfe-commits
luke957 resigned from this revision.
luke957 added a comment.

So sorry for my bad herald script.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-28 Thread Fraser Cormack via Phabricator via cfe-commits
frasercrmck added a comment.
Herald added a reviewer: luke957.

Just nits from me at this stage.




Comment at: clang/include/clang/Basic/AttrDocs.td:2150
+  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

Nit, but the use of `could` seems out of place in this documentation. Is `can` 
or `may` perhaps more common?



Comment at: clang/utils/TableGen/RISCVVEmitter.cpp:895
 ListSeparator LS;
 for (unsigned i = 0; i < InputTypes.size(); ++i)
   OS << LS << InputTypes[i]->getTypeStr();

This variable `i` shadowing the outer loop's induction variable is a little 
odd. Perhaps the outer loop could use a range-based for?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-27 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added a comment.

I think the concept seems good to me. I'd like @aaron.ballman to review the 
attribute code.




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:18610
   unsigned NF = 1;
   constexpr unsigned TAIL_UNDISTURBED = 0;
+  constexpr unsigned TAIL_AGNOSTIC = 0b01;

Is constant still used?



Comment at: clang/utils/TableGen/RISCVVEmitter.cpp:883
+
+  const char *policySuffix[] = {"tumu", "tamu", "tuma", "tama"};
+

Capitalize `policySuffix` and make it

`static const char *const PolicySuffix[]`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-26 Thread Hsiangkai Wang via Phabricator via cfe-commits
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 
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tama(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:[[TMP0:%.*]] = call  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
+// CHECK-RV64-NEXT:ret  [[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  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 1)
+// CHECK-RV64-NEXT:ret  [[TMP0]]
+//
+vint8m1_t test

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-26 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:18614
+  auto *PolicyAttr = E->getCalleeDecl()->getAttr();
+  size_t PolicyValue;
 

Why size_t? This would be the size_t of the host machine that's 
building/running the compiler and would have no connection to the architecture 
being targetted.



Comment at: clang/utils/TableGen/RISCVVEmitter.cpp:843
+  if (hasPolicy()) {
+OS << "  if (PolicyAttr) {\n";
+OS << "switch (PolicyAttr->getPolicy()) {\n";

Do we need to emit this switch for every builtin? Couldn't we assign 
`PolicyValue` before including the autogenerated file and only builtins that 
have a policy would add `PolicyValue` it to their `Ops` vector?



Comment at: clang/utils/TableGen/RISCVVEmitter.cpp:914
+// Emit function arguments
+if (!InputTypes.empty()) {
+  ListSeparator LS;

Does the `InputTypes.empty()` check provide any value. Looks like it just 
prevents constructing a `ListSeparator` that wouldn't be used, but I would 
think that's cheap to construct. I know this was copied from the function 
above, so my question applies there too.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-26 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai updated this revision to Diff 382298.
HsiangKai added a comment.

Remove redundant test case.


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,28 @@
   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 << "  if (PolicyAttr) {\n";
+OS << "switch (PolicyAttr->getPolicy()) {\n";
+OS << "default:\n";
+OS << "  PolicyValue = 0;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TAMU:\n";
+OS << "  PolicyValue = TAIL_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TUMA:\n";
+OS << "  PolicyValue = MASK_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TAMA:\n";
+OS << "  PolicyValue = MASK_AGNOSTIC | TAIL_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "}\n";
+OS << "  } else {\n";
+OS << "PolicyValue = 0;\n";
+OS << "  }\n";
+OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(), "
+  "PolicyValue));\n";
+  }
 } else {
   OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());\n";
 }
@@ -873,6 +896,30 @@
   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
+if (!InputTypes.empty()) {
+  ListSeparator LS;
+  for (unsigned i = 0; i < InputTypes.size(); ++i)
+OS << LS << InputTypes[i]->getTypeStr();
+}
+OS << ");\n";
+  }
+}
+
 void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
   OS << "__attribute__((__clang_builtin_alias__(";
   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
@@ -989,6 +1036,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 
+
+// CHECK-RV64-LABEL: @test_vadd_vv_i8m1_tama(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:[[TMP0:%.*]] = call  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  [[OP1:%.*]],  [[OP2:%.*]],  [[MASK:%.*]], i64 [[VL:%.*]], i64 3)
+// CHECK-RV64-NEXT:ret  [[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  @llvm.riscv.vadd.mask.nxv8i8.nxv8i8.i64( [[MASKEDOFF:%.*]],  

[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.

2021-10-26 Thread Hsiangkai Wang via Phabricator via cfe-commits
HsiangKai created this revision.
HsiangKai added reviewers: kito-cheng, craig.topper, frasercrmck, rogfer01.
Herald added subscribers: achieveartificialintelligence, StephenFan, vkmr, 
evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, 
jocewei, PkmX, the_o, brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, 
shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, asb.
Herald added a reviewer: aaron.ballman.
HsiangKai requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

This patch provides a proof-of-concept implementation of the proposal.
https://github.com/riscv-non-isa/rvv-intrinsic-doc/issues/120

In this patch, we create a new attribute rvv_policy to annotate C
intrinsics with its tail/inactive elements policy. The syntax is

__attribute__((rvv_policy(tama)))
vint32m1_t vadd_tama(...);

The possible policy is tama, tamu, tuma, tumu.
ta: tail agnostic
tu: tail undisturbed
ma: inactive masked-off agnostic
mu: inactive masked-off undisturbed

This attribute is used in riscv_vector.h.


Repository:
  rG LLVM Github Monorepo

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/test/CodeGen/RISCV/rvv-intrinsics/vadd-tu.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,28 @@
   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 << "  if (PolicyAttr) {\n";
+OS << "switch (PolicyAttr->getPolicy()) {\n";
+OS << "default:\n";
+OS << "  PolicyValue = 0;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TAMU:\n";
+OS << "  PolicyValue = TAIL_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TUMA:\n";
+OS << "  PolicyValue = MASK_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "case RISCVVPolicyAttr::TAMA:\n";
+OS << "  PolicyValue = MASK_AGNOSTIC | TAIL_AGNOSTIC;\n";
+OS << "  break;\n";
+OS << "}\n";
+OS << "  } else {\n";
+OS << "PolicyValue = 0;\n";
+OS << "  }\n";
+OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(), "
+  "PolicyValue));\n";
+  }
 } else {
   OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());\n";
 }
@@ -873,6 +896,30 @@
   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
+if (!InputTypes.empty()) {
+  ListSeparator LS;
+  for (unsigned i = 0; i < InputTypes.size(); ++i)
+OS << LS << InputTypes[i]->getTypeStr();
+}
+OS << ");\n";
+  }
+}
+
 void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
   OS << "__attribute__((__clang_builtin_alias__(";
   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
@@ -989,6 +1036,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-tu.c
===
--- /dev/null
+++ clang/test/CodeGen/RISCV/rvv-intrinsics/vadd-tu.c
@@ -0,0 +1,24 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc