Better handle derived classes

This commit is contained in:
William S. Moses 2021-12-26 15:49:28 -05:00 committed by William Moses
parent e84ed0ee88
commit 14f5f7cd80
2 changed files with 42 additions and 4 deletions

View File

@ -4151,15 +4151,20 @@ ValueCategory MLIRScanner::VisitCastExpr(CastExpr *E) {
}
assert(se.val);
if (auto opt = se.val.getType().dyn_cast<mlir::LLVM::LLVMPointerType>()) {
auto nt = getMLIRType(E->getType());
auto pt = nt.dyn_cast<mlir::LLVM::LLVMPointerType>();
mlir::Type nt = getMLIRType(
E->isLValue() ? Glob.CGM.getContext().getLValueReferenceType(E->getType()) : E->getType() );
auto pt = nt.dyn_cast<mlir::LLVM::LLVMPointerType>();
if (!pt) {
if (!nt.isa<MemRefType>()) {
E->dump();
E->getType()->dump();
llvm::errs() << " nt: " << nt << "\n";
assert(nt.isa<MemRefType>());
}
return ValueCategory(
builder.create<polygeist::Pointer2MemrefOp>(loc, nt, se.val),
se.isReference);
}
if (se.isReference)
pt = mlir::LLVM::LLVMPointerType::get(pt, opt.getAddressSpace());
auto nval = builder.create<mlir::LLVM::BitcastOp>(loc, pt, se.val);
return ValueCategory(nval, /*isReference*/ se.isReference);
}

View File

@ -0,0 +1,33 @@
// RUN: mlir-clang %s --function=* -S | FileCheck %s
struct A {
int x;
double y;
};
struct B : public A {
void* z;
};
int ref(struct B& v) {
return v.x;
}
int ptr(struct B* v) {
return v->x;
}
// CHECK: func @_Z3refR1B(%arg0: !llvm.ptr<struct<(struct<(i32, f64)>, ptr<i8>)>>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %0 = llvm.bitcast %arg0 : !llvm.ptr<struct<(struct<(i32, f64)>, ptr<i8>)>> to !llvm.ptr<struct<(i32, f64)>>
// CHECK-NEXT: %1 = llvm.getelementptr %0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(i32, f64)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %2 = llvm.load %1 : !llvm.ptr<i32>
// CHECK-NEXT: return %2 : i32
// CHECK-NEXT: }
// CHECK: func @_Z3ptrP1B(%arg0: !llvm.ptr<struct<(struct<(i32, f64)>, ptr<i8>)>>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %0 = llvm.bitcast %arg0 : !llvm.ptr<struct<(struct<(i32, f64)>, ptr<i8>)>> to !llvm.ptr<struct<(i32, f64)>>
// CHECK-NEXT: %1 = llvm.getelementptr %0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(i32, f64)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %2 = llvm.load %1 : !llvm.ptr<i32>
// CHECK-NEXT: return %2 : i32
// CHECK-NEXT: }