https://github.com/el-ev updated 
https://github.com/llvm/llvm-project/pull/153387

>From 5fd1ca861731daf05ea57037602be0e015525b7b Mon Sep 17 00:00:00 2001
From: Iris Shi <0...@owo.li>
Date: Wed, 13 Aug 2025 18:49:31 +0800
Subject: [PATCH 1/2] [CIR] Add InlineAsmOp lowering to LLVM

---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 67 +++++++++++++++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 17 ++++
 clang/test/CIR/Lowering/inline-asm.cir        | 86 +++++++++++++++++++
 3 files changed, 170 insertions(+)
 create mode 100644 clang/test/CIR/Lowering/inline-asm.cir

diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 88a0fe2e1f848..4c05fd7622b48 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2263,6 +2263,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
   patterns.add<CIRToLLVMCastOpLowering>(converter, patterns.getContext(), dl);
   patterns.add<CIRToLLVMPtrStrideOpLowering>(converter, patterns.getContext(),
                                              dl);
+  patterns.add<CIRToLLVMInlineAsmOpLowering>(converter, patterns.getContext(),
+                                             dl);
   patterns.add<
       // clang-format off
                CIRToLLVMAssumeOpLowering,
@@ -2896,6 +2898,71 @@ mlir::LogicalResult 
CIRToLLVMGetBitfieldOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
+    cir::InlineAsmOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type llResTy;
+  if (op.getNumResults())
+    llResTy = getTypeConverter()->convertType(op.getType(0));
+
+  auto dialect = op.getAsmFlavor();
+  auto llDialect = dialect == cir::AsmFlavor::x86_att
+                       ? mlir::LLVM::AsmDialect::AD_ATT
+                       : mlir::LLVM::AsmDialect::AD_Intel;
+
+  SmallVector<mlir::Attribute> opAttrs;
+  auto llvmAttrName = mlir::LLVM::InlineAsmOp::getElementTypeAttrName();
+
+  // this is for the lowering to LLVM from LLVM dialect. Otherwise, if we
+  // don't have the result (i.e. void type as a result of operation), the
+  // element type attribute will be attached to the whole instruction, but not
+  // to the operand
+  if (!op.getNumResults())
+    opAttrs.push_back(mlir::Attribute());
+
+  SmallVector<mlir::Value> llvmOperands;
+  SmallVector<mlir::Value> cirOperands;
+  auto llvmAsmOps = adaptor.getAsmOperands();
+  auto cirAsmOps = op.getAsmOperands();
+  for (size_t i = 0; i < llvmAsmOps.size(); ++i) {
+    auto llvmOps = llvmAsmOps[i];
+    auto cirOps = cirAsmOps[i];
+    llvmOperands.append(llvmOps.begin(), llvmOps.end());
+    cirOperands.append(cirOps.begin(), cirOps.end());
+  }
+
+  // so far we infer the llvm dialect element type attr from
+  // CIR operand type.
+  auto cirOpAttrs = op.getOperandAttrs();
+  for (std::size_t i = 0; i < cirOpAttrs.size(); ++i) {
+    if (!cirOpAttrs[i]) {
+      opAttrs.push_back(mlir::Attribute());
+      continue;
+    }
+
+    SmallVector<mlir::NamedAttribute> attrs;
+    auto typ = cast<cir::PointerType>(cirOperands[i].getType());
+    auto typAttr = mlir::TypeAttr::get(convertTypeForMemory(
+        *getTypeConverter(), dataLayout, typ.getPointee()));
+
+    attrs.push_back(rewriter.getNamedAttr(llvmAttrName, typAttr));
+    auto newDict = rewriter.getDictionaryAttr(attrs);
+    opAttrs.push_back(newDict);
+  }
+
+  rewriter.replaceOpWithNewOp<mlir::LLVM::InlineAsmOp>(
+      op, llResTy, llvmOperands, op.getAsmStringAttr(), 
op.getConstraintsAttr(),
+      op.getSideEffectsAttr(),
+      /*is_align_stack*/ mlir::UnitAttr(),
+      /*tail_call_kind*/
+      mlir::LLVM::TailCallKindAttr::get(
+          getContext(), mlir::LLVM::tailcallkind::TailCallKind::None),
+      mlir::LLVM::AsmDialectAttr::get(getContext(), llDialect),
+      rewriter.getArrayAttr(opAttrs));
+
+  return mlir::success();
+}
+
 std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass() {
   return std::make_unique<ConvertCIRToLLVMPass>();
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 51b191af24692..3928fe72d160d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -648,6 +648,23 @@ class CIRToLLVMGetBitfieldOpLowering
                   mlir::ConversionPatternRewriter &) const override;
 };
 
+class CIRToLLVMInlineAsmOpLowering
+    : public mlir::OpConversionPattern<cir::InlineAsmOp> {
+  mlir::DataLayout const &dataLayout;
+
+public:
+  CIRToLLVMInlineAsmOpLowering(const mlir::TypeConverter &typeConverter,
+                               mlir::MLIRContext *context,
+                               mlir::DataLayout const &dataLayout)
+      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
+
+  using mlir::OpConversionPattern<cir::InlineAsmOp>::OpConversionPattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(cir::InlineAsmOp op, OpAdaptor,
+                  mlir::ConversionPatternRewriter &) const override;
+};
+
 } // namespace direct
 } // namespace cir
 
diff --git a/clang/test/CIR/Lowering/inline-asm.cir 
b/clang/test/CIR/Lowering/inline-asm.cir
new file mode 100644
index 0000000000000..a8545d4c0f059
--- /dev/null
+++ b/clang/test/CIR/Lowering/inline-asm.cir
@@ -0,0 +1,86 @@
+// RUN: cir-translate %s -cir-to-llvmir --target x86_64-unknown-linux-gnu 
--disable-cc-lowering  | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+!u32i = !cir.int<u, 32>
+
+module {
+cir.func @f1() {
+  // CHECK: call void asm "", "~{dirflag},~{fpsr},~{flags}"()
+  cir.asm(x86_att, 
+    out = [],
+    in = [],
+    in_out = [],
+    {"" "~{dirflag},~{fpsr},~{flags}"})
+  cir.return
+}
+
+cir.func @f2() {
+  // CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
+  cir.asm(x86_att, 
+    out = [],
+    in = [],
+    in_out = [],
+    {"" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+  cir.return
+}
+
+cir.func @f3() {
+  // CHECK: call void asm sideeffect "abc", "~{dirflag},~{fpsr},~{flags}"()
+  cir.asm(x86_att,
+    out = [],
+    in = [],
+    in_out = [],
+    {"abc" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+  cir.return
+}
+
+cir.func @f4(%arg0: !s32i) {
+  %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
+  cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i>
+  // CHECK: call void asm sideeffect "", "*m,~{dirflag},~{fpsr},~{flags}"(ptr 
elementtype(i32) %2)
+  cir.asm(x86_att, 
+    out = [],
+    in = [%0 : !cir.ptr<!s32i> (maybe_memory)],
+    in_out = [],
+    {"" "*m,~{dirflag},~{fpsr},~{flags}"}) side_effects
+  cir.return
+}
+
+cir.func @f5() {
+  // CHECK: call void asm inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
+  cir.asm(x86_intel, 
+    out = [],
+    in = [],
+    in_out = [],
+    {"" "~{dirflag},~{fpsr},~{flags}"})
+  cir.return
+}
+
+cir.func @f6() -> !s32i {
+  %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
+  // CHECK: %2 = call i32 asm sideeffect "movl $$42, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"()
+  %1 = cir.asm(x86_att, 
+    out = [],
+    in = [],
+    in_out = [],
+    {"movl $$42, $0" "=r,~{dirflag},~{fpsr},~{flags}"}) side_effects -> !s32i
+  cir.store align(4) %1, %0 : !s32i, !cir.ptr<!s32i>
+  %3 = cir.load align(4) %0 : !cir.ptr<!s32i>, !s32i
+  cir.return %3 : !s32i
+}
+
+cir.func @f7(%arg0: !u32i) -> !u32i {
+  %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["x", init] {alignment = 4 : i64}
+  cir.store %arg0, %0 : !u32i, !cir.ptr<!u32i>
+  %1 = cir.load align(4) %0 : !cir.ptr<!u32i>, !u32i
+  // CHECK: %4 = call i32 asm sideeffect "addl $$42, $0", 
"=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %3)
+  %2 = cir.asm(x86_att, 
+    out = [],
+    in = [],
+    in_out = [%1 : !u32i],
+    {"addl $$42, $0" "=r,0,~{dirflag},~{fpsr},~{flags}"}) side_effects -> !u32i
+   cir.store align(4) %2, %0 : !u32i, !cir.ptr<!u32i>
+   %3 = cir.load align(4) %0 : !cir.ptr<!u32i>, !u32i
+   cir.return %3 : !u32i
+}
+}

>From ecea64a52ae2b3fda605bfc123fd489e245d437a Mon Sep 17 00:00:00 2001
From: Iris Shi <0...@owo.li>
Date: Thu, 14 Aug 2025 11:35:17 +0800
Subject: [PATCH 2/2] Apply review suggestions

---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 33 +++++++++----------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4c05fd7622b48..db1f119b8c4de 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2905,13 +2905,13 @@ mlir::LogicalResult 
CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
   if (op.getNumResults())
     llResTy = getTypeConverter()->convertType(op.getType(0));
 
-  auto dialect = op.getAsmFlavor();
-  auto llDialect = dialect == cir::AsmFlavor::x86_att
-                       ? mlir::LLVM::AsmDialect::AD_ATT
-                       : mlir::LLVM::AsmDialect::AD_Intel;
+  cir::AsmFlavor dialect = op.getAsmFlavor();
+  mlir::LLVM::AsmDialect llDialect = dialect == cir::AsmFlavor::x86_att
+                                         ? mlir::LLVM::AsmDialect::AD_ATT
+                                         : mlir::LLVM::AsmDialect::AD_Intel;
 
   SmallVector<mlir::Attribute> opAttrs;
-  auto llvmAttrName = mlir::LLVM::InlineAsmOp::getElementTypeAttrName();
+  StringRef llvmAttrName = mlir::LLVM::InlineAsmOp::getElementTypeAttrName();
 
   // this is for the lowering to LLVM from LLVM dialect. Otherwise, if we
   // don't have the result (i.e. void type as a result of operation), the
@@ -2922,31 +2922,28 @@ mlir::LogicalResult 
CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
 
   SmallVector<mlir::Value> llvmOperands;
   SmallVector<mlir::Value> cirOperands;
-  auto llvmAsmOps = adaptor.getAsmOperands();
-  auto cirAsmOps = op.getAsmOperands();
-  for (size_t i = 0; i < llvmAsmOps.size(); ++i) {
-    auto llvmOps = llvmAsmOps[i];
-    auto cirOps = cirAsmOps[i];
-    llvmOperands.append(llvmOps.begin(), llvmOps.end());
-    cirOperands.append(cirOps.begin(), cirOps.end());
+  for (auto [llvmOp, cirOp] :
+       llvm::zip(adaptor.getAsmOperands(), op.getAsmOperands())) {
+    llvmOperands.append(llvmOp.begin(), llvmOp.end());
+    cirOperands.append(cirOp.begin(), cirOp.end());
   }
 
   // so far we infer the llvm dialect element type attr from
   // CIR operand type.
-  auto cirOpAttrs = op.getOperandAttrs();
-  for (std::size_t i = 0; i < cirOpAttrs.size(); ++i) {
-    if (!cirOpAttrs[i]) {
+  for (auto [i, cirOpAttr] : llvm::enumerate(op.getOperandAttrs())) {
+    if (!cirOpAttr) {
       opAttrs.push_back(mlir::Attribute());
       continue;
     }
 
     SmallVector<mlir::NamedAttribute> attrs;
-    auto typ = cast<cir::PointerType>(cirOperands[i].getType());
-    auto typAttr = mlir::TypeAttr::get(convertTypeForMemory(
+    cir::PointerType typ =
+        mlir::cast<cir::PointerType>(cirOperands[i].getType());
+    mlir::TypeAttr typAttr = mlir::TypeAttr::get(convertTypeForMemory(
         *getTypeConverter(), dataLayout, typ.getPointee()));
 
     attrs.push_back(rewriter.getNamedAttr(llvmAttrName, typAttr));
-    auto newDict = rewriter.getDictionaryAttr(attrs);
+    mlir::DictionaryAttr newDict = rewriter.getDictionaryAttr(attrs);
     opAttrs.push_back(newDict);
   }
 

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

Reply via email to