diff --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md index c3d3863de6761..54b00f76bb5d5 100644 --- a/mlir/docs/Dialects/emitc.md +++ b/mlir/docs/Dialects/emitc.md @@ -18,6 +18,8 @@ The following convention is followed: floating types. * If `__bf16` is used, the code requires a compiler that supports it, such as GCC or Clang. +* If `ub.posion` values should be initialized and have an opaque type, + C++ is generated. * Else the generated code is compatible with C99. These restrictions are neither inherent to the EmitC dialect itself nor to the diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index 62b40d28c32d0..587341a433860 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -1255,6 +1255,8 @@ def ConvertUBToEmitC : Pass<"convert-ub-to-emitc"> { let summary = "Convert UB dialect to EmitC dialect"; let description = [{ This pass converts supported UB ops to EmitC dialect. + When the initialization of values is enabled and some types are opaque, the + generated code is C++. }]; let dependentDialects = ["emitc::EmitCDialect"]; let options = [ diff --git a/mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp b/mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp index ca96af4553817..6093bd2ba6a75 100644 --- a/mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp +++ b/mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp @@ -52,22 +52,30 @@ struct PoisonOpLowering : public OpConversionPattern { Attribute value; if (noInitialization) { value = emitc::OpaqueAttr::get(op->getContext(), ""); - auto var = rewriter.create(op.getLoc(), emitc::LValueType::get(convertedType), value); + auto var = rewriter.create( + op.getLoc(), emitc::LValueType::get(convertedType), value); rewriter.replaceOpWithNewOp(op, convertedType, var); return success(); } // Any constant will be fine to lower a poison op if (emitc::isIntegerIndexOrOpaqueType(convertedType)) { - value = IntegerAttr::get((emitc::isPointerWideType(convertedType)) - ? IndexType::get(op.getContext()) - : convertedType, - 42); + if (auto opaqueType = dyn_cast(convertedType)) { + // Use brace-initialization for opaque types; there is no universally + // valid constant we can use for opaque types otherwise. Generated EmitC + // will be C++. + value = emitc::OpaqueAttr::get(op->getContext(), "{}"); + } else { + value = IntegerAttr::get((emitc::isPointerWideType(convertedType)) + ? IndexType::get(op.getContext()) + : convertedType, + 42); + } } else if (emitc::isSupportedFloatType(convertedType)) { value = FloatAttr::get(convertedType, 42.0f); } rewriter.replaceOpWithNewOp(op, convertedType, value); - + return success(); } };