@@ -1243,6 +1243,140 @@ TEST_F(DILocationTest, Merge) {
12431243 auto *M2 = DILocation::getMergedLocation (A2, B);
12441244 EXPECT_EQ (M1, M2);
12451245 }
1246+
1247+ #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
1248+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1249+ EXPECT_EQ (Group, M->getAtomGroup ()); \
1250+ EXPECT_EQ (Rank, M->getAtomRank ());
1251+ #else
1252+ #define EXPECT_ATOM (Loc, Group, Rank ) \
1253+ EXPECT_EQ (0u , M->getAtomGroup ()); \
1254+ EXPECT_EQ (0u , M->getAtomRank ()); \
1255+ (void )Group; \
1256+ (void )Rank;
1257+ #endif
1258+ // Identical, including source atom numbers.
1259+ {
1260+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1261+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1262+ auto *M = DILocation::getMergedLocation (A, B);
1263+ EXPECT_ATOM (M, 1u , 1u );
1264+ // DILocations are uniqued, so we can check equality by ptr.
1265+ EXPECT_EQ (M, DILocation::getMergedLocation (A, B));
1266+ }
1267+
1268+ // Identical but different atom ranks (same atom) - choose the lowest nonzero
1269+ // rank.
1270+ {
1271+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1272+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 2 );
1273+ auto *M = DILocation::getMergedLocation (A, B);
1274+ EXPECT_ATOM (M, 1u , 1u );
1275+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1276+
1277+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 0 );
1278+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 2 );
1279+ M = DILocation::getMergedLocation (A, B);
1280+ EXPECT_ATOM (M, 1u , 2u );
1281+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1282+ }
1283+
1284+ // Identical but different atom ranks (different atom) - choose the lowest
1285+ // nonzero rank.
1286+ {
1287+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1288+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 2 );
1289+ auto *M = DILocation::getMergedLocation (A, B);
1290+ EXPECT_ATOM (M, 1u , 1u );
1291+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1292+
1293+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 0 );
1294+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 2 );
1295+ M = DILocation::getMergedLocation (A, B);
1296+ EXPECT_ATOM (M, 2u , 2u );
1297+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1298+ }
1299+
1300+ // Identical but equal atom rank (different atom) - choose the lowest non-zero
1301+ // group (arbitrary choice for deterministic behaviour).
1302+ {
1303+ auto *A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 1 , 1 );
1304+ auto *B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 1 );
1305+ auto *M = DILocation::getMergedLocation (A, B);
1306+ EXPECT_ATOM (M, 1u , 1u );
1307+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1308+
1309+ A = DILocation::get (Context, 2 , 7 , N, nullptr , false , 0 , 1 );
1310+ B = DILocation::get (Context, 2 , 7 , N, nullptr , false , 2 , 1 );
1311+ M = DILocation::getMergedLocation (A, B);
1312+ EXPECT_ATOM (M, 2u , 1u );
1313+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1314+ }
1315+
1316+ // Completely different except same atom numbers. Zero out the atoms.
1317+ {
1318+ auto *I = DILocation::get (Context, 2 , 7 , N);
1319+ auto *A = DILocation::get (Context, 1 , 6 , S, I, false , 1 , 1 );
1320+ auto *B =
1321+ DILocation::get (Context, 2 , 7 , getSubprogram (), nullptr , false , 1 , 1 );
1322+ auto *M = DILocation::getMergedLocation (A, B);
1323+ EXPECT_EQ (0u , M->getLine ());
1324+ EXPECT_EQ (0u , M->getColumn ());
1325+ EXPECT_TRUE (isa<DILocalScope>(M->getScope ()));
1326+ EXPECT_EQ (S, M->getScope ());
1327+ EXPECT_EQ (nullptr , M->getInlinedAt ());
1328+ }
1329+
1330+ // Same inlined-at chain but different atoms. Choose the lowest
1331+ // non-zero group (arbitrary choice for deterministic behaviour).
1332+ {
1333+ auto *I = DILocation::get (Context, 1 , 7 , N);
1334+ auto *F = getSubprogram ();
1335+ auto *A = DILocation::get (Context, 1 , 1 , F, I, false , 1 , 2 );
1336+ auto *B = DILocation::get (Context, 1 , 1 , F, I, false , 2 , 1 );
1337+ auto *M = DILocation::getMergedLocation (A, B);
1338+ EXPECT_ATOM (M, 2u , 1u );
1339+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1340+
1341+ A = DILocation::get (Context, 1 , 1 , F, I, false , 1 , 2 );
1342+ B = DILocation::get (Context, 1 , 1 , F, I, false , 2 , 0 );
1343+ M = DILocation::getMergedLocation (A, B);
1344+ EXPECT_ATOM (M, 1u , 2u );
1345+ EXPECT_EQ (M, DILocation::getMergedLocation (B, A));
1346+ }
1347+
1348+ // Partially equal inlined-at chain but different atoms. Generate a new atom
1349+ // group (if either have a group number). This configuration seems unlikely
1350+ // to occur as line numbers must match, but isn't impossible.
1351+ {
1352+ // Reset global counter to ensure EXPECT numbers line up.
1353+ Context.pImpl ->NextAtomGroup = 1 ;
1354+ // x1 -> y2 -> z4
1355+ // y3 -> z4
1356+ auto *FX = getSubprogram ();
1357+ auto *FY = getSubprogram ();
1358+ auto *FZ = getSubprogram ();
1359+ auto *Z4 = DILocation::get (Context, 1 , 4 , FZ);
1360+ auto *Y3IntoZ4 = DILocation::get (Context, 1 , 3 , FY, Z4, false , 1 , 1 );
1361+ auto *Y2IntoZ4 = DILocation::get (Context, 1 , 2 , FY, Z4);
1362+ auto *X1IntoY2 = DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4);
1363+ auto *M = DILocation::getMergedLocation (X1IntoY2, Y3IntoZ4);
1364+ EXPECT_EQ (M->getScope (), FY);
1365+ EXPECT_EQ (M->getInlinedAt ()->getScope (), FZ);
1366+ EXPECT_ATOM (M, 2u , 1u );
1367+
1368+ // This swapped merge will produce a new atom group too.
1369+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2);
1370+
1371+ // Same again, even if the atom numbers match.
1372+ auto *X1IntoY2SameAtom =
1373+ DILocation::get (Context, 1 , 1 , FX, Y2IntoZ4, false , 1 , 1 );
1374+ M = DILocation::getMergedLocation (X1IntoY2SameAtom, Y3IntoZ4);
1375+ EXPECT_ATOM (M, 4u , 1u );
1376+ M = DILocation::getMergedLocation (Y3IntoZ4, X1IntoY2SameAtom);
1377+ EXPECT_ATOM (M, 5u , 1u );
1378+ }
1379+ #undef EXPECT_ATOM
12461380}
12471381
12481382TEST_F (DILocationTest, getDistinct) {
0 commit comments