brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · c015a4e Raw
79 lines · plain
1; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s2 3; WinEH requires funclet tokens on nounwind intrinsics if they can lower to4; regular function calls in the course of IR transformations.5;6; Test that the code generator will emit the function call and not consider it7; an "implausible instruciton". In the past this silently truncated code on8; exception paths and caused crashes at runtime.9;10; Reduced IR generated from ObjC++ source:11;12;     @class Ety;13;     void opaque(void);14;     void test_catch_with_objc_intrinsic(void) {15;       @try {16;         opaque();17;       } @catch (Ety *ex) {18;         // Destroy ex when leaving catchpad. This would emit calls to two19;         // intrinsic functions: llvm.objc.retain and llvm.objc.storeStrong20;       }21;     }22;23; llvm.objc.retain and llvm.objc.storeStrong both lower into regular function24; calls before ISel. We only need one of them to trigger funclet truncation25; during codegen:26 27define void @test_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {28entry:29  %exn.slot = alloca ptr, align 830  %ex2 = alloca ptr, align 831  invoke void @opaque() to label %invoke.cont unwind label %catch.dispatch32 33catch.dispatch:                                   ; preds = %entry34  %0 = catchswitch within none [label %catch] unwind to caller35 36invoke.cont:                                      ; preds = %entry37  unreachable38 39catch:                                            ; preds = %catch.dispatch40  %1 = catchpad within %0 [ptr null, i32 64, ptr %exn.slot]41  %exn = load ptr, ptr %exn.slot, align 842  %2 = call ptr @llvm.objc.retain(ptr %exn) [ "funclet"(token %1) ]43  store ptr %2, ptr %ex2, align 844  catchret from %1 to label %catchret.dest45 46catchret.dest:                                    ; preds = %catch47  ret void48}49 50declare void @opaque()51declare ptr @llvm.objc.retain(ptr) #052declare i32 @__CxxFrameHandler3(...)53 54attributes #0 = { nounwind }55 56; EH catchpad with SEH prologue:57;     CHECK-LABEL:  # %catch58;     CHECK:          pushq   %rbp59;     CHECK:          .seh_pushreg %rbp60;                     ...61;     CHECK:          .seh_endprologue62;63; At this point the code used to be truncated (and sometimes terminated with an64; int3 opcode):65;     CHECK-NOT:      int366;67; Instead, the runtime call to retain should be emitted:68;     CHECK:          movq    -8(%rbp), %rcx69;     CHECK:          callq   objc_retain70;                     ...71;72; This is the end of the funclet:73;     CHECK:          popq	%rbp74;     CHECK:          retq                                    # CATCHRET75;                     ...76;     CHECK:          .seh_handlerdata77;                     ...78;     CHECK:          .seh_endproc79