Skip to content

Commit 2f5bd8b

Browse files
authored
EmitC: Use brace initialization for values of opaque type when lowering 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++.
1 parent c6d34c5 commit 2f5bd8b

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

mlir/docs/Dialects/emitc.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The following convention is followed:
1818
floating types.
1919
* If `__bf16` is used, the code requires a compiler that supports it, such as
2020
GCC or Clang.
21+
* If `ub.posion` values should be initialized and have an opaque type,
22+
C++ is generated.
2123
* Else the generated code is compatible with C99.
2224

2325
These restrictions are neither inherent to the EmitC dialect itself nor to the

mlir/include/mlir/Conversion/Passes.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,8 @@ def ConvertUBToEmitC : Pass<"convert-ub-to-emitc"> {
12551255
let summary = "Convert UB dialect to EmitC dialect";
12561256
let description = [{
12571257
This pass converts supported UB ops to EmitC dialect.
1258+
When the initialization of values is enabled and some types are opaque, the
1259+
generated code is C++.
12581260
}];
12591261
let dependentDialects = ["emitc::EmitCDialect"];
12601262
let options = [

mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,30 @@ struct PoisonOpLowering : public OpConversionPattern<ub::PoisonOp> {
5252
Attribute value;
5353
if (noInitialization) {
5454
value = emitc::OpaqueAttr::get(op->getContext(), "");
55-
auto var = rewriter.create<emitc::VariableOp>(op.getLoc(), emitc::LValueType::get(convertedType), value);
55+
auto var = rewriter.create<emitc::VariableOp>(
56+
op.getLoc(), emitc::LValueType::get(convertedType), value);
5657
rewriter.replaceOpWithNewOp<emitc::LoadOp>(op, convertedType, var);
5758
return success();
5859
}
5960

6061
// Any constant will be fine to lower a poison op
6162
if (emitc::isIntegerIndexOrOpaqueType(convertedType)) {
62-
value = IntegerAttr::get((emitc::isPointerWideType(convertedType))
63-
? IndexType::get(op.getContext())
64-
: convertedType,
65-
42);
63+
if (auto opaqueType = dyn_cast<emitc::OpaqueType>(convertedType)) {
64+
// Use brace-initialization for opaque types; there is no universally
65+
// valid constant we can use for opaque types otherwise. Generated EmitC
66+
// will be C++.
67+
value = emitc::OpaqueAttr::get(op->getContext(), "{}");
68+
} else {
69+
value = IntegerAttr::get((emitc::isPointerWideType(convertedType))
70+
? IndexType::get(op.getContext())
71+
: convertedType,
72+
42);
73+
}
6674
} else if (emitc::isSupportedFloatType(convertedType)) {
6775
value = FloatAttr::get(convertedType, 42.0f);
6876
}
6977
rewriter.replaceOpWithNewOp<emitc::ConstantOp>(op, convertedType, value);
70-
78+
7179
return success();
7280
}
7381
};

0 commit comments

Comments
 (0)