diff options
Diffstat (limited to 'llvm/test/CodeGen/X86')
37 files changed, 873 insertions, 539 deletions
diff --git a/llvm/test/CodeGen/X86/branchfolding-catchpads.ll b/llvm/test/CodeGen/X86/branchfolding-catchpads.ll index 21c7818e519..0468b3c314f 100644 --- a/llvm/test/CodeGen/X86/branchfolding-catchpads.ll +++ b/llvm/test/CodeGen/X86/branchfolding-catchpads.ll @@ -19,24 +19,18 @@ if.else:            to label %cleanup unwind label %catch.dispatch  catch.dispatch: -  catchpad [i8* null, i32 8, i8* null] -          to label %catch unwind label %catch.dispatch.2 +  %cs = catchswitch within none [ label %catch, label %catch.2 ] unwind to caller  catch: -  invoke void @throw() noreturn -          to label %unreachable unwind label %catchendblock - -catch.dispatch.2: -  catchpad [i8* null, i32 64, i8* null] -          to label %catch.2 unwind label %catchendblock +  catchpad within %cs [i8* null, i32 8, i8* null] +  call void @throw() noreturn +  br label %unreachable  catch.2: +  catchpad within %cs [i8* null, i32 64, i8* null]    store i8 1, i8* %b -  invoke void @throw() noreturn -          to label %unreachable unwind label %catchendblock - -catchendblock: -  catchendpad unwind to caller +  call void @throw() noreturn +  br label %unreachable  cleanup:    %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ] @@ -67,31 +61,22 @@ if.else:            to label %cleanup unwind label %catch.dispatch  catch.dispatch: -  catchpad [i8* null, i32 8, i8* null] -          to label %catch unwind label %catch.dispatch.2 +  %cs = catchswitch within none [ label %catch, label %catch.2, label %catch.3 ] unwind to caller  catch: -  invoke void @throw() noreturn -          to label %unreachable unwind label %catchendblock - -catch.dispatch.2: -  %c2 = catchpad [i8* null, i32 32, i8* null] -          to label %catch.2 unwind label %catch.dispatch.3 +  catchpad within %cs [i8* null, i32 8, i8* null] +  call void @throw() noreturn +  br label %unreachable  catch.2: +  %c2 = catchpad within %cs [i8* null, i32 32, i8* null]    store i8 1, i8* %b -  catchret %c2 to label %cleanup - -catch.dispatch.3: -  %c3 = catchpad [i8* null, i32 64, i8* null] -          to label %catch.3 unwind label %catchendblock +  catchret from %c2 to label %cleanup  catch.3: +  %c3 = catchpad within %cs [i8* null, i32 64, i8* null]    store i8 2, i8* %b -  catchret %c3 to label %cleanup - -catchendblock: -  catchendpad unwind to caller +  catchret from %c3 to label %cleanup  cleanup:    %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ], [ -1, %catch.2 ], [ -1, %catch.3 ] diff --git a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll index 267c69332c3..1160101792f 100644 --- a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll +++ b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll @@ -14,19 +14,17 @@ define void @f() personality i32 (...)* @__CxxFrameHandler3 {    %v1 = fadd double %v, 1.0    store double %v1, double* @fp_global    invoke void @g() -      to label %return unwind label %catch +      to label %return unwind label %catch.dispatch  return:    ret void -catch: -  %p = catchpad [i8* null, i32 64, i8* null] -      to label %catchit unwind label %endpad +catch.dispatch: +  %cs1 = catchswitch within none [label %catch] unwind to caller -catchit: -  catchret %p to label %return -endpad: -  catchendpad unwind to caller +catch: +  %p = catchpad within %cs1 [i8* null, i32 64, i8* null] +  catchret from %p to label %return  }  ; CHECK: f: # @f diff --git a/llvm/test/CodeGen/X86/catchpad-regmask.ll b/llvm/test/CodeGen/X86/catchpad-regmask.ll index fe3a238e173..0d436f6eb59 100644 --- a/llvm/test/CodeGen/X86/catchpad-regmask.ll +++ b/llvm/test/CodeGen/X86/catchpad-regmask.ll @@ -41,14 +41,14 @@ entry:            to label %unreachable unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]    %idxprom1 = sext i32 %idx2 to i64    %arrayidx2 = getelementptr inbounds [4 x i32], [4 x i32]* @array, i64 0, i64 %idxprom1    store i32 222, i32* %arrayidx2, align 4, !tbaa !2 -  catchret %0 to label %try.cont +  catchret from %0 to label %try.cont  try.cont:                                         ; preds = %catch    %idxprom3 = sext i32 %idx3 to i64 @@ -56,9 +56,6 @@ try.cont:                                         ; preds = %catch    store i32 333, i32* %arrayidx4, align 4, !tbaa !2    ret void -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller -  unreachable:                                      ; preds = %entry    unreachable  } @@ -98,20 +95,17 @@ entry:            to label %unreachable unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]    store i32 222, i32* @imported, align 4, !tbaa !2 -  catchret %0 to label %try.cont +  catchret from %0 to label %try.cont  try.cont:                                         ; preds = %catch    store i32 333, i32* @imported, align 4, !tbaa !2    ret void -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller -  unreachable:                                      ; preds = %entry    unreachable  } diff --git a/llvm/test/CodeGen/X86/catchpad-weight.ll b/llvm/test/CodeGen/X86/catchpad-weight.ll index e8b416845ec..1abcd03ac64 100644 --- a/llvm/test/CodeGen/X86/catchpad-weight.ll +++ b/llvm/test/CodeGen/X86/catchpad-weight.ll @@ -2,7 +2,7 @@  ; Check if the edge weight to the catchpad is calculated correctly. -; CHECK: Successors according to CFG: BB#3(0x7ffff100 / 0x80000000 = 100.00%) BB#1(0x00000800 / 0x80000000 = 0.00%) BB#4(0x00000400 / 0x80000000 = 0.00%) BB#6(0x00000200 / 0x80000000 = 0.00%) BB#8(0x00000100 / 0x80000000 = 0.00%) +; CHECK: Successors according to CFG: BB#2(0x7ffff100 / 0x80000000 = 100.00%) BB#1(0x00000800 / 0x80000000 = 0.00%) BB#3(0x00000400 / 0x80000000 = 0.00%) BB#4(0x00000200 / 0x80000000 = 0.00%) BB#5(0x00000100 / 0x80000000 = 0.00%)  target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"  target triple = "x86_64--windows-msvc18.0.0" @@ -31,11 +31,11 @@ entry:            to label %try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %1 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8", i32 0, i8* null] -          to label %catch.5 unwind label %catch.dispatch.1 +  %cs1 = catchswitch within none [label %catch.5] unwind label %catch.dispatch.1  catch.5:                                          ; preds = %catch.dispatch -  catchret %1 to label %try.cont +  %1 = catchpad within %cs1 [%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8", i32 0, i8* null] +  catchret from %1 to label %try.cont  try.cont:                                         ; preds = %entry, %catch, %catch.3, %catch.5    call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4 @@ -43,26 +43,23 @@ try.cont:                                         ; preds = %entry, %catch, %cat    ret i32 0  catch.dispatch.1:                                 ; preds = %catch.dispatch -  %2 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8", i32 0, i8* null] -          to label %catch.3 unwind label %catch.dispatch.2 +  %cs2 = catchswitch within none [label %catch.3] unwind label %catch.dispatch.2  catch.3:                                          ; preds = %catch.dispatch.1 -  catchret %2 to label %try.cont +  %2 = catchpad within %cs2 [%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8", i32 0, i8* null] +  catchret from %2 to label %try.cont  catch.dispatch.2:                                 ; preds = %catch.dispatch.1 -  %3 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8", i32 0, i8* null] -          to label %catch unwind label %catchendblock +  %cs3 = catchswitch within none [label %catch] unwind label %ehcleanup  catch:                                            ; preds = %catch.dispatch.2 -  catchret %3 to label %try.cont - -catchendblock:                                    ; preds = %catch.dispatch.2 -  catchendpad unwind label %ehcleanup +  %3 = catchpad within %cs3 [%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8", i32 0, i8* null] +  catchret from %3 to label %try.cont  ehcleanup:                                        ; preds = %catchendblock -  %4 = cleanuppad [] +  %4 = cleanuppad within none []    call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4 -  cleanupret %4 unwind to caller +  cleanupret from %4 unwind to caller  }  ; Function Attrs: nounwind argmemonly diff --git a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll index 3b3b3f5d091..585f7bc33e3 100644 --- a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll +++ b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll @@ -19,14 +19,11 @@ try:                                              ; preds = %entry            to label %fallthrough unwind label %dispatch  dispatch:                                         ; preds = %try -  %0 = catchpad [i8* null] -          to label %catch unwind label %catchendblock.i.i +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %dispatch -  catchret %0 to label %return - -catchendblock.i.i:                                ; preds = %dispatch -  catchendpad unwind to caller +  %0 = catchpad within %cs1 [i8* null] +  catchret from %0 to label %return  fallthrough:                                      ; preds = %try    unreachable diff --git a/llvm/test/CodeGen/X86/catchret-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-fallthrough.ll index f732566d0cb..6a94b290e82 100644 --- a/llvm/test/CodeGen/X86/catchret-fallthrough.ll +++ b/llvm/test/CodeGen/X86/catchret-fallthrough.ll @@ -18,14 +18,11 @@ entry:            to label %invoke.cont.3 unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch -  catchret %0 to label %nrvo.skipdtor - -catchendblock:                                    ; preds = %catch, %catch.dispatch -  catchendpad unwind to caller +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null] +  catchret from %0 to label %nrvo.skipdtor  invoke.cont.3:                                    ; preds = %entry    store i32 123, i32* @some_global diff --git a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll index 8858f3704a1..294ef3abc46 100644 --- a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll +++ b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll @@ -29,9 +29,9 @@ invoke.cont:                                      ; preds = %entry    ret void  ehcleanup:                                        ; preds = %entry -  %2 = cleanuppad [] +  %2 = cleanuppad within none []    call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %0) -  cleanupret %2 unwind to caller +  cleanupret from %2 unwind to caller  }  ; CHECK: _passes_two: diff --git a/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll b/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll index df866f9598a..e32cdbed73f 100644 --- a/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll +++ b/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll @@ -9,9 +9,9 @@ entry:    invoke void @bar()      to label %exit unwind label %cleanup  cleanup: -  %c = cleanuppad [] +  %c = cleanuppad within none []    call void @bar() -  cleanupret %c unwind to caller +  cleanupret from %c unwind to caller  exit:    ret void  } diff --git a/llvm/test/CodeGen/X86/cleanuppad-realign.ll b/llvm/test/CodeGen/X86/cleanuppad-realign.ll index a19cf261307..d322932da4c 100644 --- a/llvm/test/CodeGen/X86/cleanuppad-realign.ll +++ b/llvm/test/CodeGen/X86/cleanuppad-realign.ll @@ -17,9 +17,9 @@ invoke.cont:                                      ; preds = %entry    ret void  ehcleanup:                                        ; preds = %entry -  %0 = cleanuppad [] +  %0 = cleanuppad within none []    call void @Dtor(i64* %o) -  cleanupret %0 unwind to caller +  cleanupret from %0 unwind to caller  }  ; X86-LABEL: _realigned_cleanup: # @realigned_cleanup diff --git a/llvm/test/CodeGen/X86/funclet-layout.ll b/llvm/test/CodeGen/X86/funclet-layout.ll index 053d484889b..b5972df43cc 100644 --- a/llvm/test/CodeGen/X86/funclet-layout.ll +++ b/llvm/test/CodeGen/X86/funclet-layout.ll @@ -15,21 +15,21 @@ entry:            to label %unreachable unwind label %catch.dispatch  catch.dispatch: -  %cp = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch: -  br i1 %B, label %catchret, label %catch +  %cp = catchpad within %cs1 [i8* null, i32 64, i8* null] +  br label %catch.loop + +catch.loop: +  br i1 %B, label %catchret, label %catch.loop  catchret: -  catchret %cp to label %try.cont +  catchret from %cp to label %try.cont  try.cont:    ret void -catchendblock: -  catchendpad unwind to caller -  unreachable:    unreachable  } @@ -55,54 +55,50 @@ entry:            to label %unreachable unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]    invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1            to label %unreachable unwind label %catch.dispatch.1  catch.dispatch.1:                                 ; preds = %catch -  %1 = catchpad [i8* null, i32 64, i8* null] -          to label %catch.3 unwind label %catchendblock.2 +  %cs2 = catchswitch within %0 [label %catch.3] unwind to caller  catch.3:                                          ; preds = %catch.dispatch.1 -  catchret %1 to label %try.cont +  %1 = catchpad within %cs2 [i8* null, i32 64, i8* null] +  catchret from %1 to label %try.cont  try.cont:                                         ; preds = %catch.3 -  catchret %0 to label %try.cont.5 +  catchret from %0 to label %try.cont.5  try.cont.5:                                       ; preds = %try.cont    ret i32 0 -catchendblock.2:                                  ; preds = %catch.dispatch.1 -  catchendpad unwind label %catchendblock - -catchendblock:                                    ; preds = %catchendblock.2, %catch.dispatch -  catchendpad unwind to caller -  unreachable:                                      ; preds = %catch, %entry    unreachable -  }  ; CHECK-LABEL: test2: -; The entry funclet contains %entry and %try.cont.5 +; The parent function contains %entry and %try.cont.5 +; CHECK: .seh_proc  ; CHECK: # %entry  ; CHECK: # %try.cont.5  ; CHECK: retq -; The outer catch funclet contains %catch.dispatch -; CHECK: # %catch.dispatch{{$}} +; The inner catch funclet contains %catch.3 +; CHECK: .seh_proc +; CHECK: # %catch.3{{$}} +; CHECK: retq + +; The outer catch funclet contains %catch +; CHECK: .seh_proc +; CHECK: # %catch{{$}}  ; CHECK: callq _CxxThrowException  ; CHECK: # %unreachable  ; CHECK: ud2 -; The inner catch funclet contains %catch.dispatch.1 -; CHECK: # %catch.dispatch.1 -; CHECK: retq -  define void @test3(i1 %V) #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {  entry: @@ -110,24 +106,21 @@ entry:            to label %try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch.2 unwind label %catch.dispatch.1 +  %cs1 = catchswitch within none [label %catch.2] unwind label %catch.dispatch.1  catch.2:                                          ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]    tail call void @exit(i32 0) #2    unreachable  catch.dispatch.1:                                 ; preds = %catch.dispatch -  %1 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs2 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch.1 +  %1 = catchpad within %cs2 [i8* null, i32 64, i8* null]    tail call void @exit(i32 0) #2    unreachable -catchendblock:                                    ; preds = %catch.dispatch.1 -  catchendpad unwind to caller -  try.cont:                                         ; preds = %entry    br i1 %V, label %exit_one, label %exit_two @@ -150,13 +143,13 @@ exit_two:  ; CHECK-NOT: # exit_two  ; CHECK: ud2 -; The catch(...) funclet contains %catch.dispatch -; CHECK: # %catch.dispatch{{$}} +; The catch(...) funclet contains %catch.2 +; CHECK: # %catch.2{{$}}  ; CHECK: callq exit  ; CHECK: ud2 -; The catch(int) funclet contains %catch.dispatch.1 -; CHECK: # %catch.dispatch.1 +; The catch(int) funclet contains %catch +; CHECK: # %catch{{$}}  ; CHECK: callq exit  ; CHECK: ud2 diff --git a/llvm/test/CodeGen/X86/late-address-taken.ll b/llvm/test/CodeGen/X86/late-address-taken.ll index 8f85393b67c..f98c53595ab 100644 --- a/llvm/test/CodeGen/X86/late-address-taken.ll +++ b/llvm/test/CodeGen/X86/late-address-taken.ll @@ -22,19 +22,17 @@ body:    invoke void @f()            to label %exit unwind label %catch.pad  catch.pad: -  %catch = catchpad [i32 33554467] -          to label %catch.body unwind label %catch.end +  %cs1 = catchswitch within none [label %catch.body] unwind to caller  catch.body: -  catchret %catch to label %exit -catch.end: -  catchendpad unwind to caller +  %catch = catchpad within %cs1 [i32 33554467] +  catchret from %catch to label %exit  exit:    ret void  }  ; CHECK-LABEL: catchret:  # @catchret  ; CHECK: [[Exit:^[^ :]+]]: # Block address taken  ; CHECK-NEXT:              # %exit -; CHECK: # %catch.pad +; CHECK: # %catch.body  ; CHECK: .seh_endprolog  ; CHECK: leaq [[Exit]](%rip), %rax  ; CHECK: retq # CATCHRET diff --git a/llvm/test/CodeGen/X86/seh-catch-all-win32.ll b/llvm/test/CodeGen/X86/seh-catch-all-win32.ll index 5d9d5038385..69afb1b9d9c 100644 --- a/llvm/test/CodeGen/X86/seh-catch-all-win32.ll +++ b/llvm/test/CodeGen/X86/seh-catch-all-win32.ll @@ -22,16 +22,13 @@ entry:            to label %__try.cont unwind label %lpad  lpad:                                             ; preds = %entry -  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)] -          to label %__except unwind label %endpad +  %cs1 = catchswitch within none [label %__except] unwind to caller  __except:                                         ; preds = %lpad +  %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)]    %code = load i32, i32* %__exceptioncode, align 4    %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 -  catchret %p to label %__try.cont - -endpad:                                        ; preds = %lpad -  catchendpad unwind to caller +  catchret from %p to label %__try.cont  __try.cont:                                       ; preds = %entry, %__except    ret i32 0 @@ -73,7 +70,7 @@ entry:  ; CHECK: popl %edi  ; CHECK: popl %ebx  ; CHECK: retl -; CHECK: LBB0_[[lpbb:[0-9]+]]: # %lpad{{$}} +; CHECK: LBB0_[[lpbb:[0-9]+]]: # %__except{{$}}  ;       stackrestore  ; CHECK: movl -24(%ebp), %esp  ;       EH state -1 diff --git a/llvm/test/CodeGen/X86/seh-catch-all.ll b/llvm/test/CodeGen/X86/seh-catch-all.ll index aa1b6e040ff..4463485f209 100644 --- a/llvm/test/CodeGen/X86/seh-catch-all.ll +++ b/llvm/test/CodeGen/X86/seh-catch-all.ll @@ -16,16 +16,13 @@ __try.cont:    ret i32 0  lpad: -  %p = catchpad [i8* null, i32 64, i8* null] -          to label %catchall unwind label %endpad +  %cs1 = catchswitch within none [label %catchall] unwind to caller  catchall: +  %p = catchpad within %cs1 [i8* null, i32 64, i8* null]    %code = call i32 @llvm.eh.exceptioncode(token %p)    call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %code) -  catchret %p to label %__try.cont - -endpad: -  catchendpad unwind to caller +  catchret from %p to label %__try.cont  }  ; Check that we can get the exception code from eax to the printf. @@ -33,7 +30,7 @@ endpad:  ; CHECK-LABEL: main:  ; CHECK: callq crash  ; CHECK: retq -; CHECK: .LBB0_2: # %lpad +; CHECK: .LBB0_2: # %catchall  ; CHECK: leaq str(%rip), %rcx  ; CHECK: movl %eax, %edx  ; CHECK: callq printf diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll index 895dba883ae..a8be4ec1450 100644 --- a/llvm/test/CodeGen/X86/seh-catchpad.ll +++ b/llvm/test/CodeGen/X86/seh-catchpad.ll @@ -45,13 +45,6 @@ entry:    %call = invoke i32 @do_div(i32 1, i32 0) #4            to label %__try.cont.12 unwind label %catch.dispatch -catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null] -          to label %__except unwind label %catchendblock - -__except:                                         ; preds = %catch.dispatch -  catchret %0 to label %__except.2 -  __except.2:                                       ; preds = %__except    %call4 = invoke i32 @do_div(i32 1, i32 0) #4            to label %invoke.cont.3 unwind label %ehcleanup @@ -60,24 +53,6 @@ invoke.cont.3:                                    ; preds = %__except.2    invoke fastcc void @"\01?fin$0@0@main@@"() #4            to label %__try.cont.12 unwind label %catch.dispatch.7 -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind label %catch.dispatch.7 - -ehcleanup:                                        ; preds = %__except.2 -  %1 = cleanuppad [] -  invoke fastcc void @"\01?fin$0@0@main@@"() #4 -          to label %invoke.cont.6 unwind label %ehcleanup.end - -invoke.cont.6:                                    ; preds = %ehcleanup -  cleanupret %1 unwind label %catch.dispatch.7 - -catch.dispatch.7:                                 ; preds = %invoke.cont.3, %invoke.cont.6, %ehcleanup.end, %catchendblock -  %2 = catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@main@@" to i8*)] -          to label %__except.ret unwind label %catchendblock.8 - -__except.ret:                                     ; preds = %catch.dispatch.7 -  catchret %2 to label %__except.9 -  __except.9:                                       ; preds = %__except.ret    %call11 = tail call i32 @puts(i8* nonnull getelementptr inbounds ([7 x i8], [7 x i8]* @"\01??_C@_06IBDBCMGJ@caught?$AA@", i64 0, i64 0))    br label %__try.cont.12 @@ -85,11 +60,27 @@ __except.9:                                       ; preds = %__except.ret  __try.cont.12:                                    ; preds = %invoke.cont.3, %entry, %__except.9    ret i32 0 -catchendblock.8:                                  ; preds = %catch.dispatch.7 -  catchendpad unwind to caller +catch.dispatch:                                   ; preds = %entry +  %cs1 = catchswitch within none [label %__except] unwind label %catch.dispatch.7 + +__except:                                         ; preds = %catch.dispatch +  %cp1 = catchpad within %cs1 [i8* null] +  catchret from %cp1 to label %__except.2 -ehcleanup.end:                                    ; preds = %ehcleanup -  cleanupendpad %1 unwind label %catch.dispatch.7 +ehcleanup:                                        ; preds = %__except.2 +  %cp2 = cleanuppad within none [] +  invoke fastcc void @"\01?fin$0@0@main@@"() #4 +          to label %invoke.cont.6 unwind label %catch.dispatch.7 + +invoke.cont.6:                                    ; preds = %ehcleanup +  cleanupret from %cp2 unwind label %catch.dispatch.7 + +catch.dispatch.7: +  %cs2 = catchswitch within none [label %__except.ret] unwind to caller + +__except.ret:                                     ; preds = %catch.dispatch.7 +  %cp3 = catchpad within %cs2 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@main@@" to i8*)] +  catchret from %cp3 to label %__except.9  }  ; CHECK: main:                                   # @main @@ -112,7 +103,7 @@ ehcleanup.end:                                    ; preds = %ehcleanup  ; CHECK:         addq    $32, %rsp  ; CHECK:         popq    %rbp  ; CHECK:         retq -; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %catch.dispatch +; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %__except  ; CHECK: .Ltmp2:  ; CHECK:         movl    $1, %ecx  ; CHECK:         xorl    %edx, %edx @@ -120,7 +111,7 @@ ehcleanup.end:                                    ; preds = %ehcleanup  ; CHECK: .Ltmp3:  ; CHECK:         callq   "?fin$0@0@main@@"  ; CHECK:         jmp     .LBB1_[[epilogue]] -; CHECK: .LBB1_[[except2bb:[0-9]+]]:                                # %catch.dispatch.7 +; CHECK: .LBB1_[[except2bb:[0-9]+]]:                                # %__except.ret  ; CHECK:         leaq    "??_C@_06IBDBCMGJ@caught?$AA@"(%rip), %rcx  ; CHECK:         callq   puts  ; CHECK:         jmp     .LBB1_[[epilogue]] @@ -143,18 +134,18 @@ ehcleanup.end:                                    ; preds = %ehcleanup  ; CHECK-NEXT:         .long   .Ltmp2@IMGREL+1  ; CHECK-NEXT:         .long   .Ltmp3@IMGREL+1  ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL -; CHECK-NEXT:         .long   .LBB1_5@IMGREL +; CHECK-NEXT:         .long   .LBB1_3@IMGREL  ; CHECK-NEXT:         .long   .Ltmp6@IMGREL+1  ; CHECK-NEXT:         .long   .Ltmp7@IMGREL+1  ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL -; CHECK-NEXT:         .long   .LBB1_5@IMGREL +; CHECK-NEXT:         .long   .LBB1_3@IMGREL  ; CHECK-NEXT: .Llsda_end0:  ; CHECK:         .text  ; CHECK:         .seh_endproc -; CHECK: "?dtor$3@?0?main@4HA": -; CHECK: .seh_proc "?dtor$3@?0?main@4HA" +; CHECK: "?dtor$[[finbb]]@?0?main@4HA": +; CHECK: .seh_proc "?dtor$[[finbb]]@?0?main@4HA"  ; CHECK:         .seh_handler __C_specific_handler, @unwind, @except  ; CHECK: .LBB1_[[finbb]]:                                # %ehcleanup  ; CHECK:         movq    %rdx, 16(%rsp) diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll index 7acb802aa68..b252b5b1248 100644 --- a/llvm/test/CodeGen/X86/seh-except-finally.ll +++ b/llvm/test/CodeGen/X86/seh-except-finally.ll @@ -49,37 +49,24 @@ invoke.cont2:                                     ; preds = %invoke.cont    br label %__try.cont  __finally:                                             ; preds = %entry -  %cleanuppad = cleanuppad [] +  %cleanuppad = cleanuppad within none []    %locals = call i8* @llvm.localaddress()    invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %locals) #5 -          to label %invoke.cont3 unwind label %cleanupendpad +          to label %invoke.cont3 unwind label %catch.dispatch  invoke.cont3:                                     ; preds = %__finally -  cleanupret %cleanuppad unwind label %catch.dispatch - -cleanupendpad: -  cleanupendpad %cleanuppad unwind label %catch.dispatch +  cleanupret from %cleanuppad unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %invoke.cont3, %lpad1 -  %catchpad = catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)] -          to label %__except unwind label %catchendpad +  %cs1 = catchswitch within none [label %__except] unwind to caller  __except:                                         ; preds = %catch.dispatch +  %catchpad = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)]    %call = call i32 @puts(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08MLCMLGHM@__except?$AA@", i32 0, i32 0)) -  catchret %catchpad to label %__try.cont - -catchendpad: -  catchendpad unwind to caller +  catchret from %catchpad to label %__try.cont  __try.cont:                                       ; preds = %__except, %invoke.cont2    ret void - -eh.resume:                                        ; preds = %catch.dispatch -  %exn = load i8*, i8** %exn.slot -  %sel4 = load i32, i32* %ehselector.slot -  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0 -  %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %sel4, 1 -  resume { i8*, i32 } %lpad.val5  }  ; CHECK-LABEL: use_both: diff --git a/llvm/test/CodeGen/X86/seh-exception-code.ll b/llvm/test/CodeGen/X86/seh-exception-code.ll index e481a8e308c..20e1544e0b5 100644 --- a/llvm/test/CodeGen/X86/seh-exception-code.ll +++ b/llvm/test/CodeGen/X86/seh-exception-code.ll @@ -14,11 +14,11 @@ entry:            to label %__try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %pad = catchpad [i8* null] -          to label %__except unwind label %catchendblock +  %cs = catchswitch within none [label %__except] unwind to caller  __except:                                         ; preds = %catch.dispatch -  catchret %pad to label %__except.1 +  %pad = catchpad within %cs [i8* null] +  catchret from %pad to label %__except.1  __except.1:                                       ; preds = %__except    %code = call i32 @llvm.eh.exceptioncode(token %pad) @@ -27,15 +27,12 @@ __except.1:                                       ; preds = %__except  __try.cont:                                       ; preds = %entry, %__except.1    ret void - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller  }  ; CHECK-LABEL: ehcode:  ; CHECK: xorl %ecx, %ecx  ; CHECK: callq f -; CHECK: # %catch.dispatch +; CHECK: # %__except  ; CHECK: movl %eax, %ecx  ; CHECK-NEXT: callq f diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll index 57c2c8c20f7..67bce81a66a 100644 --- a/llvm/test/CodeGen/X86/seh-finally.ll +++ b/llvm/test/CodeGen/X86/seh-finally.ll @@ -17,15 +17,9 @@ invoke.cont:                                      ; preds = %entry    ret i32 0  lpad:                                             ; preds = %entry -  %p = cleanuppad [] -  %call2 = invoke i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0)) -          to label %invoke.cont1 unwind label %endpad - -invoke.cont1:                                     ; preds = %lpad -  cleanupret %p unwind to caller - -endpad:                                   ; preds = %lpad -  cleanupendpad %p unwind to caller +  %p = cleanuppad within none [] +  %call2 = call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0)) +  cleanupret from %p unwind to caller  }  ; X64-LABEL: main: diff --git a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll index 7f83b0c6466..3f88696fe60 100644 --- a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll +++ b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll @@ -31,28 +31,22 @@ entry:            to label %__try.cont unwind label %lpad0  lpad0: -  %p0 = catchpad [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)] -          to label %handler0 unwind label %endpad0 +  %cs0 = catchswitch within none [label %handler0] unwind label %lpad1  handler0: +  %p0 = catchpad within %cs0 [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)]    call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))    store i32 -1, i32* %r, align 4 -  catchret %p0 to label %__try.cont - -endpad0: -  catchendpad unwind label %lpad1 +  catchret from %p0 to label %__try.cont  lpad1: -  %p1 = catchpad [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)] -          to label %handler1 unwind label %endpad1 +  %cs1 = catchswitch within none [label %handler1] unwind to caller  handler1: +  %p1 = catchpad within %cs1 [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)]    call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))    store i32 -2, i32* %r, align 4 -  catchret %p1 to label %__try.cont - -endpad1: -  catchendpad unwind to caller +  catchret from %p1 to label %__try.cont  __try.cont:    %safe_ret = load i32, i32* %r, align 4 @@ -71,13 +65,13 @@ __try.cont:  ; Landing pad code -; CHECK: [[lpad0:LBB0_[0-9]+]]: # %lpad0 +; CHECK: [[handler0:LBB0_[0-9]+]]: # %handler0  ; 	Restore SP  ; CHECK: movl {{.*}}(%ebp), %esp  ; CHECK: calll _puts  ; CHECK: jmp [[cont_bb]] -; CHECK: [[lpad1:LBB0_[0-9]+]]: # %lpad1 +; CHECK: [[handler1:LBB0_[0-9]+]]: # %handler1  ; 	Restore SP  ; CHECK: movl {{.*}}(%ebp), %esp  ; CHECK: calll _puts @@ -87,10 +81,10 @@ __try.cont:  ; CHECK: L__ehtable$safe_div:  ; CHECK-NEXT: .long -1  ; CHECK-NEXT: .long _safe_div_filt1 -; CHECK-NEXT: .long [[lpad1]] +; CHECK-NEXT: .long [[handler1]]  ; CHECK-NEXT: .long 0  ; CHECK-NEXT: .long _safe_div_filt0 -; CHECK-NEXT: .long [[lpad0]] +; CHECK-NEXT: .long [[handler0]]  define void @try_body(i32* %r, i32* %n, i32* %d) {  entry: diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll index 1c7318b5614..3eeeab09ffb 100644 --- a/llvm/test/CodeGen/X86/seh-safe-div.ll +++ b/llvm/test/CodeGen/X86/seh-safe-div.ll @@ -30,28 +30,22 @@ entry:            to label %__try.cont unwind label %lpad0  lpad0: -  %p0 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)] -          to label %handler0 unwind label %endpad0 +  %cs0 = catchswitch within none [label %handler0] unwind label %lpad1  handler0: +  %p0 = catchpad within %cs0 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)]    call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))    store i32 -1, i32* %r, align 4 -  catchret %p0 to label %__try.cont - -endpad0: -  catchendpad unwind label %lpad1 +  catchret from %p0 to label %__try.cont  lpad1: -  %p1 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)] -          to label %handler1 unwind label %endpad1 +  %cs1 = catchswitch within none [label %handler1] unwind to caller  handler1: +  %p1 = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)]    call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))    store i32 -2, i32* %r, align 4 -  catchret %p1 to label %__try.cont - -endpad1: -  catchendpad unwind to caller +  catchret from %p1 to label %__try.cont  __try.cont:    %safe_ret = load i32, i32* %r, align 4 @@ -73,12 +67,12 @@ __try.cont:  ; Landing pad code -; CHECK: [[lpad0:\.LBB0_[0-9]+]]: # %lpad0 +; CHECK: [[handler0:\.LBB0_[0-9]+]]: # %handler0  ; CHECK: callq puts  ; CHECK: movl $-1, [[rloc]]  ; CHECK: jmp [[cont_bb]] -; CHECK: [[lpad1:\.LBB0_[0-9]+]]: # %lpad1 +; CHECK: [[handler1:\.LBB0_[0-9]+]]: # %handler1  ; CHECK: callq puts  ; CHECK: movl $-2, [[rloc]]  ; CHECK: jmp [[cont_bb]] @@ -89,11 +83,11 @@ __try.cont:  ; CHECK-NEXT: .long .Ltmp0@IMGREL+1  ; CHECK-NEXT: .long .Ltmp1@IMGREL+1  ; CHECK-NEXT: .long safe_div_filt0@IMGREL -; CHECK-NEXT: .long [[lpad0]]@IMGREL +; CHECK-NEXT: .long [[handler0]]@IMGREL  ; CHECK-NEXT: .long .Ltmp0@IMGREL+1  ; CHECK-NEXT: .long .Ltmp1@IMGREL+1  ; CHECK-NEXT: .long safe_div_filt1@IMGREL -; CHECK-NEXT: .long [[lpad1]]@IMGREL +; CHECK-NEXT: .long [[handler1]]@IMGREL  ; CHECK-NEXT: .Llsda_end0:  ; CHECK: .text  ; CHECK: .seh_endproc diff --git a/llvm/test/CodeGen/X86/seh-stack-realign.ll b/llvm/test/CodeGen/X86/seh-stack-realign.ll index 8494cadddb7..880533b4392 100644 --- a/llvm/test/CodeGen/X86/seh-stack-realign.ll +++ b/llvm/test/CodeGen/X86/seh-stack-realign.ll @@ -23,16 +23,13 @@ entry:            to label %__try.cont unwind label %lpad  lpad:                                             ; preds = %entry -  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)] -          to label %__except unwind label %endpad +  %cs1 = catchswitch within none [label %__except] unwind to caller  __except:                                         ; preds = %lpad +  %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)]    %code = load i32, i32* %__exceptioncode, align 4    %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 -  catchret %p to label %__try.cont - -endpad: -  catchendpad unwind to caller +  catchret from %p to label %__try.cont  __try.cont:                                       ; preds = %entry, %__except    ret i32 0 @@ -63,7 +60,7 @@ entry:  ; CHECK: movl $0, 40(%esi)  ; CHECK: calll _crash  ; CHECK: retl -; CHECK: LBB0_[[lpbb:[0-9]+]]: # %lpad +; CHECK: LBB0_[[lpbb:[0-9]+]]: # %__except  ;       Restore ESP  ; CHECK: movl -24(%ebp), %esp  ;       Restore ESI diff --git a/llvm/test/CodeGen/X86/tail-dup-catchret.ll b/llvm/test/CodeGen/X86/tail-dup-catchret.ll index 18682fb690e..3eeb24d20f2 100644 --- a/llvm/test/CodeGen/X86/tail-dup-catchret.ll +++ b/llvm/test/CodeGen/X86/tail-dup-catchret.ll @@ -8,19 +8,16 @@ entry:            to label %try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch -  catchret %0 to label %try.cont +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null] +  catchret from %0 to label %try.cont  try.cont:                                         ; preds = %entry, %catch    %b.0 = phi i1 [ false, %catch ], [ true, %entry ]    tail call void @h(i1 zeroext %b.0)    ret void - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller  }  ; CHECK-LABEL: _f: diff --git a/llvm/test/CodeGen/X86/tail-merge-wineh.ll b/llvm/test/CodeGen/X86/tail-merge-wineh.ll index d0f6b72df24..69c2fda6949 100644 --- a/llvm/test/CodeGen/X86/tail-merge-wineh.ll +++ b/llvm/test/CodeGen/X86/tail-merge-wineh.ll @@ -54,11 +54,11 @@ entry:            to label %unreachable unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %1 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind label %catch.dispatch.7  catch:                                            ; preds = %catch.dispatch -  catchret %1 to label %catchret.dest +  %1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  catchret from %1 to label %catchret.dest  catchret.dest:                                    ; preds = %catch    br label %try.cont @@ -70,11 +70,11 @@ try.cont:                                         ; preds = %catchret.dest            to label %unreachable unwind label %catch.dispatch.2  catch.dispatch.2:                                 ; preds = %try.cont -  %3 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch.4 unwind label %catchendblock.3 +  %cs2 = catchswitch within none [label %catch.4] unwind label %catch.dispatch.7  catch.4:                                          ; preds = %catch.dispatch.2 -  catchret %3 to label %catchret.dest.5 +  %3 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  catchret from %3 to label %catchret.dest.5  catchret.dest.5:                                  ; preds = %catch.4    br label %try.cont.6 @@ -82,15 +82,12 @@ catchret.dest.5:                                  ; preds = %catch.4  try.cont.6:                                       ; preds = %catchret.dest.5    br label %try.cont.11 -catchendblock.3:                                  ; preds = %catch.dispatch.2 -  catchendpad unwind label %catch.dispatch.7 - -catch.dispatch.7:                                 ; preds = %catchendblock.3, %catchendblock -  %4 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch.9 unwind label %catchendblock.8 +catch.dispatch.7: +  %cs3 = catchswitch within none [label %catch.9] unwind to caller  catch.9:                                          ; preds = %catch.dispatch.7 -  catchret %4 to label %catchret.dest.10 +  %4 = catchpad within %cs3 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  catchret from %4 to label %catchret.dest.10  catchret.dest.10:                                 ; preds = %catch.9    br label %try.cont.11 @@ -98,12 +95,6 @@ catchret.dest.10:                                 ; preds = %catch.9  try.cont.11:                                      ; preds = %catchret.dest.10, %try.cont.6    ret void -catchendblock.8:                                  ; preds = %catch.dispatch.7 -  catchendpad unwind to caller - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind label %catch.dispatch.7 -  unreachable:                                      ; preds = %try.cont, %entry    unreachable  } diff --git a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll index b6b4a9319b0..9f7a49536ca 100644 --- a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll +++ b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll @@ -16,7 +16,7 @@ declare void @useints(...)  declare void @f(i32 %p)  declare i32 @__CxxFrameHandler3(...) -define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 {  entry:    %a = call i32 @getint()    %b = call i32 @getint() @@ -26,22 +26,16 @@ entry:    invoke void @f(i32 1)            to label %try.cont unwind label %catch.dispatch -catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch unwind label %catchendblock - -catch: -  invoke void @f(i32 2) -          to label %invoke.cont.2 unwind label %catchendblock - -invoke.cont.2:                                    ; preds = %catch -  catchret %0 to label %try.cont - -try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3 +try.cont:    ret i32 0 -catchendblock:                                    ; preds = %catch, -  catchendpad unwind to caller +catch.dispatch: +  %cs = catchswitch within none [label %handler1] unwind to caller + +handler1: +  %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  call void @f(i32 2) +  catchret from %h1 to label %try.cont  }  ; X86-LABEL: _try_catch_catch: @@ -71,7 +65,7 @@ catchendblock:                                    ; preds = %catch,  ; X86: jmp [[contbb]]  ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X86: LBB0_[[catch1bb]]: # %catch.dispatch{{$}} +; X86: LBB0_[[catch1bb]]: # %handler1{{$}}  ; X86: pushl %ebp  ; X86-NOT: pushl  ; X86: subl $16, %esp @@ -120,7 +114,7 @@ catchendblock:                                    ; preds = %catch,  ; X64: retq  ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X64: LBB0_[[catch1bb]]: # %catch.dispatch{{$}} +; X64: LBB0_[[catch1bb]]: # %handler1{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 @@ -159,18 +153,15 @@ entry:    invoke void @f(i32 1)            to label %try.cont unwind label %catch.dispatch -catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch unwind label %catchendblock +catch.dispatch: +  %cs = catchswitch within none [label %handler1] unwind to caller -catch: -  catchret %0 to label %try.cont +handler1: +  %0 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  catchret from %0 to label %try.cont -try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3 +try.cont:    ret i32 0 - -catchendblock:                                    ; preds = %catch, -  catchendpad unwind to caller  }  ; X64-LABEL: try_one_csr: @@ -198,7 +189,7 @@ catchendblock:                                    ; preds = %catch,  ; X64: retq  ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_one_csr@4HA": -; X64: LBB1_[[catch1bb]]: # %catch.dispatch{{$}} +; X64: LBB1_[[catch1bb]]: # %handler1{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 @@ -226,18 +217,15 @@ entry:    invoke void @f(i32 1)            to label %try.cont unwind label %catch.dispatch -catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -          to label %catch unwind label %catchendblock +catch.dispatch: +  %cs = catchswitch within none [label %handler1] unwind to caller -catch: -  catchret %0 to label %try.cont +handler1: +  %cp1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  catchret from %cp1 to label %try.cont -try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3 +try.cont:    ret i32 0 - -catchendblock:                                    ; preds = %catch, -  catchendpad unwind to caller  }  ; X64-LABEL: try_no_csr: @@ -259,7 +247,7 @@ catchendblock:                                    ; preds = %catch,  ; X64: retq  ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_no_csr@4HA": -; X64: LBB2_[[catch1bb]]: # %catch.dispatch{{$}} +; X64: LBB2_[[catch1bb]]: # %handler1{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 diff --git a/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll new file mode 100644 index 00000000000..22ce7e5cd87 --- /dev/null +++ b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll @@ -0,0 +1,105 @@ +; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s \ +; RUN:     | FileCheck --check-prefix=CHECK --check-prefix=X86 %s +; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s \ +; RUN:     | FileCheck --check-prefix=CHECK --check-prefix=X64 %s + +; Loosely based on IR for this C++ source code: +;   void f(int p); +;   void try_in_catch() { +;     try { +;       f(1); +;     } catch (...) { +;       try { +;         f(2); +;       } catch (...) { +;         f(3); +;       } +;     } +;   } + +declare void @f(i32 %p) +declare i32 @__CxxFrameHandler3(...) + +define i32 @try_in_catch() personality i32 (...)* @__CxxFrameHandler3 { +entry: +  invoke void @f(i32 1) +          to label %try.cont unwind label %catch.dispatch.1 +try.cont: +  ret i32 0 + +catch.dispatch.1: +  %cs1 = catchswitch within none [label %handler1] unwind to caller +handler1: +  %h1 = catchpad within %cs1 [i8* null, i32 64, i8* null] +  invoke void @f(i32 2) +          to label %catchret1 unwind label %catch.dispatch.2 +catchret1: +  catchret from %h1 to label %try.cont + +catch.dispatch.2: +  %cs2 = catchswitch within %h1 [label %handler2] unwind to caller +handler2: +  %h2 = catchpad within %cs2 [i8* null, i32 64, i8* null] +  call void @f(i32 3) +  catchret from %h2 to label %catchret1 +} + +; X86-LABEL: L__ehtable$try_in_catch: +; X64-LABEL: $cppxdata$try_in_catch: +; CHECK-NEXT: .long   429065506 +; CHECK-NEXT: .long   4 +; CHECK-NEXT: .long   ($stateUnwindMap$try_in_catch) +; CHECK-NEXT: .long   2 +; CHECK-NEXT: .long   ($tryMap$try_in_catch) +; ip2state num + ptr +; X86-NEXT: .long   0 +; X86-NEXT: .long   0 +; X64-NEXT: .long   7 +; X64-NEXT: .long   ($ip2state$try_in_catch) +; unwindhelp offset +; X64-NEXT: .long   40 +; CHECK-NEXT: .long   0 +; EHFlags +; CHECK-NEXT: .long   1 + +; CHECK: $tryMap$try_in_catch: +; CHECK-NEXT: .long   2 +; CHECK-NEXT: .long   2 +; CHECK-NEXT: .long   3 +; CHECK-NEXT: .long   1 +; CHECK-NEXT: .long   ($handlerMap$0$try_in_catch) +; CHECK-NEXT: .long   0 +; CHECK-NEXT: .long   0 +; CHECK-NEXT: .long   3 +; CHECK-NEXT: .long   1 +; CHECK-NEXT: .long   ($handlerMap$1$try_in_catch) + +; CHECK: $handlerMap$0$try_in_catch: +; CHECK-NEXT:   .long   64 +; CHECK-NEXT:   .long   0 +; CHECK-NEXT:   .long   0 +; CHECK-NEXT:   .long   "?catch${{[0-9]+}}@?0?try_in_catch@4HA" +; X64-NEXT:   .long   56 + +; CHECK: $handlerMap$1$try_in_catch: +; CHECK-NEXT:   .long   64 +; CHECK-NEXT:   .long   0 +; CHECK-NEXT:   .long   0 +; CHECK-NEXT:   .long   "?catch${{[0-9]+}}@?0?try_in_catch@4HA" +; X64-NEXT:   .long   56 + +; X64: $ip2state$try_in_catch: +; X64-NEXT: .long   .Lfunc_begin0@IMGREL +; X64-NEXT: .long   -1 +; X64-NEXT: .long   .Ltmp0@IMGREL+1 +; X64-NEXT: .long   0 +; X64-NEXT: .long   .Ltmp1@IMGREL+1 +; X64-NEXT: .long   -1 +; X64-NEXT: .long   "?catch$2@?0?try_in_catch@4HA"@IMGREL +; X64-NEXT: .long   1 +; X64-NEXT: .long   .Ltmp2@IMGREL+1 +; X64-NEXT: .long   2 +; X64-NEXT: .long   .Ltmp3@IMGREL+1 +; X64-NEXT: .long   1 +; X64-NEXT: .long   "?catch$4@?0?try_in_catch@4HA"@IMGREL +; X64-NEXT: .long   3 diff --git a/llvm/test/CodeGen/X86/win-catchpad-nested.ll b/llvm/test/CodeGen/X86/win-catchpad-nested.ll index 25adfdf8c80..d20f9f69a5e 100644 --- a/llvm/test/CodeGen/X86/win-catchpad-nested.ll +++ b/llvm/test/CodeGen/X86/win-catchpad-nested.ll @@ -7,26 +7,25 @@ declare void @f()  define void @test1() personality void ()* @ProcessCLRException {  entry:    invoke void @f() -          to label %exit unwind label %outer.pad -outer.pad: -  %outer = catchpad [i32 1] -          to label %outer.catch unwind label %outer.end +          to label %exit unwind label %catch.dispatch.1 +exit: +  ret void + +catch.dispatch.1: +  %cs1 = catchswitch within none [label %outer.catch] unwind to caller +  outer.catch: +  %cp1 = catchpad within %cs1 [i32 1]    invoke void @f() -          to label %outer.ret unwind label %inner.pad -inner.pad: -  %inner = catchpad [i32 2] -          to label %inner.ret unwind label %inner.end -inner.ret: -  catchret %inner to label %outer.ret -inner.end: -  catchendpad unwind label %outer.end +          to label %outer.ret unwind label %catch.dispatch.2  outer.ret: -  catchret %outer to label %exit -outer.end: -  catchendpad unwind to caller -exit: -  ret void +  catchret from %cp1 to label %exit + +catch.dispatch.2: +  %cs2 = catchswitch within %cp1 [label %inner.catch] unwind to caller +inner.catch: +  %cp2 = catchpad within %cs2 [i32 2] +  catchret from %cp2 to label %outer.ret  }  ; Check the catchret targets @@ -37,7 +36,7 @@ exit:  ; CHECK-NEXT:                  # %outer.ret  ; CHECK-NEXT: leaq [[Exit]](%rip), %rax  ; CHECK:      retq   # CATCHRET -; CHECK: {{^[^: ]+}}: # %inner.pad +; CHECK: {{^[^: ]+}}: # %inner.catch  ; CHECK: .seh_endprolog  ; CHECK-NEXT: leaq [[OuterRet]](%rip), %rax  ; CHECK:      retq   # CATCHRET diff --git a/llvm/test/CodeGen/X86/win-catchpad-varargs.ll b/llvm/test/CodeGen/X86/win-catchpad-varargs.ll index a2988a3059e..6508f3bd7d6 100644 --- a/llvm/test/CodeGen/X86/win-catchpad-varargs.ll +++ b/llvm/test/CodeGen/X86/win-catchpad-varargs.ll @@ -13,20 +13,17 @@ entry:            to label %return unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch:                                            ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]    %ap1 = bitcast i8** %ap to i8*    call void @llvm.va_start(i8* %ap1)    %argp.cur = load i8*, i8** %ap    %1 = bitcast i8* %argp.cur to i32*    %arg2 = load i32, i32* %1    call void @llvm.va_end(i8* %ap1) -  catchret %0 to label %return - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller +  catchret from %0 to label %return  return:                                           ; preds = %entry, %catch    %retval.0 = phi i32 [ %arg2, %catch ], [ -1, %entry ] diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll index d9c8307cb08..5bd25046130 100644 --- a/llvm/test/CodeGen/X86/win-catchpad.ll +++ b/llvm/test/CodeGen/X86/win-catchpad.ll @@ -28,7 +28,7 @@ declare void @f(i32 %p, i32* %l)  declare i1 @getbool()  declare i32 @__CxxFrameHandler3(...) -define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 {  entry:    %e.addr = alloca i32    %local = alloca i32 @@ -36,33 +36,21 @@ entry:            to label %try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e.addr] -          to label %catch unwind label %catch.dispatch.2 +  %cs = catchswitch within none [label %handler1, label %handler2] unwind to caller -catch:                                            ; preds = %catch.dispatch +handler1: +  %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e.addr]    %e = load i32, i32* %e.addr -  invoke void @f(i32 %e, i32* %local) -          to label %invoke.cont.2 unwind label %catchendblock +  call void @f(i32 %e, i32* %local) +  catchret from %h1 to label %try.cont -invoke.cont.2:                                    ; preds = %catch -  catchret %0 to label %try.cont +handler2: +  %h2 = catchpad within %cs [i8* null, i32 64, i8* null] +  call void @f(i32 3, i32* %local) +  catchret from %h2 to label %try.cont -catch.dispatch.2:                                   ; preds = %catch.dispatch -  %1 = catchpad [i8* null, i32 u0x40, i8* null] -          to label %catch.2 unwind label %catchendblock - -catch.2:                                            ; preds = %catch.dispatch.2 -  invoke void @f(i32 3, i32* %local) -          to label %invoke.cont.3 unwind label %catchendblock - -invoke.cont.3:                                    ; preds = %catch.2 -  catchret %1 to label %try.cont - -try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3 +try.cont:    ret i32 0 - -catchendblock:                                    ; preds = %catch, %catch.2, %catch.dispatch.2 -  catchendpad unwind to caller  }  ; X86-LABEL: _try_catch_catch: @@ -76,25 +64,25 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X86: retl  ; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken -; X86-NEXT:                        # %invoke.cont.2 +; X86-NEXT:                        # %handler1  ; X86-NEXT: addl $12, %ebp  ; X86: jmp [[contbb]]  ; FIXME: These should be de-duplicated.  ; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken -; X86-NEXT:                        # %invoke.cont.3 +; X86-NEXT:                        # %handler2  ; X86-NEXT: addl $12, %ebp  ; X86: jmp [[contbb]]  ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X86: LBB0_[[catch1bb]]: # %catch.dispatch{{$}} +; X86: LBB0_[[catch1bb]]: # %handler1{{$}}  ; X86: pushl %ebp  ; X86: subl $8, %esp  ; X86: addl $12, %ebp  ; X86: movl %esp, -[[sp_offset]](%ebp) -; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]] -; X86: movl -32(%ebp), %[[e_reg:[a-z]+]] -; X86: movl $1, -{{[0-9]+}}(%ebp) +; X86-DAG: movl -32(%ebp), %[[e_reg:[a-z]+]] +; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]] +; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)  ; X86-DAG: movl %[[addr_reg]], 4(%esp)  ; X86-DAG: movl %[[e_reg]], (%esp)  ; X86: calll _f @@ -104,13 +92,13 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X86-NEXT: retl  ; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X86: LBB0_[[catch2bb]]: # %catch.dispatch.2{{$}} +; X86: LBB0_[[catch2bb]]: # %handler2{{$}}  ; X86: pushl %ebp  ; X86: subl $8, %esp  ; X86: addl $12, %ebp  ; X86: movl %esp, -[[sp_offset]](%ebp) -; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]] -; X86: movl $1, -{{[0-9]+}}(%ebp) +; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]] +; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)  ; X86-DAG: movl %[[addr_reg]], 4(%esp)  ; X86-DAG: movl $3, (%esp)  ; X86: calll _f @@ -151,7 +139,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64: retq  ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X64: LBB0_[[catch1bb]]: # %catch.dispatch{{$}} +; X64: LBB0_[[catch1bb]]: # %handler1{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 @@ -159,7 +147,6 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64: .seh_stackalloc 32  ; X64: leaq 48(%rdx), %rbp  ; X64: .seh_endprologue -; X64-DAG: .Ltmp4  ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx  ; X64-DAG: movl -12(%rbp), %ecx  ; X64: callq f @@ -169,7 +156,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64-NEXT: retq  ; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA": -; X64: LBB0_[[catch2bb]]: # %catch.dispatch.2{{$}} +; X64: LBB0_[[catch2bb]]: # %handler2{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 @@ -180,7 +167,6 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx  ; X64-DAG: movl $3, %ecx  ; X64: callq f -; X64: .Ltmp3  ; X64: leaq [[contbb]](%rip), %rax  ; X64-NEXT: addq $32, %rsp  ; X64-NEXT: popq %rbp @@ -192,7 +178,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64-NEXT: .long   ($stateUnwindMap$try_catch_catch)@IMGREL  ; X64-NEXT: .long   1  ; X64-NEXT: .long   ($tryMap$try_catch_catch)@IMGREL -; X64-NEXT: .long   4 +; X64-NEXT: .long   5  ; X64-NEXT: .long   ($ip2state$try_catch_catch)@IMGREL  ; X64-NEXT: .long   40  ; X64-NEXT: .long   0 @@ -222,33 +208,35 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c  ; X64-NEXT: .long   -1  ; X64-NEXT: .long   .Ltmp0@IMGREL+1  ; X64-NEXT: .long   0 -; X64-NEXT: .long   .Ltmp4@IMGREL+1 -; X64-NEXT: .long   1 -; X64-NEXT: .long   .Ltmp3@IMGREL+1 +; X64-NEXT: .long   .Ltmp1@IMGREL+1  ; X64-NEXT: .long   -1 +; X64-NEXT: .long   "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL +; X64-NEXT: .long   1 +; X64-NEXT: .long   "?catch$[[catch2bb]]@?0?try_catch_catch@4HA"@IMGREL +; X64-NEXT: .long   1 -define i32 @branch_to_normal_dest() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +define i32 @branch_to_normal_dest() personality i32 (...)* @__CxxFrameHandler3 {  entry:    invoke void @f(i32 1, i32* null)            to label %try.cont unwind label %catch.dispatch  catch.dispatch: -  %0 = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch: +  %cp1 = catchpad within %cs1 [i8* null, i32 64, i8* null] +  br label %loop + +loop:    %V = call i1 @getbool() -  br i1 %V, label %catch, label %catch.done +  br i1 %V, label %loop, label %catch.done  catch.done: -  catchret %0 to label %try.cont +  catchret from %cp1 to label %try.cont  try.cont:    ret i32 0 - -catchendblock: -  catchendpad unwind to caller  }  ; X86-LABEL: _branch_to_normal_dest: @@ -262,17 +250,16 @@ catchendblock:  ; X86-NEXT: addl $12, %ebp  ; X86: jmp [[contbb]] -; X86: "?catch$[[catchdispbb:[0-9]+]]@?0?branch_to_normal_dest@4HA": -; X86: LBB1_[[catchdispbb]]: # %catch.dispatch{{$}} +; X86: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA": +; X86: LBB1_[[catchbb]]: # %catch{{$}}  ; X86: pushl %ebp  ; X86: subl $8, %esp  ; X86: addl $12, %ebp - -; X86: LBB1_[[catchbb:[0-9]+]]: # %catch -; X86: movl    $-1, -16(%ebp) +; X86: LBB1_[[loopbb:[0-9]+]]: # %loop +; X86: movl    $1, -16(%ebp)  ; X86: calll   _getbool  ; X86: testb   $1, %al -; X86: jne LBB1_[[catchbb]] +; X86: jne LBB1_[[loopbb]]  ; X86: # %catch.done  ; X86-NEXT: movl $[[restorebb]], %eax  ; X86-NEXT: addl $8, %esp @@ -284,7 +271,7 @@ catchendblock:  ; X86-NEXT:   .long   64  ; X86-NEXT:   .long   0  ; X86-NEXT:   .long   0 -; X86-NEXT:   .long   "?catch$[[catchdispbb]]@?0?branch_to_normal_dest@4HA" +; X86-NEXT:   .long   "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"  ; X64-LABEL: branch_to_normal_dest:  ; X64: # %entry @@ -305,7 +292,7 @@ catchendblock:  ; X64: retq  ; X64: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA": -; X64: LBB1_[[catchbb]]: # %catch.dispatch{{$}} +; X64: LBB1_[[catchbb]]: # %catch{{$}}  ; X64: movq %rdx, 16(%rsp)  ; X64: pushq %rbp  ; X64: .seh_pushreg 5 @@ -313,7 +300,7 @@ catchendblock:  ; X64: .seh_stackalloc 32  ; X64: leaq 48(%rdx), %rbp  ; X64: .seh_endprologue -; X64: .LBB1_[[normal_dest_bb:[0-9]+]]: # %catch +; X64: .LBB1_[[normal_dest_bb:[0-9]+]]: # %loop  ; X64: callq   getbool  ; X64: testb   $1, %al  ; X64: jne     .LBB1_[[normal_dest_bb]] @@ -329,7 +316,7 @@ catchendblock:  ; X64-NEXT: .long   ($stateUnwindMap$branch_to_normal_dest)@IMGREL  ; X64-NEXT: .long   1  ; X64-NEXT: .long   ($tryMap$branch_to_normal_dest)@IMGREL -; X64-NEXT: .long   3 +; X64-NEXT: .long   4  ; X64-NEXT: .long   ($ip2state$branch_to_normal_dest)@IMGREL  ; X64-NEXT: .long   40  ; X64-NEXT: .long   0 @@ -362,3 +349,5 @@ catchendblock:  ; X64-NEXT: .long   0  ; X64-NEXT: .long   .Ltmp[[after_call]]@IMGREL+1  ; X64-NEXT: .long   -1 +; X64-NEXT: .long   "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"@IMGREL +; X64-NEXT: .long   1 diff --git a/llvm/test/CodeGen/X86/win-cleanuppad.ll b/llvm/test/CodeGen/X86/win-cleanuppad.ll index 27bb6e2abed..37090c2f6bc 100644 --- a/llvm/test/CodeGen/X86/win-cleanuppad.ll +++ b/llvm/test/CodeGen/X86/win-cleanuppad.ll @@ -14,9 +14,9 @@ invoke.cont:                                      ; preds = %entry    ret void  ehcleanup:                                        ; preds = %entry -  %0 = cleanuppad [] +  %0 = cleanuppad within none []    call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 -  cleanupret %0 unwind to caller +  cleanupret from %0 unwind to caller  }  ; CHECK: simple_cleanup:                         # @simple_cleanup @@ -77,14 +77,14 @@ invoke.cont.2:                                    ; preds = %invoke.cont.1    ret void  cleanup.inner:                                        ; preds = %invoke.cont -  %0 = cleanuppad [] +  %0 = cleanuppad within none []    call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 -  cleanupret %0 unwind label %cleanup.outer +  cleanupret from %0 unwind label %cleanup.outer  cleanup.outer:                                      ; preds = %invoke.cont.1, %cleanup.inner, %entry -  %1 = cleanuppad [] +  %1 = cleanuppad within none []    call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 -  cleanupret %1 unwind to caller +  cleanupret from %1 unwind to caller  }  ; X86-LABEL: _nested_cleanup: diff --git a/llvm/test/CodeGen/X86/win-funclet-cfi.ll b/llvm/test/CodeGen/X86/win-funclet-cfi.ll index 52589ee1918..95afa75a709 100644 --- a/llvm/test/CodeGen/X86/win-funclet-cfi.ll +++ b/llvm/test/CodeGen/X86/win-funclet-cfi.ll @@ -9,24 +9,21 @@ entry:            to label %unreachable unwind label %cleanupblock  cleanupblock: -  %cleanp = cleanuppad [] +  %cleanp = cleanuppad within none []    call void @g() -  cleanupret %cleanp unwind label %catch.dispatch +  cleanupret from %cleanp unwind label %catch.dispatch  catch.dispatch: -  %cp = catchpad [i8* null, i32 64, i8* null] -          to label %catch unwind label %catchendblock +  %cs1 = catchswitch within none [label %catch] unwind to caller  catch: +  %cp = catchpad within %cs1 [i8* null, i32 64, i8* null]    call void @g() -  catchret %cp to label %try.cont +  catchret from %cp to label %try.cont  try.cont:    ret void -catchendblock: -  catchendpad unwind to caller -  unreachable:    unreachable  } @@ -70,7 +67,7 @@ declare i32 @__CxxFrameHandler3(...)  ; CHECK: "?catch$[[catch:[0-9]+]]@?0??f@@YAXXZ@4HA":  ; CHECK: .seh_proc "?catch$[[catch]]@?0??f@@YAXXZ@4HA"  ; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except -; CHECK: LBB0_[[catch]]: # %catch.dispatch{{$}} +; CHECK: LBB0_[[catch]]: # %catch{{$}}  ; Emit CFI for pushing RBP.  ; CHECK: movq    %rdx, 16(%rsp) diff --git a/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll b/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll index 9b6916554e5..f7b6d0702eb 100644 --- a/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll +++ b/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll @@ -18,12 +18,10 @@ cont:    ret i32 0  lpad: -  %p = catchpad [i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)] -      to label %catch unwind label %endpad +  %cs = catchswitch within none [label %catch] unwind to caller  catch: -  catchret %p to label %ret1 -endpad: -  catchendpad unwind to caller +  %p = catchpad within %cs [i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)] +  catchret from %p to label %ret1  ret1:    ret i32 1 @@ -39,7 +37,7 @@ define internal i32 @filt_g(i8*, i8*) {  ; CHECK: xorl %eax, %eax  ; CHECK: .LBB0_[[epilogue:[0-9]+]]  ; CHECK: retq -; CHECK: # %lpad +; CHECK: # %catch{{$}}  ; CHECK: movl $1, %eax  ; CHECK: jmp .LBB0_[[epilogue]] diff --git a/llvm/test/CodeGen/X86/win32-eh-states.ll b/llvm/test/CodeGen/X86/win32-eh-states.ll index cb7b053e14d..fe3639b97a4 100644 --- a/llvm/test/CodeGen/X86/win32-eh-states.ll +++ b/llvm/test/CodeGen/X86/win32-eh-states.ll @@ -1,4 +1,5 @@ -; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s +; RUN: llc -mtriple=i686-pc-windows-msvc   < %s | FileCheck %s --check-prefix=X86 +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s --check-prefix=X64  ; Based on this source:  ; extern "C" void may_throw(int); @@ -40,59 +41,167 @@ invoke.cont:                                      ; preds = %entry            to label %try.cont.9 unwind label %lpad  try.cont.9:                                       ; preds = %invoke.cont.3, %invoke.cont, %catch.7 -  ; FIXME: Something about our CFG breaks TailDuplication. This empy asm blocks -  ; it so we can focus on testing the state numbering. -  call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()    ret void  lpad:                                             ; preds = %catch, %entry -  %p1 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -      to label %catch unwind label %end.inner.catch +  %cs1 = catchswitch within none [label %catch] unwind label %lpad.1  catch:                                            ; preds = %lpad.1 +  %p1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]    invoke void @may_throw(i32 3) -          to label %invoke.cont.3 unwind label %end.inner.catch +          to label %invoke.cont.3 unwind label %lpad.1  invoke.cont.3:                                    ; preds = %catch -  catchret %p1 to label %try.cont.9 - - -end.inner.catch: -  catchendpad unwind label %lpad.1 +  catchret from %p1 to label %try.cont.9  lpad.1:                                           ; preds = %invoke.cont -  %p2 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] -      to label %catch.7 unwind label %eh.resume +  %cs2 = catchswitch within none [label %catch.7] unwind to caller  catch.7: -  invoke void @may_throw(i32 4) -          to label %invoke.cont.10 unwind label %eh.resume +  %p2 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] +  call void @may_throw(i32 4) +  catchret from %p2 to label %try.cont.9 +} + +; X86-LABEL: _f: +; X86: movl $-1, [[state:[-0-9]+]](%ebp) +; X86: movl $___ehhandler$f, {{.*}} +; +; X86: movl $0, [[state]](%ebp) +; X86: movl $1, (%esp) +; X86: calll _may_throw +; +; X86: movl $1, [[state]](%ebp) +; X86: movl $2, (%esp) +; X86: calll _may_throw +; +; X86: movl $2, [[state]](%ebp) +; X86: movl $3, (%esp) +; X86: calll _may_throw +; +; X86: movl $3, [[state]](%ebp) +; X86: movl $4, (%esp) +; X86: calll _may_throw + + +; X64-LABEL: f: +; X64-LABEL: $ip2state$f: +; X64-NEXT:   .long .Lfunc_begin0@IMGREL +; X64-NEXT:   .long -1 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long 0 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long 1 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long -1 +; X64-NEXT:   .long "?catch${{.*}}@?0?f@4HA"@IMGREL +; X64-NEXT:   .long 2 +; X64-NEXT:   .long "?catch${{.*}}@?0?f@4HA"@IMGREL +; X64-NEXT:   .long 3 + +; Based on this source: +; extern "C" void may_throw(int); +; struct S { ~S(); }; +; void g() { +;   S x; +;   try { +;     may_throw(-1); +;   } catch (...) { +;     may_throw(0); +;     { +;       S y; +;       may_throw(1); +;     } +;     may_throw(2); +;   } +; } -invoke.cont.10: -  catchret %p2 to label %try.cont.9 +%struct.S = type { i8 } +declare void @"\01??1S@@QEAA@XZ"(%struct.S*) -eh.resume:                                        ; preds = %catch.dispatch.4 -  catchendpad unwind to caller +define void @g() personality i32 (...)* @__CxxFrameHandler3 { +entry: +  %x = alloca %struct.S, align 1 +  %y = alloca %struct.S, align 1 +  invoke void @may_throw(i32 -1) +          to label %unreachable unwind label %catch.dispatch + +catch.dispatch:                                   ; preds = %entry +  %0 = catchswitch within none [label %catch] unwind label %ehcleanup5 + +catch:                                            ; preds = %catch.dispatch +  %1 = catchpad within %0 [i8* null, i32 64, i8* null] +  invoke void @may_throw(i32 0) +          to label %invoke.cont unwind label %ehcleanup5 + +invoke.cont:                                      ; preds = %catch +  invoke void @may_throw(i32 1) +          to label %invoke.cont2 unwind label %ehcleanup + +invoke.cont2:                                     ; preds = %invoke.cont +  invoke void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) +          to label %invoke.cont3 unwind label %ehcleanup5 + +invoke.cont3:                                     ; preds = %invoke.cont2 +  invoke void @may_throw(i32 2) +          to label %invoke.cont4 unwind label %ehcleanup5 + +invoke.cont4:                                     ; preds = %invoke.cont3 +  catchret from %1 to label %try.cont + +try.cont:                                         ; preds = %invoke.cont4 +  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) +  ret void + +ehcleanup:                                        ; preds = %invoke.cont +  %2 = cleanuppad within %1 [] +  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) +  cleanupret from %2 unwind label %ehcleanup5 + +ehcleanup5:                                       ; preds = %invoke.cont2, %invoke.cont3, %ehcleanup, %catch, %catch.dispatch +  %3 = cleanuppad within none [] +  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) +  cleanupret from %3 unwind to caller + +unreachable:                                      ; preds = %entry +  unreachable  } -; CHECK-LABEL: _f: -; CHECK: movl $-1, [[state:[-0-9]+]](%ebp) -; CHECK: movl $___ehhandler$f, {{.*}} +; X86-LABEL: _g: +; X86: movl $-1, [[state:[-0-9]+]](%ebp) +; X86: movl $___ehhandler$g, {{.*}}  ; -; CHECK: movl $0, [[state]](%ebp) -; CHECK: movl $1, (%esp) -; CHECK: calll _may_throw +; X86: movl $1, [[state]](%ebp) +; X86: movl $-1, (%esp) +; X86: calll _may_throw  ; -; CHECK: movl $1, [[state]](%ebp) -; CHECK: movl $2, (%esp) -; CHECK: calll _may_throw +; X86: movl $2, [[state]](%ebp) +; X86: movl $0, (%esp) +; X86: calll _may_throw  ; -; CHECK: movl $2, [[state]](%ebp) -; CHECK: movl $3, (%esp) -; CHECK: calll _may_throw +; X86: movl $3, [[state]](%ebp) +; X86: movl $1, (%esp) +; X86: calll _may_throw  ; -; CHECK: movl $3, [[state]](%ebp) -; CHECK: movl $4, (%esp) -; CHECK: calll _may_throw - -; CHECK: .safeseh ___ehhandler$f +; X86: movl $2, [[state]](%ebp) +; X86: movl $2, (%esp) +; X86: calll _may_throw + +; X64-LABEL: g: +; X64-LABEL: $ip2state$g: +; X64-NEXT:   .long .Lfunc_begin1@IMGREL +; X64-NEXT:   .long -1 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long 1 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long -1 +; X64-NEXT:   .long "?catch${{.*}}@?0?g@4HA"@IMGREL +; X64-NEXT:   .long 2 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long 3 +; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1 +; X64-NEXT:   .long 2 + + +; X86: .safeseh ___ehhandler$f +; X86: .safeseh ___ehhandler$g diff --git a/llvm/test/CodeGen/X86/win32-eh.ll b/llvm/test/CodeGen/X86/win32-eh.ll index 87926a463f7..73c7b486a55 100644 --- a/llvm/test/CodeGen/X86/win32-eh.ll +++ b/llvm/test/CodeGen/X86/win32-eh.ll @@ -19,12 +19,10 @@ entry:  cont:    ret void  lpad: -  %p = catchpad [i8* bitcast (i32 ()* @catchall_filt to i8*)] -      to label %catch unwind label %endpad +  %cs = catchswitch within none [label %catch] unwind to caller  catch: -  catchret %p to label %cont -endpad: -  catchendpad unwind to caller +  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)] +  catchret from %p to label %cont  }  ; CHECK-LABEL: _use_except_handler3: @@ -45,7 +43,7 @@ endpad:  ; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]  ; CHECK: movl %[[next]], %fs:0  ; CHECK: retl -; CHECK: LBB1_2: # %lpad{{$}} +; CHECK: LBB1_2: # %catch{{$}}  ; CHECK: .section .xdata,"dr"  ; CHECK-LABEL: L__ehtable$use_except_handler3: @@ -60,12 +58,10 @@ entry:  cont:    ret void  lpad: -  %p = catchpad [i8* bitcast (i32 ()* @catchall_filt to i8*)] -      to label %catch unwind label %endpad +  %cs = catchswitch within none [label %catch] unwind to caller  catch: -  catchret %p to label %cont -endpad: -  catchendpad unwind to caller +  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)] +  catchret from %p to label %cont  }  ; CHECK-LABEL: _use_except_handler4: @@ -86,7 +82,7 @@ endpad:  ; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]  ; CHECK: movl %[[next]], %fs:0  ; CHECK: retl -; CHECK: LBB2_2: # %lpad{{$}} +; CHECK: LBB2_2: # %catch{{$}}  ; CHECK: .section .xdata,"dr"  ; CHECK-LABEL: L__ehtable$use_except_handler4: @@ -105,14 +101,10 @@ cont:    ret void  catchall: -  %p = catchpad [i8* null, i32 64, i8* null] -      to label %catch unwind label %endcatch - +  %cs = catchswitch within none [label %catch] unwind to caller  catch: -  catchret %p to label %cont - -endcatch: -  catchendpad unwind to caller +  %p = catchpad within %cs [i8* null, i32 64, i8* null] +  catchret from %p to label %cont  }  ; CHECK-LABEL: _use_CxxFrameHandler3: diff --git a/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll b/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll index 24db1649eb8..23aeea37c11 100644 --- a/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll +++ b/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll @@ -15,17 +15,14 @@ entry:            to label %__try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %pad = catchpad [i8* bitcast (i32 ()* @"\01?filt$0@0@realigned_try@@" to i8*)] -          to label %__except.ret unwind label %catchendblock +  %cs1 = catchswitch within none [label %__except.ret] unwind to caller  __except.ret:                                     ; preds = %catch.dispatch -  catchret %pad to label %__try.cont +  %pad = catchpad within %cs1 [i8* bitcast (i32 ()* @"\01?filt$0@0@realigned_try@@" to i8*)] +  catchret from %pad to label %__try.cont  __try.cont:                                       ; preds = %entry, %__except.ret    ret void - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller  }  ; Function Attrs: nounwind argmemonly @@ -69,7 +66,7 @@ declare i32 @_except_handler3(...)  ; CHECK: popl    %ebp  ; CHECK: retl  ; -; CHECK: LBB0_1:                                 # %catch.dispatch +; CHECK: LBB0_1:                                 # %__except.ret  ; Restore ESP  ; CHECK: movl    -24(%ebp), %esp  ; Recompute ESI by subtracting 60 from the end of the registration node. diff --git a/llvm/test/CodeGen/X86/win32-seh-catchpad.ll b/llvm/test/CodeGen/X86/win32-seh-catchpad.ll index 4e373af23e4..88dea367572 100644 --- a/llvm/test/CodeGen/X86/win32-seh-catchpad.ll +++ b/llvm/test/CodeGen/X86/win32-seh-catchpad.ll @@ -11,10 +11,11 @@ entry:            to label %invoke.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock +  %cs1 = catchswitch within none [label %__except.ret] unwind to caller  __except.ret:                                     ; preds = %catch.dispatch -  catchret %0 to label %__except +  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] +  catchret from %0 to label %__except  __except:                                         ; preds = %__except.ret    call void @f(i32 2) @@ -24,9 +25,6 @@ __try.cont:                                       ; preds = %__except, %invoke.c    call void @f(i32 3)    ret void -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller -  invoke.cont:                                      ; preds = %entry    br label %__try.cont  } @@ -77,81 +75,69 @@ entry:            to label %__try.cont unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock +  %cs1 = catchswitch within none [label %__except.ret] unwind label %catch.dispatch.11  __except.ret:                                     ; preds = %catch.dispatch -  catchret %0 to label %__try.cont +  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %0 to label %__try.cont  __try.cont:                                       ; preds = %entry, %__except.ret    invoke void @crash() #3            to label %__try.cont.9 unwind label %catch.dispatch.5  catch.dispatch.5:                                 ; preds = %__try.cont -  %1 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.7 unwind label %catchendblock.6 +  %cs2 = catchswitch within none [label %__except.ret.7] unwind label %catch.dispatch.11  __except.ret.7:                                   ; preds = %catch.dispatch.5 -  catchret %1 to label %__try.cont.9 +  %1 = catchpad within %cs2 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %1 to label %__try.cont.9  __try.cont.9:                                     ; preds = %__try.cont, %__except.ret.7    invoke void @crash() #3            to label %__try.cont.15 unwind label %catch.dispatch.11  catch.dispatch.11:                                ; preds = %catchendblock, %catchendblock.6, %__try.cont.9 -  %2 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.13 unwind label %catchendblock.12 +  %cs3 = catchswitch within none [label %__except.ret.13] unwind label %catch.dispatch.17  __except.ret.13:                                  ; preds = %catch.dispatch.11 -  catchret %2 to label %__try.cont.15 +  %2 = catchpad within %cs3 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %2 to label %__try.cont.15  __try.cont.15:                                    ; preds = %__try.cont.9, %__except.ret.13    invoke void @crash() #3            to label %__try.cont.35 unwind label %catch.dispatch.17  catch.dispatch.17:                                ; preds = %catchendblock.12, %__try.cont.15 -  %3 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.19 unwind label %catchendblock.18 +  %cs4 = catchswitch within none [label %__except.ret.19] unwind to caller  __except.ret.19:                                  ; preds = %catch.dispatch.17 -  catchret %3 to label %__except.20 +  %3 = catchpad within %cs4 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %3 to label %__except.20  __except.20:                                      ; preds = %__except.ret.19    invoke void @crash() #3            to label %__try.cont.27 unwind label %catch.dispatch.23  catch.dispatch.23:                                ; preds = %__except.20 -  %4 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.25 unwind label %catchendblock.24 +  %cs5 = catchswitch within none [label %__except.ret.25] unwind to caller  __except.ret.25:                                  ; preds = %catch.dispatch.23 -  catchret %4 to label %__try.cont.27 +  %4 = catchpad within %cs5 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %4 to label %__try.cont.27  __try.cont.27:                                    ; preds = %__except.20, %__except.ret.25    invoke void @crash() #3            to label %__try.cont.35 unwind label %catch.dispatch.30  catch.dispatch.30:                                ; preds = %__try.cont.27 -  %5 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.32 unwind label %catchendblock.31 +  %cs6 = catchswitch within none [label %__except.ret.32] unwind to caller  __except.ret.32:                                  ; preds = %catch.dispatch.30 -  catchret %5 to label %__try.cont.35 +  %5 = catchpad within %cs6 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] +  catchret from %5 to label %__try.cont.35  __try.cont.35:                                    ; preds = %__try.cont.15, %__try.cont.27, %__except.ret.32    ret void - -catchendblock.31:                                 ; preds = %catch.dispatch.30 -  catchendpad unwind to caller - -catchendblock.24:                                 ; preds = %catch.dispatch.23 -  catchendpad unwind to caller - -catchendblock.18:                                 ; preds = %catch.dispatch.17 -  catchendpad unwind to caller - -catchendblock.12:                                 ; preds = %catch.dispatch.11 -  catchendpad unwind label %catch.dispatch.17 - -catchendblock.6:                                  ; preds = %catch.dispatch.5 -  catchendpad unwind label %catch.dispatch.11 - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind label %catch.dispatch.11  }  ; This table is equivalent to the one produced by MSVC, even if it isn't in @@ -162,19 +148,19 @@ catchendblock:                                    ; preds = %catch.dispatch  ; CHECK:         .long   -1  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB -; CHECK:         .long   -1 +; CHECK:         .long   0  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB -; CHECK:         .long   -1 +; CHECK:         .long   1  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB -; CHECK:         .long   2 +; CHECK:         .long   1  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB -; CHECK:         .long   3 +; CHECK:         .long   -1  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB -; CHECK:         .long   3 +; CHECK:         .long   -1  ; CHECK:         .long   _nested_exceptions_filter_catchall  ; CHECK:         .long   LBB @@ -203,21 +189,19 @@ entry:            to label %__except unwind label %catch.dispatch  catch.dispatch:                                   ; preds = %entry -  %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock +  %cs1 = catchswitch within none [label %__except.ret] unwind to caller  __except.ret:                                     ; preds = %catch.dispatch +  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)]    call void @f(i32 2) -  catchret %0 to label %__except +  catchret from %0 to label %__except  __except:    ret void - -catchendblock:                                    ; preds = %catch.dispatch -  catchendpad unwind to caller  }  ; CHECK-LABEL: _code_in_catchpad: -; CHECK: # %catch.dispatch +; CHECK: # %__except.ret  ; CHECK-NEXT:         movl    -24(%ebp), %esp  ; CHECK-NEXT:         addl    $12, %ebp  ; CHECK-NEXT:         movl    $-1, -16(%ebp) diff --git a/llvm/test/CodeGen/X86/win32-seh-cleanupendpad.ll b/llvm/test/CodeGen/X86/win32-seh-nested-finally.ll index 35d9bfeb66e..c91a14278ec 100644 --- a/llvm/test/CodeGen/X86/win32-seh-cleanupendpad.ll +++ b/llvm/test/CodeGen/X86/win32-seh-nested-finally.ll @@ -17,26 +17,17 @@ invoke.cont.1:                                    ; preds = %invoke.cont    ret void  ehcleanup:                                        ; preds = %entry -  %0 = cleanuppad [] +  %0 = cleanuppad within none []    invoke void @f(i32 2) #3 -          to label %invoke.cont.2 unwind label %ehcleanup.end +          to label %invoke.cont.2 unwind label %ehcleanup.3  invoke.cont.2:                                    ; preds = %ehcleanup -  cleanupret %0 unwind label %ehcleanup.3 - -ehcleanup.end:                                    ; preds = %ehcleanup -  cleanupendpad %0 unwind label %ehcleanup.3 +  cleanupret from %0 unwind label %ehcleanup.3  ehcleanup.3:                                      ; preds = %invoke.cont.2, %ehcleanup.end, %invoke.cont -  %1 = cleanuppad [] -  invoke void @f(i32 3) #3 -          to label %invoke.cont.4 unwind label %ehcleanup.end.5 - -invoke.cont.4:                                    ; preds = %ehcleanup.3 -  cleanupret %1 unwind to caller - -ehcleanup.end.5:                                  ; preds = %ehcleanup.3 -  cleanupendpad %1 unwind to caller +  %1 = cleanuppad within none [] +  call void @f(i32 3) #3 +  cleanupret from %1 unwind to caller  }  declare void @f(i32) #0 diff --git a/llvm/test/CodeGen/X86/wineh-coreclr.ll b/llvm/test/CodeGen/X86/wineh-coreclr.ll new file mode 100644 index 00000000000..7bbc64ece8e --- /dev/null +++ b/llvm/test/CodeGen/X86/wineh-coreclr.ll @@ -0,0 +1,267 @@ +; RUN: llc -mtriple=x86_64-pc-windows-coreclr -verify-machineinstrs < %s | FileCheck %s + +declare void @ProcessCLRException() +declare void @f(i32) +declare void @g(i8 addrspace(1)*) +declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token) + +; Simplified IR for pseudo-C# like the following: +; void test1() { +;   try { +;     f(1); +;     try { +;       f(2); +;     } catch (type1) { +;       f(3); +;     } catch (type2) { +;       f(4); +;       try { +;         f(5); +;       } fault { +;         f(6); +;       } +;     } +;   } finally { +;     f(7); +;   } +;   f(8); +; } + +; CHECK-LABEL: test1:     # @test1 +; CHECK-NEXT: [[L_begin:.*func_begin.*]]: +define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) { +entry: +; CHECK: # %entry +; CHECK: leaq [[FPOffset:[0-9]+]](%rsp), %rbp +; CHECK: .seh_endprologue +; CHECK: movq %rsp, [[PSPSymOffset:[0-9]+]](%rsp) +; CHECK: [[L_before_f1:.+]]: +; CHECK-NEXT: movl $1, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f1:.+]]: +  invoke void @f(i32 1) +    to label %inner_try unwind label %finally.pad +inner_try: +; CHECK: # %inner_try +; CHECK: [[L_before_f2:.+]]: +; CHECK-NEXT: movl $2, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f2:.+]]: +  invoke void @f(i32 2) +    to label %finally.clone unwind label %catch1.pad +catch1.pad: +  %cs1 = catchswitch within none [label %catch1.body, label %catch2.body] unwind label %finally.pad +catch1.body: +  %catch1 = catchpad within %cs1 [i32 1] +; CHECK: .seh_proc [[L_catch1:[^ ]+]] +; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]] +;                        ^ all funclets use the same frame size +; CHECK: movq [[PSPSymOffset]](%rcx), %rcx +;                              ^ establisher frame pointer passed in rcx +; CHECK: movq %rcx, [[PSPSymOffset]](%rsp) +; CHECK: leaq [[FPOffset]](%rcx), %rbp +; CHECK: .seh_endprologue +; CHECK: movq %rdx, %rcx +;             ^ exception pointer passed in rdx +; CHECK-NEXT: callq g +  %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1) +  call void @g(i8 addrspace(1)* %exn1) +; CHECK: [[L_before_f3:.+]]: +; CHECK-NEXT: movl $3, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f3:.+]]: +  invoke void @f(i32 3) +    to label %catch1.ret unwind label %finally.pad +catch1.ret: +  catchret from %catch1 to label %finally.clone +catch2.body: +  %catch2 = catchpad within %cs1 [i32 2] +; CHECK: .seh_proc [[L_catch2:[^ ]+]] +; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]] +;                        ^ all funclets use the same frame size +; CHECK: movq [[PSPSymOffset]](%rcx), %rcx +;                              ^ establisher frame pointer passed in rcx +; CHECK: movq %rcx, [[PSPSymOffset]](%rsp) +; CHECK: leaq [[FPOffset]](%rcx), %rbp +; CHECK: .seh_endprologue +; CHECK: movq %rdx, %rcx +;             ^ exception pointer passed in rdx +; CHECK-NEXT: callq g +  %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2) +  call void @g(i8 addrspace(1)* %exn2) +; CHECK: [[L_before_f4:.+]]: +; CHECK-NEXT: movl $4, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f4:.+]]: +  invoke void @f(i32 4) +    to label %try_in_catch unwind label %finally.pad +try_in_catch: +; CHECK: # %try_in_catch +; CHECK: [[L_before_f5:.+]]: +; CHECK-NEXT: movl $5, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f5:.+]]: +  invoke void @f(i32 5) +    to label %catch2.ret unwind label %fault.pad +fault.pad: +; CHECK: .seh_proc [[L_fault:[^ ]+]] +  %fault = cleanuppad within none [i32 undef] +; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]] +;                        ^ all funclets use the same frame size +; CHECK: movq [[PSPSymOffset]](%rcx), %rcx +;                              ^ establisher frame pointer passed in rcx +; CHECK: movq %rcx, [[PSPSymOffset]](%rsp) +; CHECK: leaq [[FPOffset]](%rcx), %rbp +; CHECK: .seh_endprologue +; CHECK: [[L_before_f6:.+]]: +; CHECK-NEXT: movl $6, %ecx +; CHECK-NEXT: callq f +; CHECK-NEXT: [[L_after_f6:.+]]: +  invoke void @f(i32 6) +    to label %fault.ret unwind label %finally.pad +fault.ret: +  cleanupret from %fault unwind label %finally.pad +catch2.ret: +  catchret from %catch2 to label %finally.clone +finally.clone: +  call void @f(i32 7) +  br label %tail +finally.pad: +; CHECK: .seh_proc [[L_finally:[^ ]+]] +  %finally = cleanuppad within none [] +; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]] +;                        ^ all funclets use the same frame size +; CHECK: movq [[PSPSymOffset]](%rcx), %rcx +;                              ^ establisher frame pointer passed in rcx +; CHECK: movq %rcx, [[PSPSymOffset]](%rsp) +; CHECK: leaq [[FPOffset]](%rcx), %rbp +; CHECK: .seh_endprologue +; CHECK-NEXT: movl $7, %ecx +; CHECK-NEXT: callq f +  call void @f(i32 7) +  cleanupret from %finally unwind to caller +tail: +  call void @f(i32 8) +  ret void +; CHECK: [[L_end:.*func_end.*]]: +} + +; FIXME: Verify that the new clauses are correct and re-enable these checks. + +; Now check for EH table in xdata (following standard xdata) +; CHECKX-LABEL: .section .xdata +; standard xdata comes here +; CHECKX:      .long 4{{$}} +;                   ^ number of funclets +; CHECKX-NEXT: .long [[L_catch1]]-[[L_begin]] +;                   ^ offset from L_begin to start of 1st funclet +; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]] +;                   ^ offset from L_begin to start of 2nd funclet +; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]] +;                   ^ offset from L_begin to start of 3rd funclet +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset from L_begin to start of 4th funclet +; CHECKX-NEXT: .long [[L_end]]-[[L_begin]] +;                   ^ offset from L_begin to end of last funclet +; CHECKX-NEXT: .long 7 +;                   ^ number of EH clauses +; Clause 1: call f(2) is guarded by catch1 +; CHECKX-NEXT: .long 0 +;                   ^ flags (0 => catch handler) +; CHECKX-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_catch1]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 1 +;                   ^ type token of catch (from catchpad) +; Clause 2: call f(2) is also guarded by catch2 +; CHECKX-NEXT: .long 0 +;                   ^ flags (0 => catch handler) +; CHECKX-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 2 +;                   ^ type token of catch (from catchpad) +; Clause 3: calls f(1) and f(2) are guarded by finally +; CHECKX-NEXT: .long 2 +;                   ^ flags (2 => finally handler) +; CHECKX-NEXT: .long ([[L_before_f1]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_end]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 0 +;                   ^ type token slot (null for finally) +; Clause 4: call f(3) is guarded by finally +;           This is a "duplicate" because the protected range (f(3)) +;           is in funclet catch1 but the finally's immediate parent +;           is the main function, not that funclet. +; CHECKX-NEXT: .long 10 +;                   ^ flags (2 => finally handler | 8 => duplicate) +; CHECKX-NEXT: .long ([[L_before_f3]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f3]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_end]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 0 +;                   ^ type token slot (null for finally) +; Clause 5: call f(5) is guarded by fault +; CHECKX-NEXT: .long 4 +;                   ^ flags (4 => fault handler) +; CHECKX-NEXT: .long ([[L_before_f5]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 0 +;                   ^ type token slot (null for fault) +; Clause 6: calls f(4) and f(5) are guarded by finally +;           This is a "duplicate" because the protected range (f(4)-f(5)) +;           is in funclet catch2 but the finally's immediate parent +;           is the main function, not that funclet. +; CHECKX-NEXT: .long 10 +;                   ^ flags (2 => finally handler | 8 => duplicate) +; CHECKX-NEXT: .long ([[L_before_f4]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_end]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 0 +;                   ^ type token slot (null for finally) +; Clause 7: call f(6) is guarded by finally +;           This is a "duplicate" because the protected range (f(3)) +;           is in funclet catch1 but the finally's immediate parent +;           is the main function, not that funclet. +; CHECKX-NEXT: .long 10 +;                   ^ flags (2 => finally handler | 8 => duplicate) +; CHECKX-NEXT: .long ([[L_before_f6]]-[[L_begin]])+1 +;                   ^ offset of start of clause +; CHECKX-NEXT: .long ([[L_after_f6]]-[[L_begin]])+1 +;                   ^ offset of end of clause +; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]] +;                   ^ offset of start of handler +; CHECKX-NEXT: .long [[L_end]]-[[L_begin]] +;                   ^ offset of end of handler +; CHECKX-NEXT: .long 0 +;                   ^ type token slot (null for finally) diff --git a/llvm/test/CodeGen/X86/wineh-exceptionpointer.ll b/llvm/test/CodeGen/X86/wineh-exceptionpointer.ll new file mode 100644 index 00000000000..9c1f0aaf3de --- /dev/null +++ b/llvm/test/CodeGen/X86/wineh-exceptionpointer.ll @@ -0,0 +1,26 @@ +; RUN: llc -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s + +declare void @ProcessCLRException() +declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token) +declare void @f() +declare void @g(i32 addrspace(1)*) + +; CHECK-LABEL: test1: # @test1 +define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) { +entry: +  invoke void @f() +    to label %exit unwind label %catch.pad +catch.pad: +  %cs1 = catchswitch within none [label %catch.body] unwind to caller +catch.body: +  ; CHECK: {{^[^: ]+}}: # %catch.body +  ; CHECK: movq %rdx, %rcx +  ; CHECK-NEXT: callq g +  %catch = catchpad within %cs1 [i32 5] +  %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch) +  %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)* +  call void @g(i32 addrspace(1)* %cast_exn) +  catchret from %catch to label %exit +exit: +  ret void +}  | 

