@@ -1445,6 +1445,140 @@ TEST_F(DILocationTest, Merge) {
14451445 auto *M2 = DILocation::getMergedLocation (A2, B);
14461446 EXPECT_EQ (M1, M2);
14471447 }
1448+
1449+ #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
1450+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1451+ EXPECT_EQ (Group, M->getAtomGroup ()); \
1452+ EXPECT_EQ (Rank, M->getAtomRank ());
1453+ #else
1454+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1455+ EXPECT_EQ (0u , M->getAtomGroup ()); \
1456+ EXPECT_EQ (0u , M->getAtomRank ()); \
1457+ (void )Group; \
1458+ (void )Rank;
1459+ #endif
1460+ // Identical, including source atom numbers.
1461+ {
1462+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1463+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1464+ auto *M = DILocation::getMergedLocation (A, B);
1465+ EXPECT_ATOM (M, 1u , 1u );
1466+ // DILocations are uniqued, so we can check equality by ptr.
1467+ EXPECT_EQ (M, DILocation::getMergedLocation (A, B));
1468+ }
1469+
1470+ // Identical but different atom ranks (same atom) - choose the lowest nonzero
1471+ // rank.
1472+ {
1473+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1474+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 2 );
1475+ auto *M = DILocation::getMergedLocation (A, B);
1476+ EXPECT_ATOM (M, 1u , 1u );
1477+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1478+
1479+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 0 );
1480+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 2 );
1481+ M = DILocation::getMergedLocation (A, B);
1482+ EXPECT_ATOM (M, 1u , 2u );
1483+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1484+ }
1485+
1486+ // Identical but different atom ranks (different atom) - choose the lowest
1487+ // nonzero rank.
1488+ {
1489+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1490+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 2 );
1491+ auto *M = DILocation::getMergedLocation (A, B);
1492+ EXPECT_ATOM (M, 1u , 1u );
1493+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1494+
1495+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 0 );
1496+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 2 );
1497+ M = DILocation::getMergedLocation (A, B);
1498+ EXPECT_ATOM (M, 2u , 2u );
1499+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1500+ }
1501+
1502+ // Identical but equal atom rank (different atom) - choose the lowest non-zero
1503+ // group (arbitrary choice for deterministic behaviour).
1504+ {
1505+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1506+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 1 );
1507+ auto *M = DILocation::getMergedLocation (A, B);
1508+ EXPECT_ATOM (M, 1u , 1u );
1509+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1510+
1511+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 0 , 1 );
1512+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 1 );
1513+ M = DILocation::getMergedLocation (A, B);
1514+ EXPECT_ATOM (M, 2u , 1u );
1515+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1516+ }
1517+
1518+ // Completely different except same atom numbers. Zero out the atoms.
1519+ {
1520+ auto *I = DILocation::get (Context, 2 , 7 , N);
1521+ auto *A = DILocation::get (Context, 1 , 6 , S, I, false , 1 , 1 );
1522+ auto *B =
1523+ DILocation::get (Context, 2 , 7 , getSubprogram (), nullptr , false , 1 , 1 );
1524+ auto *M = DILocation::getMergedLocation (A, B);
1525+ EXPECT_EQ (0u , M->getLine ());
1526+ EXPECT_EQ (0u , M->getColumn ());
1527+ EXPECT_TRUE (isa<DILocalScope>(M->getScope ()));
1528+ EXPECT_EQ (S, M->getScope ());
1529+ EXPECT_EQ (nullptr , M->getInlinedAt ());
1530+ }
1531+
1532+ // Same inlined-at chain but different atoms. Choose the lowest
1533+ // non-zero group (arbitrary choice for deterministic behaviour).
1534+ {
1535+ auto *I = DILocation::get (Context, 1 , 7 , N);
1536+ auto *F = getSubprogram ();
1537+ auto *A = DILocation::get (Context, 1 , 1 , F, I, false , 1 , 2 );
1538+ auto *B = DILocation::get (Context, 1 , 1 , F, I, false , 2 , 1 );
1539+ auto *M = DILocation::getMergedLocation (A, B);
1540+ EXPECT_ATOM (M, 2u , 1u );
1541+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1542+
1543+ A = DILocation::get (Context, 1 , 1 , F, I, false , 1 , 2 );
1544+ B = DILocation::get (Context, 1 , 1 , F, I, false , 2 , 0 );
1545+ M = DILocation::getMergedLocation (A, B);
1546+ EXPECT_ATOM (M, 1u , 2u );
1547+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1548+ }
1549+
1550+ // Partially equal inlined-at chain but different atoms. Generate a new atom
1551+ // group (if either have a group number). This configuration seems unlikely
1552+ // to occur as line numbers must match, but isn't impossible.
1553+ {
1554+ // Reset global counter to ensure EXPECT numbers line up.
1555+ Context.pImpl ->NextAtomGroup = 1 ;
1556+ // x1 -> y2 -> z4
1557+ // y3 -> z4
1558+ auto *FX = getSubprogram ();
1559+ auto *FY = getSubprogram ();
1560+ auto *FZ = getSubprogram ();
1561+ auto *Z4 = DILocation::get (Context, 1 , 4 , FZ);
1562+ auto *Y3IntoZ4 = DILocation::get (Context, 1 , 3 , FY, Z4, false , 1 , 1 );
1563+ auto *Y2IntoZ4 = DILocation::get (Context, 1 , 2 , FY, Z4);
1564+ auto *X1IntoY2 = DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4);
1565+ auto *M = DILocation::getMergedLocation (X1IntoY2, Y3IntoZ4);
1566+ EXPECT_EQ (M->getScope (), FY);
1567+ EXPECT_EQ (M->getInlinedAt ()->getScope (), FZ);
1568+ EXPECT_ATOM (M, 2u , 1u );
1569+
1570+ // This swapped merge will produce a new atom group too.
1571+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2);
1572+
1573+ // Same again, even if the atom numbers match.
1574+ auto *X1IntoY2SameAtom =
1575+ DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4, false , 1 , 1 );
1576+ M = DILocation::getMergedLocation (X1IntoY2SameAtom, Y3IntoZ4);
1577+ EXPECT_ATOM (M, 4u , 1u );
1578+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2SameAtom);
1579+ EXPECT_ATOM (M, 5u , 1u );
1580+ }
1581+ #undef EXPECT_ATOM
14481582}
14491583
14501584TEST_F (DILocationTest, getDistinct) {
0 commit comments