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