[llvm] [NFC] Allow fragment expressions in extractIfOffset (PR #69006)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 13 09:03:47 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Orlando Cazalet-Hyams (OCHyams)
<details>
<summary>Changes</summary>
A fragment is part of the variable identity and should be ignored for the purposes of checking whether the expression contains an offset.
This NFC patch is required for a subsequent change that addresses #<!-- -->61981.
---
Full diff: https://github.com/llvm/llvm-project/pull/69006.diff
2 Files Affected:
- (modified) llvm/lib/IR/DebugInfoMetadata.cpp (+6-3)
- (modified) llvm/unittests/IR/MetadataTest.cpp (+51)
``````````diff
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index f7f36129ec8557c..2ab41e55db1caef 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1673,18 +1673,21 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const {
return false;
auto SingleLocElts = *SingleLocEltsOpt;
- if (SingleLocElts.size() == 0) {
+ unsigned FragmentOpsCount = isFragment() ? 3 : 0;
+
+ if (SingleLocElts.size() == FragmentOpsCount) {
Offset = 0;
return true;
}
- if (SingleLocElts.size() == 2 &&
+ if (SingleLocElts.size() == 2 + FragmentOpsCount &&
SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
Offset = SingleLocElts[1];
return true;
}
- if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
+ if (SingleLocElts.size() == 3 + FragmentOpsCount &&
+ SingleLocElts[0] == dwarf::DW_OP_constu) {
if (SingleLocElts[2] == dwarf::DW_OP_plus) {
Offset = SingleLocElts[1];
return true;
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 1570631287b2a78..e68d27b36054767 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -3511,6 +3511,57 @@ TEST_F(DIExpressionTest, isEqualExpression) {
#undef GET_EXPR
}
+TEST_F(DIExpressionTest, extractIfOffset) {
+#define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
+#define GET_FRAG(...) \
+ DIExpression::get(Context, {__VA_ARGS__, dwarf::DW_OP_LLVM_fragment, 0, 32})
+#define EXPECT_OFFSET_IMPL(Offset, Success, Expr) \
+ do { \
+ int64_t ActualOffset; \
+ bool Result = Expr->extractIfOffset(ActualOffset); \
+ EXPECT_EQ(Success, Result); \
+ if (Success) { \
+ EXPECT_EQ(Offset, ActualOffset); \
+ } \
+ } while (0)
+#define EXPECT_OFFSET_EQ(Offset, Expr) EXPECT_OFFSET_IMPL(Offset, true, Expr)
+#define EXPECT_NO_OFFSET(Expr) EXPECT_OFFSET_IMPL(0, false, Expr)
+
+ // Check extractIfOffset behaves as expected with and without a fragment
+ // in the expression. extractIfOffset reads a constant offset out from the
+ // expression. It fails for all but exactly these with and without fragments:
+ // no expression
+ // DW_OP_plus_uconst, <u>
+ // DW_OP_constu, <u>, DW_OP_plus/minus
+ EXPECT_OFFSET_EQ(0, GET_EXPR());
+ EXPECT_OFFSET_EQ(0, GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 32));
+
+ EXPECT_OFFSET_EQ(1, GET_EXPR(dwarf::DW_OP_plus_uconst, 1));
+ EXPECT_OFFSET_EQ(1, GET_FRAG(dwarf::DW_OP_plus_uconst, 1));
+
+ EXPECT_OFFSET_EQ(2, GET_EXPR(dwarf::DW_OP_constu, 2, dwarf::DW_OP_plus));
+ EXPECT_OFFSET_EQ(2, GET_FRAG(dwarf::DW_OP_constu, 2, dwarf::DW_OP_plus));
+
+ EXPECT_OFFSET_EQ(-3, GET_EXPR(dwarf::DW_OP_constu, 3, dwarf::DW_OP_minus));
+ EXPECT_OFFSET_EQ(-3, GET_FRAG(dwarf::DW_OP_constu, 3, dwarf::DW_OP_minus));
+
+ // Test some failure cases, e.g. unsupported operations and too many
+ // operations.
+ EXPECT_NO_OFFSET(GET_EXPR(dwarf::DW_OP_constu, 3, dwarf::DW_OP_mul));
+ EXPECT_NO_OFFSET(GET_FRAG(dwarf::DW_OP_constu, 3, dwarf::DW_OP_mul));
+
+ EXPECT_NO_OFFSET(
+ GET_EXPR(dwarf::DW_OP_constu, 3, dwarf::DW_OP_plus, dwarf::DW_OP_deref));
+ EXPECT_NO_OFFSET(
+ GET_FRAG(dwarf::DW_OP_constu, 3, dwarf::DW_OP_plus, dwarf::DW_OP_deref));
+
+#undef EXPECT_NO_OFFSET
+#undef EXPECT_OFFSET_EQ
+#undef EXPECT_OFFSET_IMPL
+#undef GET_FRAG
+#undef GET_EXPR
+}
+
TEST_F(DIExpressionTest, foldConstant) {
const ConstantInt *Int;
const ConstantInt *NewInt;
``````````
</details>
https://github.com/llvm/llvm-project/pull/69006
More information about the llvm-commits
mailing list