--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -slp-vectorizer -S -mtriple=x86_64-pc-windows-msvc19.29.30145 < %s | FileCheck %s
+
+; This used to crash in SLP vectorization when attempting to set the
+; IRBuilder's insertion point to the end of a catchswitch block, which
+; is invalid. Only phis and the catchswitch may be present, so we must
+; avoid trying to insert shuffles into such a block.
+
+%typeA = type { i8**, i8*, [20 x i8] }
+@globalA = external global %typeA
+
+declare i32 @__CxxFrameHandler3(...)
+declare void @funcA()
+
+define void @important_func() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+; CHECK-LABEL: @important_func(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LABELB:%.*]]
+; CHECK: labelB:
+; CHECK-NEXT: invoke void @funcA()
+; CHECK-NEXT: to label [[LABELC:%.*]] unwind label [[LABELD:%.*]]
+; CHECK: labelC:
+; CHECK-NEXT: invoke void @funcA()
+; CHECK-NEXT: to label [[LABELE:%.*]] unwind label [[LABELF:%.*]]
+; CHECK: labelD:
+; CHECK-NEXT: [[TMP0:%.*]] = cleanuppad within none []
+; CHECK-NEXT: unreachable
+; CHECK: labelE:
+; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 1
+; CHECK-NEXT: [[F:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 2
+; CHECK-NEXT: invoke void @funcA()
+; CHECK-NEXT: to label [[LABELG:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK: labelF:
+; CHECK-NEXT: [[TMP2:%.*]] = cleanuppad within none []
+; CHECK-NEXT: cleanupret from [[TMP2]] unwind to caller
+; CHECK: labelG:
+; CHECK-NEXT: [[G:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 0
+; CHECK-NEXT: [[H:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 3
+; CHECK-NEXT: invoke void @funcA()
+; CHECK-NEXT: to label [[LABELH:%.*]] unwind label [[CATCH_DISPATCH]]
+; CHECK: labelH:
+; CHECK-NEXT: unreachable
+; CHECK: catch.dispatch:
+; CHECK-NEXT: [[TMP3:%.*]] = phi float [ [[G]], [[LABELG]] ], [ [[TMP1]], [[LABELE]] ]
+; CHECK-NEXT: [[TMP4:%.*]] = phi float [ [[H]], [[LABELG]] ], [ [[F]], [[LABELE]] ]
+; CHECK-NEXT: [[TMP5:%.*]] = catchswitch within none [label %catch] unwind to caller
+; CHECK: catch:
+; CHECK-NEXT: [[TMP6:%.*]] = catchpad within [[TMP5]] [%typeA* @globalA, i32 8, i8* null]
+; CHECK-NEXT: unreachable
+;
+entry:
+ br label %labelB
+
+labelB:
+ invoke void @funcA()
+ to label %labelC unwind label %labelD
+
+labelC:
+ invoke void @funcA()
+ to label %labelE unwind label %labelF
+
+labelD:
+ %0 = cleanuppad within none []
+ unreachable
+
+labelE:
+ %1 = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 1
+ %f = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 2
+ invoke void @funcA()
+ to label %labelG unwind label %catch.dispatch
+
+labelF:
+ %2 = cleanuppad within none []
+ cleanupret from %2 unwind to caller
+
+labelG:
+ %g = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 0
+ %h = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 3
+ invoke void @funcA()
+ to label %labelH unwind label %catch.dispatch
+
+labelH:
+ unreachable
+
+catch.dispatch:
+ %3 = phi float [ %g, %labelG ], [ %1, %labelE ]
+ %4 = phi float [ %h, %labelG ], [ %f, %labelE ]
+ %5 = catchswitch within none [label %catch] unwind to caller
+
+catch:
+ %6 = catchpad within %5 [%typeA* @globalA, i32 8, i8* null]
+ unreachable
+}