Index: lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp @@ -106,13 +106,15 @@ PrivateLabelPrefix = ".L"; AlignmentIsInBytes = false; SupportsDebugInformation = true; - ExceptionsType = ExceptionHandling::WinEH; + CodePointerSize = 8; } AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() { CommentString = ";"; + ExceptionsType = ExceptionHandling::WinEH; } AArch64MCAsmInfoGNUCOFF::AArch64MCAsmInfoGNUCOFF() { CommentString = "//"; + ExceptionsType = ExceptionHandling::DwarfCFI; } Index: lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp @@ -23,7 +23,15 @@ std::unique_ptr CE, raw_pwrite_stream &OS) : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), OS) {} + + void FinishImpl() override; }; + +void AArch64WinCOFFStreamer::FinishImpl() { + EmitFrames(nullptr); + + MCWinCOFFStreamer::FinishImpl(); +} } // end anonymous namespace namespace llvm { Index: test/CodeGen/AArch64/dwarf-cfi.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/dwarf-cfi.ll @@ -0,0 +1,167 @@ +; RUN: llc -mtriple aarch64-windows-gnu \ +; RUN: -filetype=asm -o - %s \ +; RUN: | FileCheck %s + +;------------------------------------------------------------------------------- +; Test 1 +;------------------------------------------------------------------------------- +; This is the LLVM assembly generated from following C++ code: +; +; extern void print(int, int, int, int, int); +; extern void print(double, double, double, double, double); +; +; void test(int a, int b, int c, int d, int e, +; double m, double n, double p, double q, double r) { +; try { +; print(a, b, c, d, e); +; } catch (...) { +; print(m, n, p, q, r); +; } +; } + +declare void @_Z5printiiiii(i32, i32, i32, i32, i32) + +declare void @_Z5printddddd(double, double, double, double, double) + +define void @_Z4testiiiiiddddd(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, + double %m, double %n, double %p, + double %q, double %r) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +entry: + invoke void @_Z5printiiiii(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) + to label %try.cont unwind label %lpad + +lpad: + %0 = landingpad { i8*, i32 } + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) + invoke void @_Z5printddddd(double %m, double %n, double %p, + double %q, double %r) + to label %invoke.cont2 unwind label %lpad1 + +invoke.cont2: + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: + ret void + +lpad1: + %3 = landingpad { i8*, i32 } + cleanup + invoke void @__cxa_end_catch() + to label %eh.resume unwind label %terminate.lpad + +eh.resume: + resume { i8*, i32 } %3 + +terminate.lpad: + %4 = landingpad { i8*, i32 } + catch i8* null + %5 = extractvalue { i8*, i32 } %4, 0 + tail call void @__clang_call_terminate(i8* %5) + unreachable +} + +declare void @__clang_call_terminate(i8*) + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +declare void @_ZSt9terminatev() + +; CHECK-LABEL: _Z4testiiiiiddddd: +; CHECK: .cfi_startproc +; CHECK: .cfi_personality 0, __gxx_personality_v0 +; CHECK: .cfi_lsda 0, .Lexception0 +; CHECK: str d12, [sp, #-64]! +; CHECK: stp d11, d10, [sp, #16] +; CHECK: stp d9, d8, [sp, #32] +; CHECK: stp x19, x30, [sp, #48] +; CHECK: .cfi_def_cfa_offset 64 +; CHECK: .cfi_offset w30, -8 +; CHECK: .cfi_offset w19, -16 +; CHECK: .cfi_offset b8, -24 +; CHECK: .cfi_offset b9, -32 +; CHECK: .cfi_offset b10, -40 +; CHECK: .cfi_offset b11, -48 +; CHECK: .cfi_offset b12, -64 +; CHECK: ldp x19, x30, [sp, #48] +; CHECK: ldp d9, d8, [sp, #32] +; CHECK: ldp d11, d10, [sp, #16] +; CHECK: ldr d12, [sp], #64 +; CHECK: .cfi_endproc + +;------------------------------------------------------------------------------- +; Test 2 +;------------------------------------------------------------------------------- + +declare void @throw_exception_2() + +define void @test2() { +entry: + call void @throw_exception_2() + ret void +} + +; CHECK-LABEL: test2: +; CHECK: .cfi_startproc +; CHECK: str x30, [sp, #-16]! +; CHECK: .cfi_def_cfa_offset 16 +; CHECK: .cfi_offset w30, -16 +; CHECK: ldr x30, [sp], #16 +; CHECK: .cfi_endproc + + +;------------------------------------------------------------------------------- +; Test 3 +;------------------------------------------------------------------------------- + +declare void @throw_exception_3(i32) + +define i32 @test3(i32 %a, i32 %b, i32 %c, i32 %d, + i32 %e, i32 %f, i32 %g, i32 %h) { +entry: + %add = add nsw i32 %b, %a + %add1 = add nsw i32 %add, %c + %add2 = add nsw i32 %add1, %d + tail call void @throw_exception_3(i32 %add2) + %add3 = add nsw i32 %f, %e + %add4 = add nsw i32 %add3, %g + %add5 = add nsw i32 %add4, %h + tail call void @throw_exception_3(i32 %add5) + %add6 = add nsw i32 %add5, %add2 + ret i32 %add6 +} + +; CHECK-LABEL: test3: +; CHECK: .cfi_startproc +; CHECK: stp x23, x22, [sp, #-48]! +; CHECK: stp x21, x20, [sp, #16] +; CHECK: stp x19, x30, [sp, #32] +; CHECK: .cfi_def_cfa_offset 48 +; CHECK: .cfi_offset w30, -8 +; CHECK: .cfi_offset w19, -16 +; CHECK: .cfi_offset w20, -24 +; CHECK: .cfi_offset w21, -32 +; CHECK: .cfi_offset w22, -40 +; CHECK: .cfi_offset w23, -48 +; CHECK: .cfi_endproc + + +;------------------------------------------------------------------------------- +; Test 4 +;------------------------------------------------------------------------------- + +define void @test4() nounwind { +entry: + ret void +} + +; CHECK-LABEL: test4: +; CHECK-NOT: .cfi_startproc +; CHECK: ret +; CHECK-NOT: .cfi_endproc