================
@@ -20,6 +20,958 @@ using namespace clang;
 using namespace CodeGen;
 using namespace llvm;
 
+// The 0th bit simulates the `vta` of RVV
+// The 1st bit simulates the `vma` of RVV
+static constexpr unsigned RVV_VTA = 0x1;
+static constexpr unsigned RVV_VMA = 0x2;
+
+// RISC-V Vector builtin helper functions are marked NOINLINE to prevent
+// excessive inlining in CodeGenFunction::EmitRISCVBuiltinExpr's large switch
+// statement, which would significantly increase compilation time.
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVVLEFFBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                    ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                    Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                    int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    // Move mask to right before vl.
+    std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+    if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+    Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+    IntrinsicTypes = {ResultType, Ops[4]->getType(), Ops[2]->getType()};
+  } else {
+    if (PolicyAttrs & RVV_VTA)
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+    IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[1]->getType()};
+  }
+  Value *NewVL = Ops[2];
+  Ops.erase(Ops.begin() + 2);
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
+  llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
+  // Store new_vl.
+  clang::CharUnits Align;
+  if (IsMasked)
+    Align = CGM.getNaturalPointeeTypeAlignment(
+        E->getArg(E->getNumArgs() - 2)->getType());
+  else
+    Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(1)->getType());
+  llvm::Value *Val = Builder.CreateExtractValue(LoadValue, {1});
+  Builder.CreateStore(Val, Address(NewVL, Val->getType(), Align));
+  return V;
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVVSSEBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                   ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                   Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                   int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    // Builtin: (mask, ptr, stride, value, vl). Intrinsic: (value, ptr, stride,
+    // mask, vl)
+    std::swap(Ops[0], Ops[3]);
+  } else {
+    // Builtin: (ptr, stride, value, vl). Intrinsic: (value, ptr, stride, vl)
+    std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
+  }
+  if (IsMasked)
+    IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType()};
+  else
+    IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *emitRVVIndexedStoreBuiltin(
+    CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue,
+    llvm::Type *ResultType, Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+    int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    // Builtin: (mask, ptr, index, value, vl).
+    // Intrinsic: (value, ptr, index, mask, vl)
+    std::swap(Ops[0], Ops[3]);
+  } else {
+    // Builtin: (ptr, index, value, vl).
+    // Intrinsic: (value, ptr, index, vl)
+    std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
+  }
+  if (IsMasked)
+    IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
+                      Ops[4]->getType()};
+  else
+    IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
+                      Ops[3]->getType()};
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVPseudoUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                          ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                          Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                          int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) 
{
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+    if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+  } else {
+    if (PolicyAttrs & RVV_VTA)
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+  }
+  auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
+  Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
+  if (IsMasked) {
+    Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+    // maskedoff, op1, op2, mask, vl, policy
+    IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
+  } else {
+    // passthru, op1, op2, vl
+    IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
+  }
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVPseudoVNotBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                         ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                         Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                         int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+    if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+  } else {
+    if (PolicyAttrs & RVV_VTA)
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+  }
+  auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
+  Ops.insert(Ops.begin() + 2, llvm::Constant::getAllOnesValue(ElemTy));
+  if (IsMasked) {
+    Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+    // maskedoff, op1, po2, mask, vl, policy
+    IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
+  } else {
+    // passthru, op1, op2, vl
+    IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
+  }
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVPseudoMaskBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                         ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                         Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                         int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  // op1, vl
+  IntrinsicTypes = {ResultType, Ops[1]->getType()};
+  Ops.insert(Ops.begin() + 1, Ops[0]);
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *emitRVVPseudoVFUnaryBuiltin(
+    CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue,
+    llvm::Type *ResultType, Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+    int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
+  if (IsMasked) {
+    std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+    if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+    Ops.insert(Ops.begin() + 2, Ops[1]);
+    Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+    // maskedoff, op1, op2, mask, vl
+    IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};
+  } else {
+    if (PolicyAttrs & RVV_VTA)
+      Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+    // op1, po2, vl
+    IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
+    Ops.insert(Ops.begin() + 2, Ops[1]);
+  }
+  llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+  return Builder.CreateCall(F, Ops, "");
+}
+
+static LLVM_ATTRIBUTE_NOINLINE Value *
+emitRVVPseudoVWCVTBuiltin(CodeGenFunction *CGF, const CallExpr *E,
+                          ReturnValueSlot ReturnValue, llvm::Type *ResultType,
+                          Intrinsic::ID ID, SmallVector<Value *, 4> Ops,
+                          int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) 
{
+  auto &Builder = CGF->Builder;
+  auto &CGM = CGF->CGM;
+  llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
----------------
topperc wrote:

2 -> 4

https://github.com/llvm/llvm-project/pull/154906
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to