Skip to content

Commit 0869e81

Browse files
gitoleglanza
authored andcommitted
[CIR][Lowering] More cir.asm lowering (#472)
This PR adds lowering for `cir.asm`. Also, two flags were added to the `cir.asm` : `hasSideEffects` and `isStackAligned` in order to match with the llvm dialect. Also, I added several simple tests for lowering. I'm not sure but most likely the next PR will be the last one in this story about assembly support )
1 parent 5f1d1c1 commit 0869e81

File tree

5 files changed

+86
-16
lines changed

5 files changed

+86
-16
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+12-6
Original file line numberDiff line numberDiff line change
@@ -2890,9 +2890,9 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
28902890
...
28912891
%2 = cir.load %0 : cir.ptr <!s32i>, !s32i
28922892
%3 = cir.load %1 : cir.ptr <!s32i>, !s32i
2893-
cir.asm(x86_att, {"foo" "~{dirflag},~{fpsr},~{flags}"} : () -> ()
2894-
cir.asm(x86_att, {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"} %2 : (!s32i) -> ()
2895-
cir.asm(x86_att, {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"} %3, %2 : (!s32i, !s32i) -> ()
2893+
cir.asm(x86_att, {"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
2894+
cir.asm(x86_att, {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) %2 : (!s32i) -> ()
2895+
cir.asm(x86_att, {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) %3, %2 : (!s32i, !s32i) -> ()
28962896
```
28972897
}];
28982898

@@ -2902,11 +2902,17 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
29022902
ins Variadic<AnyType>:$operands,
29032903
StrAttr:$asm_string,
29042904
StrAttr:$constraints,
2905-
AsmFlavor:$asm_flavor);
2905+
UnitAttr:$side_effects,
2906+
AsmFlavor:$asm_flavor);
29062907

29072908
let assemblyFormat = [{
2908-
`(`$asm_flavor`,` `{` $asm_string $constraints `}` `)` attr-dict
2909-
operands `:` functional-type(operands, results)
2909+
`(`
2910+
$asm_flavor`,`
2911+
`{` $asm_string $constraints `}`
2912+
`)`
2913+
(`side_effects` $side_effects^)?
2914+
attr-dict
2915+
operands `:` functional-type(operands, results)
29102916
}];
29112917
}
29122918

clang/lib/CIR/CodeGen/CIRAsm.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,11 @@ mlir::LogicalResult CIRGenFunction::buildAsmStmt(const AsmStmt &S) {
428428
builder.getCompleteStructTy(ResultRegTypes, sname, false, nullptr);
429429
}
430430

431-
AsmFlavor AsmFlavor = inferFlavor(CGM, S);
431+
bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0;
432432

433433
builder.create<mlir::cir::InlineAsmOp>(getLoc(S.getAsmLoc()), ResultType,
434434
Args, AsmString, Constraints,
435-
AsmFlavor);
435+
HasSideEffect, inferFlavor(CGM, S));
436436

437437
return mlir::success();
438438
}

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+33-2
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,37 @@ class CIRUnreachableLowering
22312231
}
22322232
};
22332233

2234+
class CIRInlineAsmOpLowering
2235+
: public mlir::OpConversionPattern<mlir::cir::InlineAsmOp> {
2236+
2237+
using mlir::OpConversionPattern<mlir::cir::InlineAsmOp>::OpConversionPattern;
2238+
2239+
mlir::LogicalResult
2240+
matchAndRewrite(mlir::cir::InlineAsmOp op, OpAdaptor adaptor,
2241+
mlir::ConversionPatternRewriter &rewriter) const override {
2242+
2243+
mlir::Type llResTy;
2244+
if (op.getNumResults())
2245+
llResTy = getTypeConverter()->convertType(op.getType(0));
2246+
2247+
auto dialect = op.getAsmFlavor();
2248+
auto llDialect = dialect == mlir::cir::AsmFlavor::x86_att
2249+
? mlir::LLVM::AsmDialect::AD_ATT
2250+
: mlir::LLVM::AsmDialect::AD_Intel;
2251+
2252+
std::vector<mlir::Attribute> opAttrs;
2253+
2254+
rewriter.replaceOpWithNewOp<mlir::LLVM::InlineAsmOp>(
2255+
op, llResTy, adaptor.getOperands(), op.getAsmStringAttr(),
2256+
op.getConstraintsAttr(), op.getSideEffectsAttr(),
2257+
/*is_align_stack*/ mlir::UnitAttr(),
2258+
mlir::LLVM::AsmDialectAttr::get(getContext(), llDialect),
2259+
rewriter.getArrayAttr(opAttrs));
2260+
2261+
return mlir::success();
2262+
}
2263+
};
2264+
22342265
void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
22352266
mlir::TypeConverter &converter) {
22362267
patterns.add<CIRReturnLowering>(patterns.getContext());
@@ -2246,8 +2277,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
22462277
CIRPtrDiffOpLowering, CIRCopyOpLowering, CIRMemCpyOpLowering,
22472278
CIRFAbsOpLowering, CIRVTableAddrPointOpLowering, CIRVectorCreateLowering,
22482279
CIRVectorInsertLowering, CIRVectorExtractLowering, CIRVectorCmpOpLowering,
2249-
CIRStackSaveLowering, CIRStackRestoreLowering, CIRUnreachableLowering>(
2250-
converter, patterns.getContext());
2280+
CIRStackSaveLowering, CIRStackRestoreLowering, CIRUnreachableLowering,
2281+
CIRInlineAsmOpLowering>(converter, patterns.getContext());
22512282
}
22522283

22532284
namespace {

clang/test/CIR/CodeGen/asm.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
22
// RUN: FileCheck --input-file=%t.cir %s
33

4-
//CHECK: cir.asm(x86_att, {"" "~{dirflag},~{fpsr},~{flags}"}) : () -> ()
4+
//CHECK: cir.asm(x86_att, {"" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
55
void empty1() {
66
__asm__ volatile("" : : : );
77
}
88

9-
//CHECK: cir.asm(x86_att, {"xyz" "~{dirflag},~{fpsr},~{flags}"}) : () -> ()
9+
//CHECK: cir.asm(x86_att, {"xyz" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
1010
void empty2() {
1111
__asm__ volatile("xyz" : : : );
1212
}
1313

14-
//CHECK: cir.asm(x86_att, {"" "=*m,*m,~{dirflag},~{fpsr},~{flags}"}) %0, %0 : (!cir.ptr<!s32i>, !cir.ptr<!s32i>) -> ()
14+
//CHECK: cir.asm(x86_att, {"" "=*m,*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0, %0 : (!cir.ptr<!s32i>, !cir.ptr<!s32i>) -> ()
1515
void t1(int x) {
1616
__asm__ volatile("" : "+m"(x));
1717
}
1818

19-
//CHECK: cir.asm(x86_att, {"" "*m,~{dirflag},~{fpsr},~{flags}"}) %0 : (!cir.ptr<!s32i>) -> ()
19+
//CHECK: cir.asm(x86_att, {"" "*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
2020
void t2(int x) {
2121
__asm__ volatile("" : : "m"(x));
2222
}
2323

24-
//CHECK: cir.asm(x86_att, {"" "=*m,~{dirflag},~{fpsr},~{flags}"}) %0 : (!cir.ptr<!s32i>) -> ()
24+
//CHECK: cir.asm(x86_att, {"" "=*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
2525
void t3(int x) {
2626
__asm__ volatile("" : "=m"(x));
2727
}
2828

29-
//CHECK: cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) %1 : (!s32i) -> ()
29+
//CHECK: cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) side_effects %1 : (!s32i) -> ()
3030
void t4(int x) {
3131
__asm__ volatile("" : "=&r"(x), "+&r"(x));
3232
}

clang/test/CIR/Lowering/asm.cir

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s
2+
3+
!s32i = !cir.int<s, 32>
4+
5+
module {
6+
7+
cir.func @simple(%arg0: !s32i) {
8+
%0 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64}
9+
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>
10+
11+
cir.asm(x86_att, {"" "~{dirflag},~{fpsr},~{flags}"}) : () -> ()
12+
// CHECK: llvm.inline_asm asm_dialect = att operand_attrs = [] "", "~{dirflag},~{fpsr},~{flags}" : () -> ()
13+
14+
cir.asm(x86_att, {"xyz" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
15+
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "xyz", "~{dirflag},~{fpsr},~{flags}" : () -> ()
16+
17+
cir.asm(x86_att, {"" "=*m,*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0, %0 : (!cir.ptr<!s32i>, !cir.ptr<!s32i>) -> ()
18+
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=*m,*m,~{dirflag},~{fpsr},~{flags}" %1, %1 : (!llvm.ptr, !llvm.ptr) -> ()
19+
20+
cir.asm(x86_att, {"" "*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
21+
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "*m,~{dirflag},~{fpsr},~{flags}" %1 : (!llvm.ptr) -> ()
22+
23+
cir.asm(x86_att, {"" "=*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
24+
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=*m,~{dirflag},~{fpsr},~{flags}" %1 : (!llvm.ptr) -> ()
25+
26+
%1 = cir.load %0 : cir.ptr <!s32i>, !s32i
27+
cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) side_effects %1 : (!s32i) -> ()
28+
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}" %2 : (i32) -> ()
29+
30+
cir.return
31+
}
32+
33+
}

0 commit comments

Comments
 (0)