@@ -1445,6 +1445,140 @@ TEST_F(DILocationTest, Merge) {
1445
1445
auto *M2 = DILocation::getMergedLocation (A2, B);
1446
1446
EXPECT_EQ (M1, M2);
1447
1447
}
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
1448
1582
}
1449
1583
1450
1584
TEST_F (DILocationTest, getDistinct) {
0 commit comments