[CodeGen] Mark setjmp/catchret MBBs address-taken
authorJoseph Tremoulet <jotrem@microsoft.com>
Fri, 23 Oct 2015 15:06:05 +0000 (15:06 +0000)
committerJoseph Tremoulet <jotrem@microsoft.com>
Fri, 23 Oct 2015 15:06:05 +0000 (15:06 +0000)
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

llvm-svn: 251113

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/AsmPrinter/WinException.cpp
llvm/lib/CodeGen/AsmPrinter/WinException.h
llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/late-address-taken.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/win-catchpad-csrs.ll
llvm/test/CodeGen/X86/win-catchpad-nested.ll
llvm/test/CodeGen/X86/win-catchpad.ll

index 52dbd5a..f073118 100644 (file)
@@ -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.
index 5810383..3999268 100644 (file)
@@ -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<GlobalValue>(V))
-    return create32bitRef(Asm->getSymbol(GV));
-  return create32bitRef(MMI->getAddrLabelSymbol(cast<BasicBlock>(V)));
+  return create32bitRef(Asm->getSymbol(GV));
 }
 
 const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {
index e553c3f..02134d6 100644 (file)
@@ -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,
index a1a18fe..95cb760 100644 (file)
@@ -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())
index 0de6acd..0d0e482 100644 (file)
@@ -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/llvm/test/CodeGen/X86/late-address-taken.ll b/llvm/test/CodeGen/X86/late-address-taken.ll
new file mode 100644 (file)
index 0000000..7d4dde8
--- /dev/null
@@ -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 32031e2..616253e 100644 (file)
@@ -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
index d803aae..25adfdf 100644 (file)
@@ -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
index 7761839..9078366 100644 (file)
@@ -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