AArch64: support funclets in fastcall and swift_call
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 5 Dec 2018 07:09:20 +0000 (07:09 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 5 Dec 2018 07:09:20 +0000 (07:09 +0000)
Functions annotated with `__fastcall` or `__attribute__((__fastcall__))`
or `__attribute__((__swiftcall__))` may contain SEH handlers even on
Win64.  This matches the behaviour of cl which allows for
`__try`/`__except` inside a `__fastcall` function.  This was detected
while trying to self-host clang on Windows ARM64.

llvm-svn: 348337

llvm/lib/Target/AArch64/AArch64Subtarget.h
llvm/test/CodeGen/AArch64/windows-SEH-support.ll [new file with mode: 0644]

index 641c1c7..db3432b 100644 (file)
@@ -385,6 +385,8 @@ public:
   bool isCallingConvWin64(CallingConv::ID CC) const {
     switch (CC) {
     case CallingConv::C:
+    case CallingConv::Fast:
+    case CallingConv::Swift:
       return isTargetWindows();
     case CallingConv::Win64:
       return true;
diff --git a/llvm/test/CodeGen/AArch64/windows-SEH-support.ll b/llvm/test/CodeGen/AArch64/windows-SEH-support.ll
new file mode 100644 (file)
index 0000000..499ae78
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype asm -o /dev/null %s
+
+declare dllimport void @f() local_unnamed_addr
+
+declare dso_local i32 @__C_specific_handler(...)
+
+define hidden swiftcc void @g() unnamed_addr personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
+entry:
+  invoke void @f() to label %__try.cont unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %__except] unwind to caller
+
+__except:
+  %1 = catchpad within %0 [i8* null]              ; preds = %catch.dispatch
+  catchret from %1 to label %__try.cont
+
+__try.cont:                                       ; preds = %__except, %entry
+  ret void
+}
+
+define hidden fastcc void @h() unnamed_addr personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
+entry:
+  invoke void @f() to label %__try.cont unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %__except] unwind to caller
+
+__except:                                         ; preds = %catch.dispatch
+  %1 = catchpad within %0 [i8* null]
+  catchret from %1 to label %__try.cont
+
+__try.cont:                                       ; preds = %__except, %entry
+  ret void
+}
+