Skip to content

Commit

Permalink
EmitC: Use brace initialization for values of opaque type when loweri…
Browse files Browse the repository at this point in the history
…ng ub.posion (#429)

Values of opaque type are currently initialized to integers, which may be invalid. Instead, lower them using brace-initializers. The emitc code will represent C++.
  • Loading branch information
TinaAMD authored Jan 9, 2025
1 parent c6d34c5 commit 2f5bd8b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
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

0 comments on commit 2f5bd8b

Please sign in to comment.