@@ -1243,6 +1243,140 @@ TEST_F(DILocationTest, Merge) {
1243
1243
auto *M2 = DILocation::getMergedLocation (A2, B);
1244
1244
EXPECT_EQ (M1, M2);
1245
1245
}
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
1246
1380
}
1247
1381
1248
1382
TEST_F (DILocationTest, getDistinct) {
0 commit comments