|
25 | 25 | #include "clang/AST/Attr.h"
|
26 | 26 | #include "clang/AST/DeclObjC.h"
|
27 | 27 | #include "clang/AST/NSAPI.h"
|
| 28 | +#include "clang/Basic/Builtins.h" |
28 | 29 | #include "clang/Basic/CodeGenOptions.h"
|
29 | 30 | #include "llvm/ADT/Hashing.h"
|
30 | 31 | #include "llvm/ADT/StringExtras.h"
|
@@ -3418,8 +3419,20 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
|
3418 | 3419 | CharUnits eltAlign =
|
3419 | 3420 | getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize);
|
3420 | 3421 |
|
3421 |
| - llvm::Value *eltPtr = emitArraySubscriptGEP( |
3422 |
| - CGF, addr.getPointer(), indices, inbounds, signedIndices, loc, name); |
| 3422 | + llvm::Value *eltPtr; |
| 3423 | + auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back()); |
| 3424 | + if (!CGF.IsInPreservedAIRegion || !LastIndex) { |
| 3425 | + eltPtr = emitArraySubscriptGEP( |
| 3426 | + CGF, addr.getPointer(), indices, inbounds, signedIndices, |
| 3427 | + loc, name); |
| 3428 | + } else { |
| 3429 | + // Remember the original array subscript for bpf target |
| 3430 | + unsigned idx = LastIndex->getZExtValue(); |
| 3431 | + eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getPointer(), |
| 3432 | + indices.size() - 1, |
| 3433 | + idx); |
| 3434 | + } |
| 3435 | + |
3423 | 3436 | return Address(eltPtr, eltAlign);
|
3424 | 3437 | }
|
3425 | 3438 |
|
@@ -3908,6 +3921,19 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
|
3908 | 3921 | return CGF.Builder.CreateStructGEP(base, idx, field->getName());
|
3909 | 3922 | }
|
3910 | 3923 |
|
| 3924 | +static Address emitPreserveStructAccess(CodeGenFunction &CGF, Address base, |
| 3925 | + const FieldDecl *field) { |
| 3926 | + const RecordDecl *rec = field->getParent(); |
| 3927 | + llvm::DIType *DbgInfo = CGF.getDebugInfo()->getOrCreateRecordType( |
| 3928 | + CGF.getContext().getRecordType(rec), rec->getLocation()); |
| 3929 | + |
| 3930 | + unsigned idx = |
| 3931 | + CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field); |
| 3932 | + |
| 3933 | + return CGF.Builder.CreatePreserveStructAccessIndex( |
| 3934 | + base, idx, field->getFieldIndex(), DbgInfo); |
| 3935 | +} |
| 3936 | + |
3911 | 3937 | static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
|
3912 | 3938 | const auto *RD = Type.getTypePtr()->getAsCXXRecordDecl();
|
3913 | 3939 | if (!RD)
|
@@ -4015,9 +4041,24 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
|
4015 | 4041 | // a barrier every time CXXRecord field with vptr is referenced.
|
4016 | 4042 | addr = Address(Builder.CreateLaunderInvariantGroup(addr.getPointer()),
|
4017 | 4043 | addr.getAlignment());
|
| 4044 | + |
| 4045 | + if (IsInPreservedAIRegion) { |
| 4046 | + // Remember the original union field index |
| 4047 | + llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType( |
| 4048 | + getContext().getRecordType(rec), rec->getLocation()); |
| 4049 | + addr = Address( |
| 4050 | + Builder.CreatePreserveUnionAccessIndex( |
| 4051 | + addr.getPointer(), field->getFieldIndex(), DbgInfo), |
| 4052 | + addr.getAlignment()); |
| 4053 | + } |
4018 | 4054 | } else {
|
4019 |
| - // For structs, we GEP to the field that the record layout suggests. |
4020 |
| - addr = emitAddrOfFieldStorage(*this, addr, field); |
| 4055 | + |
| 4056 | + if (!IsInPreservedAIRegion) |
| 4057 | + // For structs, we GEP to the field that the record layout suggests. |
| 4058 | + addr = emitAddrOfFieldStorage(*this, addr, field); |
| 4059 | + else |
| 4060 | + // Remember the original struct field index |
| 4061 | + addr = emitPreserveStructAccess(*this, addr, field); |
4021 | 4062 |
|
4022 | 4063 | // If this is a reference field, load the reference right now.
|
4023 | 4064 | if (FieldType->isReferenceType()) {
|
|
0 commit comments