[clang] 53368bf - [CIR] Fix InlineAsmOp roundtrip parse crash on cir.asm (#186588)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 16 10:17:08 PDT 2026


Author: Vatsal Khosla
Date: 2026-04-16T10:17:02-07:00
New Revision: 53368bf9788b58b80405394e2e7554c3e6b6fc65

URL: https://github.com/llvm/llvm-project/commit/53368bf9788b58b80405394e2e7554c3e6b6fc65
DIFF: https://github.com/llvm/llvm-project/commit/53368bf9788b58b80405394e2e7554c3e6b6fc65.diff

LOG: [CIR] Fix InlineAsmOp roundtrip parse crash on cir.asm (#186588)

Fix InlineAsmOp parser/printer roundtrip for cir.asm and avoid null
operand_attrs entries that crash alias printing during
--verify-roundtrip.

- Parse attr-dict before optional result arrow to match print order.

- Use non-null sentinel attributes for non-maybe_memory operands and
check UnitAttr explicitly.

- Keep lowering semantics by treating only UnitAttr as maybe_memory
marker.

- Update inline-asm CIR IR test to run with --verify-roundtrip and add
an attr+result coverage case.

Fix https://github.com/llvm/llvm-project/issues/161441

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenAsm.cpp
    clang/lib/CIR/Dialect/IR/CIRDialect.cpp
    clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
    clang/test/CIR/IR/inline-asm.cir

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenAsm.cpp b/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
index c53ac0d6e2312..bf3d0fad2c169 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
@@ -574,7 +574,7 @@ mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &s) {
         // We need to add an attribute for every arg since later, during
         // the lowering to LLVM IR the attributes will be assigned to the
         // CallInsn argument by index, i.e. we can't skip null type here
-        operandAttrs.push_back(mlir::Attribute());
+        operandAttrs.push_back(mlir::DictionaryAttr::get(&getMLIRContext()));
       }
     }
     assert(args.size() == operandAttrs.size() &&

diff  --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 4514b04780746..35a31b0dbda63 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -3685,7 +3685,7 @@ void cir::InlineAsmOp::print(OpAsmPrinter &p) {
                           [&](Value value) {
                             p.printOperand(value);
                             p << " : " << value.getType();
-                            if (*attrIt)
+                            if (mlir::isa<mlir::UnitAttr>(*attrIt))
                               p << " (maybe_memory)";
                             attrIt++;
                           });
@@ -3805,7 +3805,7 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
         size++;
 
         if (parser.parseOptionalLParen().failed()) {
-          operandAttrs.push_back(mlir::Attribute());
+          operandAttrs.push_back(mlir::DictionaryAttr::get(ctxt));
           return mlir::success();
         }
 
@@ -3848,11 +3848,11 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
   if (parser.parseOptionalKeyword("side_effects").succeeded())
     result.attributes.set("side_effects", UnitAttr::get(ctxt));
 
-  if (parser.parseOptionalArrow().succeeded() &&
-      parser.parseType(resType).failed())
+  if (parser.parseOptionalAttrDict(result.attributes).failed())
     return mlir::failure();
 
-  if (parser.parseOptionalAttrDict(result.attributes).failed())
+  if (parser.parseOptionalArrow().succeeded() &&
+      parser.parseType(resType).failed())
     return mlir::failure();
 
   result.attributes.set("asm_flavor", AsmFlavorAttr::get(ctxt, *flavor));

diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 79c4c48a9fde1..497a692c27f1a 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -4457,7 +4457,7 @@ mlir::LogicalResult CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
   // CIR operand type.
   for (auto const &[cirOpAttr, cirOp] :
        zip(op.getOperandAttrs(), cirOperands)) {
-    if (!cirOpAttr) {
+    if (!mlir::isa<mlir::UnitAttr>(cirOpAttr)) {
       opAttrs.push_back(mlir::Attribute());
       continue;
     }

diff  --git a/clang/test/CIR/IR/inline-asm.cir b/clang/test/CIR/IR/inline-asm.cir
index fb1f6315a7d72..907c7944670e2 100644
--- a/clang/test/CIR/IR/inline-asm.cir
+++ b/clang/test/CIR/IR/inline-asm.cir
@@ -1,4 +1,4 @@
-// RUN: cir-opt %s | FileCheck %s
+// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
 
 !s32i = !cir.int<s, 32>
 !u32i = !cir.int<u, 32>
@@ -109,4 +109,18 @@ cir.func @f7(%arg0: !u32i) -> !u32i {
    %3 = cir.load align(4) %0 : !cir.ptr<!u32i>, !u32i
    cir.return %3 : !u32i
 }
+
+cir.func @f8() -> !s32i {
+  // CHECK: %[[RES:.*]] = cir.asm(x86_att,
+  // CHECK:   out = [],
+  // CHECK:   in = [],
+  // CHECK:   in_out = [],
+  // CHECK:   {"movl $$7, $0" "=r,~{dirflag},~{fpsr},~{flags}"}) side_effects {test.attr = 7 : i32} -> !s32i
+  %0 = cir.asm(x86_att,
+    out = [],
+    in = [],
+    in_out = [],
+    {"movl $$7, $0" "=r,~{dirflag},~{fpsr},~{flags}"}) side_effects {test.attr = 7 : i32} -> !s32i
+  cir.return %0 : !s32i
+}
 }


        


More information about the cfe-commits mailing list