1 //===-- NumericalStabilitySanitizer.cpp -----------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the instrumentation pass for the numerical sanitizer. 10 // Conceptually the pass injects shadow computations using higher precision 11 // types and inserts consistency checks. For details see the paper 12 // https://arxiv.org/abs/2102.12782. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h" 17 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/Statistic.h" 22 #include "llvm/ADT/StringExtras.h" 23 #include "llvm/Analysis/TargetLibraryInfo.h" 24 #include "llvm/Analysis/ValueTracking.h" 25 #include "llvm/IR/DataLayout.h" 26 #include "llvm/IR/Function.h" 27 #include "llvm/IR/IRBuilder.h" 28 #include "llvm/IR/IntrinsicInst.h" 29 #include "llvm/IR/Intrinsics.h" 30 #include "llvm/IR/LLVMContext.h" 31 #include "llvm/IR/MDBuilder.h" 32 #include "llvm/IR/Metadata.h" 33 #include "llvm/IR/Module.h" 34 #include "llvm/IR/Type.h" 35 #include "llvm/InitializePasses.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/Debug.h" 38 #include "llvm/Support/MathExtras.h" 39 #include "llvm/Support/Regex.h" 40 #include "llvm/Support/raw_ostream.h" 41 #include "llvm/Transforms/Instrumentation.h" 42 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 43 #include "llvm/Transforms/Utils/EscapeEnumerator.h" 44 #include "llvm/Transforms/Utils/Local.h" 45 #include "llvm/Transforms/Utils/ModuleUtils.h" 46 47 #include <cstdint> 48 49 using namespace llvm; 50 51 #define DEBUG_TYPE "nsan" 52 53 STATISTIC(NumInstrumentedFTLoads, 54 "Number of instrumented floating-point loads"); 55 56 STATISTIC(NumInstrumentedFTCalls, 57 "Number of instrumented floating-point calls"); 58 STATISTIC(NumInstrumentedFTRets, 59 "Number of instrumented floating-point returns"); 60 STATISTIC(NumInstrumentedFTStores, 61 "Number of instrumented floating-point stores"); 62 STATISTIC(NumInstrumentedNonFTStores, 63 "Number of instrumented non floating-point stores"); 64 STATISTIC( 65 NumInstrumentedNonFTMemcpyStores, 66 "Number of instrumented non floating-point stores with memcpy semantics"); 67 STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps"); 68 69 // Using smaller shadow types types can help improve speed. For example, `dlq` 70 // is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared to 71 // `dqq`. 72 static cl::opt<std::string> ClShadowMapping( 73 "nsan-shadow-type-mapping", cl::init("dqq"), 74 cl::desc("One shadow type id for each of `float`, `double`, `long double`. " 75 "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and " 76 "ppc_fp128 (extended double) respectively. The default is to " 77 "shadow `float` as `double`, and `double` and `x86_fp80` as " 78 "`fp128`"), 79 cl::Hidden); 80 81 static cl::opt<bool> 82 ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true), 83 cl::desc("Instrument floating-point comparisons"), 84 cl::Hidden); 85 86 static cl::opt<std::string> ClCheckFunctionsFilter( 87 "check-functions-filter", 88 cl::desc("Only emit checks for arguments of functions " 89 "whose names match the given regular expression"), 90 cl::value_desc("regex")); 91 92 static cl::opt<bool> ClTruncateFCmpEq( 93 "nsan-truncate-fcmp-eq", cl::init(true), 94 cl::desc( 95 "This flag controls the behaviour of fcmp equality comparisons." 96 "For equality comparisons such as `x == 0.0f`, we can perform the " 97 "shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app " 98 " domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps " 99 "catch the case when `x_shadow` is accurate enough (and therefore " 100 "close enough to zero) so that `trunc(x_shadow)` is zero even though " 101 "both `x` and `x_shadow` are not"), 102 cl::Hidden); 103 104 // When there is external, uninstrumented code writing to memory, the shadow 105 // memory can get out of sync with the application memory. Enabling this flag 106 // emits consistency checks for loads to catch this situation. 107 // When everything is instrumented, this is not strictly necessary because any 108 // load should have a corresponding store, but can help debug cases when the 109 // framework did a bad job at tracking shadow memory modifications by failing on 110 // load rather than store. 111 // TODO: provide a way to resume computations from the FT value when the load 112 // is inconsistent. This ensures that further computations are not polluted. 113 static cl::opt<bool> ClCheckLoads("nsan-check-loads", 114 cl::desc("Check floating-point load"), 115 cl::Hidden); 116 117 static cl::opt<bool> ClCheckStores("nsan-check-stores", cl::init(true), 118 cl::desc("Check floating-point stores"), 119 cl::Hidden); 120 121 static cl::opt<bool> ClCheckRet("nsan-check-ret", cl::init(true), 122 cl::desc("Check floating-point return values"), 123 cl::Hidden); 124 125 // LLVM may store constant floats as bitcasted ints. 126 // It's not really necessary to shadow such stores, 127 // if the shadow value is unknown the framework will re-extend it on load 128 // anyway. Moreover, because of size collisions (e.g. bf16 vs f16) it is 129 // impossible to determine the floating-point type based on the size. 130 // However, for debugging purposes it can be useful to model such stores. 131 static cl::opt<bool> ClPropagateNonFTConstStoresAsFT( 132 "nsan-propagate-non-ft-const-stores-as-ft", 133 cl::desc( 134 "Propagate non floating-point const stores as floating point values." 135 "For debugging purposes only"), 136 cl::Hidden); 137 138 constexpr StringLiteral kNsanModuleCtorName("nsan.module_ctor"); 139 constexpr StringLiteral kNsanInitName("__nsan_init"); 140 141 // The following values must be kept in sync with the runtime. 142 constexpr int kShadowScale = 2; 143 constexpr int kMaxVectorWidth = 8; 144 constexpr int kMaxNumArgs = 128; 145 constexpr int kMaxShadowTypeSizeBytes = 16; // fp128 146 147 namespace { 148 149 // Defines the characteristics (type id, type, and floating-point semantics) 150 // attached for all possible shadow types. 151 class ShadowTypeConfig { 152 public: 153 static std::unique_ptr<ShadowTypeConfig> fromNsanTypeId(char TypeId); 154 155 // The LLVM Type corresponding to the shadow type. 156 virtual Type *getType(LLVMContext &Context) const = 0; 157 158 // The nsan type id of the shadow type (`d`, `l`, `q`, ...). 159 virtual char getNsanTypeId() const = 0; 160 161 virtual ~ShadowTypeConfig() = default; 162 }; 163 164 template <char NsanTypeId> 165 class ShadowTypeConfigImpl : public ShadowTypeConfig { 166 public: 167 char getNsanTypeId() const override { return NsanTypeId; } 168 static constexpr const char kNsanTypeId = NsanTypeId; 169 }; 170 171 // `double` (`d`) shadow type. 172 class F64ShadowConfig : public ShadowTypeConfigImpl<'d'> { 173 Type *getType(LLVMContext &Context) const override { 174 return Type::getDoubleTy(Context); 175 } 176 }; 177 178 // `x86_fp80` (`l`) shadow type: X86 long double. 179 class F80ShadowConfig : public ShadowTypeConfigImpl<'l'> { 180 Type *getType(LLVMContext &Context) const override { 181 return Type::getX86_FP80Ty(Context); 182 } 183 }; 184 185 // `fp128` (`q`) shadow type. 186 class F128ShadowConfig : public ShadowTypeConfigImpl<'q'> { 187 Type *getType(LLVMContext &Context) const override { 188 return Type::getFP128Ty(Context); 189 } 190 }; 191 192 // `ppc_fp128` (`e`) shadow type: IBM extended double with 106 bits of mantissa. 193 class PPC128ShadowConfig : public ShadowTypeConfigImpl<'e'> { 194 Type *getType(LLVMContext &Context) const override { 195 return Type::getPPC_FP128Ty(Context); 196 } 197 }; 198 199 // Creates a ShadowTypeConfig given its type id. 200 std::unique_ptr<ShadowTypeConfig> 201 ShadowTypeConfig::fromNsanTypeId(const char TypeId) { 202 switch (TypeId) { 203 case F64ShadowConfig::kNsanTypeId: 204 return std::make_unique<F64ShadowConfig>(); 205 case F80ShadowConfig::kNsanTypeId: 206 return std::make_unique<F80ShadowConfig>(); 207 case F128ShadowConfig::kNsanTypeId: 208 return std::make_unique<F128ShadowConfig>(); 209 case PPC128ShadowConfig::kNsanTypeId: 210 return std::make_unique<PPC128ShadowConfig>(); 211 } 212 report_fatal_error("nsan: invalid shadow type id '" + Twine(TypeId) + "'"); 213 } 214 215 // An enum corresponding to shadow value types. Used as indices in arrays, so 216 // not an `enum class`. 217 enum FTValueType { kFloat, kDouble, kLongDouble, kNumValueTypes }; 218 219 // If `FT` corresponds to a primitive FTValueType, return it. 220 static std::optional<FTValueType> ftValueTypeFromType(Type *FT) { 221 if (FT->isFloatTy()) 222 return kFloat; 223 if (FT->isDoubleTy()) 224 return kDouble; 225 if (FT->isX86_FP80Ty()) 226 return kLongDouble; 227 return {}; 228 } 229 230 // Returns the LLVM type for an FTValueType. 231 static Type *typeFromFTValueType(FTValueType VT, LLVMContext &Context) { 232 switch (VT) { 233 case kFloat: 234 return Type::getFloatTy(Context); 235 case kDouble: 236 return Type::getDoubleTy(Context); 237 case kLongDouble: 238 return Type::getX86_FP80Ty(Context); 239 case kNumValueTypes: 240 return nullptr; 241 } 242 llvm_unreachable("Unhandled FTValueType enum"); 243 } 244 245 // Returns the type name for an FTValueType. 246 static const char *typeNameFromFTValueType(FTValueType VT) { 247 switch (VT) { 248 case kFloat: 249 return "float"; 250 case kDouble: 251 return "double"; 252 case kLongDouble: 253 return "longdouble"; 254 case kNumValueTypes: 255 return nullptr; 256 } 257 llvm_unreachable("Unhandled FTValueType enum"); 258 } 259 260 // A specific mapping configuration of application type to shadow type for nsan 261 // (see -nsan-shadow-mapping flag). 262 class MappingConfig { 263 public: 264 explicit MappingConfig(LLVMContext &C) : Context(C) { 265 if (ClShadowMapping.size() != 3) 266 report_fatal_error("Invalid nsan mapping: " + Twine(ClShadowMapping)); 267 unsigned ShadowTypeSizeBits[kNumValueTypes]; 268 for (int VT = 0; VT < kNumValueTypes; ++VT) { 269 auto Config = ShadowTypeConfig::fromNsanTypeId(ClShadowMapping[VT]); 270 if (!Config) 271 report_fatal_error("Failed to get ShadowTypeConfig for " + 272 Twine(ClShadowMapping[VT])); 273 const unsigned AppTypeSize = 274 typeFromFTValueType(static_cast<FTValueType>(VT), Context) 275 ->getScalarSizeInBits(); 276 const unsigned ShadowTypeSize = 277 Config->getType(Context)->getScalarSizeInBits(); 278 // Check that the shadow type size is at most kShadowScale times the 279 // application type size, so that shadow memory compoutations are valid. 280 if (ShadowTypeSize > kShadowScale * AppTypeSize) 281 report_fatal_error("Invalid nsan mapping f" + Twine(AppTypeSize) + 282 "->f" + Twine(ShadowTypeSize) + 283 ": The shadow type size should be at most " + 284 Twine(kShadowScale) + 285 " times the application type size"); 286 ShadowTypeSizeBits[VT] = ShadowTypeSize; 287 Configs[VT] = std::move(Config); 288 } 289 290 // Check that the mapping is monotonous. This is required because if one 291 // does an fpextend of `float->long double` in application code, nsan is 292 // going to do an fpextend of `shadow(float) -> shadow(long double)` in 293 // shadow code. This will fail in `qql` mode, since nsan would be 294 // fpextending `f128->long`, which is invalid. 295 // TODO: Relax this. 296 if (ShadowTypeSizeBits[kFloat] > ShadowTypeSizeBits[kDouble] || 297 ShadowTypeSizeBits[kDouble] > ShadowTypeSizeBits[kLongDouble]) 298 report_fatal_error("Invalid nsan mapping: { float->f" + 299 Twine(ShadowTypeSizeBits[kFloat]) + "; double->f" + 300 Twine(ShadowTypeSizeBits[kDouble]) + 301 "; long double->f" + 302 Twine(ShadowTypeSizeBits[kLongDouble]) + " }"); 303 } 304 305 const ShadowTypeConfig &byValueType(FTValueType VT) const { 306 assert(VT < FTValueType::kNumValueTypes && "invalid value type"); 307 return *Configs[VT]; 308 } 309 310 // Returns the extended shadow type for a given application type. 311 Type *getExtendedFPType(Type *FT) const { 312 if (const auto VT = ftValueTypeFromType(FT)) 313 return Configs[*VT]->getType(Context); 314 if (FT->isVectorTy()) { 315 auto *VecTy = cast<VectorType>(FT); 316 // TODO: add support for scalable vector types. 317 if (VecTy->isScalableTy()) 318 return nullptr; 319 Type *ExtendedScalar = getExtendedFPType(VecTy->getElementType()); 320 return ExtendedScalar 321 ? VectorType::get(ExtendedScalar, VecTy->getElementCount()) 322 : nullptr; 323 } 324 return nullptr; 325 } 326 327 private: 328 LLVMContext &Context; 329 std::unique_ptr<ShadowTypeConfig> Configs[FTValueType::kNumValueTypes]; 330 }; 331 332 // The memory extents of a type specifies how many elements of a given 333 // FTValueType needs to be stored when storing this type. 334 struct MemoryExtents { 335 FTValueType ValueType; 336 uint64_t NumElts; 337 }; 338 339 static MemoryExtents getMemoryExtentsOrDie(Type *FT) { 340 if (const auto VT = ftValueTypeFromType(FT)) 341 return {*VT, 1}; 342 if (auto *VecTy = dyn_cast<VectorType>(FT)) { 343 const auto ScalarExtents = getMemoryExtentsOrDie(VecTy->getElementType()); 344 return {ScalarExtents.ValueType, 345 ScalarExtents.NumElts * VecTy->getElementCount().getFixedValue()}; 346 } 347 llvm_unreachable("invalid value type"); 348 } 349 350 // The location of a check. Passed as parameters to runtime checking functions. 351 class CheckLoc { 352 public: 353 // Creates a location that references an application memory location. 354 static CheckLoc makeStore(Value *Address) { 355 CheckLoc Result(kStore); 356 Result.Address = Address; 357 return Result; 358 } 359 static CheckLoc makeLoad(Value *Address) { 360 CheckLoc Result(kLoad); 361 Result.Address = Address; 362 return Result; 363 } 364 365 // Creates a location that references an argument, given by id. 366 static CheckLoc makeArg(int ArgId) { 367 CheckLoc Result(kArg); 368 Result.ArgId = ArgId; 369 return Result; 370 } 371 372 // Creates a location that references the return value of a function. 373 static CheckLoc makeRet() { return CheckLoc(kRet); } 374 375 // Creates a location that references a vector insert. 376 static CheckLoc makeInsert() { return CheckLoc(kInsert); } 377 378 // Returns the CheckType of location this refers to, as an integer-typed LLVM 379 // IR value. 380 Value *getType(LLVMContext &C) const { 381 return ConstantInt::get(Type::getInt32Ty(C), static_cast<int>(CheckTy)); 382 } 383 384 // Returns a CheckType-specific value representing details of the location 385 // (e.g. application address for loads or stores), as an `IntptrTy`-typed LLVM 386 // IR value. 387 Value *getValue(Type *IntptrTy, IRBuilder<> &Builder) const { 388 switch (CheckTy) { 389 case kUnknown: 390 llvm_unreachable("unknown type"); 391 case kRet: 392 case kInsert: 393 return ConstantInt::get(IntptrTy, 0); 394 case kArg: 395 return ConstantInt::get(IntptrTy, ArgId); 396 case kLoad: 397 case kStore: 398 return Builder.CreatePtrToInt(Address, IntptrTy); 399 } 400 llvm_unreachable("Unhandled CheckType enum"); 401 } 402 403 private: 404 // Must be kept in sync with the runtime, 405 // see compiler-rt/lib/nsan/nsan_stats.h 406 enum CheckType { 407 kUnknown = 0, 408 kRet, 409 kArg, 410 kLoad, 411 kStore, 412 kInsert, 413 }; 414 explicit CheckLoc(CheckType CheckTy) : CheckTy(CheckTy) {} 415 416 Value *Address = nullptr; 417 const CheckType CheckTy; 418 int ArgId = -1; 419 }; 420 421 // A map of LLVM IR values to shadow LLVM IR values. 422 class ValueToShadowMap { 423 public: 424 explicit ValueToShadowMap(const MappingConfig &Config) : Config(Config) {} 425 426 ValueToShadowMap(const ValueToShadowMap &) = delete; 427 ValueToShadowMap &operator=(const ValueToShadowMap &) = delete; 428 429 // Sets the shadow value for a value. Asserts that the value does not already 430 // have a value. 431 void setShadow(Value &V, Value &Shadow) { 432 [[maybe_unused]] const bool Inserted = Map.try_emplace(&V, &Shadow).second; 433 LLVM_DEBUG({ 434 if (!Inserted) { 435 if (auto *I = dyn_cast<Instruction>(&V)) 436 errs() << I->getFunction()->getName() << ": "; 437 errs() << "duplicate shadow (" << &V << "): "; 438 V.dump(); 439 } 440 }); 441 assert(Inserted && "duplicate shadow"); 442 } 443 444 // Returns true if the value already has a shadow (including if the value is a 445 // constant). If true, calling getShadow() is valid. 446 bool hasShadow(Value *V) const { 447 return isa<Constant>(V) || (Map.find(V) != Map.end()); 448 } 449 450 // Returns the shadow value for a given value. Asserts that the value has 451 // a shadow value. Lazily creates shadows for constant values. 452 Value *getShadow(Value *V) const { 453 if (Constant *C = dyn_cast<Constant>(V)) 454 return getShadowConstant(C); 455 return Map.find(V)->second; 456 } 457 458 bool empty() const { return Map.empty(); } 459 460 private: 461 // Extends a constant application value to its shadow counterpart. 462 APFloat extendConstantFP(APFloat CV, const fltSemantics &To) const { 463 bool LosesInfo = false; 464 CV.convert(To, APFloatBase::rmTowardZero, &LosesInfo); 465 return CV; 466 } 467 468 // Returns the shadow constant for the given application constant. 469 Constant *getShadowConstant(Constant *C) const { 470 if (UndefValue *U = dyn_cast<UndefValue>(C)) { 471 return UndefValue::get(Config.getExtendedFPType(U->getType())); 472 } 473 if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { 474 // Floating-point constants. 475 Type *Ty = Config.getExtendedFPType(CFP->getType()); 476 return ConstantFP::get( 477 Ty, extendConstantFP(CFP->getValueAPF(), Ty->getFltSemantics())); 478 } 479 // Vector, array, or aggregate constants. 480 if (C->getType()->isVectorTy()) { 481 SmallVector<Constant *, 8> Elements; 482 for (int I = 0, E = cast<VectorType>(C->getType()) 483 ->getElementCount() 484 .getFixedValue(); 485 I < E; ++I) 486 Elements.push_back(getShadowConstant(C->getAggregateElement(I))); 487 return ConstantVector::get(Elements); 488 } 489 llvm_unreachable("unimplemented"); 490 } 491 492 const MappingConfig &Config; 493 DenseMap<Value *, Value *> Map; 494 }; 495 496 /// Instantiating NumericalStabilitySanitizer inserts the nsan runtime library 497 /// API function declarations into the module if they don't exist already. 498 /// Instantiating ensures the __nsan_init function is in the list of global 499 /// constructors for the module. 500 class NumericalStabilitySanitizer { 501 public: 502 NumericalStabilitySanitizer(Module &M); 503 bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI); 504 505 private: 506 bool instrumentMemIntrinsic(MemIntrinsic *MI); 507 void maybeAddSuffixForNsanInterface(CallBase *CI); 508 bool addrPointsToConstantData(Value *Addr); 509 void maybeCreateShadowValue(Instruction &Root, const TargetLibraryInfo &TLI, 510 ValueToShadowMap &Map); 511 Value *createShadowValueWithOperandsAvailable(Instruction &Inst, 512 const TargetLibraryInfo &TLI, 513 const ValueToShadowMap &Map); 514 PHINode *maybeCreateShadowPhi(PHINode &Phi, const TargetLibraryInfo &TLI); 515 void createShadowArguments(Function &F, const TargetLibraryInfo &TLI, 516 ValueToShadowMap &Map); 517 518 void populateShadowStack(CallBase &CI, const TargetLibraryInfo &TLI, 519 const ValueToShadowMap &Map); 520 521 void propagateShadowValues(Instruction &Inst, const TargetLibraryInfo &TLI, 522 const ValueToShadowMap &Map); 523 Value *emitCheck(Value *V, Value *ShadowV, IRBuilder<> &Builder, 524 CheckLoc Loc); 525 Value *emitCheckInternal(Value *V, Value *ShadowV, IRBuilder<> &Builder, 526 CheckLoc Loc); 527 void emitFCmpCheck(FCmpInst &FCmp, const ValueToShadowMap &Map); 528 529 // Value creation handlers. 530 Value *handleLoad(LoadInst &Load, Type *VT, Type *ExtendedVT); 531 Value *handleCallBase(CallBase &Call, Type *VT, Type *ExtendedVT, 532 const TargetLibraryInfo &TLI, 533 const ValueToShadowMap &Map, IRBuilder<> &Builder); 534 Value *maybeHandleKnownCallBase(CallBase &Call, Type *VT, Type *ExtendedVT, 535 const TargetLibraryInfo &TLI, 536 const ValueToShadowMap &Map, 537 IRBuilder<> &Builder); 538 Value *handleTrunc(const FPTruncInst &Trunc, Type *VT, Type *ExtendedVT, 539 const ValueToShadowMap &Map, IRBuilder<> &Builder); 540 Value *handleExt(const FPExtInst &Ext, Type *VT, Type *ExtendedVT, 541 const ValueToShadowMap &Map, IRBuilder<> &Builder); 542 543 // Value propagation handlers. 544 void propagateFTStore(StoreInst &Store, Type *VT, Type *ExtendedVT, 545 const ValueToShadowMap &Map); 546 void propagateNonFTStore(StoreInst &Store, Type *VT, 547 const ValueToShadowMap &Map); 548 549 const DataLayout &DL; 550 LLVMContext &Context; 551 MappingConfig Config; 552 IntegerType *IntptrTy = nullptr; 553 FunctionCallee NsanGetShadowPtrForStore[FTValueType::kNumValueTypes] = {}; 554 FunctionCallee NsanGetShadowPtrForLoad[FTValueType::kNumValueTypes] = {}; 555 FunctionCallee NsanCheckValue[FTValueType::kNumValueTypes] = {}; 556 FunctionCallee NsanFCmpFail[FTValueType::kNumValueTypes] = {}; 557 FunctionCallee NsanCopyValues; 558 FunctionCallee NsanSetValueUnknown; 559 FunctionCallee NsanGetRawShadowTypePtr; 560 FunctionCallee NsanGetRawShadowPtr; 561 GlobalValue *NsanShadowRetTag = nullptr; 562 563 Type *NsanShadowRetType = nullptr; 564 GlobalValue *NsanShadowRetPtr = nullptr; 565 566 GlobalValue *NsanShadowArgsTag = nullptr; 567 568 Type *NsanShadowArgsType = nullptr; 569 GlobalValue *NsanShadowArgsPtr = nullptr; 570 571 std::optional<Regex> CheckFunctionsFilter; 572 }; 573 } // end anonymous namespace 574 575 PreservedAnalyses 576 NumericalStabilitySanitizerPass::run(Module &M, ModuleAnalysisManager &MAM) { 577 getOrCreateSanitizerCtorAndInitFunctions( 578 M, kNsanModuleCtorName, kNsanInitName, /*InitArgTypes=*/{}, 579 /*InitArgs=*/{}, 580 // This callback is invoked when the functions are created the first 581 // time. Hook them into the global ctors list in that case: 582 [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); }); 583 584 NumericalStabilitySanitizer Nsan(M); 585 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 586 for (Function &F : M) 587 Nsan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)); 588 589 return PreservedAnalyses::none(); 590 } 591 592 static GlobalValue *createThreadLocalGV(const char *Name, Module &M, Type *Ty) { 593 return dyn_cast<GlobalValue>(M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] { 594 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, 595 nullptr, Name, nullptr, 596 GlobalVariable::InitialExecTLSModel); 597 })); 598 } 599 600 NumericalStabilitySanitizer::NumericalStabilitySanitizer(Module &M) 601 : DL(M.getDataLayout()), Context(M.getContext()), Config(Context) { 602 IntptrTy = DL.getIntPtrType(Context); 603 Type *PtrTy = PointerType::getUnqual(Context); 604 Type *Int32Ty = Type::getInt32Ty(Context); 605 Type *Int1Ty = Type::getInt1Ty(Context); 606 Type *VoidTy = Type::getVoidTy(Context); 607 608 AttributeList Attr; 609 Attr = Attr.addFnAttribute(Context, Attribute::NoUnwind); 610 // Initialize the runtime values (functions and global variables). 611 for (int I = 0; I < kNumValueTypes; ++I) { 612 const FTValueType VT = static_cast<FTValueType>(I); 613 const char *VTName = typeNameFromFTValueType(VT); 614 Type *VTTy = typeFromFTValueType(VT, Context); 615 616 // Load/store. 617 const std::string GetterPrefix = 618 std::string("__nsan_get_shadow_ptr_for_") + VTName; 619 NsanGetShadowPtrForStore[VT] = M.getOrInsertFunction( 620 GetterPrefix + "_store", Attr, PtrTy, PtrTy, IntptrTy); 621 NsanGetShadowPtrForLoad[VT] = M.getOrInsertFunction( 622 GetterPrefix + "_load", Attr, PtrTy, PtrTy, IntptrTy); 623 624 // Check. 625 const auto &ShadowConfig = Config.byValueType(VT); 626 Type *ShadowTy = ShadowConfig.getType(Context); 627 NsanCheckValue[VT] = 628 M.getOrInsertFunction(std::string("__nsan_internal_check_") + VTName + 629 "_" + ShadowConfig.getNsanTypeId(), 630 Attr, Int32Ty, VTTy, ShadowTy, Int32Ty, IntptrTy); 631 NsanFCmpFail[VT] = M.getOrInsertFunction( 632 std::string("__nsan_fcmp_fail_") + VTName + "_" + 633 ShadowConfig.getNsanTypeId(), 634 Attr, VoidTy, VTTy, VTTy, ShadowTy, ShadowTy, Int32Ty, Int1Ty, Int1Ty); 635 } 636 637 NsanCopyValues = M.getOrInsertFunction("__nsan_copy_values", Attr, VoidTy, 638 PtrTy, PtrTy, IntptrTy); 639 NsanSetValueUnknown = M.getOrInsertFunction("__nsan_set_value_unknown", Attr, 640 VoidTy, PtrTy, IntptrTy); 641 642 // TODO: Add attributes nofree, nosync, readnone, readonly, 643 NsanGetRawShadowTypePtr = M.getOrInsertFunction( 644 "__nsan_internal_get_raw_shadow_type_ptr", Attr, PtrTy, PtrTy); 645 NsanGetRawShadowPtr = M.getOrInsertFunction( 646 "__nsan_internal_get_raw_shadow_ptr", Attr, PtrTy, PtrTy); 647 648 NsanShadowRetTag = createThreadLocalGV("__nsan_shadow_ret_tag", M, IntptrTy); 649 650 NsanShadowRetType = ArrayType::get(Type::getInt8Ty(Context), 651 kMaxVectorWidth * kMaxShadowTypeSizeBytes); 652 NsanShadowRetPtr = 653 createThreadLocalGV("__nsan_shadow_ret_ptr", M, NsanShadowRetType); 654 655 NsanShadowArgsTag = 656 createThreadLocalGV("__nsan_shadow_args_tag", M, IntptrTy); 657 658 NsanShadowArgsType = 659 ArrayType::get(Type::getInt8Ty(Context), 660 kMaxVectorWidth * kMaxNumArgs * kMaxShadowTypeSizeBytes); 661 662 NsanShadowArgsPtr = 663 createThreadLocalGV("__nsan_shadow_args_ptr", M, NsanShadowArgsType); 664 665 if (!ClCheckFunctionsFilter.empty()) { 666 Regex R = Regex(ClCheckFunctionsFilter); 667 std::string RegexError; 668 assert(R.isValid(RegexError)); 669 CheckFunctionsFilter = std::move(R); 670 } 671 } 672 673 // Returns true if the given LLVM Value points to constant data (typically, a 674 // global variable reference). 675 bool NumericalStabilitySanitizer::addrPointsToConstantData(Value *Addr) { 676 // If this is a GEP, just analyze its pointer operand. 677 if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr)) 678 Addr = GEP->getPointerOperand(); 679 680 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) 681 return GV->isConstant(); 682 return false; 683 } 684 685 // This instruments the function entry to create shadow arguments. 686 // Pseudocode: 687 // if (this_fn_ptr == __nsan_shadow_args_tag) { 688 // s(arg0) = LOAD<sizeof(arg0)>(__nsan_shadow_args); 689 // s(arg1) = LOAD<sizeof(arg1)>(__nsan_shadow_args + sizeof(arg0)); 690 // ... 691 // __nsan_shadow_args_tag = 0; 692 // } else { 693 // s(arg0) = fext(arg0); 694 // s(arg1) = fext(arg1); 695 // ... 696 // } 697 void NumericalStabilitySanitizer::createShadowArguments( 698 Function &F, const TargetLibraryInfo &TLI, ValueToShadowMap &Map) { 699 assert(!F.getIntrinsicID() && "found a definition of an intrinsic"); 700 701 // Do not bother if there are no FP args. 702 if (all_of(F.args(), [this](const Argument &Arg) { 703 return Config.getExtendedFPType(Arg.getType()) == nullptr; 704 })) 705 return; 706 707 IRBuilder<> Builder(F.getEntryBlock().getFirstNonPHI()); 708 // The function has shadow args if the shadow args tag matches the function 709 // address. 710 Value *HasShadowArgs = Builder.CreateICmpEQ( 711 Builder.CreateLoad(IntptrTy, NsanShadowArgsTag, /*isVolatile=*/false), 712 Builder.CreatePtrToInt(&F, IntptrTy)); 713 714 unsigned ShadowArgsOffsetBytes = 0; 715 for (Argument &Arg : F.args()) { 716 Type *VT = Arg.getType(); 717 Type *ExtendedVT = Config.getExtendedFPType(VT); 718 if (ExtendedVT == nullptr) 719 continue; // Not an FT value. 720 Value *L = Builder.CreateAlignedLoad( 721 ExtendedVT, 722 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0, 723 ShadowArgsOffsetBytes), 724 Align(1), /*isVolatile=*/false); 725 Value *Shadow = Builder.CreateSelect(HasShadowArgs, L, 726 Builder.CreateFPExt(&Arg, ExtendedVT)); 727 Map.setShadow(Arg, *Shadow); 728 TypeSize SlotSize = DL.getTypeStoreSize(ExtendedVT); 729 assert(!SlotSize.isScalable() && "unsupported"); 730 ShadowArgsOffsetBytes += SlotSize; 731 } 732 Builder.CreateStore(ConstantInt::get(IntptrTy, 0), NsanShadowArgsTag); 733 } 734 735 // Returns true if the instrumentation should emit code to check arguments 736 // before a function call. 737 static bool shouldCheckArgs(CallBase &CI, const TargetLibraryInfo &TLI, 738 const std::optional<Regex> &CheckFunctionsFilter) { 739 740 Function *Fn = CI.getCalledFunction(); 741 742 if (CheckFunctionsFilter) { 743 // Skip checking args of indirect calls. 744 if (Fn == nullptr) 745 return false; 746 if (CheckFunctionsFilter->match(Fn->getName())) 747 return true; 748 return false; 749 } 750 751 if (Fn == nullptr) 752 return true; // Always check args of indirect calls. 753 754 // Never check nsan functions, the user called them for a reason. 755 if (Fn->getName().starts_with("__nsan_")) 756 return false; 757 758 const auto ID = Fn->getIntrinsicID(); 759 LibFunc LFunc = LibFunc::NumLibFuncs; 760 // Always check args of unknown functions. 761 if (ID == Intrinsic::ID() && !TLI.getLibFunc(*Fn, LFunc)) 762 return true; 763 764 // Do not check args of an `fabs` call that is used for a comparison. 765 // This is typically used for `fabs(a-b) < tolerance`, where what matters is 766 // the result of the comparison, which is already caught be the fcmp checks. 767 if (ID == Intrinsic::fabs || LFunc == LibFunc_fabsf || 768 LFunc == LibFunc_fabs || LFunc == LibFunc_fabsl) 769 for (const auto &U : CI.users()) 770 if (isa<CmpInst>(U)) 771 return false; 772 773 return true; // Default is check. 774 } 775 776 // Populates the shadow call stack (which contains shadow values for every 777 // floating-point parameter to the function). 778 void NumericalStabilitySanitizer::populateShadowStack( 779 CallBase &CI, const TargetLibraryInfo &TLI, const ValueToShadowMap &Map) { 780 // Do not create a shadow stack for inline asm. 781 if (CI.isInlineAsm()) 782 return; 783 784 // Do not bother if there are no FP args. 785 if (all_of(CI.operands(), [this](const Value *Arg) { 786 return Config.getExtendedFPType(Arg->getType()) == nullptr; 787 })) 788 return; 789 790 IRBuilder<> Builder(&CI); 791 SmallVector<Value *, 8> ArgShadows; 792 const bool ShouldCheckArgs = shouldCheckArgs(CI, TLI, CheckFunctionsFilter); 793 for (auto [ArgIdx, Arg] : enumerate(CI.operands())) { 794 if (Config.getExtendedFPType(Arg->getType()) == nullptr) 795 continue; // Not an FT value. 796 Value *ArgShadow = Map.getShadow(Arg); 797 ArgShadows.push_back(ShouldCheckArgs ? emitCheck(Arg, ArgShadow, Builder, 798 CheckLoc::makeArg(ArgIdx)) 799 : ArgShadow); 800 } 801 802 // Do not create shadow stacks for intrinsics/known lib funcs. 803 if (Function *Fn = CI.getCalledFunction()) { 804 LibFunc LFunc; 805 if (Fn->isIntrinsic() || TLI.getLibFunc(*Fn, LFunc)) 806 return; 807 } 808 809 // Set the shadow stack tag. 810 Builder.CreateStore(CI.getCalledOperand(), NsanShadowArgsTag); 811 TypeSize ShadowArgsOffsetBytes = TypeSize::getFixed(0); 812 813 unsigned ShadowArgId = 0; 814 for (const Value *Arg : CI.operands()) { 815 Type *VT = Arg->getType(); 816 Type *ExtendedVT = Config.getExtendedFPType(VT); 817 if (ExtendedVT == nullptr) 818 continue; // Not an FT value. 819 Builder.CreateAlignedStore( 820 ArgShadows[ShadowArgId++], 821 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0, 822 ShadowArgsOffsetBytes), 823 Align(1), /*isVolatile=*/false); 824 TypeSize SlotSize = DL.getTypeStoreSize(ExtendedVT); 825 assert(!SlotSize.isScalable() && "unsupported"); 826 ShadowArgsOffsetBytes += SlotSize; 827 } 828 } 829 830 // Internal part of emitCheck(). Returns a value that indicates whether 831 // computation should continue with the shadow or resume by re-fextending the 832 // value. 833 enum class ContinuationType { // Keep in sync with runtime. 834 ContinueWithShadow = 0, 835 ResumeFromValue = 1, 836 }; 837 838 Value *NumericalStabilitySanitizer::emitCheckInternal(Value *V, Value *ShadowV, 839 IRBuilder<> &Builder, 840 CheckLoc Loc) { 841 // Do not emit checks for constant values, this is redundant. 842 if (isa<Constant>(V)) 843 return ConstantInt::get( 844 Builder.getInt32Ty(), 845 static_cast<int>(ContinuationType::ContinueWithShadow)); 846 847 Type *Ty = V->getType(); 848 if (const auto VT = ftValueTypeFromType(Ty)) 849 return Builder.CreateCall( 850 NsanCheckValue[*VT], 851 {V, ShadowV, Loc.getType(Context), Loc.getValue(IntptrTy, Builder)}); 852 853 if (Ty->isVectorTy()) { 854 auto *VecTy = cast<VectorType>(Ty); 855 // We currently skip scalable vector types in MappingConfig, 856 // thus we should not encounter any such types here. 857 assert(!VecTy->isScalableTy() && 858 "Scalable vector types are not supported yet"); 859 Value *CheckResult = nullptr; 860 for (int I = 0, E = VecTy->getElementCount().getFixedValue(); I < E; ++I) { 861 // We resume if any element resumes. Another option would be to create a 862 // vector shuffle with the array of ContinueWithShadow, but that is too 863 // complex. 864 Value *ExtractV = Builder.CreateExtractElement(V, I); 865 Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I); 866 Value *ComponentCheckResult = 867 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc); 868 CheckResult = CheckResult 869 ? Builder.CreateOr(CheckResult, ComponentCheckResult) 870 : ComponentCheckResult; 871 } 872 return CheckResult; 873 } 874 if (Ty->isArrayTy()) { 875 Value *CheckResult = nullptr; 876 for (auto I : seq(Ty->getArrayNumElements())) { 877 Value *ExtractV = Builder.CreateExtractElement(V, I); 878 Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I); 879 Value *ComponentCheckResult = 880 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc); 881 CheckResult = CheckResult 882 ? Builder.CreateOr(CheckResult, ComponentCheckResult) 883 : ComponentCheckResult; 884 } 885 return CheckResult; 886 } 887 if (Ty->isStructTy()) { 888 Value *CheckResult = nullptr; 889 for (auto I : seq(Ty->getStructNumElements())) { 890 if (Config.getExtendedFPType(Ty->getStructElementType(I)) == nullptr) 891 continue; // Only check FT values. 892 Value *ExtractV = Builder.CreateExtractValue(V, I); 893 Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I); 894 Value *ComponentCheckResult = 895 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc); 896 CheckResult = CheckResult 897 ? Builder.CreateOr(CheckResult, ComponentCheckResult) 898 : ComponentCheckResult; 899 } 900 if (!CheckResult) 901 return ConstantInt::get( 902 Builder.getInt32Ty(), 903 static_cast<int>(ContinuationType::ContinueWithShadow)); 904 return CheckResult; 905 } 906 907 llvm_unreachable("not implemented"); 908 } 909 910 // Inserts a runtime check of V against its shadow value ShadowV. 911 // We check values whenever they escape: on return, call, stores, and 912 // insertvalue. 913 // Returns the shadow value that should be used to continue the computations, 914 // depending on the answer from the runtime. 915 // TODO: Should we check on select ? phi ? 916 Value *NumericalStabilitySanitizer::emitCheck(Value *V, Value *ShadowV, 917 IRBuilder<> &Builder, 918 CheckLoc Loc) { 919 // Do not emit checks for constant values, this is redundant. 920 if (isa<Constant>(V)) 921 return ShadowV; 922 923 if (Instruction *Inst = dyn_cast<Instruction>(V)) { 924 Function *F = Inst->getFunction(); 925 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(F->getName())) { 926 return ShadowV; 927 } 928 } 929 930 Value *CheckResult = emitCheckInternal(V, ShadowV, Builder, Loc); 931 Value *ICmpEQ = Builder.CreateICmpEQ( 932 CheckResult, 933 ConstantInt::get(Builder.getInt32Ty(), 934 static_cast<int>(ContinuationType::ResumeFromValue))); 935 return Builder.CreateSelect( 936 ICmpEQ, Builder.CreateFPExt(V, Config.getExtendedFPType(V->getType())), 937 ShadowV); 938 } 939 940 // Inserts a check that fcmp on shadow values are consistent with that on base 941 // values. 942 void NumericalStabilitySanitizer::emitFCmpCheck(FCmpInst &FCmp, 943 const ValueToShadowMap &Map) { 944 if (!ClInstrumentFCmp) 945 return; 946 947 Function *F = FCmp.getFunction(); 948 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(F->getName())) 949 return; 950 951 Value *LHS = FCmp.getOperand(0); 952 if (Config.getExtendedFPType(LHS->getType()) == nullptr) 953 return; 954 Value *RHS = FCmp.getOperand(1); 955 956 // Split the basic block. On mismatch, we'll jump to the new basic block with 957 // a call to the runtime for error reporting. 958 BasicBlock *FCmpBB = FCmp.getParent(); 959 BasicBlock *NextBB = FCmpBB->splitBasicBlock(FCmp.getNextNode()); 960 // Remove the newly created terminator unconditional branch. 961 FCmpBB->back().eraseFromParent(); 962 BasicBlock *FailBB = 963 BasicBlock::Create(Context, "", FCmpBB->getParent(), NextBB); 964 965 // Create the shadow fcmp and comparison between the fcmps. 966 IRBuilder<> FCmpBuilder(FCmpBB); 967 FCmpBuilder.SetCurrentDebugLocation(FCmp.getDebugLoc()); 968 Value *ShadowLHS = Map.getShadow(LHS); 969 Value *ShadowRHS = Map.getShadow(RHS); 970 // See comment on ClTruncateFCmpEq. 971 if (FCmp.isEquality() && ClTruncateFCmpEq) { 972 Type *Ty = ShadowLHS->getType(); 973 ShadowLHS = FCmpBuilder.CreateFPExt( 974 FCmpBuilder.CreateFPTrunc(ShadowLHS, LHS->getType()), Ty); 975 ShadowRHS = FCmpBuilder.CreateFPExt( 976 FCmpBuilder.CreateFPTrunc(ShadowRHS, RHS->getType()), Ty); 977 } 978 Value *ShadowFCmp = 979 FCmpBuilder.CreateFCmp(FCmp.getPredicate(), ShadowLHS, ShadowRHS); 980 Value *OriginalAndShadowFcmpMatch = 981 FCmpBuilder.CreateICmpEQ(&FCmp, ShadowFCmp); 982 983 if (OriginalAndShadowFcmpMatch->getType()->isVectorTy()) { 984 // If we have a vector type, `OriginalAndShadowFcmpMatch` is a vector of i1, 985 // where an element is true if the corresponding elements in original and 986 // shadow are the same. We want all elements to be 1. 987 OriginalAndShadowFcmpMatch = 988 FCmpBuilder.CreateAndReduce(OriginalAndShadowFcmpMatch); 989 } 990 991 // Use MDBuilder(*C).createLikelyBranchWeights() because "match" is the common 992 // case. 993 FCmpBuilder.CreateCondBr(OriginalAndShadowFcmpMatch, NextBB, FailBB, 994 MDBuilder(Context).createLikelyBranchWeights()); 995 996 // Fill in FailBB. 997 IRBuilder<> FailBuilder(FailBB); 998 FailBuilder.SetCurrentDebugLocation(FCmp.getDebugLoc()); 999 1000 const auto EmitFailCall = [this, &FCmp, &FCmpBuilder, 1001 &FailBuilder](Value *L, Value *R, Value *ShadowL, 1002 Value *ShadowR, Value *Result, 1003 Value *ShadowResult) { 1004 Type *FT = L->getType(); 1005 FunctionCallee *Callee = nullptr; 1006 if (FT->isFloatTy()) { 1007 Callee = &(NsanFCmpFail[kFloat]); 1008 } else if (FT->isDoubleTy()) { 1009 Callee = &(NsanFCmpFail[kDouble]); 1010 } else if (FT->isX86_FP80Ty()) { 1011 // TODO: make NsanFCmpFailLongDouble work. 1012 Callee = &(NsanFCmpFail[kDouble]); 1013 L = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(Context)); 1014 R = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(Context)); 1015 } else { 1016 llvm_unreachable("not implemented"); 1017 } 1018 FailBuilder.CreateCall(*Callee, {L, R, ShadowL, ShadowR, 1019 ConstantInt::get(FCmpBuilder.getInt32Ty(), 1020 FCmp.getPredicate()), 1021 Result, ShadowResult}); 1022 }; 1023 if (LHS->getType()->isVectorTy()) { 1024 for (int I = 0, E = cast<VectorType>(LHS->getType()) 1025 ->getElementCount() 1026 .getFixedValue(); 1027 I < E; ++I) { 1028 Value *ExtractLHS = FailBuilder.CreateExtractElement(LHS, I); 1029 Value *ExtractRHS = FailBuilder.CreateExtractElement(RHS, I); 1030 Value *ExtractShaodwLHS = FailBuilder.CreateExtractElement(ShadowLHS, I); 1031 Value *ExtractShaodwRHS = FailBuilder.CreateExtractElement(ShadowRHS, I); 1032 Value *ExtractFCmp = FailBuilder.CreateExtractElement(&FCmp, I); 1033 Value *ExtractShadowFCmp = 1034 FailBuilder.CreateExtractElement(ShadowFCmp, I); 1035 EmitFailCall(ExtractLHS, ExtractRHS, ExtractShaodwLHS, ExtractShaodwRHS, 1036 ExtractFCmp, ExtractShadowFCmp); 1037 } 1038 } else { 1039 EmitFailCall(LHS, RHS, ShadowLHS, ShadowRHS, &FCmp, ShadowFCmp); 1040 } 1041 FailBuilder.CreateBr(NextBB); 1042 1043 ++NumInstrumentedFCmp; 1044 } 1045 1046 // Creates a shadow phi value for any phi that defines a value of FT type. 1047 PHINode *NumericalStabilitySanitizer::maybeCreateShadowPhi( 1048 PHINode &Phi, const TargetLibraryInfo &TLI) { 1049 Type *VT = Phi.getType(); 1050 Type *ExtendedVT = Config.getExtendedFPType(VT); 1051 if (ExtendedVT == nullptr) 1052 return nullptr; // Not an FT value. 1053 // The phi operands are shadow values and are not available when the phi is 1054 // created. They will be populated in a final phase, once all shadow values 1055 // have been created. 1056 PHINode *Shadow = PHINode::Create(ExtendedVT, Phi.getNumIncomingValues()); 1057 Shadow->insertAfter(&Phi); 1058 return Shadow; 1059 } 1060 1061 Value *NumericalStabilitySanitizer::handleLoad(LoadInst &Load, Type *VT, 1062 Type *ExtendedVT) { 1063 IRBuilder<> Builder(Load.getNextNode()); 1064 Builder.SetCurrentDebugLocation(Load.getDebugLoc()); 1065 if (addrPointsToConstantData(Load.getPointerOperand())) { 1066 // No need to look into the shadow memory, the value is a constant. Just 1067 // convert from FT to 2FT. 1068 return Builder.CreateFPExt(&Load, ExtendedVT); 1069 } 1070 1071 // if (%shadowptr == &) 1072 // %shadow = fpext %v 1073 // else 1074 // %shadow = load (ptrcast %shadow_ptr)) 1075 // Considered options here: 1076 // - Have `NsanGetShadowPtrForLoad` return a fixed address 1077 // &__nsan_unknown_value_shadow_address that is valid to load from, and 1078 // use a select. This has the advantage that the generated IR is simpler. 1079 // - Have `NsanGetShadowPtrForLoad` return nullptr. Because `select` does 1080 // not short-circuit, dereferencing the returned pointer is no longer an 1081 // option, have to split and create a separate basic block. This has the 1082 // advantage of being easier to debug because it crashes if we ever mess 1083 // up. 1084 1085 const auto Extents = getMemoryExtentsOrDie(VT); 1086 Value *ShadowPtr = Builder.CreateCall( 1087 NsanGetShadowPtrForLoad[Extents.ValueType], 1088 {Load.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)}); 1089 ++NumInstrumentedFTLoads; 1090 1091 // Split the basic block. 1092 BasicBlock *LoadBB = Load.getParent(); 1093 BasicBlock *NextBB = LoadBB->splitBasicBlock(Builder.GetInsertPoint()); 1094 // Create the two options for creating the shadow value. 1095 BasicBlock *ShadowLoadBB = 1096 BasicBlock::Create(Context, "", LoadBB->getParent(), NextBB); 1097 BasicBlock *FExtBB = 1098 BasicBlock::Create(Context, "", LoadBB->getParent(), NextBB); 1099 1100 // Replace the newly created terminator unconditional branch by a conditional 1101 // branch to one of the options. 1102 { 1103 LoadBB->back().eraseFromParent(); 1104 IRBuilder<> LoadBBBuilder(LoadBB); // The old builder has been invalidated. 1105 LoadBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc()); 1106 LoadBBBuilder.CreateCondBr(LoadBBBuilder.CreateIsNull(ShadowPtr), FExtBB, 1107 ShadowLoadBB); 1108 } 1109 1110 // Fill in ShadowLoadBB. 1111 IRBuilder<> ShadowLoadBBBuilder(ShadowLoadBB); 1112 ShadowLoadBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc()); 1113 Value *ShadowLoad = ShadowLoadBBBuilder.CreateAlignedLoad( 1114 ExtendedVT, ShadowPtr, Align(1), Load.isVolatile()); 1115 if (ClCheckLoads) { 1116 ShadowLoad = emitCheck(&Load, ShadowLoad, ShadowLoadBBBuilder, 1117 CheckLoc::makeLoad(Load.getPointerOperand())); 1118 } 1119 ShadowLoadBBBuilder.CreateBr(NextBB); 1120 1121 // Fill in FExtBB. 1122 IRBuilder<> FExtBBBuilder(FExtBB); 1123 FExtBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc()); 1124 Value *FExt = FExtBBBuilder.CreateFPExt(&Load, ExtendedVT); 1125 FExtBBBuilder.CreateBr(NextBB); 1126 1127 // The shadow value come from any of the options. 1128 IRBuilder<> NextBBBuilder(&*NextBB->begin()); 1129 NextBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc()); 1130 PHINode *ShadowPhi = NextBBBuilder.CreatePHI(ExtendedVT, 2); 1131 ShadowPhi->addIncoming(ShadowLoad, ShadowLoadBB); 1132 ShadowPhi->addIncoming(FExt, FExtBB); 1133 return ShadowPhi; 1134 } 1135 1136 Value *NumericalStabilitySanitizer::handleTrunc(const FPTruncInst &Trunc, 1137 Type *VT, Type *ExtendedVT, 1138 const ValueToShadowMap &Map, 1139 IRBuilder<> &Builder) { 1140 Value *OrigSource = Trunc.getOperand(0); 1141 Type *OrigSourceTy = OrigSource->getType(); 1142 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy); 1143 1144 // When truncating: 1145 // - (A) If the source has a shadow, we truncate from the shadow, else we 1146 // truncate from the original source. 1147 // - (B) If the shadow of the source is larger than the shadow of the dest, 1148 // we still need a truncate. Else, the shadow of the source is the same 1149 // type as the shadow of the dest (because mappings are non-decreasing), so 1150 // we don't need to emit a truncate. 1151 // Examples, 1152 // with a mapping of {f32->f64;f64->f80;f80->f128} 1153 // fptrunc double %1 to float -> fptrunc x86_fp80 s(%1) to double 1154 // fptrunc x86_fp80 %1 to float -> fptrunc fp128 s(%1) to double 1155 // fptrunc fp128 %1 to float -> fptrunc fp128 %1 to double 1156 // fptrunc x86_fp80 %1 to double -> x86_fp80 s(%1) 1157 // fptrunc fp128 %1 to double -> fptrunc fp128 %1 to x86_fp80 1158 // fptrunc fp128 %1 to x86_fp80 -> fp128 %1 1159 // with a mapping of {f32->f64;f64->f128;f80->f128} 1160 // fptrunc double %1 to float -> fptrunc fp128 s(%1) to double 1161 // fptrunc x86_fp80 %1 to float -> fptrunc fp128 s(%1) to double 1162 // fptrunc fp128 %1 to float -> fptrunc fp128 %1 to double 1163 // fptrunc x86_fp80 %1 to double -> fp128 %1 1164 // fptrunc fp128 %1 to double -> fp128 %1 1165 // fptrunc fp128 %1 to x86_fp80 -> fp128 %1 1166 // with a mapping of {f32->f32;f64->f32;f80->f64} 1167 // fptrunc double %1 to float -> float s(%1) 1168 // fptrunc x86_fp80 %1 to float -> fptrunc double s(%1) to float 1169 // fptrunc fp128 %1 to float -> fptrunc fp128 %1 to float 1170 // fptrunc x86_fp80 %1 to double -> fptrunc double s(%1) to float 1171 // fptrunc fp128 %1 to double -> fptrunc fp128 %1 to float 1172 // fptrunc fp128 %1 to x86_fp80 -> fptrunc fp128 %1 to double 1173 1174 // See (A) above. 1175 Value *Source = ExtendedSourceTy ? Map.getShadow(OrigSource) : OrigSource; 1176 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy; 1177 // See (B) above. 1178 if (SourceTy == ExtendedVT) 1179 return Source; 1180 1181 return Builder.CreateFPTrunc(Source, ExtendedVT); 1182 } 1183 1184 Value *NumericalStabilitySanitizer::handleExt(const FPExtInst &Ext, Type *VT, 1185 Type *ExtendedVT, 1186 const ValueToShadowMap &Map, 1187 IRBuilder<> &Builder) { 1188 Value *OrigSource = Ext.getOperand(0); 1189 Type *OrigSourceTy = OrigSource->getType(); 1190 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy); 1191 // When extending: 1192 // - (A) If the source has a shadow, we extend from the shadow, else we 1193 // extend from the original source. 1194 // - (B) If the shadow of the dest is larger than the shadow of the source, 1195 // we still need an extend. Else, the shadow of the source is the same 1196 // type as the shadow of the dest (because mappings are non-decreasing), so 1197 // we don't need to emit an extend. 1198 // Examples, 1199 // with a mapping of {f32->f64;f64->f80;f80->f128} 1200 // fpext half %1 to float -> fpext half %1 to double 1201 // fpext half %1 to double -> fpext half %1 to x86_fp80 1202 // fpext half %1 to x86_fp80 -> fpext half %1 to fp128 1203 // fpext float %1 to double -> double s(%1) 1204 // fpext float %1 to x86_fp80 -> fpext double s(%1) to fp128 1205 // fpext double %1 to x86_fp80 -> fpext x86_fp80 s(%1) to fp128 1206 // with a mapping of {f32->f64;f64->f128;f80->f128} 1207 // fpext half %1 to float -> fpext half %1 to double 1208 // fpext half %1 to double -> fpext half %1 to fp128 1209 // fpext half %1 to x86_fp80 -> fpext half %1 to fp128 1210 // fpext float %1 to double -> fpext double s(%1) to fp128 1211 // fpext float %1 to x86_fp80 -> fpext double s(%1) to fp128 1212 // fpext double %1 to x86_fp80 -> fp128 s(%1) 1213 // with a mapping of {f32->f32;f64->f32;f80->f64} 1214 // fpext half %1 to float -> fpext half %1 to float 1215 // fpext half %1 to double -> fpext half %1 to float 1216 // fpext half %1 to x86_fp80 -> fpext half %1 to double 1217 // fpext float %1 to double -> s(%1) 1218 // fpext float %1 to x86_fp80 -> fpext float s(%1) to double 1219 // fpext double %1 to x86_fp80 -> fpext float s(%1) to double 1220 1221 // See (A) above. 1222 Value *Source = ExtendedSourceTy ? Map.getShadow(OrigSource) : OrigSource; 1223 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy; 1224 // See (B) above. 1225 if (SourceTy == ExtendedVT) 1226 return Source; 1227 1228 return Builder.CreateFPExt(Source, ExtendedVT); 1229 } 1230 1231 namespace { 1232 // TODO: This should be tablegen-ed. 1233 struct KnownIntrinsic { 1234 struct WidenedIntrinsic { 1235 const char *NarrowName; 1236 Intrinsic::ID ID; // wide id. 1237 using FnTypeFactory = FunctionType *(*)(LLVMContext &); 1238 FnTypeFactory MakeFnTy; 1239 }; 1240 1241 static const char *get(LibFunc LFunc); 1242 1243 // Given an intrinsic with an `FT` argument, try to find a wider intrinsic 1244 // that applies the same operation on the shadow argument. 1245 // Options are: 1246 // - pass in the ID and full function type, 1247 // - pass in the name, which includes the function type through mangling. 1248 static const WidenedIntrinsic *widen(StringRef Name); 1249 1250 private: 1251 struct LFEntry { 1252 LibFunc LFunc; 1253 const char *IntrinsicName; 1254 }; 1255 static const LFEntry kLibfuncIntrinsics[]; 1256 1257 static const WidenedIntrinsic kWidenedIntrinsics[]; 1258 }; 1259 } // namespace 1260 1261 static FunctionType *makeDoubleDouble(LLVMContext &C) { 1262 return FunctionType::get(Type::getDoubleTy(C), {Type::getDoubleTy(C)}, false); 1263 } 1264 1265 static FunctionType *makeX86FP80X86FP80(LLVMContext &C) { 1266 return FunctionType::get(Type::getX86_FP80Ty(C), {Type::getX86_FP80Ty(C)}, 1267 false); 1268 } 1269 1270 static FunctionType *makeDoubleDoubleI32(LLVMContext &C) { 1271 return FunctionType::get(Type::getDoubleTy(C), 1272 {Type::getDoubleTy(C), Type::getInt32Ty(C)}, false); 1273 } 1274 1275 static FunctionType *makeX86FP80X86FP80I32(LLVMContext &C) { 1276 return FunctionType::get(Type::getX86_FP80Ty(C), 1277 {Type::getX86_FP80Ty(C), Type::getInt32Ty(C)}, 1278 false); 1279 } 1280 1281 static FunctionType *makeDoubleDoubleDouble(LLVMContext &C) { 1282 return FunctionType::get(Type::getDoubleTy(C), 1283 {Type::getDoubleTy(C), Type::getDoubleTy(C)}, false); 1284 } 1285 1286 static FunctionType *makeX86FP80X86FP80X86FP80(LLVMContext &C) { 1287 return FunctionType::get(Type::getX86_FP80Ty(C), 1288 {Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C)}, 1289 false); 1290 } 1291 1292 static FunctionType *makeDoubleDoubleDoubleDouble(LLVMContext &C) { 1293 return FunctionType::get( 1294 Type::getDoubleTy(C), 1295 {Type::getDoubleTy(C), Type::getDoubleTy(C), Type::getDoubleTy(C)}, 1296 false); 1297 } 1298 1299 static FunctionType *makeX86FP80X86FP80X86FP80X86FP80(LLVMContext &C) { 1300 return FunctionType::get( 1301 Type::getX86_FP80Ty(C), 1302 {Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C)}, 1303 false); 1304 } 1305 1306 const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = { 1307 // TODO: Right now we ignore vector intrinsics. 1308 // This is hard because we have to model the semantics of the intrinsics, 1309 // e.g. llvm.x86.sse2.min.sd means extract first element, min, insert back. 1310 // Intrinsics that take any non-vector FT types: 1311 // NOTE: Right now because of 1312 // https://github.com/llvm/llvm-project/issues/44744 1313 // for f128 we need to use makeX86FP80X86FP80 (go to a lower precision and 1314 // come back). 1315 {"llvm.sqrt.f32", Intrinsic::sqrt, makeDoubleDouble}, 1316 {"llvm.sqrt.f64", Intrinsic::sqrt, makeX86FP80X86FP80}, 1317 {"llvm.sqrt.f80", Intrinsic::sqrt, makeX86FP80X86FP80}, 1318 {"llvm.powi.f32", Intrinsic::powi, makeDoubleDoubleI32}, 1319 {"llvm.powi.f64", Intrinsic::powi, makeX86FP80X86FP80I32}, 1320 {"llvm.powi.f80", Intrinsic::powi, makeX86FP80X86FP80I32}, 1321 {"llvm.sin.f32", Intrinsic::sin, makeDoubleDouble}, 1322 {"llvm.sin.f64", Intrinsic::sin, makeX86FP80X86FP80}, 1323 {"llvm.sin.f80", Intrinsic::sin, makeX86FP80X86FP80}, 1324 {"llvm.cos.f32", Intrinsic::cos, makeDoubleDouble}, 1325 {"llvm.cos.f64", Intrinsic::cos, makeX86FP80X86FP80}, 1326 {"llvm.cos.f80", Intrinsic::cos, makeX86FP80X86FP80}, 1327 {"llvm.pow.f32", Intrinsic::pow, makeDoubleDoubleDouble}, 1328 {"llvm.pow.f64", Intrinsic::pow, makeX86FP80X86FP80X86FP80}, 1329 {"llvm.pow.f80", Intrinsic::pow, makeX86FP80X86FP80X86FP80}, 1330 {"llvm.exp.f32", Intrinsic::exp, makeDoubleDouble}, 1331 {"llvm.exp.f64", Intrinsic::exp, makeX86FP80X86FP80}, 1332 {"llvm.exp.f80", Intrinsic::exp, makeX86FP80X86FP80}, 1333 {"llvm.exp2.f32", Intrinsic::exp2, makeDoubleDouble}, 1334 {"llvm.exp2.f64", Intrinsic::exp2, makeX86FP80X86FP80}, 1335 {"llvm.exp2.f80", Intrinsic::exp2, makeX86FP80X86FP80}, 1336 {"llvm.log.f32", Intrinsic::log, makeDoubleDouble}, 1337 {"llvm.log.f64", Intrinsic::log, makeX86FP80X86FP80}, 1338 {"llvm.log.f80", Intrinsic::log, makeX86FP80X86FP80}, 1339 {"llvm.log10.f32", Intrinsic::log10, makeDoubleDouble}, 1340 {"llvm.log10.f64", Intrinsic::log10, makeX86FP80X86FP80}, 1341 {"llvm.log10.f80", Intrinsic::log10, makeX86FP80X86FP80}, 1342 {"llvm.log2.f32", Intrinsic::log2, makeDoubleDouble}, 1343 {"llvm.log2.f64", Intrinsic::log2, makeX86FP80X86FP80}, 1344 {"llvm.log2.f80", Intrinsic::log2, makeX86FP80X86FP80}, 1345 {"llvm.fma.f32", Intrinsic::fma, makeDoubleDoubleDoubleDouble}, 1346 1347 {"llvm.fmuladd.f32", Intrinsic::fmuladd, makeDoubleDoubleDoubleDouble}, 1348 1349 {"llvm.fma.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80}, 1350 1351 {"llvm.fmuladd.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80}, 1352 1353 {"llvm.fma.f80", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80}, 1354 {"llvm.fabs.f32", Intrinsic::fabs, makeDoubleDouble}, 1355 {"llvm.fabs.f64", Intrinsic::fabs, makeX86FP80X86FP80}, 1356 {"llvm.fabs.f80", Intrinsic::fabs, makeX86FP80X86FP80}, 1357 {"llvm.minnum.f32", Intrinsic::minnum, makeDoubleDoubleDouble}, 1358 {"llvm.minnum.f64", Intrinsic::minnum, makeX86FP80X86FP80X86FP80}, 1359 {"llvm.minnum.f80", Intrinsic::minnum, makeX86FP80X86FP80X86FP80}, 1360 {"llvm.maxnum.f32", Intrinsic::maxnum, makeDoubleDoubleDouble}, 1361 {"llvm.maxnum.f64", Intrinsic::maxnum, makeX86FP80X86FP80X86FP80}, 1362 {"llvm.maxnum.f80", Intrinsic::maxnum, makeX86FP80X86FP80X86FP80}, 1363 {"llvm.minimum.f32", Intrinsic::minimum, makeDoubleDoubleDouble}, 1364 {"llvm.minimum.f64", Intrinsic::minimum, makeX86FP80X86FP80X86FP80}, 1365 {"llvm.minimum.f80", Intrinsic::minimum, makeX86FP80X86FP80X86FP80}, 1366 {"llvm.maximum.f32", Intrinsic::maximum, makeDoubleDoubleDouble}, 1367 {"llvm.maximum.f64", Intrinsic::maximum, makeX86FP80X86FP80X86FP80}, 1368 {"llvm.maximum.f80", Intrinsic::maximum, makeX86FP80X86FP80X86FP80}, 1369 {"llvm.copysign.f32", Intrinsic::copysign, makeDoubleDoubleDouble}, 1370 {"llvm.copysign.f64", Intrinsic::copysign, makeX86FP80X86FP80X86FP80}, 1371 {"llvm.copysign.f80", Intrinsic::copysign, makeX86FP80X86FP80X86FP80}, 1372 {"llvm.floor.f32", Intrinsic::floor, makeDoubleDouble}, 1373 {"llvm.floor.f64", Intrinsic::floor, makeX86FP80X86FP80}, 1374 {"llvm.floor.f80", Intrinsic::floor, makeX86FP80X86FP80}, 1375 {"llvm.ceil.f32", Intrinsic::ceil, makeDoubleDouble}, 1376 {"llvm.ceil.f64", Intrinsic::ceil, makeX86FP80X86FP80}, 1377 {"llvm.ceil.f80", Intrinsic::ceil, makeX86FP80X86FP80}, 1378 {"llvm.trunc.f32", Intrinsic::trunc, makeDoubleDouble}, 1379 {"llvm.trunc.f64", Intrinsic::trunc, makeX86FP80X86FP80}, 1380 {"llvm.trunc.f80", Intrinsic::trunc, makeX86FP80X86FP80}, 1381 {"llvm.rint.f32", Intrinsic::rint, makeDoubleDouble}, 1382 {"llvm.rint.f64", Intrinsic::rint, makeX86FP80X86FP80}, 1383 {"llvm.rint.f80", Intrinsic::rint, makeX86FP80X86FP80}, 1384 {"llvm.nearbyint.f32", Intrinsic::nearbyint, makeDoubleDouble}, 1385 {"llvm.nearbyint.f64", Intrinsic::nearbyint, makeX86FP80X86FP80}, 1386 {"llvm.nearbyin80f64", Intrinsic::nearbyint, makeX86FP80X86FP80}, 1387 {"llvm.round.f32", Intrinsic::round, makeDoubleDouble}, 1388 {"llvm.round.f64", Intrinsic::round, makeX86FP80X86FP80}, 1389 {"llvm.round.f80", Intrinsic::round, makeX86FP80X86FP80}, 1390 {"llvm.lround.f32", Intrinsic::lround, makeDoubleDouble}, 1391 {"llvm.lround.f64", Intrinsic::lround, makeX86FP80X86FP80}, 1392 {"llvm.lround.f80", Intrinsic::lround, makeX86FP80X86FP80}, 1393 {"llvm.llround.f32", Intrinsic::llround, makeDoubleDouble}, 1394 {"llvm.llround.f64", Intrinsic::llround, makeX86FP80X86FP80}, 1395 {"llvm.llround.f80", Intrinsic::llround, makeX86FP80X86FP80}, 1396 {"llvm.lrint.f32", Intrinsic::lrint, makeDoubleDouble}, 1397 {"llvm.lrint.f64", Intrinsic::lrint, makeX86FP80X86FP80}, 1398 {"llvm.lrint.f80", Intrinsic::lrint, makeX86FP80X86FP80}, 1399 {"llvm.llrint.f32", Intrinsic::llrint, makeDoubleDouble}, 1400 {"llvm.llrint.f64", Intrinsic::llrint, makeX86FP80X86FP80}, 1401 {"llvm.llrint.f80", Intrinsic::llrint, makeX86FP80X86FP80}, 1402 }; 1403 1404 const KnownIntrinsic::LFEntry KnownIntrinsic::kLibfuncIntrinsics[] = { 1405 {LibFunc_sqrtf, "llvm.sqrt.f32"}, 1406 {LibFunc_sqrt, "llvm.sqrt.f64"}, 1407 {LibFunc_sqrtl, "llvm.sqrt.f80"}, 1408 {LibFunc_sinf, "llvm.sin.f32"}, 1409 {LibFunc_sin, "llvm.sin.f64"}, 1410 {LibFunc_sinl, "llvm.sin.f80"}, 1411 {LibFunc_cosf, "llvm.cos.f32"}, 1412 {LibFunc_cos, "llvm.cos.f64"}, 1413 {LibFunc_cosl, "llvm.cos.f80"}, 1414 {LibFunc_powf, "llvm.pow.f32"}, 1415 {LibFunc_pow, "llvm.pow.f64"}, 1416 {LibFunc_powl, "llvm.pow.f80"}, 1417 {LibFunc_expf, "llvm.exp.f32"}, 1418 {LibFunc_exp, "llvm.exp.f64"}, 1419 {LibFunc_expl, "llvm.exp.f80"}, 1420 {LibFunc_exp2f, "llvm.exp2.f32"}, 1421 {LibFunc_exp2, "llvm.exp2.f64"}, 1422 {LibFunc_exp2l, "llvm.exp2.f80"}, 1423 {LibFunc_logf, "llvm.log.f32"}, 1424 {LibFunc_log, "llvm.log.f64"}, 1425 {LibFunc_logl, "llvm.log.f80"}, 1426 {LibFunc_log10f, "llvm.log10.f32"}, 1427 {LibFunc_log10, "llvm.log10.f64"}, 1428 {LibFunc_log10l, "llvm.log10.f80"}, 1429 {LibFunc_log2f, "llvm.log2.f32"}, 1430 {LibFunc_log2, "llvm.log2.f64"}, 1431 {LibFunc_log2l, "llvm.log2.f80"}, 1432 {LibFunc_fabsf, "llvm.fabs.f32"}, 1433 {LibFunc_fabs, "llvm.fabs.f64"}, 1434 {LibFunc_fabsl, "llvm.fabs.f80"}, 1435 {LibFunc_copysignf, "llvm.copysign.f32"}, 1436 {LibFunc_copysign, "llvm.copysign.f64"}, 1437 {LibFunc_copysignl, "llvm.copysign.f80"}, 1438 {LibFunc_floorf, "llvm.floor.f32"}, 1439 {LibFunc_floor, "llvm.floor.f64"}, 1440 {LibFunc_floorl, "llvm.floor.f80"}, 1441 {LibFunc_fmaxf, "llvm.maxnum.f32"}, 1442 {LibFunc_fmax, "llvm.maxnum.f64"}, 1443 {LibFunc_fmaxl, "llvm.maxnum.f80"}, 1444 {LibFunc_fminf, "llvm.minnum.f32"}, 1445 {LibFunc_fmin, "llvm.minnum.f64"}, 1446 {LibFunc_fminl, "llvm.minnum.f80"}, 1447 {LibFunc_ceilf, "llvm.ceil.f32"}, 1448 {LibFunc_ceil, "llvm.ceil.f64"}, 1449 {LibFunc_ceill, "llvm.ceil.f80"}, 1450 {LibFunc_truncf, "llvm.trunc.f32"}, 1451 {LibFunc_trunc, "llvm.trunc.f64"}, 1452 {LibFunc_truncl, "llvm.trunc.f80"}, 1453 {LibFunc_rintf, "llvm.rint.f32"}, 1454 {LibFunc_rint, "llvm.rint.f64"}, 1455 {LibFunc_rintl, "llvm.rint.f80"}, 1456 {LibFunc_nearbyintf, "llvm.nearbyint.f32"}, 1457 {LibFunc_nearbyint, "llvm.nearbyint.f64"}, 1458 {LibFunc_nearbyintl, "llvm.nearbyint.f80"}, 1459 {LibFunc_roundf, "llvm.round.f32"}, 1460 {LibFunc_round, "llvm.round.f64"}, 1461 {LibFunc_roundl, "llvm.round.f80"}, 1462 }; 1463 1464 const char *KnownIntrinsic::get(LibFunc LFunc) { 1465 for (const auto &E : kLibfuncIntrinsics) { 1466 if (E.LFunc == LFunc) 1467 return E.IntrinsicName; 1468 } 1469 return nullptr; 1470 } 1471 1472 const KnownIntrinsic::WidenedIntrinsic *KnownIntrinsic::widen(StringRef Name) { 1473 for (const auto &E : kWidenedIntrinsics) { 1474 if (E.NarrowName == Name) 1475 return &E; 1476 } 1477 return nullptr; 1478 } 1479 1480 // Returns the name of the LLVM intrinsic corresponding to the given function. 1481 static const char *getIntrinsicFromLibfunc(Function &Fn, Type *VT, 1482 const TargetLibraryInfo &TLI) { 1483 LibFunc LFunc; 1484 if (!TLI.getLibFunc(Fn, LFunc)) 1485 return nullptr; 1486 1487 if (const char *Name = KnownIntrinsic::get(LFunc)) 1488 return Name; 1489 1490 LLVM_DEBUG(errs() << "TODO: LibFunc: " << TLI.getName(LFunc) << "\n"); 1491 return nullptr; 1492 } 1493 1494 // Try to handle a known function call. 1495 Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase( 1496 CallBase &Call, Type *VT, Type *ExtendedVT, const TargetLibraryInfo &TLI, 1497 const ValueToShadowMap &Map, IRBuilder<> &Builder) { 1498 Function *Fn = Call.getCalledFunction(); 1499 if (Fn == nullptr) 1500 return nullptr; 1501 1502 Intrinsic::ID WidenedId = Intrinsic::ID(); 1503 FunctionType *WidenedFnTy = nullptr; 1504 if (const auto ID = Fn->getIntrinsicID()) { 1505 const auto *Widened = KnownIntrinsic::widen(Fn->getName()); 1506 if (Widened) { 1507 WidenedId = Widened->ID; 1508 WidenedFnTy = Widened->MakeFnTy(Context); 1509 } else { 1510 // If we don't know how to widen the intrinsic, we have no choice but to 1511 // call the non-wide version on a truncated shadow and extend again 1512 // afterwards. 1513 WidenedId = ID; 1514 WidenedFnTy = Fn->getFunctionType(); 1515 } 1516 } else if (const char *Name = getIntrinsicFromLibfunc(*Fn, VT, TLI)) { 1517 // We might have a call to a library function that we can replace with a 1518 // wider Intrinsic. 1519 const auto *Widened = KnownIntrinsic::widen(Name); 1520 assert(Widened && "make sure KnownIntrinsic entries are consistent"); 1521 WidenedId = Widened->ID; 1522 WidenedFnTy = Widened->MakeFnTy(Context); 1523 } else { 1524 // This is not a known library function or intrinsic. 1525 return nullptr; 1526 } 1527 1528 // Check that the widened intrinsic is valid. 1529 SmallVector<Intrinsic::IITDescriptor, 8> Table; 1530 getIntrinsicInfoTableEntries(WidenedId, Table); 1531 SmallVector<Type *, 4> ArgTys; 1532 ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; 1533 [[maybe_unused]] Intrinsic::MatchIntrinsicTypesResult MatchResult = 1534 Intrinsic::matchIntrinsicSignature(WidenedFnTy, TableRef, ArgTys); 1535 assert(MatchResult == Intrinsic::MatchIntrinsicTypes_Match && 1536 "invalid widened intrinsic"); 1537 // For known intrinsic functions, we create a second call to the same 1538 // intrinsic with a different type. 1539 SmallVector<Value *, 4> Args; 1540 // The last operand is the intrinsic itself, skip it. 1541 for (unsigned I = 0, E = Call.getNumOperands() - 1; I < E; ++I) { 1542 Value *Arg = Call.getOperand(I); 1543 Type *OrigArgTy = Arg->getType(); 1544 Type *IntrinsicArgTy = WidenedFnTy->getParamType(I); 1545 if (OrigArgTy == IntrinsicArgTy) { 1546 Args.push_back(Arg); // The arg is passed as is. 1547 continue; 1548 } 1549 Type *ShadowArgTy = Config.getExtendedFPType(Arg->getType()); 1550 assert(ShadowArgTy && 1551 "don't know how to get the shadow value for a non-FT"); 1552 Value *Shadow = Map.getShadow(Arg); 1553 if (ShadowArgTy == IntrinsicArgTy) { 1554 // The shadow is the right type for the intrinsic. 1555 assert(Shadow->getType() == ShadowArgTy); 1556 Args.push_back(Shadow); 1557 continue; 1558 } 1559 // There is no intrinsic with his level of precision, truncate the shadow. 1560 Args.push_back(Builder.CreateFPTrunc(Shadow, IntrinsicArgTy)); 1561 } 1562 Value *IntrinsicCall = Builder.CreateIntrinsic(WidenedId, ArgTys, Args); 1563 return WidenedFnTy->getReturnType() == ExtendedVT 1564 ? IntrinsicCall 1565 : Builder.CreateFPExt(IntrinsicCall, ExtendedVT); 1566 } 1567 1568 // Handle a CallBase, i.e. a function call, an inline asm sequence, or an 1569 // invoke. 1570 Value *NumericalStabilitySanitizer::handleCallBase(CallBase &Call, Type *VT, 1571 Type *ExtendedVT, 1572 const TargetLibraryInfo &TLI, 1573 const ValueToShadowMap &Map, 1574 IRBuilder<> &Builder) { 1575 // We cannot look inside inline asm, just expand the result again. 1576 if (Call.isInlineAsm()) 1577 return Builder.CreateFPExt(&Call, ExtendedVT); 1578 1579 // Intrinsics and library functions (e.g. sin, exp) are handled 1580 // specifically, because we know their semantics and can do better than 1581 // blindly calling them (e.g. compute the sinus in the actual shadow domain). 1582 if (Value *V = 1583 maybeHandleKnownCallBase(Call, VT, ExtendedVT, TLI, Map, Builder)) 1584 return V; 1585 1586 // If the return tag matches that of the called function, read the extended 1587 // return value from the shadow ret ptr. Else, just extend the return value. 1588 Value *L = 1589 Builder.CreateLoad(IntptrTy, NsanShadowRetTag, /*isVolatile=*/false); 1590 Value *HasShadowRet = Builder.CreateICmpEQ( 1591 L, Builder.CreatePtrToInt(Call.getCalledOperand(), IntptrTy)); 1592 1593 Value *ShadowRetVal = Builder.CreateLoad( 1594 ExtendedVT, 1595 Builder.CreateConstGEP2_64(NsanShadowRetType, NsanShadowRetPtr, 0, 0), 1596 /*isVolatile=*/false); 1597 Value *Shadow = Builder.CreateSelect(HasShadowRet, ShadowRetVal, 1598 Builder.CreateFPExt(&Call, ExtendedVT)); 1599 ++NumInstrumentedFTCalls; 1600 return Shadow; 1601 } 1602 1603 // Creates a shadow value for the given FT value. At that point all operands are 1604 // guaranteed to be available. 1605 Value *NumericalStabilitySanitizer::createShadowValueWithOperandsAvailable( 1606 Instruction &Inst, const TargetLibraryInfo &TLI, 1607 const ValueToShadowMap &Map) { 1608 Type *VT = Inst.getType(); 1609 Type *ExtendedVT = Config.getExtendedFPType(VT); 1610 assert(ExtendedVT != nullptr && "trying to create a shadow for a non-FT"); 1611 1612 if (auto *Load = dyn_cast<LoadInst>(&Inst)) 1613 return handleLoad(*Load, VT, ExtendedVT); 1614 1615 if (auto *Call = dyn_cast<CallInst>(&Inst)) { 1616 // Insert after the call. 1617 BasicBlock::iterator It(Inst); 1618 IRBuilder<> Builder(Call->getParent(), ++It); 1619 Builder.SetCurrentDebugLocation(Call->getDebugLoc()); 1620 return handleCallBase(*Call, VT, ExtendedVT, TLI, Map, Builder); 1621 } 1622 1623 if (auto *Invoke = dyn_cast<InvokeInst>(&Inst)) { 1624 // The Invoke terminates the basic block, create a new basic block in 1625 // between the successful invoke and the next block. 1626 BasicBlock *InvokeBB = Invoke->getParent(); 1627 BasicBlock *NextBB = Invoke->getNormalDest(); 1628 BasicBlock *NewBB = 1629 BasicBlock::Create(Context, "", NextBB->getParent(), NextBB); 1630 Inst.replaceSuccessorWith(NextBB, NewBB); 1631 1632 IRBuilder<> Builder(NewBB); 1633 Builder.SetCurrentDebugLocation(Invoke->getDebugLoc()); 1634 Value *Shadow = handleCallBase(*Invoke, VT, ExtendedVT, TLI, Map, Builder); 1635 Builder.CreateBr(NextBB); 1636 NewBB->replaceSuccessorsPhiUsesWith(InvokeBB, NewBB); 1637 return Shadow; 1638 } 1639 1640 IRBuilder<> Builder(Inst.getNextNode()); 1641 Builder.SetCurrentDebugLocation(Inst.getDebugLoc()); 1642 1643 if (auto *Trunc = dyn_cast<FPTruncInst>(&Inst)) 1644 return handleTrunc(*Trunc, VT, ExtendedVT, Map, Builder); 1645 if (auto *Ext = dyn_cast<FPExtInst>(&Inst)) 1646 return handleExt(*Ext, VT, ExtendedVT, Map, Builder); 1647 1648 if (auto *UnaryOp = dyn_cast<UnaryOperator>(&Inst)) 1649 return Builder.CreateUnOp(UnaryOp->getOpcode(), 1650 Map.getShadow(UnaryOp->getOperand(0))); 1651 1652 if (auto *BinOp = dyn_cast<BinaryOperator>(&Inst)) 1653 return Builder.CreateBinOp(BinOp->getOpcode(), 1654 Map.getShadow(BinOp->getOperand(0)), 1655 Map.getShadow(BinOp->getOperand(1))); 1656 1657 if (isa<UIToFPInst>(&Inst) || isa<SIToFPInst>(&Inst)) { 1658 auto *Cast = dyn_cast<CastInst>(&Inst); 1659 return Builder.CreateCast(Cast->getOpcode(), Cast->getOperand(0), 1660 ExtendedVT); 1661 } 1662 1663 if (auto *S = dyn_cast<SelectInst>(&Inst)) 1664 return Builder.CreateSelect(S->getCondition(), 1665 Map.getShadow(S->getTrueValue()), 1666 Map.getShadow(S->getFalseValue())); 1667 1668 if (auto *Extract = dyn_cast<ExtractElementInst>(&Inst)) 1669 return Builder.CreateExtractElement( 1670 Map.getShadow(Extract->getVectorOperand()), Extract->getIndexOperand()); 1671 1672 if (auto *Insert = dyn_cast<InsertElementInst>(&Inst)) 1673 return Builder.CreateInsertElement(Map.getShadow(Insert->getOperand(0)), 1674 Map.getShadow(Insert->getOperand(1)), 1675 Insert->getOperand(2)); 1676 1677 if (auto *Shuffle = dyn_cast<ShuffleVectorInst>(&Inst)) 1678 return Builder.CreateShuffleVector(Map.getShadow(Shuffle->getOperand(0)), 1679 Map.getShadow(Shuffle->getOperand(1)), 1680 Shuffle->getShuffleMask()); 1681 // TODO: We could make aggregate object first class citizens. For now we 1682 // just extend the extracted value. 1683 if (auto *Extract = dyn_cast<ExtractValueInst>(&Inst)) 1684 return Builder.CreateFPExt(Extract, ExtendedVT); 1685 1686 if (auto *BC = dyn_cast<BitCastInst>(&Inst)) 1687 return Builder.CreateFPExt(BC, ExtendedVT); 1688 1689 report_fatal_error("Unimplemented support for " + 1690 Twine(Inst.getOpcodeName())); 1691 } 1692 1693 // Creates a shadow value for an instruction that defines a value of FT type. 1694 // FT operands that do not already have shadow values are created recursively. 1695 // The DFS is guaranteed to not loop as phis and arguments already have 1696 // shadows. 1697 void NumericalStabilitySanitizer::maybeCreateShadowValue( 1698 Instruction &Root, const TargetLibraryInfo &TLI, ValueToShadowMap &Map) { 1699 Type *VT = Root.getType(); 1700 Type *ExtendedVT = Config.getExtendedFPType(VT); 1701 if (ExtendedVT == nullptr) 1702 return; // Not an FT value. 1703 1704 if (Map.hasShadow(&Root)) 1705 return; // Shadow already exists. 1706 1707 assert(!isa<PHINode>(Root) && "phi nodes should already have shadows"); 1708 1709 std::vector<Instruction *> DfsStack(1, &Root); 1710 while (!DfsStack.empty()) { 1711 // Ensure that all operands to the instruction have shadows before 1712 // proceeding. 1713 Instruction *I = DfsStack.back(); 1714 // The shadow for the instruction might have been created deeper in the DFS, 1715 // see `forward_use_with_two_uses` test. 1716 if (Map.hasShadow(I)) { 1717 DfsStack.pop_back(); 1718 continue; 1719 } 1720 1721 bool MissingShadow = false; 1722 for (Value *Op : I->operands()) { 1723 Type *VT = Op->getType(); 1724 if (!Config.getExtendedFPType(VT)) 1725 continue; // Not an FT value. 1726 if (Map.hasShadow(Op)) 1727 continue; // Shadow is already available. 1728 MissingShadow = true; 1729 DfsStack.push_back(cast<Instruction>(Op)); 1730 } 1731 if (MissingShadow) 1732 continue; // Process operands and come back to this instruction later. 1733 1734 // All operands have shadows. Create a shadow for the current value. 1735 Value *Shadow = createShadowValueWithOperandsAvailable(*I, TLI, Map); 1736 Map.setShadow(*I, *Shadow); 1737 DfsStack.pop_back(); 1738 } 1739 } 1740 1741 // A floating-point store needs its value and type written to shadow memory. 1742 void NumericalStabilitySanitizer::propagateFTStore( 1743 StoreInst &Store, Type *VT, Type *ExtendedVT, const ValueToShadowMap &Map) { 1744 Value *StoredValue = Store.getValueOperand(); 1745 IRBuilder<> Builder(&Store); 1746 Builder.SetCurrentDebugLocation(Store.getDebugLoc()); 1747 const auto Extents = getMemoryExtentsOrDie(VT); 1748 Value *ShadowPtr = Builder.CreateCall( 1749 NsanGetShadowPtrForStore[Extents.ValueType], 1750 {Store.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)}); 1751 1752 Value *StoredShadow = Map.getShadow(StoredValue); 1753 if (!Store.getParent()->getParent()->hasOptNone()) { 1754 // Only check stores when optimizing, because non-optimized code generates 1755 // too many stores to the stack, creating false positives. 1756 if (ClCheckStores) { 1757 StoredShadow = emitCheck(StoredValue, StoredShadow, Builder, 1758 CheckLoc::makeStore(Store.getPointerOperand())); 1759 ++NumInstrumentedFTStores; 1760 } 1761 } 1762 1763 Builder.CreateAlignedStore(StoredShadow, ShadowPtr, Align(1), 1764 Store.isVolatile()); 1765 } 1766 1767 // A non-ft store needs to invalidate shadow memory. Exceptions are: 1768 // - memory transfers of floating-point data through other pointer types (llvm 1769 // optimization passes transform `*(float*)a = *(float*)b` into 1770 // `*(i32*)a = *(i32*)b` ). These have the same semantics as memcpy. 1771 // - Writes of FT-sized constants. LLVM likes to do float stores as bitcasted 1772 // ints. Note that this is not really necessary because if the value is 1773 // unknown the framework will re-extend it on load anyway. It just felt 1774 // easier to debug tests with vectors of FTs. 1775 void NumericalStabilitySanitizer::propagateNonFTStore( 1776 StoreInst &Store, Type *VT, const ValueToShadowMap &Map) { 1777 Value *PtrOp = Store.getPointerOperand(); 1778 IRBuilder<> Builder(Store.getNextNode()); 1779 Builder.SetCurrentDebugLocation(Store.getDebugLoc()); 1780 Value *Dst = PtrOp; 1781 TypeSize SlotSize = DL.getTypeStoreSize(VT); 1782 assert(!SlotSize.isScalable() && "unsupported"); 1783 const auto LoadSizeBytes = SlotSize.getFixedValue(); 1784 Value *ValueSize = Constant::getIntegerValue( 1785 IntptrTy, APInt(IntptrTy->getPrimitiveSizeInBits(), LoadSizeBytes)); 1786 1787 ++NumInstrumentedNonFTStores; 1788 Value *StoredValue = Store.getValueOperand(); 1789 if (LoadInst *Load = dyn_cast<LoadInst>(StoredValue)) { 1790 // TODO: Handle the case when the value is from a phi. 1791 // This is a memory transfer with memcpy semantics. Copy the type and 1792 // value from the source. Note that we cannot use __nsan_copy_values() 1793 // here, because that will not work when there is a write to memory in 1794 // between the load and the store, e.g. in the case of a swap. 1795 Type *ShadowTypeIntTy = Type::getIntNTy(Context, 8 * LoadSizeBytes); 1796 Type *ShadowValueIntTy = 1797 Type::getIntNTy(Context, 8 * kShadowScale * LoadSizeBytes); 1798 IRBuilder<> LoadBuilder(Load->getNextNode()); 1799 Builder.SetCurrentDebugLocation(Store.getDebugLoc()); 1800 Value *LoadSrc = Load->getPointerOperand(); 1801 // Read the shadow type and value at load time. The type has the same size 1802 // as the FT value, the value has twice its size. 1803 // TODO: cache them to avoid re-creating them when a load is used by 1804 // several stores. Maybe create them like the FT shadows when a load is 1805 // encountered. 1806 Value *RawShadowType = LoadBuilder.CreateAlignedLoad( 1807 ShadowTypeIntTy, 1808 LoadBuilder.CreateCall(NsanGetRawShadowTypePtr, {LoadSrc}), Align(1), 1809 /*isVolatile=*/false); 1810 Value *RawShadowValue = LoadBuilder.CreateAlignedLoad( 1811 ShadowValueIntTy, 1812 LoadBuilder.CreateCall(NsanGetRawShadowPtr, {LoadSrc}), Align(1), 1813 /*isVolatile=*/false); 1814 1815 // Write back the shadow type and value at store time. 1816 Builder.CreateAlignedStore( 1817 RawShadowType, Builder.CreateCall(NsanGetRawShadowTypePtr, {Dst}), 1818 Align(1), 1819 /*isVolatile=*/false); 1820 Builder.CreateAlignedStore(RawShadowValue, 1821 Builder.CreateCall(NsanGetRawShadowPtr, {Dst}), 1822 Align(1), 1823 /*isVolatile=*/false); 1824 1825 ++NumInstrumentedNonFTMemcpyStores; 1826 return; 1827 } 1828 // ClPropagateNonFTConstStoresAsFT is by default false. 1829 if (Constant *C; ClPropagateNonFTConstStoresAsFT && 1830 (C = dyn_cast<Constant>(StoredValue))) { 1831 // This might be a fp constant stored as an int. Bitcast and store if it has 1832 // appropriate size. 1833 Type *BitcastTy = nullptr; // The FT type to bitcast to. 1834 if (auto *CInt = dyn_cast<ConstantInt>(C)) { 1835 switch (CInt->getType()->getScalarSizeInBits()) { 1836 case 32: 1837 BitcastTy = Type::getFloatTy(Context); 1838 break; 1839 case 64: 1840 BitcastTy = Type::getDoubleTy(Context); 1841 break; 1842 case 80: 1843 BitcastTy = Type::getX86_FP80Ty(Context); 1844 break; 1845 default: 1846 break; 1847 } 1848 } else if (auto *CDV = dyn_cast<ConstantDataVector>(C)) { 1849 const int NumElements = 1850 cast<VectorType>(CDV->getType())->getElementCount().getFixedValue(); 1851 switch (CDV->getType()->getScalarSizeInBits()) { 1852 case 32: 1853 BitcastTy = 1854 VectorType::get(Type::getFloatTy(Context), NumElements, false); 1855 break; 1856 case 64: 1857 BitcastTy = 1858 VectorType::get(Type::getDoubleTy(Context), NumElements, false); 1859 break; 1860 case 80: 1861 BitcastTy = 1862 VectorType::get(Type::getX86_FP80Ty(Context), NumElements, false); 1863 break; 1864 default: 1865 break; 1866 } 1867 } 1868 if (BitcastTy) { 1869 const MemoryExtents Extents = getMemoryExtentsOrDie(BitcastTy); 1870 Value *ShadowPtr = Builder.CreateCall( 1871 NsanGetShadowPtrForStore[Extents.ValueType], 1872 {PtrOp, ConstantInt::get(IntptrTy, Extents.NumElts)}); 1873 // Bitcast the integer value to the appropriate FT type and extend to 2FT. 1874 Type *ExtVT = Config.getExtendedFPType(BitcastTy); 1875 Value *Shadow = 1876 Builder.CreateFPExt(Builder.CreateBitCast(C, BitcastTy), ExtVT); 1877 Builder.CreateAlignedStore(Shadow, ShadowPtr, Align(1), 1878 Store.isVolatile()); 1879 return; 1880 } 1881 } 1882 // All other stores just reset the shadow value to unknown. 1883 Builder.CreateCall(NsanSetValueUnknown, {Dst, ValueSize}); 1884 } 1885 1886 void NumericalStabilitySanitizer::propagateShadowValues( 1887 Instruction &Inst, const TargetLibraryInfo &TLI, 1888 const ValueToShadowMap &Map) { 1889 if (auto *Store = dyn_cast<StoreInst>(&Inst)) { 1890 Value *StoredValue = Store->getValueOperand(); 1891 Type *VT = StoredValue->getType(); 1892 Type *ExtendedVT = Config.getExtendedFPType(VT); 1893 if (ExtendedVT == nullptr) 1894 return propagateNonFTStore(*Store, VT, Map); 1895 return propagateFTStore(*Store, VT, ExtendedVT, Map); 1896 } 1897 1898 if (auto *FCmp = dyn_cast<FCmpInst>(&Inst)) { 1899 emitFCmpCheck(*FCmp, Map); 1900 return; 1901 } 1902 1903 if (auto *CB = dyn_cast<CallBase>(&Inst)) { 1904 maybeAddSuffixForNsanInterface(CB); 1905 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) 1906 maybeMarkSanitizerLibraryCallNoBuiltin(CI, &TLI); 1907 if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst)) { 1908 instrumentMemIntrinsic(MI); 1909 return; 1910 } 1911 populateShadowStack(*CB, TLI, Map); 1912 return; 1913 } 1914 1915 if (auto *RetInst = dyn_cast<ReturnInst>(&Inst)) { 1916 if (!ClCheckRet) 1917 return; 1918 1919 Value *RV = RetInst->getReturnValue(); 1920 if (RV == nullptr) 1921 return; // This is a `ret void`. 1922 Type *VT = RV->getType(); 1923 Type *ExtendedVT = Config.getExtendedFPType(VT); 1924 if (ExtendedVT == nullptr) 1925 return; // Not an FT ret. 1926 Value *RVShadow = Map.getShadow(RV); 1927 IRBuilder<> Builder(RetInst); 1928 1929 RVShadow = emitCheck(RV, RVShadow, Builder, CheckLoc::makeRet()); 1930 ++NumInstrumentedFTRets; 1931 // Store tag. 1932 Value *FnAddr = 1933 Builder.CreatePtrToInt(Inst.getParent()->getParent(), IntptrTy); 1934 Builder.CreateStore(FnAddr, NsanShadowRetTag); 1935 // Store value. 1936 Value *ShadowRetValPtr = 1937 Builder.CreateConstGEP2_64(NsanShadowRetType, NsanShadowRetPtr, 0, 0); 1938 Builder.CreateStore(RVShadow, ShadowRetValPtr); 1939 return; 1940 } 1941 1942 if (InsertValueInst *Insert = dyn_cast<InsertValueInst>(&Inst)) { 1943 Value *V = Insert->getOperand(1); 1944 Type *VT = V->getType(); 1945 Type *ExtendedVT = Config.getExtendedFPType(VT); 1946 if (ExtendedVT == nullptr) 1947 return; 1948 IRBuilder<> Builder(Insert); 1949 emitCheck(V, Map.getShadow(V), Builder, CheckLoc::makeInsert()); 1950 return; 1951 } 1952 } 1953 1954 // Moves fast math flags from the function to individual instructions, and 1955 // removes the attribute from the function. 1956 // TODO: Make this controllable with a flag. 1957 static void moveFastMathFlags(Function &F, 1958 std::vector<Instruction *> &Instructions) { 1959 FastMathFlags FMF; 1960 #define MOVE_FLAG(attr, setter) \ 1961 if (F.getFnAttribute(attr).getValueAsString() == "true") { \ 1962 F.removeFnAttr(attr); \ 1963 FMF.set##setter(); \ 1964 } 1965 MOVE_FLAG("unsafe-fp-math", Fast) 1966 MOVE_FLAG("no-infs-fp-math", NoInfs) 1967 MOVE_FLAG("no-nans-fp-math", NoNaNs) 1968 MOVE_FLAG("no-signed-zeros-fp-math", NoSignedZeros) 1969 #undef MOVE_FLAG 1970 1971 for (Instruction *I : Instructions) 1972 if (isa<FPMathOperator>(I)) 1973 I->setFastMathFlags(FMF); 1974 } 1975 1976 bool NumericalStabilitySanitizer::sanitizeFunction( 1977 Function &F, const TargetLibraryInfo &TLI) { 1978 if (!F.hasFnAttribute(Attribute::SanitizeNumericalStability)) 1979 return false; 1980 1981 // This is required to prevent instrumenting call to __nsan_init from within 1982 // the module constructor. 1983 if (F.getName() == kNsanModuleCtorName) 1984 return false; 1985 SmallVector<Instruction *, 8> AllLoadsAndStores; 1986 SmallVector<Instruction *, 8> LocalLoadsAndStores; 1987 1988 // The instrumentation maintains: 1989 // - for each IR value `v` of floating-point (or vector floating-point) type 1990 // FT, a shadow IR value `s(v)` with twice the precision 2FT (e.g. 1991 // double for float and f128 for double). 1992 // - A shadow memory, which stores `s(v)` for any `v` that has been stored, 1993 // along with a shadow memory tag, which stores whether the value in the 1994 // corresponding shadow memory is valid. Note that this might be 1995 // incorrect if a non-instrumented function stores to memory, or if 1996 // memory is stored to through a char pointer. 1997 // - A shadow stack, which holds `s(v)` for any floating-point argument `v` 1998 // of a call to an instrumented function. This allows 1999 // instrumented functions to retrieve the shadow values for their 2000 // arguments. 2001 // Because instrumented functions can be called from non-instrumented 2002 // functions, the stack needs to include a tag so that the instrumented 2003 // function knows whether shadow values are available for their 2004 // parameters (i.e. whether is was called by an instrumented function). 2005 // When shadow arguments are not available, they have to be recreated by 2006 // extending the precision of the non-shadow arguments to the non-shadow 2007 // value. Non-instrumented functions do not modify (or even know about) the 2008 // shadow stack. The shadow stack pointer is __nsan_shadow_args. The shadow 2009 // stack tag is __nsan_shadow_args_tag. The tag is any unique identifier 2010 // for the function (we use the address of the function). Both variables 2011 // are thread local. 2012 // Example: 2013 // calls shadow stack tag shadow stack 2014 // ======================================================================= 2015 // non_instrumented_1() 0 0 2016 // | 2017 // v 2018 // instrumented_2(float a) 0 0 2019 // | 2020 // v 2021 // instrumented_3(float b, double c) &instrumented_3 s(b),s(c) 2022 // | 2023 // v 2024 // instrumented_4(float d) &instrumented_4 s(d) 2025 // | 2026 // v 2027 // non_instrumented_5(float e) &non_instrumented_5 s(e) 2028 // | 2029 // v 2030 // instrumented_6(float f) &non_instrumented_5 s(e) 2031 // 2032 // On entry, instrumented_2 checks whether the tag corresponds to its 2033 // function ptr. 2034 // Note that functions reset the tag to 0 after reading shadow parameters. 2035 // This ensures that the function does not erroneously read invalid data if 2036 // called twice in the same stack, once from an instrumented function and 2037 // once from an uninstrumented one. For example, in the following example, 2038 // resetting the tag in (A) ensures that (B) does not reuse the same the 2039 // shadow arguments (which would be incorrect). 2040 // instrumented_1(float a) 2041 // | 2042 // v 2043 // instrumented_2(float b) (A) 2044 // | 2045 // v 2046 // non_instrumented_3() 2047 // | 2048 // v 2049 // instrumented_2(float b) (B) 2050 // 2051 // - A shadow return slot. Any function that returns a floating-point value 2052 // places a shadow return value in __nsan_shadow_ret_val. Again, because 2053 // we might be calling non-instrumented functions, this value is guarded 2054 // by __nsan_shadow_ret_tag marker indicating which instrumented function 2055 // placed the value in __nsan_shadow_ret_val, so that the caller can check 2056 // that this corresponds to the callee. Both variables are thread local. 2057 // 2058 // For example, in the following example, the instrumentation in 2059 // `instrumented_1` rejects the shadow return value from `instrumented_3` 2060 // because is is not tagged as expected (`&instrumented_3` instead of 2061 // `non_instrumented_2`): 2062 // 2063 // instrumented_1() 2064 // | 2065 // v 2066 // float non_instrumented_2() 2067 // | 2068 // v 2069 // float instrumented_3() 2070 // 2071 // Calls of known math functions (sin, cos, exp, ...) are duplicated to call 2072 // their overload on the shadow type. 2073 2074 // Collect all instructions before processing, as creating shadow values 2075 // creates new instructions inside the function. 2076 std::vector<Instruction *> OriginalInstructions; 2077 for (BasicBlock &BB : F) 2078 for (Instruction &Inst : BB) 2079 OriginalInstructions.emplace_back(&Inst); 2080 2081 moveFastMathFlags(F, OriginalInstructions); 2082 ValueToShadowMap ValueToShadow(Config); 2083 2084 // In the first pass, we create shadow values for all FT function arguments 2085 // and all phis. This ensures that the DFS of the next pass does not have 2086 // any loops. 2087 std::vector<PHINode *> OriginalPhis; 2088 createShadowArguments(F, TLI, ValueToShadow); 2089 for (Instruction *I : OriginalInstructions) { 2090 if (PHINode *Phi = dyn_cast<PHINode>(I)) { 2091 if (PHINode *Shadow = maybeCreateShadowPhi(*Phi, TLI)) { 2092 OriginalPhis.push_back(Phi); 2093 ValueToShadow.setShadow(*Phi, *Shadow); 2094 } 2095 } 2096 } 2097 2098 // Create shadow values for all instructions creating FT values. 2099 for (Instruction *I : OriginalInstructions) 2100 maybeCreateShadowValue(*I, TLI, ValueToShadow); 2101 2102 // Propagate shadow values across stores, calls and rets. 2103 for (Instruction *I : OriginalInstructions) 2104 propagateShadowValues(*I, TLI, ValueToShadow); 2105 2106 // The last pass populates shadow phis with shadow values. 2107 for (PHINode *Phi : OriginalPhis) { 2108 PHINode *ShadowPhi = dyn_cast<PHINode>(ValueToShadow.getShadow(Phi)); 2109 for (unsigned I : seq(Phi->getNumOperands())) { 2110 Value *V = Phi->getOperand(I); 2111 Value *Shadow = ValueToShadow.getShadow(V); 2112 BasicBlock *IncomingBB = Phi->getIncomingBlock(I); 2113 // For some instructions (e.g. invoke), we create the shadow in a separate 2114 // block, different from the block where the original value is created. 2115 // In that case, the shadow phi might need to refer to this block instead 2116 // of the original block. 2117 // Note that this can only happen for instructions as constant shadows are 2118 // always created in the same block. 2119 ShadowPhi->addIncoming(Shadow, IncomingBB); 2120 } 2121 } 2122 2123 return !ValueToShadow.empty(); 2124 } 2125 2126 // Instrument the memory intrinsics so that they properly modify the shadow 2127 // memory. 2128 bool NumericalStabilitySanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 2129 IRBuilder<> Builder(MI); 2130 if (auto *M = dyn_cast<MemSetInst>(MI)) { 2131 Builder.CreateCall( 2132 NsanSetValueUnknown, 2133 {/*Address=*/M->getArgOperand(0), 2134 /*Size=*/Builder.CreateIntCast(M->getArgOperand(2), IntptrTy, false)}); 2135 } else if (auto *M = dyn_cast<MemTransferInst>(MI)) { 2136 Builder.CreateCall( 2137 NsanCopyValues, 2138 {/*Destination=*/M->getArgOperand(0), 2139 /*Source=*/M->getArgOperand(1), 2140 /*Size=*/Builder.CreateIntCast(M->getArgOperand(2), IntptrTy, false)}); 2141 } 2142 return false; 2143 } 2144 2145 void NumericalStabilitySanitizer::maybeAddSuffixForNsanInterface(CallBase *CI) { 2146 Function *Fn = CI->getCalledFunction(); 2147 if (Fn == nullptr) 2148 return; 2149 2150 if (!Fn->getName().starts_with("__nsan_")) 2151 return; 2152 2153 if (Fn->getName() == "__nsan_dump_shadow_mem") { 2154 assert(CI->arg_size() == 4 && 2155 "invalid prototype for __nsan_dump_shadow_mem"); 2156 // __nsan_dump_shadow_mem requires an extra parameter with the dynamic 2157 // configuration: 2158 // (shadow_type_id_for_long_double << 16) | (shadow_type_id_for_double << 8) 2159 // | shadow_type_id_for_double 2160 const uint64_t shadow_value_type_ids = 2161 (static_cast<size_t>(Config.byValueType(kLongDouble).getNsanTypeId()) 2162 << 16) | 2163 (static_cast<size_t>(Config.byValueType(kDouble).getNsanTypeId()) 2164 << 8) | 2165 static_cast<size_t>(Config.byValueType(kFloat).getNsanTypeId()); 2166 CI->setArgOperand(3, ConstantInt::get(IntptrTy, shadow_value_type_ids)); 2167 } 2168 } 2169