@@ -1468,6 +1468,160 @@ TEST_F(DILocationTest, Merge) {
1468
1468
EXPECT_EQ (N, M2->getScope ());
1469
1469
PickMergedSourceLocations = false ;
1470
1470
}
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
1471
1625
}
1472
1626
1473
1627
TEST_F (DILocationTest, getDistinct) {
0 commit comments