Skip to content

Commit a6f286a

Browse files
committed
[IsolatePath] Refactor and improve pass
This commit provides several improvements to the IsolatePath pass: - Refactors the main processing function into smaller, more focused helpers to improve readability and maintainability. - Fixes a bug where the pass would crash with a 'terminator in the middle of a basic block' error due to incorrect instruction mapping in cloned blocks. - Ensures LoopInfo is correctly updated when a block within a loop is split, and preserves the analysis. - Removes stale FIXME comments regarding SwitchInst support. - Expands the test suite to cover more complex scenarios, including UB in loops and blocks terminated by SwitchInst.
1 parent fe0c218 commit a6f286a

File tree

3 files changed

+604
-150
lines changed

3 files changed

+604
-150
lines changed

llvm/include/llvm/Transforms/Scalar/IsolatePath.h

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
1-
//===- IsolatePath.cpp - Code to isolate paths with UB ----------*- C++ -*-===//
1+
//===- IsolatePath.h - Path isolation for undefined behavior ----*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This pass isolates code paths with undefined behavior from paths without
10-
// undefined behavior, and then add a trap instruction on that path. This
11-
// prevents code generation where, after the UB instruction's eliminated, the
12-
// code can wander off the end of a function.
9+
// This file defines the interface for the IsolatePath pass.
1310
//
14-
// For example, a nullptr dereference:
11+
// The pass identifies undefined behavior (UB) that is reachable via a PHI node
12+
// that can select a null pointer. It then refactors the control-flow graph to
13+
// isolate the UB-triggering path from the safe paths.
1514
//
16-
// foo:
17-
// %phi.val = phi ptr [ %arrayidx.i, %pred1 ], [ null, %pred2 ]
18-
// %load.val = load i32, ptr %phi.val, align 4
15+
// Once isolated, the UB path is terminated, either with an 'unreachable'
16+
// instruction or, optionally, with a 'trap' followed by 'unreachable'. This
17+
// prevents the optimizer from making unsafe assumptions based on the presence
18+
// of UB, which could otherwise lead to miscompilations.
1919
//
20-
// is converted into:
20+
// For example, a null pointer dereference is transformed from:
2121
//
22-
// foo.ub.path:
23-
// %load.val.ub = load volatile i32, ptr null, align 4
24-
// tail call void @llvm.trap()
22+
// bb:
23+
// %phi = phi ptr [ %valid_ptr, %pred1 ], [ null, %pred2 ]
24+
// %val = load i32, ptr %phi
25+
//
26+
// To:
27+
//
28+
// bb:
29+
// %phi = phi ptr [ %valid_ptr, %pred1 ]
30+
// %val = load i32, ptr %phi
31+
// ...
32+
//
33+
// bb.ub.path:
34+
// %phi.ub = phi ptr [ null, %pred2 ]
35+
// unreachable
36+
//
37+
// Or to this with the optional trap-unreachable flag:
38+
//
39+
// bb.ub.path:
40+
// %phi.ub = phi ptr [ null, %pred2 ]
41+
// %val.ub = load volatile i32, ptr %phi.ub ; Optional trap
42+
// call void @llvm.trap()
2543
// unreachable
2644
//
27-
// Note: we allow the NULL dereference to actually occur so that code that
28-
// wishes to catch the signal can do so.
45+
// This ensures that the presence of the null path does not interfere with
46+
// valid code paths.
2947
//
3048
//===----------------------------------------------------------------------===//
3149

@@ -40,14 +58,15 @@ namespace llvm {
4058
class BasicBlock;
4159
class DomTreeUpdater;
4260
class Function;
61+
class LoopInfo;
4362

44-
/// This pass performs 'path isolation', which looks for undefined behavior and
45-
/// isolates the path from non-undefined behavior code and converts the UB into
46-
/// a trap call.
63+
/// A pass that isolates paths with undefined behavior and converts the UB into
64+
/// a trap or unreachable instruction.
4765
class IsolatePathPass : public PassInfoMixin<IsolatePathPass> {
4866
SmallPtrSet<BasicBlock *, 4> SplitUBBlocks;
4967

50-
bool ProcessPointerUndefinedBehavior(BasicBlock *BB, DomTreeUpdater *DTU);
68+
bool ProcessPointerUndefinedBehavior(BasicBlock *BB, DomTreeUpdater *DTU,
69+
LoopInfo *LI);
5170

5271
public:
5372
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

0 commit comments

Comments
 (0)