[llvm] r327521 - SjLjEHPrepare: Don't reg-to-mem swifterror values

Arnold Schwaighofer via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 08:44:07 PDT 2018


Author: arnolds
Date: Wed Mar 14 08:44:07 2018
New Revision: 327521

URL: http://llvm.org/viewvc/llvm-project?rev=327521&view=rev
Log:
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

Modified:
    llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp
    llvm/trunk/test/CodeGen/ARM/sjljeh-swifterror.ll

Modified: llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp?rev=327521&r1=327520&r2=327521&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Wed Mar 14 08:44:07 2018
@@ -64,7 +64,6 @@ public:
 
 private:
   bool setupEntryBlockAndCallSites(Function &F);
-  bool undoSwiftErrorSelect(Function &F);
   void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, Value *SelVal);
   Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst *> LPads);
   void lowerIncomingArguments(Function &F);
@@ -233,6 +232,13 @@ void SjLjEHPrepare::lowerIncomingArgumen
   assert(AfterAllocaInsPt != F.front().end());
 
   for (auto &AI : F.args()) {
+    // Swift error really is a register that we model as memory -- instruction
+    // selection will perform mem-to-reg for us and spill/reload appropriately
+    // around calls that clobber it. There is no need to spill this
+    // value to the stack and doing so would not be allowed.
+    if (AI.isSwiftError())
+      continue;
+
     Type *Ty = AI.getType();
 
     // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
@@ -462,25 +468,6 @@ bool SjLjEHPrepare::setupEntryBlockAndCa
   return true;
 }
 
-bool SjLjEHPrepare::undoSwiftErrorSelect(Function &F) {
-  // We have inserted dummy copies 'select true, arg, undef' in the entry block
-  // for arguments to simplify this pass.
-  // swifterror arguments cannot be used in this way. Undo the select for the
-  // swifterror argument.
-  for (auto &AI : F.args()) {
-    if (AI.isSwiftError()) {
-      assert(AI.hasOneUse() && "Must have converted the argument to a select");
-      auto *Select = dyn_cast<SelectInst>(AI.use_begin()->getUser());
-      assert(Select && "There must be single select user");
-      auto *OrigSwiftError = cast<Argument>(Select->getTrueValue());
-      Select->replaceAllUsesWith(OrigSwiftError);
-      Select->eraseFromParent();
-      return true;
-    }
-  }
-  return false;
-}
-
 bool SjLjEHPrepare::runOnFunction(Function &F) {
   Module &M = *F.getParent();
   RegisterFn = M.getOrInsertFunction(
@@ -499,7 +486,5 @@ bool SjLjEHPrepare::runOnFunction(Functi
   FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext);
 
   bool Res = setupEntryBlockAndCallSites(F);
-  if (Res)
-    Res |= undoSwiftErrorSelect(F);
   return Res;
 }

Modified: llvm/trunk/test/CodeGen/ARM/sjljeh-swifterror.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/sjljeh-swifterror.ll?rev=327521&r1=327520&r2=327521&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/sjljeh-swifterror.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/sjljeh-swifterror.ll Wed Mar 14 08:44:07 2018
@@ -1,4 +1,4 @@
-; RUN: opt -sjljehprepare -verify < %s | FileCheck %s
+; RUN: opt -sjljehprepare -verify < %s -S | FileCheck %s
 target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
 target triple = "armv7s-apple-ios7.0"
 
@@ -9,7 +9,7 @@ declare void @objc_msgSend() local_unnam
 declare i32 @__objc_personality_v0(...)
 
 ; Make sure we don't leave a select on a swifterror argument.
-; CHECK-LABEL; @test
+; CHECK-LABEL: @test
 ; CHECK-NOT: select true, %0
 define swiftcc void @test(%swift.error** swifterror) local_unnamed_addr personality i32 (...)* @__objc_personality_v0 {
 entry:
@@ -25,3 +25,32 @@ lpad.i:
   resume { i8*, i32 } undef
 }
 
+%struct._objc_typeinfo = type { i8**, i8*, i64* }
+@"OBJC_EHTYPE_$_NSException" = external global %struct._objc_typeinfo
+
+; Make sure this does not crash.
+; CHECK-LABEL: @swift_error_bug
+; CHECK: store %swift.error* null, %swift.error** %0
+
+define hidden swiftcc void @swift_error_bug(%swift.error** swifterror, void (i8*)** %fun, i1 %b) local_unnamed_addr #0 personality i32 (...)* @__objc_personality_v0 {
+  %2 = load void (i8*)*, void (i8*)** %fun, align 4
+  invoke void %2(i8* null) #1
+          to label %tryBlock.exit unwind label %3, !clang.arc.no_objc_arc_exceptions !1
+
+; <label>:3:
+  %4 = landingpad { i8*, i32 }
+          catch %struct._objc_typeinfo* @"OBJC_EHTYPE_$_NSException"
+  br label %tryBlock.exit
+
+tryBlock.exit:
+  br i1 %b, label %5, label %_T0ypMa.exit.i.i
+
+_T0ypMa.exit.i.i:
+  store %swift.error* null, %swift.error** %0, align 4
+  ret void
+
+; <label>:5:
+  ret void
+}
+
+!1 = !{}




More information about the llvm-commits mailing list