Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 915f319

Browse files
committed
SjLjEHPrepare: Don't reg-to-mem swifterror values
swifterror llvm values model the swifterror register as memory at the LLVM IR level. ISel will perform adhoc mem-to-reg on them. swifterror values are constraint in how they can be used. Spilling them to memory is not allowed. SjLjEHPrepare tried to lower swifterror values to memory which is unecessary since the back-end will spill and reload the register as neccessary (as long as clobbering calls are marked as such which is the case here) and further leads to invalid IR because swifterror values can't be stored to memory. rdar://38164004 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327521 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit 1fd0177)
1 parent 70fee35 commit 915f319

File tree

2 files changed

+38
-24
lines changed

2 files changed

+38
-24
lines changed

lib/CodeGen/SjLjEHPrepare.cpp

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class SjLjEHPrepare : public FunctionPass {
6464

6565
private:
6666
bool setupEntryBlockAndCallSites(Function &F);
67-
bool undoSwiftErrorSelect(Function &F);
6867
void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, Value *SelVal);
6968
Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst *> LPads);
7069
void lowerIncomingArguments(Function &F);
@@ -233,6 +232,13 @@ void SjLjEHPrepare::lowerIncomingArguments(Function &F) {
233232
assert(AfterAllocaInsPt != F.front().end());
234233

235234
for (auto &AI : F.args()) {
235+
// Swift error really is a register that we model as memory -- instruction
236+
// selection will perform mem-to-reg for us and spill/reload appropriately
237+
// around calls that clobber it. There is no need to spill this
238+
// value to the stack and doing so would not be allowed.
239+
if (AI.isSwiftError())
240+
continue;
241+
236242
Type *Ty = AI.getType();
237243

238244
// Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
@@ -462,25 +468,6 @@ bool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) {
462468
return true;
463469
}
464470

465-
bool SjLjEHPrepare::undoSwiftErrorSelect(Function &F) {
466-
// We have inserted dummy copies 'select true, arg, undef' in the entry block
467-
// for arguments to simplify this pass.
468-
// swifterror arguments cannot be used in this way. Undo the select for the
469-
// swifterror argument.
470-
for (auto &AI : F.args()) {
471-
if (AI.isSwiftError()) {
472-
assert(AI.hasOneUse() && "Must have converted the argument to a select");
473-
auto *Select = dyn_cast<SelectInst>(AI.use_begin()->getUser());
474-
assert(Select && "There must be single select user");
475-
auto *OrigSwiftError = cast<Argument>(Select->getTrueValue());
476-
Select->replaceAllUsesWith(OrigSwiftError);
477-
Select->eraseFromParent();
478-
return true;
479-
}
480-
}
481-
return false;
482-
}
483-
484471
bool SjLjEHPrepare::runOnFunction(Function &F) {
485472
Module &M = *F.getParent();
486473
RegisterFn = M.getOrInsertFunction(
@@ -499,7 +486,5 @@ bool SjLjEHPrepare::runOnFunction(Function &F) {
499486
FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext);
500487

501488
bool Res = setupEntryBlockAndCallSites(F);
502-
if (Res)
503-
Res |= undoSwiftErrorSelect(F);
504489
return Res;
505490
}

test/CodeGen/ARM/sjljeh-swifterror.ll

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -sjljehprepare -verify < %s | FileCheck %s
1+
; RUN: opt -sjljehprepare -verify < %s -S | FileCheck %s
22
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
33
target triple = "armv7s-apple-ios7.0"
44

@@ -9,7 +9,7 @@ declare void @objc_msgSend() local_unnamed_addr
99
declare i32 @__objc_personality_v0(...)
1010

1111
; Make sure we don't leave a select on a swifterror argument.
12-
; CHECK-LABEL; @test
12+
; CHECK-LABEL: @test
1313
; CHECK-NOT: select true, %0
1414
define swiftcc void @test(%swift.error** swifterror) local_unnamed_addr personality i32 (...)* @__objc_personality_v0 {
1515
entry:
@@ -25,3 +25,32 @@ lpad.i:
2525
resume { i8*, i32 } undef
2626
}
2727

28+
%struct._objc_typeinfo = type { i8**, i8*, i64* }
29+
@"OBJC_EHTYPE_$_NSException" = external global %struct._objc_typeinfo
30+
31+
; Make sure this does not crash.
32+
; CHECK-LABEL: @swift_error_bug
33+
; CHECK: store %swift.error* null, %swift.error** %0
34+
35+
define hidden swiftcc void @swift_error_bug(%swift.error** swifterror, void (i8*)** %fun, i1 %b) local_unnamed_addr #0 personality i32 (...)* @__objc_personality_v0 {
36+
%2 = load void (i8*)*, void (i8*)** %fun, align 4
37+
invoke void %2(i8* null) #1
38+
to label %tryBlock.exit unwind label %3, !clang.arc.no_objc_arc_exceptions !1
39+
40+
; <label>:3:
41+
%4 = landingpad { i8*, i32 }
42+
catch %struct._objc_typeinfo* @"OBJC_EHTYPE_$_NSException"
43+
br label %tryBlock.exit
44+
45+
tryBlock.exit:
46+
br i1 %b, label %5, label %_T0ypMa.exit.i.i
47+
48+
_T0ypMa.exit.i.i:
49+
store %swift.error* null, %swift.error** %0, align 4
50+
ret void
51+
52+
; <label>:5:
53+
ret void
54+
}
55+
56+
!1 = !{}

0 commit comments

Comments
 (0)