Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -758,9 +758,9 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
the LLVM function type that uses an explicit void type to model functions
that do not return a value.

If this operatin has the `no_inline` attribute, then this specific function call
will never be inlined. The opposite behavior will occur if the call has `always_inline`
attribute. The `inline_hint` attribute indicates that it is desirable to inline
If this operatin has the `no_inline` attribute, then this specific function call
will never be inlined. The opposite behavior will occur if the call has `always_inline`
attribute. The `inline_hint` attribute indicates that it is desirable to inline
this function call.

Examples:
Expand Down Expand Up @@ -2298,13 +2298,17 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
written, or referenced.
Attempting to define or reference any symbol or any global behavior is
considered undefined behavior at this time.
If `tail_call_kind` is used, the operation behaves like the specified
tail call kind. The `musttail` kind it's not available for this operation,
since it isn't supported by LLVM's inline asm.
}];
let arguments = (
ins Variadic<LLVM_Type>:$operands,
StrAttr:$asm_string,
StrAttr:$constraints,
UnitAttr:$has_side_effects,
UnitAttr:$is_align_stack,
DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$tail_call_kind,
OptionalAttr<
DefaultValuedAttr<AsmATTOrIntel, "AsmDialect::AD_ATT">>:$asm_dialect,
OptionalAttr<ArrayAttr>:$operand_attrs);
Expand All @@ -2314,6 +2318,7 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
let assemblyFormat = [{
(`has_side_effects` $has_side_effects^)?
(`is_align_stack` $is_align_stack^)?
(`tail_call_kind` `=` $tail_call_kind^)?
(`asm_dialect` `=` $asm_dialect^)?
(`operand_attrs` `=` $operand_attrs^)?
attr-dict
Expand All @@ -2326,6 +2331,8 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
return "elementtype";
}
}];

let hasVerifier = 1;
}

//===--------------------------------------------------------------------===//
Expand Down
3 changes: 2 additions & 1 deletion mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,8 @@ struct LDSBarrierOpLowering : public ConvertOpToLLVMPattern<LDSBarrierOp> {
op,
/*resultTypes=*/TypeRange(), /*operands=*/ValueRange(),
/*asm_string=*/asmStr, constraints, /*has_side_effects=*/true,
/*is_align_stack=*/false, /*asm_dialect=*/asmDialectAttr,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
return success();
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ static FailureOr<LLVM::InlineAsmOp> emitMmaSparseSyncOpAsm(
/*asm_string=*/asmStr,
/*constraints=*/constraintStr,
/*has_side_effects=*/true,
/*is_align_stack=*/false,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ LLVM::InlineAsmOp PtxBuilder::build() {
/*asm_string=*/llvm::StringRef(ptxInstruction),
/*constraints=*/registerConstraints.data(),
/*has_side_effects=*/interfaceOp.hasSideEffect(),
/*is_align_stack=*/false,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
}
Expand Down
15 changes: 15 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4042,6 +4042,21 @@ LogicalResult LLVM::masked_scatter::verify() {
return success();
}

//===----------------------------------------------------------------------===//
// InlineAsmOp
//===----------------------------------------------------------------------===//

LogicalResult InlineAsmOp::verify() {
if (!getTailCallKindAttr())
return success();

if (getTailCallKindAttr().getTailCallKind() == TailCallKind::MustTail)
return emitOpError(
"tail call kind 'musttail' is not supported by this operation");

return success();
}

//===----------------------------------------------------------------------===//
// LLVMDialect initialization, type parsing, and registration.
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 2 additions & 1 deletion mlir/lib/Dialect/X86Vector/Transforms/AVXTranspose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ Value mlir::x86vector::avx2::inline_asm::mm256BlendPsAsm(
auto asmOp = b.create<LLVM::InlineAsmOp>(
v1.getType(), /*operands=*/asmVals, /*asm_string=*/asmStr,
/*constraints=*/asmCstr, /*has_side_effects=*/false,
/*is_align_stack=*/false, /*asm_dialect=*/asmDialectAttr,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
return asmOp.getResult(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/IR/Operator.h"
Expand Down Expand Up @@ -507,6 +508,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
llvm::CallInst *inst = builder.CreateCall(
inlineAsmInst,
moduleTranslation.lookupValues(inlineAsmOp.getOperands()));
inst->setTailCallKind(convertTailCallKindToLLVM(
inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
if (auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
llvm::AttributeList attrList;
for (const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
builder.getStringAttr(asmI->getAsmString()),
builder.getStringAttr(asmI->getConstraintString()),
asmI->hasSideEffects(), asmI->isAlignStack(),
convertTailCallKindFromLLVM(callInst->getTailCallKind()),
AsmDialectAttr::get(
mlirModule.getContext(),
convertAsmDialectFromLLVM(asmI->getDialect())),
Expand Down
8 changes: 8 additions & 0 deletions mlir/test/Dialect/LLVMIR/invalid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -1882,3 +1882,11 @@ llvm.mlir.global internal constant @bad_array_attr_simple_type() : !llvm.array<2
%0 = llvm.mlir.constant([2.5, 7.4]) : !llvm.array<2 x f64>
llvm.return %0 : !llvm.array<2 x f64>
}

// ----

llvm.func @inlineAsmMustTail(%arg0: i32, %arg1 : !llvm.ptr) {
// expected-error@+1 {{op tail call kind 'musttail' is not supported}}
%8 = llvm.inline_asm tail_call_kind = <musttail> "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>
llvm.return
}
7 changes: 5 additions & 2 deletions mlir/test/Target/LLVMIR/Import/instructions.ll
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,11 @@ define i32 @inlineasm(i32 %arg1) {
define void @inlineasm2() {
%p = alloca ptr, align 8
; CHECK: {{.*}} = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr
; CHECK-NEXT: llvm.inline_asm has_side_effects asm_dialect = att operand_attrs = [{elementtype = !llvm.ptr}] "", "*m,~{memory}" {{.*}} : (!llvm.ptr) -> !llvm.void
call void asm sideeffect "", "*m,~{memory}"(ptr elementtype(ptr) %p)
; CHECK-NEXT: llvm.inline_asm has_side_effects tail_call_kind = <tail> asm_dialect = att operand_attrs = [{elementtype = !llvm.ptr}] "", "*m,~{memory}" {{.*}} : (!llvm.ptr) -> !llvm.void
tail call void asm sideeffect "", "*m,~{memory}"(ptr elementtype(ptr) %p)

; CHECK: llvm.inline_asm has_side_effects tail_call_kind = <notail> asm_dialect = att operand_attrs = [{elementtype = !llvm.ptr}] "", "*m,~{memory}" {{.*}} : (!llvm.ptr) -> !llvm.void
notail call void asm sideeffect "", "*m,~{memory}"(ptr elementtype(ptr) %p)
ret void
}

Expand Down
10 changes: 8 additions & 2 deletions mlir/test/Target/LLVMIR/llvmir.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -2081,8 +2081,14 @@ llvm.func @useInlineAsm(%arg0: i32, %arg1 : !llvm.ptr) {
// CHECK-NEXT: call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
%5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>

// CHECK-NEXT: call void asm sideeffect "", "*m,~{memory}"(ptr elementtype(ptr) %1)
%6 = llvm.inline_asm has_side_effects operand_attrs = [{elementtype = !llvm.ptr}] "", "*m,~{memory}" %arg1 : (!llvm.ptr) -> !llvm.void
// CHECK-NEXT: tail call void asm sideeffect "", "*m,~{memory}"(ptr elementtype(ptr) %1)
%6 = llvm.inline_asm has_side_effects tail_call_kind = <tail> operand_attrs = [{elementtype = !llvm.ptr}] "", "*m,~{memory}" %arg1 : (!llvm.ptr) -> !llvm.void

// CHECK-NEXT: = call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
%7 = llvm.inline_asm tail_call_kind = <none> "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>

// CHECK-NEXT: notail call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
%8 = llvm.inline_asm tail_call_kind = <notail> "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>

llvm.return
}
Expand Down