================
@@ -47,114 +138,96 @@ mlir::Value
CIRBasicAliasAnalysis::getUnderlyingObject(mlir::Value val) {
break;
}
- // Pointer stride: only strip through when we can prove the access stays
- // within the bounds of the underlying allocation.
+ // A stride moves the pointer by `stride * sizeof(pointee)` bytes.
if (auto strideOp = mlir::dyn_cast<cir::PtrStrideOp>(defOp)) {
- auto constOp = strideOp.getStride().getDefiningOp<cir::ConstantOp>();
- if (constOp) {
- if (auto intAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue())) {
- APInt stride = intAttr.getValue();
-
- // Zero stride is trivially in-bounds.
- if (stride.isZero()) {
- LDBG() << "Walking past zero-strided PtrStrideOp";
- val = strideOp.getBase();
- continue;
- }
- }
- }
- // Dynamic stride or unverifiable bounds — stop here conservatively.
- LDBG() << "Non-zero or dynamic PtrStrideOp, stopping";
- break;
+ LDBG() << "Walking past PtrStrideOp";
+ addToOffset(offset,
+ scaleOffset(getConstantIndex(strideOp.getStride()),
+ getTypeSizeInBytes(strideOp.getElementType(),
+ dataLayout)));
+ val = strideOp.getBase();
+ continue;
}
- // Handle special cases for zero-offset sub-object accesses.
- if (auto op = mlir::dyn_cast<cir::GetMemberOp>(defOp)) {
- if (op.getIndex() == 0) {
- LDBG() << "GetMemberOp[0], following to underlying object";
- val = op.getAddr();
- continue;
- } else {
- LDBG() << "GetMemberOp, non-zero index, stopping";
- break;
- }
+ // A record member sits at a fixed offset given by the record layout.
+ if (auto memberOp = mlir::dyn_cast<cir::GetMemberOp>(defOp)) {
+ LDBG() << "Walking past GetMemberOp";
+ auto recordTy =
+ mlir::cast<cir::RecordType>(memberOp.getAddrTy().getPointee());
+ std::optional<int64_t> memberOffset;
+ if (!recordTy.isIncomplete())
+ memberOffset =
+ recordTy.getElementOffset(dataLayout, memberOp.getIndex());
+ addToOffset(offset, memberOffset);
+ val = memberOp.getAddr();
+ continue;
}
- if (auto op = mlir::dyn_cast<cir::GetElementOp>(defOp)) {
- cir::IntAttr index;
- if (auto constOp = op.getIndex().getDefiningOp<cir::ConstantOp>())
- index = mlir::dyn_cast<cir::IntAttr>(constOp.getValue());
- if (index && index.getValue().isZero()) {
- LDBG() << "GetElementOp[0], following to underlying object";
- val = op.getBase();
- continue;
- }
- LDBG() << "GetElementOp, non-zero or dynamic index, stopping";
- break;
+
+ // An array element sits at `index * sizeof(element)` bytes into the array.
+ if (auto elementOp = mlir::dyn_cast<cir::GetElementOp>(defOp)) {
+ LDBG() << "Walking past GetElementOp";
+ addToOffset(offset,
+ scaleOffset(getConstantIndex(elementOp.getIndex()),
+ getTypeSizeInBytes(elementOp.getElementType(),
+ dataLayout)));
+ val = elementOp.getBase();
+ continue;
}
- if (auto op = mlir::dyn_cast<cir::BaseClassAddrOp>(defOp)) {
- // A zero byte offset means the base subobject starts at the same address
- // as the derived object.
- if (op.getOffset().isZero()) {
- LDBG() << "BaseClassAddrOp[0], following to underlying object";
- val = op.getDerivedAddr();
- continue;
- }
- LDBG() << "BaseClassAddrOp, non-zero offset, stopping";
- break;
+
+ // A base class subobject starts the given number of bytes into the derived
+ // object.
+ if (auto baseOp = mlir::dyn_cast<cir::BaseClassAddrOp>(defOp)) {
+ LDBG() << "Walking past BaseClassAddrOp";
+ addToOffset(offset, baseOp.getOffset().tryZExtValue());
----------------
SharmaRithik wrote:
Should we check and handle the null case here?
https://github.com/llvm/llvm-project/pull/219047
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits