Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2480,8 +2480,11 @@ if (isVerbose()) OutStreamer->AddComment("Block address taken"); - for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB)) - OutStreamer->EmitLabel(Sym); + // MBBs can have their address taken as part of CodeGen without having + // their corresponding BB's address taken in IR + if (BB->hasAddressTaken()) + for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB)) + OutStreamer->EmitLabel(Sym); } // Print some verbose block comments. Index: lib/CodeGen/AsmPrinter/WinException.h =================================================================== --- lib/CodeGen/AsmPrinter/WinException.h +++ lib/CodeGen/AsmPrinter/WinException.h @@ -18,6 +18,7 @@ namespace llvm { class Function; +class GlobalValue; class MachineFunction; class MCExpr; class Value; @@ -66,7 +67,7 @@ StringRef FLinkageName); const MCExpr *create32bitRef(const MCSymbol *Value); - const MCExpr *create32bitRef(const Value *V); + const MCExpr *create32bitRef(const GlobalValue *GV); const MCExpr *getLabelPlusOne(const MCSymbol *Label); const MCExpr *getOffset(const MCSymbol *OffsetOf, const MCSymbol *OffsetFrom); const MCExpr *getOffsetPlusOne(const MCSymbol *OffsetOf, Index: lib/CodeGen/AsmPrinter/WinException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/WinException.cpp +++ lib/CodeGen/AsmPrinter/WinException.cpp @@ -273,12 +273,10 @@ Asm->OutContext); } -const MCExpr *WinException::create32bitRef(const Value *V) { - if (!V) +const MCExpr *WinException::create32bitRef(const GlobalValue *GV) { + if (!GV) return MCConstantExpr::create(0, Asm->OutContext); - if (const auto *GV = dyn_cast(V)) - return create32bitRef(Asm->getSymbol(GV)); - return create32bitRef(MMI->getAddrLabelSymbol(cast(V))); + return create32bitRef(Asm->getSymbol(GV)); } const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) { Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== --- lib/Target/X86/X86FrameLowering.cpp +++ lib/Target/X86/X86FrameLowering.cpp @@ -1178,6 +1178,9 @@ .addReg(ReturnReg) .addMBB(RestoreMBB); } + // Record that we've taken the address of RestoreMBB and no longer just + // reference it in a terminator. + RestoreMBB->setHasAddressTaken(); } if (MBBI != MBB.end()) Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -21470,7 +21470,7 @@ // For v = setjmp(buf), we generate // // thisMBB: - // buf[LabelOffset] = restoreMBB + // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB // SjLjSetup restoreMBB // // mainMBB: @@ -21490,6 +21490,7 @@ MF->insert(I, mainMBB); MF->insert(I, sinkMBB); MF->push_back(restoreMBB); + restoreMBB->setHasAddressTaken(); MachineInstrBuilder MIB; Index: test/CodeGen/X86/late-address-taken.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/late-address-taken.ll @@ -0,0 +1,68 @@ +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s + +; Repro cases from PR25168 + +; test @catchret - catchret target is not address-taken until PEI +; splits it into lea/mov followed by ret. Make sure the MBB is +; handled, both by tempting BranchFolding to merge it with %early_out +; and delete it, and by checking that we emit a proper reference +; to it in the LEA + +declare void @ProcessCLRException() +declare void @f() + +define void @catchret(i1 %b) personality void ()* @ProcessCLRException { +entry: + br i1 %b, label %body, label %early_out +early_out: + ret void +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 +catch.body: + catchret %catch to label %exit +catch.end: + catchendpad unwind to caller +exit: + ret void +} +; CHECK-LABEL: catchret: # @catchret +; CHECK: [[Exit:^[^ :]+]]: # Block address taken +; CHECK-NEXT: # %exit +; CHECK: # %catch.pad +; CHECK: .seh_endprolog +; CHECK: leaq [[Exit]](%rip), %rax +; CHECK: retq # CATCHRET + + +; test @setjmp - similar to @catchret, but the MBB in question +; is the one generated when the setjmp's block is split + +@buf = internal global [5 x i8*] zeroinitializer +declare i8* @llvm.frameaddress(i32) nounwind readnone +declare i8* @llvm.stacksave() nounwind +declare i32 @llvm.eh.sjlj.setjmp(i8*) nounwind +declare void @llvm.eh.sjlj.longjmp(i8*) nounwind + +define void @setjmp(i1 %b) nounwind { +entry: + br i1 %b, label %early_out, label %sj +early_out: + ret void +sj: + %fp = call i8* @llvm.frameaddress(i32 0) + store i8* %fp, i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @buf, i64 0, i64 0), align 16 + %sp = call i8* @llvm.stacksave() + store i8* %sp, i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @buf, i64 0, i64 2), align 16 + call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*)) + ret void +} +; CHECK-LABEL: setjmp: # @setjmp +; CHECK: # %sj +; CHECK: leaq [[Label:\..+]](%rip), %[[Reg:.+]]{{$}} +; CHECK-NEXT: movq %[[Reg]], buf +; CHECK: {{^}}[[Label]]: # Block address taken +; CHECK-NEXT: # %sj Index: test/CodeGen/X86/win-catchpad-csrs.ll =================================================================== --- test/CodeGen/X86/win-catchpad-csrs.ll +++ test/CodeGen/X86/win-catchpad-csrs.ll @@ -113,7 +113,8 @@ ; X64: callq useints ; X64: movl $1, %ecx ; X64: callq f -; X64: [[contbb:\.LBB0_[0-9]+]]: # %try.cont +; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken +; X64-NEXT: # %try.cont ; X64: addq $40, %rsp ; X64: popq %rbp ; X64: retq Index: test/CodeGen/X86/win-catchpad.ll =================================================================== --- test/CodeGen/X86/win-catchpad.ll +++ test/CodeGen/X86/win-catchpad.ll @@ -74,13 +74,15 @@ ; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont ; X86: retl -; X86: [[restorebb1:LBB0_[0-9]+]]: # %invoke.cont.2 +; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken +; X86-NEXT: # %invoke.cont.2 ; X86: movl -16(%ebp), %esp ; X86: addl $12, %ebp ; X86: jmp [[contbb]] ; FIXME: These should be de-duplicated. -; X86: [[restorebb2:LBB0_[0-9]+]]: # %invoke.cont.3 +; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken +; X86-NEXT: # %invoke.cont.3 ; X86: movl -16(%ebp), %esp ; X86: addl $12, %ebp ; X86: jmp [[contbb]] @@ -140,7 +142,8 @@ ; X64-DAG: leaq -[[local_offs:[0-9]+]](%rbp), %rdx ; X64-DAG: movl $1, %ecx ; X64: callq f -; X64: [[contbb:\.LBB0_[0-9]+]]: # %try.cont +; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken +; X64-NEXT: # %try.cont ; X64: addq $48, %rsp ; X64: popq %rbp ; X64: retq @@ -253,7 +256,8 @@ ; X86: [[contbb:LBB1_[0-9]+]]: # %try.cont ; X86: retl -; X86: [[restorebb:LBB1_[0-9]+]]: # %catch.done +; X86: [[restorebb:LBB1_[0-9]+]]: # Block address taken +; X86-NEXT: # %catch.done ; X86: movl -16(%ebp), %esp ; X86: addl $12, %ebp ; X86: jmp [[contbb]] @@ -294,7 +298,8 @@ ; X64: .Ltmp[[before_call:[0-9]+]]: ; X64: callq f ; X64: .Ltmp[[after_call:[0-9]+]]: -; X64: [[contbb:\.LBB1_[0-9]+]]: # %try.cont +; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken +; X64-NEXT: # %try.cont ; X64: addq $48, %rsp ; X64: popq %rbp ; X64: retq