From 53fbda20e98149dc991df87dbcea7dea8ece392f Mon Sep 17 00:00:00 2001 From: Joseph Tremoulet Date: Fri, 23 Oct 2015 15:06:05 +0000 Subject: [PATCH] [CodeGen] Mark setjmp/catchret MBBs address-taken Summary: This ensures that BranchFolding (and similar) won't remove these blocks. Also allow AsmPrinter::EmitBasicBlockStart to process MBBs which are address-taken but do not have BBs that are address-taken, since otherwise its call to getAddrLabelSymbolTableToEmit would fail an assertion on such blocks. I audited the other callers of getAddrLabelSymbolTableToEmit (and getAddrLabelSymbol); they all have BBs known to be address-taken except for the call through getAddrLabelSymbol from WinException::create32bitRef; that call is actually now unreachable, so I've removed it and updated the signature of create32bitRef. This fixes PR25168. Reviewers: majnemer, andrew.w.kaylor, rnk Subscribers: pgavlin, llvm-commits Differential Revision: http://reviews.llvm.org/D13774 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251113 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 7 +++- lib/CodeGen/AsmPrinter/WinException.cpp | 8 ++-- lib/CodeGen/AsmPrinter/WinException.h | 3 +- lib/Target/X86/X86FrameLowering.cpp | 3 ++ lib/Target/X86/X86ISelLowering.cpp | 3 +- test/CodeGen/X86/late-address-taken.ll | 68 +++++++++++++++++++++++++++++++++ test/CodeGen/X86/win-catchpad-csrs.ll | 9 +++-- test/CodeGen/X86/win-catchpad-nested.ll | 6 ++- test/CodeGen/X86/win-catchpad.ll | 15 +++++--- 9 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 test/CodeGen/X86/late-address-taken.ll diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 52dbd5a9df4..f073118fd00 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2480,8 +2480,11 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { 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. diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp index 58103836a09..3999268b407 100644 --- a/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -273,12 +273,10 @@ const MCExpr *WinException::create32bitRef(const MCSymbol *Value) { 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) { diff --git a/lib/CodeGen/AsmPrinter/WinException.h b/lib/CodeGen/AsmPrinter/WinException.h index e553c3ff736..02134d6aa98 100644 --- a/lib/CodeGen/AsmPrinter/WinException.h +++ b/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 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { 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, diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index a1a18fe6bd2..95cb76094ec 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1178,6 +1178,9 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, .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()) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 0de6acd5879..0d0e4823c38 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -21471,7 +21471,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI, // For v = setjmp(buf), we generate // // thisMBB: - // buf[LabelOffset] = restoreMBB + // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB // SjLjSetup restoreMBB // // mainMBB: @@ -21491,6 +21491,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI, MF->insert(I, mainMBB); MF->insert(I, sinkMBB); MF->push_back(restoreMBB); + restoreMBB->setHasAddressTaken(); MachineInstrBuilder MIB; diff --git a/test/CodeGen/X86/late-address-taken.ll b/test/CodeGen/X86/late-address-taken.ll new file mode 100644 index 00000000000..7d4dde80bbd --- /dev/null +++ b/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 diff --git a/test/CodeGen/X86/win-catchpad-csrs.ll b/test/CodeGen/X86/win-catchpad-csrs.ll index 32031e2787e..616253e2701 100644 --- a/test/CodeGen/X86/win-catchpad-csrs.ll +++ b/test/CodeGen/X86/win-catchpad-csrs.ll @@ -113,7 +113,8 @@ catchendblock: ; preds = %catch, ; 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 @@ -188,7 +189,8 @@ catchendblock: ; preds = %catch, ; X64: callq useints ; X64: movl $1, %ecx ; X64: callq f -; X64: [[contbb:\.LBB1_[0-9]+]]: # %try.cont +; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken +; X64-NEXT: # %try.cont ; X64: addq $40, %rsp ; X64-NOT: popq ; X64: popq %rsi @@ -249,7 +251,8 @@ catchendblock: ; preds = %catch, ; X64: .seh_endprologue ; X64: movl $1, %ecx ; X64: callq f -; X64: [[contbb:\.LBB2_[0-9]+]]: # %try.cont +; X64: [[contbb:\.LBB2_[0-9]+]]: # Block address taken +; X64-NEXT: # %try.cont ; X64: addq $48, %rsp ; X64-NOT: popq ; X64: popq %rbp diff --git a/test/CodeGen/X86/win-catchpad-nested.ll b/test/CodeGen/X86/win-catchpad-nested.ll index d803aaeb65d..25adfdf8c80 100644 --- a/test/CodeGen/X86/win-catchpad-nested.ll +++ b/test/CodeGen/X86/win-catchpad-nested.ll @@ -31,8 +31,10 @@ exit: ; Check the catchret targets ; CHECK-LABEL: test1: # @test1 -; CHECK: [[Exit:^[^: ]+]]: # %exit -; CHECK: [[OuterRet:^[^: ]+]]: # %outer.ret +; CHECK: [[Exit:^[^: ]+]]: # Block address taken +; CHECK-NEXT: # %exit +; CHECK: [[OuterRet:^[^: ]+]]: # Block address taken +; CHECK-NEXT: # %outer.ret ; CHECK-NEXT: leaq [[Exit]](%rip), %rax ; CHECK: retq # CATCHRET ; CHECK: {{^[^: ]+}}: # %inner.pad diff --git a/test/CodeGen/X86/win-catchpad.ll b/test/CodeGen/X86/win-catchpad.ll index 7761839b7a8..9078366d170 100644 --- a/test/CodeGen/X86/win-catchpad.ll +++ b/test/CodeGen/X86/win-catchpad.ll @@ -74,13 +74,15 @@ catchendblock: ; preds = %catch, %catch.2, %c ; 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 @@ catchendblock: ; preds = %catch, %catch.2, %c ; 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 @@ catchendblock: ; 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 @@ catchendblock: ; 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 -- 2.11.0