Skip to content
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

EmitC: Use brace initialization for values of opaque type when lowering ub.posion #429

Merged
merged 8 commits into from
Jan 9, 2025
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();
TinaAMD marked this conversation as resolved.
Show resolved Hide resolved
}
};
Expand Down
Loading