================ @@ -1243,6 +1243,140 @@ TEST_F(DILocationTest, Merge) { auto *M2 = DILocation::getMergedLocation(A2, B); EXPECT_EQ(M1, M2); } + +#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS +#define EXPECT_ATOM(Loc, Group, Rank) \ + EXPECT_EQ(Group, M->getAtomGroup()); \ + EXPECT_EQ(Rank, M->getAtomRank()); +#else +#define EXPECT_ATOM(Loc, Group, Rank) \ + EXPECT_EQ(0u, M->getAtomGroup()); \ + EXPECT_EQ(0u, M->getAtomRank()); \ + (void)Group; \ + (void)Rank; +#endif + // Identical, including source atom numbers. + { + auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1); + auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 1u); + // DILocations are uniqued, so we can check equality by ptr. + EXPECT_EQ(M, DILocation::getMergedLocation(A, B)); + } + + // Identical but different atom ranks (same atom) - choose the lowest nonzero + // rank. + { + auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1); + auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 2); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 1u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + + A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 0); + B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 2); + M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 2u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + } + + // Identical but different atom ranks (different atom) - choose the lowest + // nonzero rank. + { + auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1); + auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 2); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 1u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + + A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 0); + B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 2); + M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 2u, 2u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + } + + // Identical but equal atom rank (different atom) - choose the lowest non-zero + // group (arbitrary choice for deterministic behaviour). + { + auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1); + auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 1); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 1u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + + A = DILocation::get(Context, 2, 7, N, nullptr, false, 0, 1); + B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 1); + M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 2u, 1u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + } + + // Completely different except same atom numbers. Zero out the atoms. + { + auto *I = DILocation::get(Context, 2, 7, N); + auto *A = DILocation::get(Context, 1, 6, S, I, false, 1, 1); + auto *B = + DILocation::get(Context, 2, 7, getSubprogram(), nullptr, false, 1, 1); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_EQ(0u, M->getLine()); + EXPECT_EQ(0u, M->getColumn()); + EXPECT_TRUE(isa<DILocalScope>(M->getScope())); + EXPECT_EQ(S, M->getScope()); + EXPECT_EQ(nullptr, M->getInlinedAt()); + } + + // Same inlined-at chain but different atoms. Choose the lowest + // non-zero group (arbitrary choice for deterministic behaviour). + { + auto *I = DILocation::get(Context, 1, 7, N); + auto *F = getSubprogram(); + auto *A = DILocation::get(Context, 1, 1, F, I, false, 1, 2); + auto *B = DILocation::get(Context, 1, 1, F, I, false, 2, 1); + auto *M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 2u, 1u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + + A = DILocation::get(Context, 1, 1, F, I, false, 1, 2); + B = DILocation::get(Context, 1, 1, F, I, false, 2, 0); + M = DILocation::getMergedLocation(A, B); + EXPECT_ATOM(M, 1u, 2u); + EXPECT_EQ(M, DILocation::getMergedLocation(B, A)); + } + + // Partially equal inlined-at chain but different atoms. Generate a new atom + // group (if either have a group number). This configuration seems unlikely + // to occur as line numbers must match, but isn't impossible. + { ---------------- jmorse wrote:
I believe it's a desired and supported configuration for this to occur when a function is inlined multiple times then the copies are merged: we keep the line number of the instruction, but put line-zero in the inlinedAt field so that the inlining-callstack refers to a nonexistant location. Thus, we're saying "It's definitely this line, but we can't tell you what inlining context it came from, there were a few". I don't know whether it makes sense to try and support key instructions in that situation; I feel that falling back to old stepping behaviour is fine in these rare circumstances. https://github.com/llvm/llvm-project/pull/133480 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits