llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Andy Kaylor (andykaylor) <details> <summary>Changes</summary> This adds basic support for handling reference values. --- Full diff: https://github.com/llvm/llvm-project/pull/138001.diff 4 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+35-1) - (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+5) - (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+10) - (modified) clang/test/CIR/CodeGen/basic.cpp (+17) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index ff14798b9d34c..080209ca04b4c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -439,7 +439,13 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) { cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: static local"); } - return makeAddrLValue(addr, ty, AlignmentSource::Type); + // Drill into reference types. + LValue lv = + vd->getType()->isReferenceType() + ? emitLoadOfReferenceLValue(addr, getLoc(e->getSourceRange()), + vd->getType(), AlignmentSource::Decl) + : makeAddrLValue(addr, ty, AlignmentSource::Decl); + return lv; } cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: unhandled decl type"); @@ -1065,6 +1071,34 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty, return addr; } +Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc, + LValueBaseInfo *pointeeBaseInfo) { + if (refLVal.isVolatile()) + cgm.errorNYI(loc, "load of volatile reference"); + + cir::LoadOp load = + builder.create<cir::LoadOp>(loc, refLVal.getAddress().getElementType(), + refLVal.getAddress().getPointer()); + + assert(!cir::MissingFeatures::opTBAA()); + + QualType pointeeType = refLVal.getType()->getPointeeType(); + CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo); + return Address(load, convertTypeForMem(pointeeType), align); +} + +LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr, + mlir::Location loc, + QualType refTy, + AlignmentSource source) { + LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source)); + LValueBaseInfo pointeeBaseInfo; + assert(!cir::MissingFeatures::opTBAA()); + Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo); + return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(), + pointeeBaseInfo); +} + mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc, clang::QualType qt) { mlir::Type t = convertType(qt); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 592d39930089d..b4e1d24e0feda 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -560,6 +560,11 @@ class CIRGenFunction : public CIRGenTypeCache { /// returning the rvalue. RValue emitLoadOfLValue(LValue lv, SourceLocation loc); + Address emitLoadOfReference(LValue refLVal, mlir::Location loc, + LValueBaseInfo *pointeeBaseInfo); + LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc, + QualType refTy, AlignmentSource source); + /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to /// the LLVM value representation. The l-value must be a simple diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index de8ea0bd92158..98c9398fd4d94 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -381,6 +381,16 @@ mlir::Type CIRGenTypes::convertType(QualType type) { break; } + case Type::LValueReference: + case Type::RValueReference: { + const ReferenceType *refTy = cast<ReferenceType>(ty); + QualType elemTy = refTy->getPointeeType(); + auto pointeeType = convertTypeForMem(elemTy); + resultType = builder.getPointerTo(pointeeType); + assert(resultType && "Cannot get pointer type?"); + break; + } + case Type::Pointer: { const PointerType *ptrTy = cast<PointerType>(ty); QualType elemTy = ptrTy->getPointeeType(); diff --git a/clang/test/CIR/CodeGen/basic.cpp b/clang/test/CIR/CodeGen/basic.cpp index 1f289e905dd09..cf3fab5de510e 100644 --- a/clang/test/CIR/CodeGen/basic.cpp +++ b/clang/test/CIR/CodeGen/basic.cpp @@ -102,3 +102,20 @@ size_type max_size() { // CHECK: %3 = cir.cast(integral, %2 : !s32i), !u64i // CHECK: %4 = cir.const #cir.int<8> : !u64i // CHECK: %5 = cir.binop(div, %3, %4) : !u64i + +void ref_arg(int &x) { + int y = x; + x = 3; +} + +// CHECK: cir.func @_Z7ref_argRi(%[[ARG:.*]]: !cir.ptr<!s32i> {{.*}}) +// CHECK: %[[X_REF_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["x", init, const] {alignment = 8 : i64} +// CHECK: %[[Y_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init] {alignment = 4 : i64} +// CHECK: cir.store %[[ARG]], %[[X_REF_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> +// CHECK: %[[X_REF:.*]] = cir.load %[[X_REF_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> +// CHECK: %[[Y:.*]] = cir.load %[[X_REF]] : !cir.ptr<!s32i>, !s32i +// CHECK: cir.store %[[Y]], %[[Y_ADDR]] : !s32i, !cir.ptr<!s32i> +// CHECK: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i +// CHECK: %[[X_REF:.*]] = cir.load %[[X_REF_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> +// CHECK: cir.store %[[THREE]], %[[X_REF]] : !s32i, !cir.ptr<!s32i> +// CHECK: cir.return `````````` </details> https://github.com/llvm/llvm-project/pull/138001 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits