llvm.org GIT mirror llvm / 3f92d75
[CodeExtractor] Prevent extraction of block involving blockaddress BlockAddress are only valid within their function context, which does not interact well with CodeExtractor. Detect this case and prevent it. Differential Revision: https://reviews.llvm.org/D33839 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306448 91177308-0d34-0410-b5e6-96231b3b80d8 Serge Guelton 2 years ago
3 changed file(s) with 106 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
5858 // Landing pads must be in the function where they were inserted for cleanup.
5959 if (BB.isEHPad())
6060 return false;
61 // taking the address of a basic block moved to another function is illegal
62 if (BB.hasAddressTaken())
63 return false;
64
65 // don't hoist code that uses another basicblock address, as it's likely to
66 // lead to unexpected behavior, like cross-function jumps
67 SmallPtrSet Visited;
68 SmallVector ToVisit;
69
70 for (Instruction const &Inst : BB)
71 ToVisit.push_back(&Inst);
72
73 while (!ToVisit.empty()) {
74 User const *Curr = ToVisit.pop_back_val();
75 if (!Visited.insert(Curr).second)
76 continue;
77 if (isa(Curr))
78 return false; // even a reference to self is likely to be not compatible
79
80 if (isa(Curr) && cast(Curr)->getParent() != &BB)
81 continue;
82
83 for (auto const &U : Curr->operands()) {
84 if (auto *UU = dyn_cast(U))
85 ToVisit.push_back(UU);
86 }
87 }
6188
6289 // Don't hoist code containing allocas, invokes, or vastarts.
6390 for (BasicBlock::const_iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
0 ; RUN: opt < %s -loop-extract -S | FileCheck %s
1
2 @label = common local_unnamed_addr global i8* null
3
4 ; CHECK: define
5 ; no outlined function
6 ; CHECK-NOT: define
7 define i32 @sterix(i32 %n) {
8 entry:
9 %tobool = icmp ne i32 %n, 0
10 ; this blockaddress references a basic block that goes in the extracted loop
11 %cond = select i1 %tobool, i8* blockaddress(@sterix, %for.cond), i8* blockaddress(@sterix, %exit)
12 store i8* %cond, i8** @label
13 %cmp5 = icmp sgt i32 %n, 0
14 br i1 %cmp5, label %for.body, label %exit
15
16 for.cond:
17 %mul = shl nsw i32 %s.06, 1
18 %exitcond = icmp eq i32 %inc, %n
19 br i1 %exitcond, label %exit.loopexit, label %for.body
20
21 for.body:
22 %i.07 = phi i32 [ %inc, %for.cond ], [ 0, %entry ]
23 %s.06 = phi i32 [ %mul, %for.cond ], [ 1, %entry ]
24 %inc = add nuw nsw i32 %i.07, 1
25 br label %for.cond
26
27 exit.loopexit:
28 %phitmp = icmp ne i32 %s.06, 2
29 %phitmp8 = zext i1 %phitmp to i32
30 br label %exit
31
32 exit:
33 %s.1 = phi i32 [ 1, %entry ], [ %phitmp8, %exit.loopexit ]
34 ret i32 %s.1
35 }
0 ; RUN: opt < %s -loop-extract -S | FileCheck %s
1
2 @choum.addr = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@choum, %12), i8* blockaddress(@choum, %16), i8* blockaddress(@choum, %20)]
3
4 ; CHECK: define
5 ; no outlined function
6 ; CHECK-NOT: define
7
8 define void @choum(i32, i32* nocapture, i32) {
9 %4 = icmp sgt i32 %0, 0
10 br i1 %4, label %5, label %26
11
12 %6 = sext i32 %2 to i64
13 %7 = getelementptr inbounds [3 x i8*], [3 x i8*]* @choum.addr, i64 0, i64 %6
14 %8 = load i8*, i8** %7
15 %9 = zext i32 %0 to i64
16 br label %10
17
18 %11 = phi i64 [ 0, %5 ], [ %24, %20 ]
19 indirectbr i8* %8, [label %12, label %16, label %20]
20
21 %13 = getelementptr inbounds i32, i32* %1, i64 %11
22 %14 = load i32, i32* %13
23 %15 = add nsw i32 %14, 1
24 store i32 %15, i32* %13
25 br label %16
26
27 %17 = getelementptr inbounds i32, i32* %1, i64 %11
28 %18 = load i32, i32* %17
29 %19 = shl nsw i32 %18, 1
30 store i32 %19, i32* %17
31 br label %20
32
33 %21 = getelementptr inbounds i32, i32* %1, i64 %11
34 %22 = load i32, i32* %21
35 %23 = add nsw i32 %22, -3
36 store i32 %23, i32* %21
37 %24 = add nuw nsw i64 %11, 1
38 %25 = icmp eq i64 %24, %9
39 br i1 %25, label %26, label %10
40
41 ret void
42 }