-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[CIR] Add InlineAsmOp lowering to LLVM #153387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Add InlineAsmOp lowering to LLVM #153387
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangir Author: Iris Shi (el-ev) Changes
Added support for lowering https://github.com/llvm/clangir/blob/main/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp#L3950 Full diff: https://github.com/llvm/llvm-project/pull/153387.diff 3 Files Affected:
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 88a0fe2e1f848..4c05fd7622b48 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2263,6 +2263,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
patterns.add<CIRToLLVMCastOpLowering>(converter, patterns.getContext(), dl);
patterns.add<CIRToLLVMPtrStrideOpLowering>(converter, patterns.getContext(),
dl);
+ patterns.add<CIRToLLVMInlineAsmOpLowering>(converter, patterns.getContext(),
+ dl);
patterns.add<
// clang-format off
CIRToLLVMAssumeOpLowering,
@@ -2896,6 +2898,71 @@ mlir::LogicalResult CIRToLLVMGetBitfieldOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
+ cir::InlineAsmOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type llResTy;
+ if (op.getNumResults())
+ llResTy = getTypeConverter()->convertType(op.getType(0));
+
+ auto dialect = op.getAsmFlavor();
+ auto llDialect = dialect == cir::AsmFlavor::x86_att
+ ? mlir::LLVM::AsmDialect::AD_ATT
+ : mlir::LLVM::AsmDialect::AD_Intel;
+
+ SmallVector<mlir::Attribute> opAttrs;
+ auto llvmAttrName = mlir::LLVM::InlineAsmOp::getElementTypeAttrName();
+
+ // this is for the lowering to LLVM from LLVM dialect. Otherwise, if we
+ // don't have the result (i.e. void type as a result of operation), the
+ // element type attribute will be attached to the whole instruction, but not
+ // to the operand
+ if (!op.getNumResults())
+ opAttrs.push_back(mlir::Attribute());
+
+ SmallVector<mlir::Value> llvmOperands;
+ SmallVector<mlir::Value> cirOperands;
+ auto llvmAsmOps = adaptor.getAsmOperands();
+ auto cirAsmOps = op.getAsmOperands();
+ for (size_t i = 0; i < llvmAsmOps.size(); ++i) {
+ auto llvmOps = llvmAsmOps[i];
+ auto cirOps = cirAsmOps[i];
+ llvmOperands.append(llvmOps.begin(), llvmOps.end());
+ cirOperands.append(cirOps.begin(), cirOps.end());
+ }
+
+ // so far we infer the llvm dialect element type attr from
+ // CIR operand type.
+ auto cirOpAttrs = op.getOperandAttrs();
+ for (std::size_t i = 0; i < cirOpAttrs.size(); ++i) {
+ if (!cirOpAttrs[i]) {
+ opAttrs.push_back(mlir::Attribute());
+ continue;
+ }
+
+ SmallVector<mlir::NamedAttribute> attrs;
+ auto typ = cast<cir::PointerType>(cirOperands[i].getType());
+ auto typAttr = mlir::TypeAttr::get(convertTypeForMemory(
+ *getTypeConverter(), dataLayout, typ.getPointee()));
+
+ attrs.push_back(rewriter.getNamedAttr(llvmAttrName, typAttr));
+ auto newDict = rewriter.getDictionaryAttr(attrs);
+ opAttrs.push_back(newDict);
+ }
+
+ rewriter.replaceOpWithNewOp<mlir::LLVM::InlineAsmOp>(
+ op, llResTy, llvmOperands, op.getAsmStringAttr(), op.getConstraintsAttr(),
+ op.getSideEffectsAttr(),
+ /*is_align_stack*/ mlir::UnitAttr(),
+ /*tail_call_kind*/
+ mlir::LLVM::TailCallKindAttr::get(
+ getContext(), mlir::LLVM::tailcallkind::TailCallKind::None),
+ mlir::LLVM::AsmDialectAttr::get(getContext(), llDialect),
+ rewriter.getArrayAttr(opAttrs));
+
+ return mlir::success();
+}
+
std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass() {
return std::make_unique<ConvertCIRToLLVMPass>();
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 51b191af24692..3928fe72d160d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -648,6 +648,23 @@ class CIRToLLVMGetBitfieldOpLowering
mlir::ConversionPatternRewriter &) const override;
};
+class CIRToLLVMInlineAsmOpLowering
+ : public mlir::OpConversionPattern<cir::InlineAsmOp> {
+ mlir::DataLayout const &dataLayout;
+
+public:
+ CIRToLLVMInlineAsmOpLowering(const mlir::TypeConverter &typeConverter,
+ mlir::MLIRContext *context,
+ mlir::DataLayout const &dataLayout)
+ : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
+
+ using mlir::OpConversionPattern<cir::InlineAsmOp>::OpConversionPattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(cir::InlineAsmOp op, OpAdaptor,
+ mlir::ConversionPatternRewriter &) const override;
+};
+
} // namespace direct
} // namespace cir
diff --git a/clang/test/CIR/Lowering/inline-asm.cir b/clang/test/CIR/Lowering/inline-asm.cir
new file mode 100644
index 0000000000000..a8545d4c0f059
--- /dev/null
+++ b/clang/test/CIR/Lowering/inline-asm.cir
@@ -0,0 +1,86 @@
+// RUN: cir-translate %s -cir-to-llvmir --target x86_64-unknown-linux-gnu --disable-cc-lowering | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+!u32i = !cir.int<u, 32>
+
+module {
+cir.func @f1() {
+ // CHECK: call void asm "", "~{dirflag},~{fpsr},~{flags}"()
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [],
+ {"" "~{dirflag},~{fpsr},~{flags}"})
+ cir.return
+}
+
+cir.func @f2() {
+ // CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
+ cir.asm(x86_att,
+ out = [],
+ in = [],
+ in_out = [],
+ {"" "~{dirflag},~{fpsr},~{flags}"}) side_effects
+ cir.return
+}
+
+cir.func @f3() {
+ // CHECK: call void asm sideeffect "abc", "~{dirflag},~{fpsr},~{flags}"()
+ 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: call void asm sideeffect "", "*m,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %2)
+ 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: call void asm inteldialect "", "~{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: %2 = call i32 asm sideeffect "movl $$42, $0", "=r,~{dirflag},~{fpsr},~{flags}"()
+ %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: %4 = call i32 asm sideeffect "addl $$42, $0", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %3)
+ %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
+}
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after nits addressed
d49c098
to
ecea64a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Co-authored-by: Andy Kaylor <[email protected]>
Co-authored-by: Morris Hafner <[email protected]>
Co-authored-by: Morris Hafner <[email protected]>
ecea64a
to
dec7dd8
Compare
451d8b8
to
5fe3669
Compare
Co-authored-by: Andy Kaylor <[email protected]>
Co-authored-by: Morris Hafner <[email protected]>
5fe3669
to
024a77e
Compare
Co-authored-by: Andy Kaylor <[email protected]>
…ev/_CIR_Add_InlineAsmOp_lowering_to_LLVM
Added support for lowering
InlineAsmOp
directly to LLVM IRhttps://github.com/llvm/clangir/blob/main/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp#L3950