@@ -1468,6 +1468,160 @@ TEST_F(DILocationTest, Merge) {
14681468 EXPECT_EQ (N, M2->getScope ());
14691469 PickMergedSourceLocations = false ;
14701470 }
1471+
1472+ #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
1473+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1474+ EXPECT_EQ (Group, M->getAtomGroup ()); \
1475+ EXPECT_EQ (Rank, M->getAtomRank ());
1476+ #else
1477+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1478+ EXPECT_EQ (0u , M->getAtomGroup ()); \
1479+ EXPECT_EQ (0u , M->getAtomRank ()); \
1480+ (void )Group; \
1481+ (void )Rank;
1482+ #endif
1483+ // Identical, including source atom numbers.
1484+ {
1485+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1486+ /* AtomRank*/ 1 );
1487+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1488+ /* AtomRank*/ 1 );
1489+ auto *M = DILocation::getMergedLocation (A, B);
1490+ EXPECT_ATOM (M, /* AtomGroup*/ 1u , 1u );
1491+ // DILocations are uniqued, so we can check equality by ptr.
1492+ EXPECT_EQ (M, DILocation::getMergedLocation (A, B));
1493+ }
1494+
1495+ // Identical but different atom ranks (same atom) - choose the lowest nonzero
1496+ // rank.
1497+ {
1498+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1499+ /* AtomRank*/ 1 );
1500+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1501+ /* AtomRank*/ 2 );
1502+ auto *M = DILocation::getMergedLocation (A, B);
1503+ EXPECT_ATOM (M, /* AtomGroup*/ 1u , /* AtomRank*/ 1u );
1504+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1505+
1506+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1507+ /* AtomRank*/ 0 );
1508+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1509+ /* AtomRank*/ 2 );
1510+ M = DILocation::getMergedLocation (A, B);
1511+ EXPECT_ATOM (M, /* AtomGroup*/ 1u , /* AtomRank*/ 2u );
1512+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1513+ }
1514+
1515+ // Identical but different atom ranks (different atom) - choose the lowest
1516+ // nonzero rank.
1517+ {
1518+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1519+ /* AtomRank*/ 1 );
1520+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 2 ,
1521+ /* AtomRank*/ 2 );
1522+ auto *M = DILocation::getMergedLocation (A, B);
1523+ EXPECT_ATOM (M, 1u , 1u );
1524+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1525+
1526+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1527+ /* AtomRank*/ 0 );
1528+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 2 ,
1529+ /* AtomRank*/ 2 );
1530+ M = DILocation::getMergedLocation (A, B);
1531+ EXPECT_ATOM (M, /* AtomGroup*/ 2u , /* AtomRank*/ 2u );
1532+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1533+ }
1534+
1535+ // Identical but equal atom rank (different atom) - choose the lowest non-zero
1536+ // group (arbitrary choice for deterministic behaviour).
1537+ {
1538+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 1 ,
1539+ /* AtomRank*/ 1 );
1540+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 2 ,
1541+ /* AtomRank*/ 1 );
1542+ auto *M = DILocation::getMergedLocation (A, B);
1543+ EXPECT_ATOM (M, 1u , 1u );
1544+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1545+
1546+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 0 ,
1547+ /* AtomRank*/ 1 );
1548+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , /* AtomGroup*/ 2 ,
1549+ /* AtomRank*/ 1 );
1550+ M = DILocation::getMergedLocation (A, B);
1551+ EXPECT_ATOM (M, /* AtomGroup*/ 2u , /* AtomRank*/ 1u );
1552+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1553+ }
1554+
1555+ // Completely different except same atom numbers. Zero out the atoms.
1556+ {
1557+ auto *I = DILocation::get (Context, 2 , 7 , N);
1558+ auto *A = DILocation::get (Context, 1 , 6 , S, I, false , /* AtomGroup*/ 1 ,
1559+ /* AtomRank*/ 1 );
1560+ auto *B = DILocation::get (Context, 2 , 7 , getSubprogram (), nullptr , false ,
1561+ /* AtomGroup*/ 1 , /* AtomRank*/ 1 );
1562+ auto *M = DILocation::getMergedLocation (A, B);
1563+ EXPECT_EQ (0u , M->getLine ());
1564+ EXPECT_EQ (0u , M->getColumn ());
1565+ EXPECT_TRUE (isa<DILocalScope>(M->getScope ()));
1566+ EXPECT_EQ (S, M->getScope ());
1567+ EXPECT_EQ (nullptr , M->getInlinedAt ());
1568+ }
1569+
1570+ // Same inlined-at chain but different atoms. Choose the lowest
1571+ // non-zero group (arbitrary choice for deterministic behaviour).
1572+ {
1573+ auto *I = DILocation::get (Context, 1 , 7 , N);
1574+ auto *F = getSubprogram ();
1575+ auto *A = DILocation::get (Context, 1 , 1 , F, I, false , /* AtomGroup*/ 1 ,
1576+ /* AtomRank*/ 2 );
1577+ auto *B = DILocation::get (Context, 1 , 1 , F, I, false , /* AtomGroup*/ 2 ,
1578+ /* AtomRank*/ 2 );
1579+ auto *M = DILocation::getMergedLocation (A, B);
1580+ EXPECT_ATOM (M, /* AtomGroup*/ 1u , /* AtomRank*/ 2u );
1581+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1582+
1583+ A = DILocation::get (Context, 1 , 1 , F, I, false , /* AtomGroup*/ 1 ,
1584+ /* AtomRank*/ 2 );
1585+ B = DILocation::get (Context, 1 , 1 , F, I, false , /* AtomGroup*/ 2 ,
1586+ /* AtomRank*/ 0 );
1587+ M = DILocation::getMergedLocation (A, B);
1588+ EXPECT_ATOM (M, /* AtomGroup*/ 1u , /* AtomRank*/ 2u );
1589+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1590+ }
1591+
1592+ // Partially equal inlined-at chain but different atoms. Generate a new atom
1593+ // group (if either have a group number). This configuration seems unlikely
1594+ // to occur as line numbers must match, but isn't impossible.
1595+ {
1596+ // Reset global counter to ensure EXPECT numbers line up.
1597+ Context.pImpl ->NextAtomGroup = 1 ;
1598+ // x1 -> y2 -> z4
1599+ // y3 -> z4
1600+ auto *FX = getSubprogram ();
1601+ auto *FY = getSubprogram ();
1602+ auto *FZ = getSubprogram ();
1603+ auto *Z4 = DILocation::get (Context, 1 , 4 , FZ);
1604+ auto *Y3IntoZ4 = DILocation::get (Context, 1 , 3 , FY, Z4, false ,
1605+ /* AtomGroup*/ 1 , /* AtomRank*/ 1 );
1606+ auto *Y2IntoZ4 = DILocation::get (Context, 1 , 2 , FY, Z4);
1607+ auto *X1IntoY2 = DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4);
1608+ auto *M = DILocation::getMergedLocation (X1IntoY2, Y3IntoZ4);
1609+ EXPECT_EQ (M->getScope (), FY);
1610+ EXPECT_EQ (M->getInlinedAt ()->getScope (), FZ);
1611+ EXPECT_ATOM (M, /* AtomGroup*/ 2u , /* AtomRank*/ 1u );
1612+
1613+ // This swapped merge will produce a new atom group too.
1614+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2);
1615+
1616+ // Same again, even if the atom numbers match.
1617+ auto *X1IntoY2SameAtom = DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4, false ,
1618+ /* AtomGroup*/ 1 , /* AtomRank*/ 1 );
1619+ M = DILocation::getMergedLocation (X1IntoY2SameAtom, Y3IntoZ4);
1620+ EXPECT_ATOM (M, /* AtomGroup*/ 4u , /* AtomRank*/ 1u );
1621+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2SameAtom);
1622+ EXPECT_ATOM (M, /* AtomGroup*/ 5u , /* AtomRank*/ 1u );
1623+ }
1624+ #undef EXPECT_ATOM
14711625}
14721626
14731627TEST_F (DILocationTest, getDistinct) {
0 commit comments