[llvm] [mlir] [mlir][x86vector] Simplify intrinsic generation (PR #133692)

Andrzej Warzyński via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 09:25:42 PDT 2025


================
@@ -19,47 +18,53 @@
 using namespace mlir;
 using namespace mlir::x86vector;
 
-/// Extracts the "main" vector element type from the given X86Vector operation.
-template <typename OpTy>
-static Type getSrcVectorElementType(OpTy op) {
-  return cast<VectorType>(op.getSrc().getType()).getElementType();
-}
-template <>
-Type getSrcVectorElementType(Vp2IntersectOp op) {
-  return cast<VectorType>(op.getA().getType()).getElementType();
-}
-
 namespace {
 
-/// Base conversion for AVX512 ops that can be lowered to one of the two
-/// intrinsics based on the bitwidth of their "main" vector element type. This
-/// relies on the to-LLVM-dialect conversion helpers to correctly pack the
-/// results of multi-result intrinsic ops.
-template <typename OpTy, typename Intr32OpTy, typename Intr64OpTy>
-struct LowerToIntrinsic : public OpConversionPattern<OpTy> {
-  explicit LowerToIntrinsic(const LLVMTypeConverter &converter)
-      : OpConversionPattern<OpTy>(converter, &converter.getContext()) {}
-
-  const LLVMTypeConverter &getTypeConverter() const {
-    return *static_cast<const LLVMTypeConverter *>(
-        OpConversionPattern<OpTy>::getTypeConverter());
+// Replaces an operation with a call to an LLVM intrinsic.
+LogicalResult intrinsicRewrite(Operation *op, StringAttr intrinsic,
+                               ValueRange operands,
+                               const LLVMTypeConverter &typeConverter,
+                               ConversionPatternRewriter &rewriter) {
+  auto loc = op->getLoc();
+
+  unsigned numResults = op->getNumResults();
+  Type resType;
+  if (numResults != 0)
+    resType = typeConverter.packOperationResults(op->getResultTypes());
+
+  auto callIntrOp =
+      rewriter.create<LLVM::CallIntrinsicOp>(loc, resType, intrinsic, operands);
+  // Propagate attributes.
+  callIntrOp->setAttrs(op->getAttrDictionary());
+
+  if (numResults <= 1) {
+    // Directly replace the original op.
+    rewriter.replaceOp(op, callIntrOp);
+  } else {
+    // Extract individual results from packed structure and use them as
+    // replacements.
+    SmallVector<Value, 4> results;
+    results.reserve(numResults);
+    Value intrRes = callIntrOp.getResults();
+    for (unsigned i = 0; i < numResults; ++i) {
+      results.push_back(rewriter.create<LLVM::ExtractValueOp>(loc, intrRes, i));
+    }
+    rewriter.replaceOp(op, results);
----------------
banach-space wrote:

[nit] This way you can avoid extra indentation (it would also be closer to https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code)
```suggestion
  if (numResults <= 1) {
    // Directly replace the original op.
    rewriter.replaceOp(op, callIntrOp);
    return success();
  }
  
    // Extract individual results from packed structure and use them as
    // replacements.
    SmallVector<Value, 4> results;
    results.reserve(numResults);
    Value intrRes = callIntrOp.getResults();
    for (unsigned i = 0; i < numResults; ++i) {
      results.push_back(rewriter.create<LLVM::ExtractValueOp>(loc, intrRes, i));
    
    rewriter.replaceOp(op, results);
```

I appreciate that this is, to a large extent, a matter of personal preference 😅 

https://github.com/llvm/llvm-project/pull/133692


More information about the llvm-commits mailing list