@@ -274,13 +274,19 @@ static cl::opt<bool>
274
274
cl::desc (" propagate shadow through ICmpEQ and ICmpNE" ),
275
275
cl::Hidden, cl::init(true ));
276
276
277
- static cl::opt<uint > ClEmbedFaultingInst (
277
+ static cl::opt<MSanEmbedFaultingInstructionMode > ClEmbedFaultingInst (
278
278
" msan-embed-faulting-instruction" ,
279
- cl::desc (" If set to 1, embed the name of the LLVM IR instruction that "
280
- " failed the shadow check."
281
- " If set to 2, embed the full LLVM IR instruction. "
282
- " The runtime can print the embedded instruction." ),
283
- cl::Hidden, cl::init(0 ));
279
+ cl::desc (" [EXPERIMENTAL] Sets whether to embed the LLVM IR instruction "
280
+ " info for each UUM check." ),
281
+ cl::values(
282
+ clEnumValN (MSanEmbedFaultingInstructionMode::None, " none" ,
283
+ " Do not embed the faulting instruction information." ),
284
+ clEnumValN(MSanEmbedFaultingInstructionMode::Name, " name" ,
285
+ " Embed the LLVM IR instruction name (excluding operands)." ),
286
+ clEnumValN(
287
+ MSanEmbedFaultingInstructionMode::Full, " full" ,
288
+ " Embed the complete LLVM IR instruction (including operands)." )),
289
+ cl::Hidden, cl::init(MSanEmbedFaultingInstructionMode::None));
284
290
285
291
static cl::opt<bool >
286
292
ClHandleICmpExact (" msan-handle-icmp-exact" ,
@@ -824,7 +830,7 @@ void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
824
830
VAArgOriginTLS = nullptr ;
825
831
VAArgOverflowSizeTLS = nullptr ;
826
832
827
- if (ClEmbedFaultingInst)
833
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None )
828
834
WarningFn = M.getOrInsertFunction (
829
835
" __msan_warning_instname" , TLI.getAttrList (C, {0 }, /* Signed=*/ false ),
830
836
IRB.getVoidTy (), IRB.getInt32Ty (), IRB.getPtrTy ());
@@ -889,7 +895,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
889
895
// FIXME: this function should have "Cold" calling conv,
890
896
// which is not yet implemented.
891
897
if (TrackOrigins) {
892
- if (ClEmbedFaultingInst) {
898
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None ) {
893
899
StringRef WarningFnName =
894
900
Recover ? " __msan_warning_with_origin_instname"
895
901
: " __msan_warning_with_origin_noreturn_instname" ;
@@ -904,7 +910,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
904
910
IRB.getVoidTy (), IRB.getInt32Ty ());
905
911
}
906
912
} else {
907
- if (ClEmbedFaultingInst) {
913
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None ) {
908
914
StringRef WarningFnName = Recover ? " __msan_warning_instname"
909
915
: " __msan_warning_noreturn_instname" ;
910
916
WarningFn =
@@ -946,7 +952,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
946
952
AccessSizeIndex++) {
947
953
unsigned AccessSize = 1 << AccessSizeIndex;
948
954
std::string FunctionName;
949
- if (ClEmbedFaultingInst) {
955
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None ) {
950
956
FunctionName = " __msan_maybe_warning_instname_" + itostr (AccessSize);
951
957
MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction (
952
958
FunctionName, TLI.getAttrList (C, {0 , 1 }, /* Signed=*/ false ),
@@ -1450,7 +1456,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1450
1456
}
1451
1457
}
1452
1458
1453
- if (ClEmbedFaultingInst) {
1459
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None ) {
1454
1460
if (MS.CompileKernel || MS.TrackOrigins )
1455
1461
IRB.CreateCall (MS.WarningFn , {Origin, InstName})->setCannotMerge ();
1456
1462
else
@@ -1479,7 +1485,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1479
1485
Value *ConvertedShadow2 =
1480
1486
IRB.CreateZExt (ConvertedShadow, IRB.getIntNTy (8 * (1 << SizeIndex)));
1481
1487
CallBase *CB;
1482
- if (ClEmbedFaultingInst)
1488
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None )
1483
1489
CB = IRB.CreateCall (
1484
1490
Fn, {ConvertedShadow2,
1485
1491
MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32 (0 ),
@@ -1500,34 +1506,28 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1500
1506
1501
1507
IRB.SetInsertPoint (CheckTerm);
1502
1508
// InstName will be ignored by insertWarningFn if ClEmbedFaultingInst is
1503
- // false
1509
+ // MSanEmbedFaultingInstructionMode::None
1504
1510
insertWarningFn (IRB, Origin, InstName);
1505
1511
LLVM_DEBUG (dbgs () << " CHECK: " << *Cmp << " \n " );
1506
1512
}
1507
1513
}
1508
1514
1509
- void materializeInstructionChecks (
1510
- ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1511
- const DataLayout &DL = F.getDataLayout ();
1512
- // Disable combining in some cases. TrackOrigins checks each shadow to pick
1513
- // correct origin.
1514
- bool Combine = !MS.TrackOrigins ;
1515
- Instruction *Instruction = InstructionChecks.front ().OrigIns ;
1516
-
1515
+ Value *getInstName (Instruction *Instruction) {
1517
1516
Value *InstName = nullptr ;
1518
- if (ClEmbedFaultingInst >= 1 ) {
1517
+ if (ClEmbedFaultingInst != MSanEmbedFaultingInstructionMode::None ) {
1519
1518
IRBuilder<> IRB0 (Instruction);
1520
1519
std::string str;
1521
1520
StringRef InstNameStrRef;
1522
1521
1523
1522
// Dumping the full instruction is expensive because the operands etc.
1524
1523
// likely make the string unique per instruction instance, hence we
1525
1524
// offer a choice whether to only print the instruction name.
1526
- if (ClEmbedFaultingInst >= 2 ) {
1525
+ if (ClEmbedFaultingInst == MSanEmbedFaultingInstructionMode::Full ) {
1527
1526
llvm::raw_string_ostream buf (str);
1528
1527
Instruction->print (buf);
1529
1528
InstNameStrRef = StringRef (str);
1530
- } else if (ClEmbedFaultingInst >= 1 ) {
1529
+ } else if (ClEmbedFaultingInst ==
1530
+ MSanEmbedFaultingInstructionMode::Name) {
1531
1531
if (CallInst *CI = dyn_cast<CallInst>(Instruction)) {
1532
1532
if (CI->getCalledFunction ()) {
1533
1533
Twine description = " call " + CI->getCalledFunction ()->getName ();
@@ -1544,12 +1544,26 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1544
1544
InstName = IRB0.CreateGlobalString (InstNameStrRef);
1545
1545
}
1546
1546
1547
+ return InstName;
1548
+ }
1549
+
1550
+ void materializeInstructionChecks (
1551
+ ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1552
+ const DataLayout &DL = F.getDataLayout ();
1553
+ // Disable combining in some cases. TrackOrigins checks each shadow to pick
1554
+ // correct origin.
1555
+ bool Combine = !MS.TrackOrigins ;
1556
+ Instruction *Instruction = InstructionChecks.front ().OrigIns ;
1557
+
1558
+ Value *InstName = getInstName (Instruction);
1559
+
1547
1560
Value *Shadow = nullptr ;
1548
1561
for (const auto &ShadowData : InstructionChecks) {
1549
1562
assert (ShadowData.OrigIns == Instruction);
1550
1563
IRBuilder<> IRB (Instruction);
1551
1564
1552
1565
Value *ConvertedShadow = ShadowData.Shadow ;
1566
+
1553
1567
if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1554
1568
if (!ClCheckConstantShadow || ConstantShadow->isZeroValue ()) {
1555
1569
// Skip, value is initialized or const shadow is ignored.
0 commit comments