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
2 changes: 2 additions & 0 deletions mlir/docs/Dialects/emitc.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions mlir/include/mlir/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
20 changes: 14 additions & 6 deletions mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,30 @@ struct PoisonOpLowering : public OpConversionPattern<ub::PoisonOp> {
Attribute value;
if (noInitialization) {
value = emitc::OpaqueAttr::get(op->getContext(), "");
auto var = rewriter.create<emitc::VariableOp>(op.getLoc(), emitc::LValueType::get(convertedType), value);
auto var = rewriter.create<emitc::VariableOp>(
op.getLoc(), emitc::LValueType::get(convertedType), value);
rewriter.replaceOpWithNewOp<emitc::LoadOp>(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<emitc::OpaqueType>(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<emitc::ConstantOp>(op, convertedType, value);

return success();
}
};
Expand Down
Loading