[clang] [CIR] Add `InlineAsmOp` (PR #153362)
Iris Shi via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 14 09:00:46 PDT 2025
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/153362
>From a5a32a00acc2e66a264afbb8fa4efcce337eadde Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Wed, 13 Aug 2025 13:18:57 +0800
Subject: [PATCH 1/4] [CIR] Add `InlineAsmOp`
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 83 ++++++++
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 202 +++++++++++++++++++
2 files changed, 285 insertions(+)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index b64fd2734a63c..08afd2ddb1b80 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2254,6 +2254,89 @@ def CIR_StackRestoreOp : CIR_Op<"stackrestore"> {
let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))";
}
+//===----------------------------------------------------------------------===//
+// InlineAsmOp
+//===----------------------------------------------------------------------===//
+
+def CIR_AsmFlavor : CIR_I32EnumAttr<"AsmFlavor", "ATT or Intel",
+ [I32EnumAttrCase<"x86_att", 0>,
+ I32EnumAttrCase<"x86_intel", 1>]>;
+
+def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
+ let description = [{
+ The `cir.asm` operation represents C/C++ asm inline.
+
+ CIR constraints strings follow barely the same rules that are established
+ for the C level assembler constraints with several differences caused by
+ clang::AsmStmt processing.
+
+ Thus, numbers that appears in the constraint string may also refer to:
+ - the output variable index referenced by the input operands.
+ - the index of early-clobber operand
+
+ Operand attributes are a storage, where each element corresponds to the
+ operand with the same index. The first index relates to the operation
+ result (if any).
+ Note, the operands themselves are stored as VariadicOfVariadic in the next
+ order: output, input and then in/out operands.
+
+ Note, when several output operands are present, the result type may be
+ represented as an anon record type.
+
+ Example:
+ ```C++
+ __asm__("foo" : : : );
+ __asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
+ __asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
+ ```
+
+ ```mlir
+ !rec_22anon2E022 = !cir.record<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
+ !rec_22anon2E122 = !cir.record<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>}>
+ ...
+ %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
+ %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init]
+ ...
+ %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
+ %3 = cir.load %1 : !cir.ptr<!s32i>, !s32i
+
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [],
+ {"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [%2 : !s32i],
+ {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E022
+
+ cir.asm(x86_att,
+ out = [],
+ in = [%3 : !s32i],
+ in_out = [%2 : !s32i],
+ {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E122
+ ```
+ }];
+
+ let results = (outs Optional<CIR_AnyType>:$res);
+
+ let arguments =
+ (ins VariadicOfVariadic<AnyType, "operands_segments">:$asm_operands,
+ StrAttr:$asm_string, StrAttr:$constraints, UnitAttr:$side_effects,
+ CIR_AsmFlavor:$asm_flavor, ArrayAttr:$operand_attrs,
+ DenseI32ArrayAttr:$operands_segments);
+
+ let builders = [OpBuilder<(ins
+ "llvm::ArrayRef<mlir::ValueRange>":$asmOperands,
+ "llvm::StringRef":$asmString, "llvm::StringRef":$constraints,
+ "bool":$sideEffects, "AsmFlavor":$asmFlavor,
+ "llvm::ArrayRef<mlir::Attribute>":$operandAttrs)>];
+
+ let hasCustomAssemblyFormat = 1;
+}
+
//===----------------------------------------------------------------------===//
// UnreachableOp
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 936247e9d8fbb..2404755cde1e0 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2419,6 +2419,208 @@ OpFoldResult RotateOp::fold(FoldAdaptor adaptor) {
return IntAttr::get(input.getContext(), input.getType(), resultValue);
}
+//===----------------------------------------------------------------------===//
+// InlineAsmOp
+//===----------------------------------------------------------------------===//
+
+void cir::InlineAsmOp::print(OpAsmPrinter &p) {
+ p << '(' << getAsmFlavor() << ", ";
+ p.increaseIndent();
+ p.printNewline();
+
+ llvm::SmallVector<std::string, 3> names{"out", "in", "in_out"};
+ auto *nameIt = names.begin();
+ auto *attrIt = getOperandAttrs().begin();
+
+ for (auto ops : getAsmOperands()) {
+ p << *nameIt << " = ";
+
+ p << '[';
+ llvm::interleaveComma(llvm::make_range(ops.begin(), ops.end()), p,
+ [&](Value value) {
+ p.printOperand(value);
+ p << " : " << value.getType();
+ if (*attrIt)
+ p << " (maybe_memory)";
+ attrIt++;
+ });
+ p << "],";
+ p.printNewline();
+ ++nameIt;
+ }
+
+ p << "{";
+ p.printString(getAsmString());
+ p << " ";
+ p.printString(getConstraints());
+ p << "}";
+ p.decreaseIndent();
+ p << ')';
+ if (getSideEffects())
+ p << " side_effects";
+
+ llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs;
+ elidedAttrs.push_back("asm_flavor");
+ elidedAttrs.push_back("asm_string");
+ elidedAttrs.push_back("constraints");
+ elidedAttrs.push_back("operand_attrs");
+ elidedAttrs.push_back("operands_segments");
+ elidedAttrs.push_back("side_effects");
+ p.printOptionalAttrDict(getOperation()->getAttrs(), elidedAttrs);
+
+ if (auto v = getRes())
+ p << " -> " << v.getType();
+}
+
+void cir::InlineAsmOp::build(OpBuilder &odsBuilder, OperationState &odsState,
+ ArrayRef<ValueRange> asmOperands,
+ StringRef asmString, StringRef constraints,
+ bool sideEffects, cir::AsmFlavor asmFlavor,
+ ArrayRef<Attribute> operandAttrs) {
+ // Set up the operands_segments for VariadicOfVariadic
+ SmallVector<int32_t> segments;
+ for (auto operandRange : asmOperands) {
+ segments.push_back(operandRange.size());
+ odsState.addOperands(operandRange);
+ }
+
+ odsState.addAttribute(
+ "operands_segments",
+ DenseI32ArrayAttr::get(odsBuilder.getContext(), segments));
+ odsState.addAttribute("asm_string", odsBuilder.getStringAttr(asmString));
+ odsState.addAttribute("constraints", odsBuilder.getStringAttr(constraints));
+ odsState.addAttribute("asm_flavor",
+ AsmFlavorAttr::get(odsBuilder.getContext(), asmFlavor));
+
+ if (sideEffects)
+ odsState.addAttribute("side_effects", odsBuilder.getUnitAttr());
+
+ odsState.addAttribute("operand_attrs", odsBuilder.getArrayAttr(operandAttrs));
+}
+
+ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
+ OperationState &result) {
+ llvm::SmallVector<mlir::Attribute> operandAttrs;
+ llvm::SmallVector<int32_t> operandsGroupSizes;
+ std::string asmString, constraints;
+ Type resType;
+ auto *ctxt = parser.getBuilder().getContext();
+
+ auto error = [&](const Twine &msg) -> LogicalResult {
+ return parser.emitError(parser.getCurrentLocation(), msg);
+ };
+
+ auto expected = [&](const std::string &c) {
+ return error("expected '" + c + "'");
+ };
+
+ if (parser.parseLParen().failed())
+ return expected("(");
+
+ auto flavor = FieldParser<AsmFlavor, AsmFlavor>::parse(parser);
+ if (failed(flavor))
+ return error("Unknown AsmFlavor");
+
+ if (parser.parseComma().failed())
+ return expected(",");
+
+ auto parseValue = [&](Value &v) {
+ OpAsmParser::UnresolvedOperand op;
+
+ if (parser.parseOperand(op) || parser.parseColon())
+ return mlir::failure();
+
+ Type typ;
+ if (parser.parseType(typ).failed())
+ return error("can't parse operand type");
+ llvm::SmallVector<mlir::Value> tmp;
+ if (parser.resolveOperand(op, typ, tmp))
+ return error("can't resolve operand");
+ v = tmp[0];
+ return mlir::success();
+ };
+
+ auto parseOperands = [&](llvm::StringRef name) {
+ if (parser.parseKeyword(name).failed())
+ return error("expected " + name + " operands here");
+ if (parser.parseEqual().failed())
+ return expected("=");
+ if (parser.parseLSquare().failed())
+ return expected("[");
+
+ int size = 0;
+ if (parser.parseOptionalRSquare().succeeded()) {
+ operandsGroupSizes.push_back(size);
+ if (parser.parseComma())
+ return expected(",");
+ return mlir::success();
+ }
+
+ if (parser.parseCommaSeparatedList([&]() {
+ Value val;
+ if (parseValue(val).succeeded()) {
+ result.operands.push_back(val);
+ size++;
+
+ if (parser.parseOptionalLParen().failed()) {
+ operandAttrs.push_back(mlir::Attribute());
+ return mlir::success();
+ }
+
+ if (parser.parseKeyword("maybe_memory").succeeded()) {
+ operandAttrs.push_back(mlir::UnitAttr::get(ctxt));
+ if (parser.parseRParen())
+ return expected(")");
+ return mlir::success();
+ }
+ }
+ return mlir::failure();
+ }))
+ return mlir::failure();
+
+ if (parser.parseRSquare().failed() || parser.parseComma().failed())
+ return expected("]");
+ operandsGroupSizes.push_back(size);
+ return mlir::success();
+ };
+
+ if (parseOperands("out").failed() || parseOperands("in").failed() ||
+ parseOperands("in_out").failed())
+ return error("failed to parse operands");
+
+ if (parser.parseLBrace())
+ return expected("{");
+ if (parser.parseString(&asmString))
+ return error("asm string parsing failed");
+ if (parser.parseString(&constraints))
+ return error("constraints string parsing failed");
+ if (parser.parseRBrace())
+ return expected("}");
+ if (parser.parseRParen())
+ return expected(")");
+
+ if (parser.parseOptionalKeyword("side_effects").succeeded())
+ result.attributes.set("side_effects", UnitAttr::get(ctxt));
+
+ if (parser.parseOptionalArrow().succeeded() &&
+ parser.parseType(resType).failed())
+ return mlir::failure();
+
+ if (parser.parseOptionalAttrDict(result.attributes))
+ return mlir::failure();
+
+ result.attributes.set("asm_flavor", AsmFlavorAttr::get(ctxt, *flavor));
+ result.attributes.set("asm_string", StringAttr::get(ctxt, asmString));
+ result.attributes.set("constraints", StringAttr::get(ctxt, constraints));
+ result.attributes.set("operand_attrs", ArrayAttr::get(ctxt, operandAttrs));
+ result.getOrAddProperties<InlineAsmOp::Properties>().operands_segments =
+ parser.getBuilder().getDenseI32ArrayAttr(operandsGroupSizes);
+ if (resType)
+ result.addTypes(TypeRange{resType});
+
+ return mlir::success();
+}
+
//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
>From 9e595741e4529e6050c3cdf78f84d41478e85947 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Wed, 13 Aug 2025 15:51:03 +0800
Subject: [PATCH 2/4] add parsing test
---
clang/test/CIR/IR/inline-asm.cir | 112 +++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
create mode 100644 clang/test/CIR/IR/inline-asm.cir
diff --git a/clang/test/CIR/IR/inline-asm.cir b/clang/test/CIR/IR/inline-asm.cir
new file mode 100644
index 0000000000000..fb1f6315a7d72
--- /dev/null
+++ b/clang/test/CIR/IR/inline-asm.cir
@@ -0,0 +1,112 @@
+// RUN: cir-opt %s | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+!u32i = !cir.int<u, 32>
+
+module {
+cir.func @f1() {
+ // CHECK: cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [],
+ // CHECK: {"" "~{dirflag},~{fpsr},~{flags}"})
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [],
+ {"" "~{dirflag},~{fpsr},~{flags}"})
+ cir.return
+}
+
+cir.func @f2() {
+ // CHECK: cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [],
+ // CHECK: {"" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [],
+ {"" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+ cir.return
+}
+
+cir.func @f3() {
+ // CHECK: cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [],
+ // CHECK: {"abc" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+ 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: cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [%0 : !cir.ptr<!s32i> (maybe_memory)],
+ // CHECK: in_out = [],
+ // CHECK: {"" "*m,~{dirflag},~{fpsr},~{flags}"}) side_effects
+ 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: cir.asm(x86_intel,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [],
+ // CHECK: {"" "~{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: %1 = cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [],
+ // CHECK: {"movl $$42, $0" "=r,~{dirflag},~{fpsr},~{flags}"}) side_effects -> !s32i
+ %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: %2 = cir.asm(x86_att,
+ // CHECK: out = [],
+ // CHECK: in = [],
+ // CHECK: in_out = [%1 : !u32i],
+ // CHECK: {"addl $$42, $0" "=r,0,~{dirflag},~{fpsr},~{flags}"}) side_effects -> !u32i
+ %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 2f6570bbad7a2352c84a0ee6a14074ad67c64d12 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Thu, 14 Aug 2025 11:17:54 +0800
Subject: [PATCH 3/4] Apply review suggestions
Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 12 ++---
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 50 +++++++++++---------
2 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 08afd2ddb1b80..a77e9199cdc96 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2266,8 +2266,8 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
let description = [{
The `cir.asm` operation represents C/C++ asm inline.
- CIR constraints strings follow barely the same rules that are established
- for the C level assembler constraints with several differences caused by
+ CIR constraints strings follow the same rules that are established for
+ the C level assembler constraints with several differences caused by
clang::AsmStmt processing.
Thus, numbers that appears in the constraint string may also refer to:
@@ -2277,11 +2277,9 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
Operand attributes are a storage, where each element corresponds to the
operand with the same index. The first index relates to the operation
result (if any).
- Note, the operands themselves are stored as VariadicOfVariadic in the next
- order: output, input and then in/out operands.
-
- Note, when several output operands are present, the result type may be
- represented as an anon record type.
+ The operands themselves are stored as VariadicOfVariadic in the following
+ order: output, input and then in/out operands. When several output operands
+ are present, the result type may be represented as an anonymous record type.
Example:
```C++
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 2404755cde1e0..55f3262a32abd 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2432,7 +2432,7 @@ void cir::InlineAsmOp::print(OpAsmPrinter &p) {
auto *nameIt = names.begin();
auto *attrIt = getOperandAttrs().begin();
- for (auto ops : getAsmOperands()) {
+ for (mlir::OperandRange ops : getAsmOperands()) {
p << *nameIt << " = ";
p << '[';
@@ -2504,7 +2504,7 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
llvm::SmallVector<int32_t> operandsGroupSizes;
std::string asmString, constraints;
Type resType;
- auto *ctxt = parser.getBuilder().getContext();
+ MLIRContext *ctxt = parser.getBuilder().getContext();
auto error = [&](const Twine &msg) -> LogicalResult {
return parser.emitError(parser.getCurrentLocation(), msg);
@@ -2528,7 +2528,7 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
OpAsmParser::UnresolvedOperand op;
if (parser.parseOperand(op) || parser.parseColon())
- return mlir::failure();
+ return error("can't parse operand");
Type typ;
if (parser.parseType(typ).failed())
@@ -2556,26 +2556,30 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
return mlir::success();
}
- if (parser.parseCommaSeparatedList([&]() {
- Value val;
- if (parseValue(val).succeeded()) {
- result.operands.push_back(val);
- size++;
-
- if (parser.parseOptionalLParen().failed()) {
- operandAttrs.push_back(mlir::Attribute());
- return mlir::success();
- }
-
- if (parser.parseKeyword("maybe_memory").succeeded()) {
- operandAttrs.push_back(mlir::UnitAttr::get(ctxt));
- if (parser.parseRParen())
- return expected(")");
- return mlir::success();
- }
- }
- return mlir::failure();
- }))
+ auto parseOperand = [&]() {
+ Value val;
+ if (parseValue(val).succeeded()) {
+ result.operands.push_back(val);
+ size++;
+
+ if (parser.parseOptionalLParen().failed()) {
+ operandAttrs.push_back(mlir::Attribute());
+ return mlir::success();
+ }
+
+ if (parser.parseKeyword("maybe_memory").succeeded()) {
+ operandAttrs.push_back(mlir::UnitAttr::get(ctxt));
+ if (parser.parseRParen())
+ return expected(")");
+ return mlir::success();
+ } else {
+ return expected("maybe_memory");
+ }
+ }
+ return mlir::failure();
+ };
+
+ if (parser.parseCommaSeparatedList(parseOperand).failed())
return mlir::failure();
if (parser.parseRSquare().failed() || parser.parseComma().failed())
>From 0c87d3bec68b06ffaeb05b68d3ebcaab1d3b8b41 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Thu, 14 Aug 2025 23:19:49 +0800
Subject: [PATCH 4/4] Update clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Co-authored-by: Morris Hafner <mmha at users.noreply.github.com>
---
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 55f3262a32abd..7984f735d8e25 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2459,13 +2459,10 @@ void cir::InlineAsmOp::print(OpAsmPrinter &p) {
if (getSideEffects())
p << " side_effects";
- llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs;
- elidedAttrs.push_back("asm_flavor");
- elidedAttrs.push_back("asm_string");
- elidedAttrs.push_back("constraints");
- elidedAttrs.push_back("operand_attrs");
- elidedAttrs.push_back("operands_segments");
- elidedAttrs.push_back("side_effects");
+ std::array elidedAttrs{
+ llvm::StringRef("asm_flavor"), llvm::StringRef("asm_string"),
+ llvm::StringRef("constraints"), llvm::StringRef("operand_attrs"),
+ llvm::StringRef("operands_segments"), llvm::StringRef("side_effects")};
p.printOptionalAttrDict(getOperation()->getAttrs(), elidedAttrs);
if (auto v = getRes())
More information about the cfe-commits
mailing list