Skip to content

Commit

Permalink
[CIR][Lowering] More cir.asm lowering (#472)
Browse files Browse the repository at this point in the history
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 )
  • Loading branch information
gitoleg authored and lanza committed Nov 2, 2024
1 parent f19d39c commit a9dfe60
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 16 deletions.
18 changes: 12 additions & 6 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2890,9 +2890,9 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {
...
%2 = cir.load %0 : cir.ptr <!s32i>, !s32i
%3 = cir.load %1 : cir.ptr <!s32i>, !s32i
cir.asm(x86_att, {"foo" "~{dirflag},~{fpsr},~{flags}"} : () -> ()
cir.asm(x86_att, {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"} %2 : (!s32i) -> ()
cir.asm(x86_att, {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"} %3, %2 : (!s32i, !s32i) -> ()
cir.asm(x86_att, {"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
cir.asm(x86_att, {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) %2 : (!s32i) -> ()
cir.asm(x86_att, {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) %3, %2 : (!s32i, !s32i) -> ()
```
}];

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

let assemblyFormat = [{
`(`$asm_flavor`,` `{` $asm_string $constraints `}` `)` attr-dict
operands `:` functional-type(operands, results)
`(`
$asm_flavor`,`
`{` $asm_string $constraints `}`
`)`
(`side_effects` $side_effects^)?
attr-dict
operands `:` functional-type(operands, results)
}];
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRAsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,11 @@ mlir::LogicalResult CIRGenFunction::buildAsmStmt(const AsmStmt &S) {
builder.getCompleteStructTy(ResultRegTypes, sname, false, nullptr);
}

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

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

return mlir::success();
}
35 changes: 33 additions & 2 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2231,6 +2231,37 @@ class CIRUnreachableLowering
}
};

class CIRInlineAsmOpLowering
: public mlir::OpConversionPattern<mlir::cir::InlineAsmOp> {

using mlir::OpConversionPattern<mlir::cir::InlineAsmOp>::OpConversionPattern;

mlir::LogicalResult
matchAndRewrite(mlir::cir::InlineAsmOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {

mlir::Type llResTy;
if (op.getNumResults())
llResTy = getTypeConverter()->convertType(op.getType(0));

auto dialect = op.getAsmFlavor();
auto llDialect = dialect == mlir::cir::AsmFlavor::x86_att
? mlir::LLVM::AsmDialect::AD_ATT
: mlir::LLVM::AsmDialect::AD_Intel;

std::vector<mlir::Attribute> opAttrs;

rewriter.replaceOpWithNewOp<mlir::LLVM::InlineAsmOp>(
op, llResTy, adaptor.getOperands(), op.getAsmStringAttr(),
op.getConstraintsAttr(), op.getSideEffectsAttr(),
/*is_align_stack*/ mlir::UnitAttr(),
mlir::LLVM::AsmDialectAttr::get(getContext(), llDialect),
rewriter.getArrayAttr(opAttrs));

return mlir::success();
}
};

void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
mlir::TypeConverter &converter) {
patterns.add<CIRReturnLowering>(patterns.getContext());
Expand All @@ -2246,8 +2277,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
CIRPtrDiffOpLowering, CIRCopyOpLowering, CIRMemCpyOpLowering,
CIRFAbsOpLowering, CIRVTableAddrPointOpLowering, CIRVectorCreateLowering,
CIRVectorInsertLowering, CIRVectorExtractLowering, CIRVectorCmpOpLowering,
CIRStackSaveLowering, CIRStackRestoreLowering, CIRUnreachableLowering>(
converter, patterns.getContext());
CIRStackSaveLowering, CIRStackRestoreLowering, CIRUnreachableLowering,
CIRInlineAsmOpLowering>(converter, patterns.getContext());
}

namespace {
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CIR/CodeGen/asm.c
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

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

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

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

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

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

//CHECK: cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) %1 : (!s32i) -> ()
//CHECK: cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) side_effects %1 : (!s32i) -> ()
void t4(int x) {
__asm__ volatile("" : "=&r"(x), "+&r"(x));
}
33 changes: 33 additions & 0 deletions clang/test/CIR/Lowering/asm.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s

!s32i = !cir.int<s, 32>

module {

cir.func @simple(%arg0: !s32i) {
%0 = cir.alloca !s32i, cir.ptr <!s32i>, ["x", init] {alignment = 4 : i64}
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>

cir.asm(x86_att, {"" "~{dirflag},~{fpsr},~{flags}"}) : () -> ()
// CHECK: llvm.inline_asm asm_dialect = att operand_attrs = [] "", "~{dirflag},~{fpsr},~{flags}" : () -> ()

cir.asm(x86_att, {"xyz" "~{dirflag},~{fpsr},~{flags}"}) side_effects : () -> ()
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "xyz", "~{dirflag},~{fpsr},~{flags}" : () -> ()

cir.asm(x86_att, {"" "=*m,*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0, %0 : (!cir.ptr<!s32i>, !cir.ptr<!s32i>) -> ()
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=*m,*m,~{dirflag},~{fpsr},~{flags}" %1, %1 : (!llvm.ptr, !llvm.ptr) -> ()

cir.asm(x86_att, {"" "*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "*m,~{dirflag},~{fpsr},~{flags}" %1 : (!llvm.ptr) -> ()

cir.asm(x86_att, {"" "=*m,~{dirflag},~{fpsr},~{flags}"}) side_effects %0 : (!cir.ptr<!s32i>) -> ()
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=*m,~{dirflag},~{fpsr},~{flags}" %1 : (!llvm.ptr) -> ()

%1 = cir.load %0 : cir.ptr <!s32i>, !s32i
cir.asm(x86_att, {"" "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) side_effects %1 : (!s32i) -> ()
// CHECK: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [] "", "=&r,=&r,1,~{dirflag},~{fpsr},~{flags}" %2 : (i32) -> ()

cir.return
}

}

0 comments on commit a9dfe60

Please sign in to comment.