================
@@ -4248,6 +4193,76 @@ mlir::LogicalResult
CIRToLLVMAwaitOpLowering::matchAndRewrite(
return mlir::failure();
}
+mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite(
+ cir::CpuIdOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type i32Ty = rewriter.getI32Type();
+ mlir::Type i64Ty = rewriter.getI64Type();
+ mlir::Type i32PtrTy = mlir::LLVM::LLVMPointerType::get(i32Ty.getContext(),
0);
+
+ mlir::Type cpuidRetTy = mlir::LLVM::LLVMStructType::getLiteral(
+ rewriter.getContext(), {i32Ty, i32Ty, i32Ty, i32Ty});
+
+ mlir::Value funcId = adaptor.getFuncId();
+ mlir::Value subFuncId = adaptor.getSubFuncId();
+ mlir::StringAttr opNameAttr = op->getAttrOfType<mlir::StringAttr>("name");
+ if (!opNameAttr)
+ return mlir::failure();
+ if (opNameAttr.getValue() == "cpuid")
+ subFuncId = mlir::LLVM::ConstantOp::create(rewriter, op.getLoc(), i32Ty,
0);
+ std::vector operands{funcId, subFuncId};
+
+ StringRef asmString, constraints;
+ mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>();
+ mlir::StringAttr tripleAttr =
+ moduleOp->getAttrOfType<mlir::StringAttr>("llvm.target_triple");
+ if (!tripleAttr)
+ return mlir::failure();
+ llvm::Triple triple(tripleAttr.getValue().str());
+ if (triple.getArch() == llvm::Triple::x86) {
+ asmString = "cpuid";
+ constraints = "={ax},={bx},={cx},={dx},{ax},{cx}";
+ } else {
+ // x86-64 uses %rbx as the base register, so preserve it.
+ asmString = "xchgq %rbx, ${1:q}\n"
+ "cpuid\n"
+ "xchgq %rbx, ${1:q}";
+ constraints = "={ax},=r,={cx},={dx},0,2";
+ }
+
+ mlir::Value inlineAsm =
+ mlir::LLVM::InlineAsmOp::create(
+ rewriter, op.getLoc(), cpuidRetTy, mlir::ValueRange(operands),
+ rewriter.getStringAttr(asmString),
+ rewriter.getStringAttr(constraints),
+ /*has_side_effects=*/mlir::UnitAttr{},
+ /*is_align_stack=*/mlir::UnitAttr{},
+ /*tail_call_kind=*/mlir::LLVM::TailCallKindAttr{},
+ /*asm_dialect=*/mlir::LLVM::AsmDialectAttr{},
+ /*operand_attrs=*/mlir::ArrayAttr{})
+ .getResult(0);
+
+ mlir::Value basePtr = adaptor.getBasePtr();
+
+ mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+ unsigned alignment = layout.getTypeABIAlignment(i32Ty);
+ for (unsigned i = 0; i < 4; i++) {
+ mlir::Value extracted =
+ mlir::LLVM::ExtractValueOp::create(rewriter, op.getLoc(), inlineAsm, i)
+ .getResult();
+ mlir::Value index = mlir::LLVM::ConstantOp::create(
+ rewriter, op.getLoc(), i64Ty, rewriter.getI64IntegerAttr(i));
+ llvm::SmallVector<mlir::Value, 1> gepIndices = {index};
+ mlir::Value storePtr = mlir::LLVM::GEPOp::create(
+ rewriter, op.getLoc(), i32PtrTy, i32Ty, basePtr,
+ gepIndices, mlir::LLVM::GEPNoWrapFlags::none)
+ .getResult();
+ mlir::LLVM::StoreOp::create(rewriter, op.getLoc(), extracted, storePtr,
+ alignment);
+ }
+ return mlir::success();
----------------
rturrado wrote:
At the end of the function, 4 `mlir::LLVM::StoreOp` are added. Since CpuID
returns void and only writes to memory, shouldn't we just
`rewriter.eraseOp(op)`?
https://github.com/llvm/llvm-project/pull/173197
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits