[PATCH] D112534: [PoC][RISCV] Use an attribute to declare C intrinsics with different policy.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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