-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Handled UnrealizedConversionCast for C code generation and validated tests #160159
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
base: main
Are you sure you want to change the base?
Handled UnrealizedConversionCast for C code generation and validated tests #160159
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-emitc Author: Lekkala_Sravya-mcw (LekkalaSravya3) ChangesThis PR addresses issue #159746
Full diff: https://github.com/llvm/llvm-project/pull/160159.diff 2 Files Affected:
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index a5bd80e9d6b8b..80d0c83049ac7 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -782,6 +782,64 @@ static LogicalResult printOperation(CppEmitter &emitter,
return success();
}
+static LogicalResult printOperation(CppEmitter &emitter,
+ mlir::UnrealizedConversionCastOp castOp) {
+ raw_ostream &os = emitter.ostream();
+ Operation &op = *castOp.getOperation();
+
+ if (castOp.getResults().size() != 1 || castOp.getOperands().size() != 1) {
+ return castOp.emitOpError(
+ "expected single result and single operand for conversion cast");
+ }
+
+ Type destType = castOp.getResult(0).getType();
+
+ auto srcPtrType =
+ mlir::dyn_cast<emitc::PointerType>(castOp.getOperand(0).getType());
+ auto destArrayType = mlir::dyn_cast<emitc::ArrayType>(destType);
+
+ if (srcPtrType && destArrayType) {
+
+ // Emit declaration: (*v13)[dims] =
+ if (failed(emitter.emitType(op.getLoc(), destArrayType.getElementType())))
+ return failure();
+ os << " (*" << emitter.getOrCreateName(op.getResult(0)) << ")";
+ for (int64_t dim : destArrayType.getShape())
+ os << "[" << dim << "]";
+ os << " = ";
+
+ os << "(";
+
+ // Emit the C++ type for "datatype (*)[dim1][dim2]..."
+ if (failed(emitter.emitType(op.getLoc(), destArrayType.getElementType())))
+ return failure();
+
+ os << "(*)"; // Pointer to array
+
+ for (int64_t dim : destArrayType.getShape()) {
+ os << "[" << dim << "]";
+ }
+ os << ")";
+ if (failed(emitter.emitOperand(castOp.getOperand(0))))
+ return failure();
+
+ return success();
+ }
+
+ // Fallback to generic C-style cast for other cases
+ if (failed(emitter.emitAssignPrefix(op)))
+ return failure();
+
+ os << "(";
+ if (failed(emitter.emitType(op.getLoc(), destType)))
+ return failure();
+ os << ")";
+ if (failed(emitter.emitOperand(castOp.getOperand(0))))
+ return failure();
+
+ return success();
+}
+
static LogicalResult printOperation(CppEmitter &emitter,
emitc::ApplyOp applyOp) {
raw_ostream &os = emitter.ostream();
@@ -1291,7 +1349,29 @@ CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
std::string CppEmitter::getSubscriptName(emitc::SubscriptOp op) {
std::string out;
llvm::raw_string_ostream ss(out);
- ss << getOrCreateName(op.getValue());
+ Value baseValue = op.getValue();
+
+ // Check if the baseValue (%arg1) is a result of UnrealizedConversionCastOp
+ // that converts a pointer to an array type.
+ if (auto castOp = dyn_cast_or_null<mlir::UnrealizedConversionCastOp>(
+ baseValue.getDefiningOp())) {
+ auto destArrayType =
+ mlir::dyn_cast<emitc::ArrayType>(castOp.getResult(0).getType());
+ auto srcPtrType =
+ mlir::dyn_cast<emitc::PointerType>(castOp.getOperand(0).getType());
+
+ // If it's a pointer being cast to an array, emit (*varName)
+ if (srcPtrType && destArrayType) {
+ ss << "(*" << getOrCreateName(baseValue) << ")";
+ } else {
+ // Fallback if the cast is not our specific pointer-to-array case
+ ss << getOrCreateName(baseValue);
+ }
+ } else {
+ // Default behavior for a regular array or other base types
+ ss << getOrCreateName(baseValue);
+ }
+
for (auto index : op.getIndices()) {
ss << "[" << getOrCreateName(index) << "]";
}
@@ -1747,6 +1827,8 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
cacheDeferredOpResult(op.getResult(), getSubscriptName(op));
return success();
})
+ .Case<mlir::UnrealizedConversionCastOp>(
+ [&](auto op) { return printOperation(*this, op); })
.Default([&](Operation *) {
return op.emitOpError("unable to find printer for op");
});
diff --git a/mlir/test/Target/Cpp/unrealized_conversion_cast.mlir b/mlir/test/Target/Cpp/unrealized_conversion_cast.mlir
new file mode 100644
index 0000000000000..075a268821fa1
--- /dev/null
+++ b/mlir/test/Target/Cpp/unrealized_conversion_cast.mlir
@@ -0,0 +1,15 @@
+// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
+
+// CHECK-LABEL: void builtin_cast
+func.func @builtin_cast(%arg0: !emitc.ptr<f32>){
+ // CHECK : float (*v2)[1][3][4][4] = (float(*)[1][3][4][4])v1
+ %1 = builtin.unrealized_conversion_cast %arg0 : !emitc.ptr<f32> to !emitc.array<1x3x4x4xf32>
+return
+}
+
+// CHECK-LABEL: void builtin_cast_index
+func.func @builtin_cast_index(%arg0: !emitc.size_t){
+ // CHECK : size_t v2 = (size_t)v1
+ %1 = builtin.unrealized_conversion_cast %arg0 : !emitc.size_t to index
+return
+}
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by comment. Also assigned reviewers, will try to allocate time for a proper review later if the others don't get to me before I have a chance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
…tests Signed-off-by: LekkalaSravya3 <[email protected]>
Signed-off-by: LekkalaSravya3 <[email protected]>
354a234
to
ec47d01
Compare
Thanks for reporting and addressing this issue. |
Hi @LekkalaSravya3, thanks for the contribution. Wouldn't we need to decay the outer most array dimension to pointer, i.e.
I think that is the correct place to fix this. Adding support for Do you suggest that subscript will support |
Not sure I follow: operators
Yes, as
Right, the
Right, as an alternative to adding |
Thank you for the detailed suggestion @simon-camp , @aniragil From my understanding, I should modify the conversion to directly lower the input memref type to the !emitc.ptr<!emitc.array<...>> format and handle conversions using emitc::ApplyOp, ensuring that emitc::SubscriptOp supports the necessary index handling. I just wanted to clarify one point — for cases like:
Would it make sense to handle the !emitc.size_t ↔ index conversion in a similar way within the TypeConverter? Specifically, by mapping index directly to !emitc.size_t and handling it uniformly during lowering, so we can avoid introducing UnrealizedConversionCastOp for these cases? Would that approach be consistent with your suggestion? |
This PR addresses issue #159746