diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index be5e0f6ef058b01..cedcb9580b486ba 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8606,6 +8606,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, if (EHPadBB) { DAG.setRoot(lowerEndEH(getRoot(), cast_or_null(CLI.CB), EHPadBB, BeginLabel)); + Result.second = getRoot(); } return Result; @@ -10448,6 +10449,8 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB, std::pair Result = lowerInvokable(CLI, EHPadBB); SDNode *CallEnd = Result.second.getNode(); + if (CallEnd->getOpcode() == ISD::EH_LABEL) + CallEnd = CallEnd->getOperand(0).getNode(); if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg)) CallEnd = CallEnd->getOperand(0).getNode(); diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index d7f4d1c8937563b..671ec84fb941637 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -340,6 +340,9 @@ static std::pair lowerCallFromStatepointLoweringInfo( // to grab the return value from the return register(s), or it can be a LOAD // to load a value returned by reference via a stack slot. + if (CallEnd->getOpcode() == ISD::EH_LABEL) + CallEnd = CallEnd->getOperand(0).getNode(); + bool HasDef = !SI.CLI.RetTy->isVoidTy(); if (HasDef) { if (CallEnd->getOpcode() == ISD::LOAD) diff --git a/llvm/test/CodeGen/X86/issue64826-switferror-eh.ll b/llvm/test/CodeGen/X86/issue64826-switferror-eh.ll new file mode 100644 index 000000000000000..83b6fb11bc98532 --- /dev/null +++ b/llvm/test/CodeGen/X86/issue64826-switferror-eh.ll @@ -0,0 +1,77 @@ +; RUN: llc %s -filetype=obj -o - | llvm-readobj -r - | FileCheck %s --check-prefix=RELOC +; RUN: llc %s -o - | FileCheck %s --check-prefix=ASM + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx" + +declare void @issue64826(i64, ptr, ptr swifterror) + +define swiftcc void @rdar113994760() personality ptr @__gcc_personality_v0 { +entry: + %swifterror = alloca swifterror ptr, align 8 + invoke swiftcc void @issue64826(i64 0, ptr null, ptr swifterror %swifterror) + to label %.noexc unwind label %tsan_cleanup + +.noexc: ; preds = %entry + ret void + +tsan_cleanup: ; preds = %entry + %cleanup.lpad = landingpad { ptr, i32 } + cleanup + resume { ptr, i32 } zeroinitializer +} + +declare i32 @__gcc_personality_v0(...) + +; RELOC-LABEL: Relocations [ +; RELOC-NEXT: Section __text { +; RELOC-NEXT: 0x19 1 2 1 X86_64_RELOC_BRANCH 0 __Unwind_Resume +; RELOC-NEXT: 0xB 1 2 1 X86_64_RELOC_BRANCH 0 _issue64826 +; RELOC-NEXT: } +; RELOC-NEXT: Section __eh_frame { +; RELOC-NEXT: 0x13 1 2 1 X86_64_RELOC_GOT 0 ___gcc_personality_v0 +; RELOC-NEXT: } +; RELOC-NEXT: ] + +; ASM-LABEL: rdar113994760: +; ASM: ## %bb.0: ## %entry +; ASM-NEXT: pushq %r12 +; ASM-NEXT: .cfi_def_cfa_offset 16 +; ASM-NEXT: subq $16, %rsp +; ASM-NEXT: .cfi_def_cfa_offset 32 +; ASM-NEXT: .cfi_offset %r12, -16 +; ASM-NEXT: Ltmp0: +; ASM-NEXT: xorl %edi, %edi +; ASM-NEXT: xorl %esi, %esi +; ASM-NEXT: callq _issue64826 +; ASM-NEXT: Ltmp1: +; ASM-NEXT: ## %bb.1: ## %.noexc +; ASM-NEXT: addq $16, %rsp +; ASM-NEXT: popq %r12 +; ASM-NEXT: retq +; ASM-NEXT: LBB0_2: ## %tsan_cleanup +; ASM-NEXT: Ltmp2: +; ASM-NEXT: xorl %edi, %edi +; ASM-NEXT: callq __Unwind_Resume +; ASM-NEXT: Lfunc_end0: +; ASM-NEXT: .cfi_endproc +; ASM-NEXT: .section __TEXT,__gcc_except_tab +; ASM-NEXT: .p2align 2, 0x0 +; ASM-NEXT: GCC_except_table0: +; ASM-NEXT: Lexception0: +; ASM-NEXT: .byte 255 ## @LPStart Encoding = omit +; ASM-NEXT: .byte 255 ## @TType Encoding = omit +; ASM-NEXT: .byte 1 ## Call site Encoding = uleb128 +; ASM-NEXT: .uleb128 Lcst_end0-Lcst_begin0 +; ASM-NEXT: Lcst_begin0: +; ASM-NEXT: .uleb128 Ltmp0-Lfunc_begin0 ## >> Call Site 1 << +; ASM-NEXT: .uleb128 Ltmp1-Ltmp0 ## Call between Ltmp0 and Ltmp1 +; ASM-NEXT: .uleb128 Ltmp2-Lfunc_begin0 ## jumps to Ltmp2 +; ASM-NEXT: .byte 0 ## On action: cleanup +; ASM-NEXT: .uleb128 Ltmp1-Lfunc_begin0 ## >> Call Site 2 << +; ASM-NEXT: .uleb128 Lfunc_end0-Ltmp1 ## Call between Ltmp1 and Lfunc_end0 +; ASM-NEXT: .byte 0 ## has no landing pad +; ASM-NEXT: .byte 0 ## On action: cleanup +; ASM-NEXT: Lcst_end0: +; ASM-NEXT: .p2align 2, 0x0 +; ASM-NEXT: ## -- End function diff --git a/llvm/test/CodeGen/X86/statepoint-invoke.ll b/llvm/test/CodeGen/X86/statepoint-invoke.ll index d0b08c05af3fffc..34dbc21a8a8cb80 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke.ll +++ b/llvm/test/CodeGen/X86/statepoint-invoke.ll @@ -9,6 +9,28 @@ declare ptr addrspace(1) @"some_other_call"(ptr addrspace(1)) declare i32 @"personality_function"() define ptr addrspace(1) @test_basic(ptr addrspace(1) %obj, +; CHECK-LABEL: test_basic: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subq $24, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: # %bb.1: # %invoke_safepoint_normal_dest +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: addq $24, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB0_2: # %exceptional_return +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: .Ltmp2: +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: addq $24, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq ptr addrspace(1) %obj1) gc "statepoint-example" personality ptr @"personality_function" { entry: @@ -37,6 +59,26 @@ exceptional_return: ; CHECK: .p2align 4 define ptr addrspace(1) @test_result(ptr addrspace(1) %obj, +; CHECK-LABEL: test_result: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: movq %rdi, (%rsp) +; CHECK-NEXT: .Ltmp4: +; CHECK-NEXT: callq some_other_call@PLT +; CHECK-NEXT: .Ltmp7: +; CHECK-NEXT: .Ltmp5: +; CHECK-NEXT: # %bb.1: # %normal_return +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB1_2: # %exceptional_return +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp6: +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq ptr addrspace(1) %obj1) gc "statepoint-example" personality ptr @personality_function { entry: @@ -60,6 +102,57 @@ exceptional_return: ; CHECK: .p2align 4 define ptr addrspace(1) @test_same_val(i1 %cond, ptr addrspace(1) %val1, ptr addrspace(1) %val2, ptr addrspace(1) %val3) +; CHECK-LABEL: test_same_val: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: subq $16, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: .cfi_offset %rbx, -16 +; CHECK-NEXT: movl %edi, %ebx +; CHECK-NEXT: testb $1, %bl +; CHECK-NEXT: je .LBB2_3 +; CHECK-NEXT: # %bb.1: # %left +; CHECK-NEXT: movq %rsi, (%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: .Ltmp11: +; CHECK-NEXT: movq %rsi, %rdi +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp14: +; CHECK-NEXT: .Ltmp12: +; CHECK-NEXT: # %bb.2: # %left.relocs +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: jmp .LBB2_5 +; CHECK-NEXT: .LBB2_3: # %right +; CHECK-NEXT: movq %rdx, (%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: .Ltmp8: +; CHECK-NEXT: movq %rsi, %rdi +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp15: +; CHECK-NEXT: .Ltmp9: +; CHECK-NEXT: # %bb.4: # %right.relocs +; CHECK-NEXT: movq (%rsp), %rcx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: .LBB2_5: # %normal_return +; CHECK-NEXT: testb $1, %bl +; CHECK-NEXT: cmoveq %rcx, %rax +; CHECK-NEXT: .LBB2_6: # %normal_return +; CHECK-NEXT: addq $16, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB2_9: # %exceptional_return.right +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: .Ltmp10: +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: jmp .LBB2_6 +; CHECK-NEXT: .LBB2_7: # %exceptional_return.left +; CHECK-NEXT: .Ltmp13: +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: jmp .LBB2_6 gc "statepoint-example" personality ptr @"personality_function" { entry: br i1 %cond, label %left, label %right @@ -102,6 +195,23 @@ exceptional_return.right: } define ptr addrspace(1) @test_null_undef(ptr addrspace(1) %val1) +; CHECK-LABEL: test_null_undef: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp16: +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp19: +; CHECK-NEXT: .Ltmp17: +; CHECK-NEXT: .LBB3_1: # %normal_return +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB3_2: # %exceptional_return +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp18: +; CHECK-NEXT: jmp .LBB3_1 gc "statepoint-example" personality ptr @"personality_function" { entry: %sp1 = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) @some_call, i32 1, i32 0, ptr addrspace(1) %val1, i32 0, i32 0) ["gc-live"(ptr addrspace(1) null, ptr addrspace(1) undef)] @@ -121,6 +231,26 @@ exceptional_return: } define ptr addrspace(1) @test_alloca_and_const(ptr addrspace(1) %val1) +; CHECK-LABEL: test_alloca_and_const: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp20: +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp23: +; CHECK-NEXT: .Ltmp21: +; CHECK-NEXT: # %bb.1: # %normal_return +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB4_2: # %exceptional_return +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp22: +; CHECK-NEXT: movl $15, %eax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq gc "statepoint-example" personality ptr @"personality_function" { entry: %a = alloca i32 diff --git a/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll b/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll index 180925d3235252c..2b921b11eb48b97 100644 --- a/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll +++ b/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll @@ -8,8 +8,29 @@ target triple = "x86_64-pc-linux-gnu" declare void @"some_call"(ptr addrspace(1)) declare i32 @"personality_function"() -; CHECK-LABEL: test_invoke: define ptr addrspace(1) @test_invoke(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e, ptr addrspace(1) %f, ptr addrspace(1) %g, ptr addrspace(1) %h, ptr addrspace(1) %j, ptr addrspace(1) %k, ptr addrspace(1) %l, ptr addrspace(1) %m, ptr addrspace(1) %n, ptr addrspace(1) %o, ptr addrspace(1) %p, ptr addrspace(1) %q, ptr addrspace(1) %r, ptr addrspace(1) %s, ptr addrspace(1) %t) +; CHECK-LABEL: test_invoke: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: movq %rdi, (%rsp) +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: # %bb.1: # %invoke_safepoint_normal_dest +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB0_2: # %exceptional_return +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .Ltmp2: +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq gc "statepoint-example" personality ptr @"personality_function" { entry: %0 = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) @some_call, i32 1, i32 0, ptr addrspace(1) %t, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %t)] @@ -25,8 +46,19 @@ exceptional_return: ret ptr addrspace(1) null } -; CHECK-LABEL: test_call: define ptr addrspace(1) @test_call(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e, ptr addrspace(1) %f, ptr addrspace(1) %g, ptr addrspace(1) %h, ptr addrspace(1) %j, ptr addrspace(1) %k, ptr addrspace(1) %l, ptr addrspace(1) %m, ptr addrspace(1) %n, ptr addrspace(1) %o, ptr addrspace(1) %p, ptr addrspace(1) %q, ptr addrspace(1) %r, ptr addrspace(1) %s, ptr addrspace(1) %t) +; CHECK-LABEL: test_call: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: movq %rdi, (%rsp) +; CHECK-NEXT: callq some_call@PLT +; CHECK-NEXT: .Ltmp4: +; CHECK-NEXT: movq (%rsp), %rax +; CHECK-NEXT: popq %rcx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq gc "statepoint-example" personality ptr @"personality_function" { entry: %0 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) @some_call, i32 1, i32 0, ptr addrspace(1) %t, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %t)]