Skip to content

Commit 267c6ed

Browse files
hiradityacompnerd
authored andcommitted
Fix 40056: Prevent outlining of blocks with token type instructions (llvm#99759)
Hot cold splitting should not outline: 1. Basic blocks with token type instructions 1. Functions with scoped EH personality (As suggested by Vedant in llvm#40056 (comment)) Fixes: llvm#40056 (cherry picked from commit c59ee7e)
1 parent 3427f33 commit 267c6ed

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

llvm/lib/Transforms/IPO/HotColdSplitting.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "llvm/IR/CFG.h"
4040
#include "llvm/IR/DiagnosticInfo.h"
4141
#include "llvm/IR/Dominators.h"
42+
#include "llvm/IR/EHPersonalities.h"
4243
#include "llvm/IR/Function.h"
4344
#include "llvm/IR/Instruction.h"
4445
#include "llvm/IR/Instructions.h"
@@ -136,10 +137,24 @@ static bool mayExtractBlock(const BasicBlock &BB) {
136137
//
137138
// Resumes that are not reachable from a cleanup landing pad are considered to
138139
// be unreachable. It’s not safe to split them out either.
140+
139141
if (BB.hasAddressTaken() || BB.isEHPad())
140142
return false;
141143
auto Term = BB.getTerminator();
142-
return !isa<InvokeInst>(Term) && !isa<ResumeInst>(Term);
144+
if (isa<InvokeInst>(Term) || isa<ResumeInst>(Term))
145+
return false;
146+
147+
// Do not outline basic blocks that have token type instructions. e.g.,
148+
// exception:
149+
// %0 = cleanuppad within none []
150+
// call void @"?terminate@@YAXXZ"() [ "funclet"(token %0) ]
151+
// br label %continue-exception
152+
if (llvm::any_of(
153+
BB, [](const Instruction &I) { return I.getType()->isTokenTy(); })) {
154+
return false;
155+
}
156+
157+
return true;
143158
}
144159

145160
/// Mark \p F cold. Based on this assumption, also optimize it for minimum size.
@@ -203,6 +218,11 @@ bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
203218
F.hasFnAttribute(Attribute::SanitizeMemory))
204219
return false;
205220

221+
// Do not outline scoped EH personality functions.
222+
if (F.hasPersonalityFn())
223+
if (isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
224+
return false;
225+
206226
return true;
207227
}
208228

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
; RUN: opt -passes=hotcoldsplit -hotcoldsplit-threshold=-1 -S < %s | FileCheck %s
2+
; Hot cold splitting should not outline:
3+
; 1. Basic blocks with token type instructions
4+
; 2. Functions with scoped EH personality
5+
6+
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
7+
target triple = "x86_64-pc-windows-msvc19.0.0"
8+
9+
; CHECK-LABEL: define {{.*}}@with_funclet
10+
; CHECK-NOT: with_funclet.cold
11+
define void @with_funclet() personality ptr @__CxxFrameHandler3 {
12+
entry:
13+
invoke void @fYAXXZ()
14+
to label %normal unwind label %exception
15+
16+
normal: ; preds = %entry
17+
ret void
18+
19+
exception: ; preds = %entry
20+
%0 = cleanuppad within none []
21+
call void @terminateYAXXZ() [ "funclet"(token %0) ]
22+
br label %continueexception
23+
24+
continueexception: ; preds = %exception
25+
ret void
26+
}
27+
28+
; CHECK-LABEL: define {{.*}}@with_personality
29+
; CHECK-NOT: with_personality.cold
30+
define void @with_personality(i32 %cond) personality ptr @__CxxFrameHandler3 {
31+
entry:
32+
%cond.addr = alloca i32
33+
store i32 %cond, ptr %cond.addr
34+
%0 = load i32, ptr %cond.addr
35+
%tobool = icmp ne i32 %0, 0
36+
br i1 %tobool, label %if.then, label %if.end2
37+
38+
if.then: ; preds = %entry
39+
%1 = load i32, ptr %cond.addr
40+
%cmp = icmp sgt i32 %1, 10
41+
br i1 %cmp, label %if.then1, label %if.else
42+
43+
if.then1: ; preds = %if.then
44+
call void @sideeffect(i32 0)
45+
br label %if.end
46+
47+
if.else: ; preds = %if.then
48+
call void @sideeffect(i32 1)
49+
br label %if.end
50+
51+
if.end: ; preds = %if.else, %if.then1
52+
call void (...) @sink()
53+
ret void
54+
55+
if.end2: ; preds = %entry
56+
call void @sideeffect(i32 2)
57+
ret void
58+
}
59+
60+
declare i32 @__CxxFrameHandler3(...)
61+
62+
declare void @fYAXXZ()
63+
64+
declare void @bar() #0
65+
66+
declare void @terminateYAXXZ()
67+
68+
declare void @sideeffect(i32)
69+
70+
declare void @sink(...) #0
71+
72+
attributes #0 = { cold }

0 commit comments

Comments
 (0)