[clang] [Clang][CodeGen] Add metadata for load from reference (PR #98746)
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 22 12:28:51 PDT 2024
================
@@ -2799,9 +2799,37 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
llvm::LoadInst *Load =
Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
- return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(),
- CharUnits(), /*ForPointeeType=*/true,
- PointeeBaseInfo, PointeeTBAAInfo);
+ QualType PTy = RefLVal.getType()->getPointeeType();
+ if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
+ llvm::LLVMContext &Ctx = getLLVMContext();
+ llvm::MDBuilder MDB(Ctx);
+ // Emit !dereferenceable metadata
+ Load->setMetadata(
+ llvm::LLVMContext::MD_dereferenceable,
+ llvm::MDNode::get(Ctx,
+ MDB.createConstant(llvm::ConstantInt::get(
+ Builder.getInt64Ty(),
----------------
rjmccall wrote:
Nikita is right. It is undefined behavior to bind a reference to an invalid object, but it is not undefined behavior to allow that object to be destroyed during the scope of a reference. This same limitation applies to reference parameters, so we may have existing miscompiles here. (IIUC, it's not surprising that such bugs could linger because `dereferenceable` only has any effect on relatively specific code patterns.)
The only places we can use `dereferenceable` are when we have an ABI guarantee about the lifetime of the pointee, such as when the ABI indirects an aggregate argument or return value.
For references, we could use a weaker form of `dereferenceable` that accounts for object invalidation. Conservatively, we would have to treat all calls and synchronization as removing dereferenceability. That would still allow us to optimize functions with no function calls (or only function calls known to not invalidate any objects).
https://github.com/llvm/llvm-project/pull/98746
More information about the cfe-commits
mailing list