@@ -232,6 +232,11 @@ static cl::opt<bool>
232
232
cl::desc (" instrument byval call arguments" ), cl::Hidden,
233
233
cl::init(true ));
234
234
235
+ static cl::opt<bool >
236
+ ClInstrumentAMDGPULDS (" asan-instrument-amdgpu-lds" ,
237
+ cl::desc (" instrument amdgpu LDS accesses" ),
238
+ cl::Hidden, cl::init(true ));
239
+
235
240
static cl::opt<bool > ClAlwaysSlowPath (
236
241
" asan-always-slow-path" ,
237
242
cl::desc (" use instrumentation with slow path for all accesses" ), cl::Hidden,
@@ -1293,8 +1298,8 @@ static GlobalVariable *getKernelSwLDSBaseGlobal(Module &M) {
1293
1298
static void updateLDSSizeFnAttr (Function *Func, uint32_t Offset,
1294
1299
bool UsesDynLDS) {
1295
1300
if (Offset != 0 ) {
1296
- std::string Buffer;
1297
- raw_string_ostream SS{ Buffer} ;
1301
+ SmallString< 256 > Buffer;
1302
+ raw_svector_ostream SS ( Buffer) ;
1298
1303
SS << format (" %u" , Offset);
1299
1304
if (UsesDynLDS)
1300
1305
SS << format (" ,%u" , Offset);
@@ -1312,33 +1317,30 @@ static void recordLDSAbsoluteAddress(Module &M, GlobalVariable *GV,
1312
1317
MDNode::get (Ctx, {MinC, MaxC}));
1313
1318
}
1314
1319
1315
- static void UpdateSwLDSMetadataWithRedzoneInfo (Function &F, int Scale) {
1320
+ // / Update SwLDS Metadata global initializer with redzone info.
1321
+ static SmallVector<std::pair<uint32_t , uint32_t >, 64 >
1322
+ UpdateSwLDSMetadataWithRedzoneInfo (Function &F, int Scale) {
1316
1323
Module *M = F.getParent ();
1317
1324
GlobalVariable *SwLDSMetadataGlobal = getKernelSwLDSMetadataGlobal (*M, F);
1318
1325
GlobalVariable *SwLDSGlobal = getKernelSwLDSGlobal (*M, F);
1319
1326
if (!SwLDSMetadataGlobal || !SwLDSGlobal)
1320
- return ;
1327
+ return {} ;
1321
1328
1322
1329
LLVMContext &Ctx = M->getContext ();
1323
1330
Type *Int32Ty = Type::getInt32Ty (Ctx);
1324
-
1331
+ SmallVector<std::pair< uint32_t , uint32_t >, 64 > RedzoneOffsetAndSizeVector;
1325
1332
Constant *MdInit = SwLDSMetadataGlobal->getInitializer ();
1326
- Align MdAlign = Align (SwLDSMetadataGlobal->getAlign ().valueOrOne ());
1327
1333
Align LDSAlign = Align (SwLDSGlobal->getAlign ().valueOrOne ());
1328
1334
1329
1335
StructType *MDStructType =
1330
1336
cast<StructType>(SwLDSMetadataGlobal->getValueType ());
1331
- assert (MDStructType);
1332
1337
unsigned NumStructs = MDStructType->getNumElements ();
1333
-
1334
- std::vector<Type *> Items;
1335
1338
std::vector<Constant *> Initializers;
1336
1339
uint32_t MallocSize = 0 ;
1337
- // {GV.start, Align(GV.size + Redzone.size), Redzone.start, Redzone.size}
1338
- StructType *LDSItemTy = StructType::create (
1339
- Ctx, {Int32Ty, Int32Ty, Int32Ty, Int32Ty, Int32Ty}, " " );
1340
+ StructType *LDSItemTy =
1341
+ cast< StructType>(MDStructType-> getStructElementType ( 0 ));
1342
+
1340
1343
for (unsigned i = 0 ; i < NumStructs; i++) {
1341
- Items.push_back (LDSItemTy);
1342
1344
ConstantStruct *member =
1343
1345
dyn_cast<ConstantStruct>(MdInit->getAggregateElement (i));
1344
1346
Constant *NewInitItem;
@@ -1353,91 +1355,48 @@ static void UpdateSwLDSMetadataWithRedzoneInfo(Function &F, int Scale) {
1353
1355
const uint64_t RightRedzoneSize =
1354
1356
getRedzoneSizeForGlobal (Scale, GlobalSizeValue);
1355
1357
MallocSize += GlobalSizeValue;
1356
- Constant *NewItemRedzoneStartOffset =
1357
- ConstantInt::get (Int32Ty, MallocSize);
1358
+ RedzoneOffsetAndSizeVector.emplace_back (MallocSize, RightRedzoneSize);
1358
1359
MallocSize += RightRedzoneSize;
1359
- Constant *NewItemRedzoneSize =
1360
- ConstantInt::get (Int32Ty, RightRedzoneSize);
1361
-
1362
1360
unsigned NewItemAlignGlobalPlusRedzoneSize =
1363
1361
alignTo (GlobalSizeValue + RightRedzoneSize, LDSAlign);
1364
1362
Constant *NewItemAlignGlobalPlusRedzoneSizeConst =
1365
1363
ConstantInt::get (Int32Ty, NewItemAlignGlobalPlusRedzoneSize);
1366
1364
NewInitItem = ConstantStruct::get (
1367
1365
LDSItemTy, {NewItemStartOffset, NewItemGlobalSizeConst,
1368
- NewItemAlignGlobalPlusRedzoneSizeConst,
1369
- NewItemRedzoneStartOffset, NewItemRedzoneSize});
1366
+ NewItemAlignGlobalPlusRedzoneSizeConst});
1370
1367
MallocSize = alignTo (MallocSize, LDSAlign);
1371
1368
} else {
1372
1369
Constant *CurrMallocSize = ConstantInt::get (Int32Ty, MallocSize);
1373
1370
Constant *zero = ConstantInt::get (Int32Ty, 0 );
1374
- NewInitItem = ConstantStruct::get (
1375
- LDSItemTy, {CurrMallocSize, zero, zero, zero, zero});
1371
+ NewInitItem =
1372
+ ConstantStruct::get (LDSItemTy, {CurrMallocSize, zero, zero});
1373
+ RedzoneOffsetAndSizeVector.emplace_back (0 , 0 );
1376
1374
}
1377
1375
} else {
1378
1376
Constant *CurrMallocSize = ConstantInt::get (Int32Ty, MallocSize);
1379
1377
Constant *zero = ConstantInt::get (Int32Ty, 0 );
1380
- NewInitItem = ConstantStruct::get (
1381
- LDSItemTy, {CurrMallocSize, zero, zero, zero, zero});
1378
+ NewInitItem =
1379
+ ConstantStruct::get (LDSItemTy, {CurrMallocSize, zero, zero});
1380
+ RedzoneOffsetAndSizeVector.emplace_back (0 , 0 );
1382
1381
}
1383
1382
Initializers.push_back (NewInitItem);
1384
1383
}
1385
1384
GlobalVariable *SwDynLDS = getKernelSwDynLDSGlobal (*M, F);
1386
- bool usesDynLDS = SwDynLDS ? true : false ;
1385
+ bool usesDynLDS = SwDynLDS != nullptr ;
1387
1386
updateLDSSizeFnAttr (&F, MallocSize, usesDynLDS);
1388
1387
if (usesDynLDS)
1389
1388
recordLDSAbsoluteAddress (*M, SwDynLDS, MallocSize);
1390
1389
1391
- StructType *MetadataStructType = StructType::create (Ctx, Items, " " );
1392
-
1393
- GlobalVariable *NewSwLDSMetadataGlobal = new GlobalVariable (
1394
- *M, MetadataStructType, false , GlobalValue::InternalLinkage,
1395
- PoisonValue::get (MetadataStructType), " " , nullptr ,
1396
- GlobalValue::NotThreadLocal, 1 , false );
1397
- Constant *Data = ConstantStruct::get (MetadataStructType, Initializers);
1398
- NewSwLDSMetadataGlobal->setInitializer (Data);
1399
- NewSwLDSMetadataGlobal->setAlignment (MdAlign);
1400
- GlobalValue::SanitizerMetadata MD;
1401
- MD.NoAddress = true ;
1402
- NewSwLDSMetadataGlobal->setSanitizerMetadata (MD);
1403
-
1404
- for (Use &U : make_early_inc_range (SwLDSMetadataGlobal->uses ())) {
1405
- if (GEPOperator *GEP = dyn_cast<GEPOperator>(U.getUser ())) {
1406
- SmallVector<Constant *> Indices;
1407
- for (Use &Idx : GEP->indices ()) {
1408
- Indices.push_back (cast<Constant>(Idx));
1409
- }
1410
- Constant *NewGEP = ConstantExpr::getGetElementPtr (
1411
- MetadataStructType, NewSwLDSMetadataGlobal, Indices, true );
1412
- GEP->replaceAllUsesWith (NewGEP);
1413
- } else if (LoadInst *Load = dyn_cast<LoadInst>(U.getUser ())) {
1414
- Constant *zero = ConstantInt::get (Int32Ty, 0 );
1415
- SmallVector<Constant *> Indices{zero, zero, zero};
1416
- Constant *NewGEP = ConstantExpr::getGetElementPtr (
1417
- MetadataStructType, NewSwLDSMetadataGlobal, Indices, true );
1418
- IRBuilder<> IRB (Load);
1419
- LoadInst *NewLoad = IRB.CreateLoad (Load->getType (), NewGEP);
1420
- Load->replaceAllUsesWith (NewLoad);
1421
- Load->eraseFromParent ();
1422
- } else if (StoreInst *Store = dyn_cast<StoreInst>(U.getUser ())) {
1423
- Constant *zero = ConstantInt::get (Int32Ty, 0 );
1424
- SmallVector<Constant *> Indices{zero, zero, zero};
1425
- Constant *NewGEP = ConstantExpr::getGetElementPtr (
1426
- MetadataStructType, NewSwLDSMetadataGlobal, Indices, true );
1427
- IRBuilder<> IRB (Store);
1428
- StoreInst *NewStore = IRB.CreateStore (Store->getValueOperand (), NewGEP);
1429
- Store->replaceAllUsesWith (NewStore);
1430
- Store->eraseFromParent ();
1431
- } else
1432
- report_fatal_error (" AMDGPU Sw LDS Metadata User instruction not handled" );
1433
- }
1434
- SwLDSMetadataGlobal->replaceAllUsesWith (NewSwLDSMetadataGlobal);
1435
- NewSwLDSMetadataGlobal->takeName (SwLDSMetadataGlobal);
1436
- SwLDSMetadataGlobal->eraseFromParent ();
1437
- return ;
1390
+ Constant *Data = ConstantStruct::get (MDStructType, Initializers);
1391
+ SwLDSMetadataGlobal->setInitializer (Data);
1392
+ return RedzoneOffsetAndSizeVector;
1438
1393
}
1439
1394
1440
- static void poisonRedzonesForSwLDS (Function &F) {
1395
+ // / Poison redzone regions using the redzone size and offset info.
1396
+ static void
1397
+ poisonRedzonesForSwLDS (Function &F,
1398
+ SmallVector<std::pair<uint32_t , uint32_t >, 64 >
1399
+ &RedzoneOffsetAndSizeVector) {
1441
1400
Module *M = F.getParent ();
1442
1401
GlobalVariable *SwLDSGlobal = getKernelSwLDSGlobal (*M, F);
1443
1402
GlobalVariable *SwLDSMetadataGlobal = getKernelSwLDSMetadataGlobal (*M, F);
@@ -1466,10 +1425,10 @@ static void poisonRedzonesForSwLDS(Function &F) {
1466
1425
1467
1426
StructType *MDStructType =
1468
1427
cast<StructType>(SwLDSMetadataGlobal->getValueType ());
1469
- assert (MDStructType);
1470
1428
unsigned NumStructs = MDStructType->getNumElements ();
1471
1429
Value *StoreMallocPointer = SI->getValueOperand ();
1472
1430
1431
+ assert (RedzoneOffsetAndSizeVector.size () == NumStructs);
1473
1432
for (unsigned i = 0 ; i < NumStructs; i++) {
1474
1433
ConstantStruct *member =
1475
1434
dyn_cast<ConstantStruct>(MdInit->getAggregateElement (i));
@@ -1484,35 +1443,28 @@ static void poisonRedzonesForSwLDS(Function &F) {
1484
1443
continue ;
1485
1444
IRBuilder<> IRB (SI);
1486
1445
IRB.SetInsertPoint (SI->getNextNode ());
1446
+ auto &RedzonePair = RedzoneOffsetAndSizeVector[i];
1447
+ uint64_t RedzoneOffset = RedzonePair.first ;
1448
+ uint64_t RedzoneSize = RedzonePair.second ;
1487
1449
1488
- auto *GEPForOffset = IRB.CreateInBoundsGEP (
1489
- MDStructType, SwLDSMetadataGlobal,
1490
- {IRB.getInt32 (0 ), IRB.getInt32 (i), IRB.getInt32 (3 )});
1491
-
1492
- auto *GEPForSize = IRB.CreateInBoundsGEP (
1493
- MDStructType, SwLDSMetadataGlobal,
1494
- {IRB.getInt32 (0 ), IRB.getInt32 (i), IRB.getInt32 (4 )});
1495
-
1496
- Value *RedzoneOffset = IRB.CreateLoad (IRB.getInt32Ty (), GEPForOffset);
1497
- RedzoneOffset = IRB.CreateZExt (RedzoneOffset, IRB.getInt64Ty ());
1498
1450
Value *RedzoneAddrOffset = IRB.CreateInBoundsGEP (
1499
- IRB.getInt8Ty (), StoreMallocPointer, {RedzoneOffset});
1451
+ IRB.getInt8Ty (), StoreMallocPointer, {IRB. getInt64 ( RedzoneOffset) });
1500
1452
Value *RedzoneAddress =
1501
1453
IRB.CreatePtrToInt (RedzoneAddrOffset, IRB.getInt64Ty ());
1502
- Value *RedzoneSize = IRB.CreateLoad (IRB.getInt32Ty (), GEPForSize);
1503
- RedzoneSize = IRB.CreateZExt (RedzoneSize, IRB.getInt64Ty ());
1504
- IRB.CreateCall (AsanPoisonRegion, {RedzoneAddress, RedzoneSize});
1454
+ IRB.CreateCall (AsanPoisonRegion,
1455
+ {RedzoneAddress, IRB.getInt64 (RedzoneSize)});
1505
1456
}
1506
1457
}
1507
- return ;
1508
1458
}
1509
1459
1460
+ // / Update SwLDS Metadata global initializer with redzone info.
1461
+ // / Poison redzone regions using the redzone size and offset info.
1510
1462
static void preProcessAMDGPULDSAccesses (Module &M, int Scale) {
1511
1463
for (Function &F : M) {
1512
- UpdateSwLDSMetadataWithRedzoneInfo (F, Scale);
1513
- poisonRedzonesForSwLDS (F);
1464
+ auto RedzoneOffsetAndSizeVector =
1465
+ UpdateSwLDSMetadataWithRedzoneInfo (F, Scale);
1466
+ poisonRedzonesForSwLDS (F, RedzoneOffsetAndSizeVector);
1514
1467
}
1515
- return ;
1516
1468
}
1517
1469
1518
1470
AddressSanitizerPass::AddressSanitizerPass (
@@ -1527,7 +1479,7 @@ PreservedAnalyses AddressSanitizerPass::run(Module &M,
1527
1479
ModuleAnalysisManager &MAM) {
1528
1480
Triple TargetTriple = Triple (M.getTargetTriple ());
1529
1481
1530
- if (TargetTriple.isAMDGPU ()) {
1482
+ if (TargetTriple.isAMDGPU () && ClInstrumentAMDGPULDS ) {
1531
1483
unsigned LongSize = M.getDataLayout ().getPointerSizeInBits ();
1532
1484
ShadowMapping Mapping = getShadowMapping (TargetTriple, LongSize, false );
1533
1485
preProcessAMDGPULDSAccesses (M, Mapping.Scale );
@@ -2147,7 +2099,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
2147
2099
}
2148
2100
2149
2101
Value *AddrLong;
2150
- if (TargetTriple.isAMDGCN () ) {
2102
+ if (TargetTriple.isAMDGPU () && ClInstrumentAMDGPULDS ) {
2151
2103
Type *PtrTy = cast<PointerType>(Addr->getType ()->getScalarType ());
2152
2104
if (PtrTy->getPointerAddressSpace () == 3 ) {
2153
2105
Module *M = IRB.GetInsertBlock ()->getParent ()->getParent ();
@@ -2168,6 +2120,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
2168
2120
SwLDS = IRB.CreateIntToPtr (IRB.getInt32 (0 ), IRB.getPtrTy (3 ));
2169
2121
}
2170
2122
}
2123
+ assert (SwLDS && " Invalid AMDGPU Sw LDS base ptr" );
2171
2124
Value *PtrToInt = IRB.CreatePtrToInt (Addr, IRB.getInt32Ty ());
2172
2125
Value *LoadMallocPtr = IRB.CreateLoad (IRB.getPtrTy (1 ), SwLDS);
2173
2126
Value *GEP =
0 commit comments