diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -248,6 +248,9 @@ Option<"indexBitwidth", "index-bitwidth", "unsigned", /*default=kDeriveIndexBitwidthFromDataLayout*/"0", "Bitwidth of the index type, 0 to use size of machine word">, + Option<"useOpaquePointers", "use-opaque-pointers", "bool", + /*default=*/"false", "Generate LLVM IR using opaque pointers " + "instead of typed pointers">, ]; } diff --git a/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp b/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp --- a/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp +++ b/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp @@ -45,7 +45,7 @@ /// Generate IR that prints the given string to stderr. static void createPrintMsg(OpBuilder &builder, Location loc, ModuleOp moduleOp, - StringRef msg) { + StringRef msg, LLVMTypeConverter &typeConverter) { auto ip = builder.saveInsertionPoint(); builder.setInsertionPointToStart(moduleOp.getBody()); MLIRContext *ctx = builder.getContext(); @@ -68,12 +68,13 @@ // Emit call to `printStr` in runtime library. builder.restoreInsertionPoint(ip); auto msgAddr = builder.create( - loc, LLVM::LLVMPointerType::get(arrayTy), globalOp.getName()); + loc, typeConverter.getPointerType(arrayTy), globalOp.getName()); SmallVector indices(1, 0); Value gep = builder.create( - loc, LLVM::LLVMPointerType::get(builder.getI8Type()), msgAddr, indices); - Operation *printer = - LLVM::lookupOrCreatePrintStrFn(moduleOp, /*TODO: opaquePointers=*/false); + loc, typeConverter.getPointerType(builder.getI8Type()), arrayTy, msgAddr, + indices); + Operation *printer = LLVM::lookupOrCreatePrintStrFn( + moduleOp, typeConverter.useOpaquePointers()); builder.create(loc, TypeRange(), SymbolRefAttr::get(printer), gep); } @@ -102,7 +103,7 @@ // Failed block: Generate IR to print the message and call `abort`. Block *failureBlock = rewriter.createBlock(opBlock->getParent()); - createPrintMsg(rewriter, loc, module, op.getMsg()); + createPrintMsg(rewriter, loc, module, op.getMsg(), *getTypeConverter()); if (abortOnFailedAssert) { // Insert the `abort` declaration if necessary. auto abortFunc = module.lookupSymbol("abort"); @@ -274,6 +275,7 @@ LowerToLLVMOptions options(&getContext()); if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout) options.overrideIndexBitwidth(indexBitwidth); + options.useOpaquePointers = useOpaquePointers; LLVMTypeConverter converter(&getContext(), options); mlir::cf::populateControlFlowToLLVMConversionPatterns(converter, patterns); diff --git a/mlir/test/Conversion/ControlFlowToLLVM/assert.mlir b/mlir/test/Conversion/ControlFlowToLLVM/assert.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Conversion/ControlFlowToLLVM/assert.mlir @@ -0,0 +1,17 @@ +// RUN: mlir-opt %s -convert-cf-to-llvm='use-opaque-pointers=1' | FileCheck %s + +func.func @main() { + %a = arith.constant 0 : i1 + cf.assert %a, "assertion foo" + return +} + +// CHECK: llvm.func @puts(!llvm.ptr) + +// CHECK-LABEL: @main +// CHECK: llvm.cond_br %{{.*}}, ^{{.*}}, ^[[FALSE_BRANCH:[[:alnum:]]+]] + +// CHECK: ^[[FALSE_BRANCH]]: +// CHECK: %[[ADDRESS_OF:.*]] = llvm.mlir.addressof @{{.*}} : !llvm.ptr{{$}} +// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ADDRESS_OF]][0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<{{[0-9]+}} x i8> +// CHECK: llvm.call @puts(%[[GEP]]) : (!llvm.ptr) -> ()