Index: llvm/test/Transforms/Reg2Mem/catchswitch-crach2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Reg2Mem/catchswitch-crach2.ll @@ -0,0 +1,81 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=reg2mem -S < %s | FileCheck %s +%"type1" = type { i32 (...)**, i8*, i8*, i8**, i8**, i8*, i8*, i8**, i8**, i32, i32, i32*, i32*, %"type2"* } +%"type2" = type { [8 x i8], %"type3"* } +%"type3" = type { %"type4", %"type4"**, i64, i32, i8, %"type6" } +%"type4" = type { %"type5", i32 } +%"type5" = type { i32 (...)** } +%"type6" = type { i8*, i8 } + +declare i32 @__CxxFrameHandler3(...) + +define void @testreg2mem(i8* %_Val) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +; CHECK-LABEL: @testreg2mem( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[_STATE_3_REG2MEM:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[_STATE_3_REG2MEM1:%.*]] = alloca i32, align 4 +; CHECK-NEXT: %"reg2mem alloca point" = bitcast i32 0 to i32 +; CHECK-NEXT: store i32 0, i32* [[_STATE_3_REG2MEM1]], align 4 +; CHECK-NEXT: [[CALL_I166167:%.*]] = invoke noundef i64 undef(%type1* noundef nonnull align 8 dereferenceable(104) undef, i8* noundef [[_VAL:%.*]], i64 noundef undef) +; CHECK-NEXT: to label [[IF_END56:%.*]] unwind label [[CATCH_DISPATCH:%.*]] +; CHECK: if.end56: +; CHECK-NEXT: store i32 undef, i32* [[_STATE_3_REG2MEM1]], align 4 +; CHECK-NEXT: invoke void @extfunc1() +; CHECK-NEXT: to label [[INVOKE_CONT75:%.*]] unwind label [[CATCH_DISPATCH]] +; CHECK: invoke.cont75: +; CHECK-NEXT: unreachable +; CHECK: catch.dispatch: +; CHECK-NEXT: [[TMP0:%.*]] = catchswitch within none [label %catch] unwind label [[EHCLEANUP105:%.*]] +; CHECK: catch: +; CHECK-NEXT: [[TMP1:%.*]] = catchpad within [[TMP0]] [i8* null, i32 64, i8* null] +; CHECK-NEXT: [[_STATE_3_RELOAD3:%.*]] = load i32, i32* [[_STATE_3_REG2MEM1]], align 4 +; CHECK-NEXT: store i32 [[_STATE_3_RELOAD3]], i32* [[_STATE_3_REG2MEM]], align 4 +; CHECK-NEXT: invoke void @extfunc2() [ "funclet"(token [[TMP1]]) ] +; CHECK-NEXT: to label [[INVOKE_CONT98:%.*]] unwind label [[EHCLEANUP105]] +; CHECK: invoke.cont98: +; CHECK-NEXT: catchret from [[TMP1]] to label [[IF_END99:%.*]] +; CHECK: if.end99: +; CHECK-NEXT: [[_STATE_3_RELOAD:%.*]] = load i32, i32* [[_STATE_3_REG2MEM]], align 4 +; CHECK-NEXT: [[OR_I:%.*]] = or i32 undef, [[_STATE_3_RELOAD]] +; CHECK-NEXT: unreachable +; CHECK: ehcleanup105: +; CHECK-NEXT: [[TMP2:%.*]] = cleanuppad within none [] +; CHECK-NEXT: [[_STATE_3_RELOAD2:%.*]] = load i32, i32* [[_STATE_3_REG2MEM1]], align 4 +; CHECK-NEXT: store i32 [[_STATE_3_RELOAD2]], i32* [[_STATE_3_REG2MEM]], align 4 +; CHECK-NEXT: cleanupret from [[TMP2]] unwind to caller +; +entry: + %call.i166167 = invoke noundef i64 undef(%"type1"* noundef nonnull align 8 dereferenceable(104) undef, i8* noundef %_Val, i64 noundef undef) + to label %if.end56 unwind label %catch.dispatch + +if.end56: ; preds = %entry + invoke void @"extfunc1"() + to label %invoke.cont75 unwind label %catch.dispatch + +invoke.cont75: ; preds = %if.end56 + unreachable + +catch.dispatch: ; preds = %if.end56, %entry + %_State.3 = phi i32 [ undef, %if.end56 ], [ 0, %entry ] + %0 = catchswitch within none [label %catch] unwind label %ehcleanup105 + +catch: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + invoke void @"extfunc2"() [ "funclet"(token %1) ] + to label %invoke.cont98 unwind label %ehcleanup105 + +invoke.cont98: ; preds = %catch + catchret from %1 to label %if.end99 + +if.end99: ; preds = %invoke.cont98 + %or.i = or i32 undef, %_State.3 + unreachable + +ehcleanup105: ; preds = %catch, %catch.dispatch + %2 = cleanuppad within none [] + cleanupret from %2 unwind to caller +} + +declare void @"extfunc1"() + +declare void @"extfunc2"()