@@ -330,6 +330,37 @@ static void canonicalizePHIOperands(MachineFunction &MF) {
330
330
}
331
331
}
332
332
333
+ // / Helper to scan a function for loads vulnerable to misspeculation that we
334
+ // / want to harden.
335
+ // /
336
+ // / We use this to avoid making changes to functions where there is nothing we
337
+ // / need to do to harden against misspeculation.
338
+ static bool hasVulnerableLoad (MachineFunction &MF) {
339
+ for (MachineBasicBlock &MBB : MF) {
340
+ for (MachineInstr &MI : MBB) {
341
+ // Loads within this basic block after an LFENCE are not at risk of
342
+ // speculatively executing with invalid predicates from prior control
343
+ // flow. So break out of this block but continue scanning the function.
344
+ if (MI.getOpcode () == X86::LFENCE)
345
+ break ;
346
+
347
+ // Looking for loads only.
348
+ if (!MI.mayLoad ())
349
+ continue ;
350
+
351
+ // An MFENCE is modeled as a load but isn't vulnerable to misspeculation.
352
+ if (MI.getOpcode () == X86::MFENCE)
353
+ continue ;
354
+
355
+ // We found a load.
356
+ return true ;
357
+ }
358
+ }
359
+
360
+ // No loads found.
361
+ return false ;
362
+ }
363
+
333
364
bool X86SpeculativeLoadHardeningPass::runOnMachineFunction (
334
365
MachineFunction &MF) {
335
366
LLVM_DEBUG (dbgs () << " ********** " << getPassName () << " : " << MF.getName ()
@@ -359,34 +390,14 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
359
390
auto EntryInsertPt = Entry.SkipPHIsLabelsAndDebug (Entry.begin ());
360
391
361
392
// Do a quick scan to see if we have any checkable loads.
362
- bool HasCheckableLoad = false ;
363
- for (MachineBasicBlock &MBB : MF) {
364
- for (MachineInstr &MI : MBB) {
365
- // Stop searching blocks at an LFENCE.
366
- if (MI.getOpcode () == X86::LFENCE)
367
- break ;
368
-
369
- // Looking for loads only.
370
- if (!MI.mayLoad ())
371
- continue ;
372
-
373
- // An MFENCE is modeled as a load but doesn't require hardening.
374
- if (MI.getOpcode () == X86::MFENCE)
375
- continue ;
376
-
377
- HasCheckableLoad = true ;
378
- break ;
379
- }
380
- if (HasCheckableLoad)
381
- break ;
382
- }
393
+ bool HasVulnerableLoad = hasVulnerableLoad (MF);
383
394
384
395
// See if we have any conditional branching blocks that we will need to trace
385
396
// predicate state through.
386
397
SmallVector<BlockCondInfo, 16 > Infos = collectBlockCondInfo (MF);
387
398
388
399
// If we have no interesting conditions or loads, nothing to do here.
389
- if (!HasCheckableLoad && Infos.empty ())
400
+ if (!HasVulnerableLoad && Infos.empty ())
390
401
return true ;
391
402
392
403
unsigned PredStateReg;
@@ -402,7 +413,7 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
402
413
403
414
// If we have loads being hardened and we've asked for call and ret edges to
404
415
// get a full fence-based mitigation, inject that fence.
405
- if (HasCheckableLoad && FenceCallAndRet) {
416
+ if (HasVulnerableLoad && FenceCallAndRet) {
406
417
// We need to insert an LFENCE at the start of the function to suspend any
407
418
// incoming misspeculation from the caller. This helps two-fold: the caller
408
419
// may not have been protected as this code has been, and this code gets to
0 commit comments