diff options
author | OCHyams <orlando.hyams@sony.com> | 2023-02-10 12:33:16 +0000 |
---|---|---|
committer | OCHyams <orlando.hyams@sony.com> | 2023-02-10 13:49:05 +0000 |
commit | 25d0f3c4d0d9f01755b008b5af92448ba593adf9 (patch) | |
tree | 7db16a85b077562a80fae527998c00c186998d9a /llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp | |
parent | 4d7c879d33a22a125923449150e493df3dc9fd05 (diff) | |
download | llvm-25d0f3c4d0d9f01755b008b5af92448ba593adf9.zip llvm-25d0f3c4d0d9f01755b008b5af92448ba593adf9.tar.gz llvm-25d0f3c4d0d9f01755b008b5af92448ba593adf9.tar.bz2 |
[Assignment Tracking] Fix fragment index error in getDerefOffsetInBytes
Without this patch `getDerefOffsetInBytes` incorrectly always returns
`std::nullopt` for expressions with fragments due to an off-by-one error with
fragment element indices.
Reviewed By: StephenTozer
Differential Revision: https://reviews.llvm.org/D143567
Diffstat (limited to 'llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp index 7098824..d3c9d14 100644 --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -234,13 +234,13 @@ getDerefOffsetInBytes(const DIExpression *DIExpr) { int64_t Offset = 0; const unsigned NumElements = DIExpr->getNumElements(); const auto Elements = DIExpr->getElements(); - unsigned NextElement = 0; + unsigned ExpectedDerefIdx = 0; // Extract the offset. if (NumElements > 2 && Elements[0] == dwarf::DW_OP_plus_uconst) { Offset = Elements[1]; - NextElement = 2; + ExpectedDerefIdx = 2; } else if (NumElements > 3 && Elements[0] == dwarf::DW_OP_constu) { - NextElement = 3; + ExpectedDerefIdx = 3; if (Elements[2] == dwarf::DW_OP_plus) Offset = Elements[1]; else if (Elements[2] == dwarf::DW_OP_minus) @@ -250,19 +250,21 @@ getDerefOffsetInBytes(const DIExpression *DIExpr) { } // If that's all there is it means there's no deref. - if (NextElement >= NumElements) + if (ExpectedDerefIdx >= NumElements) return std::nullopt; // Check the next element is DW_OP_deref - otherwise this is too complex or // isn't a deref expression. - if (Elements[NextElement] != dwarf::DW_OP_deref) + if (Elements[ExpectedDerefIdx] != dwarf::DW_OP_deref) return std::nullopt; // Check the final operation is either the DW_OP_deref or is a fragment. - if (NumElements == NextElement + 1) + if (NumElements == ExpectedDerefIdx + 1) return Offset; // Ends with deref. - else if (NumElements == NextElement + 3 && - Elements[NextElement] == dwarf::DW_OP_LLVM_fragment) + unsigned ExpectedFragFirstIdx = ExpectedDerefIdx + 1; + unsigned ExpectedFragFinalIdx = ExpectedFragFirstIdx + 2; + if (NumElements == ExpectedFragFinalIdx + 1 && + Elements[ExpectedFragFirstIdx] == dwarf::DW_OP_LLVM_fragment) return Offset; // Ends with deref + fragment. // Don't bother trying to interpret anything more complex. |