[WinEH] Undo the effect of r249578 for 32-bit
authorReid Kleckner <rnk@google.com>
Wed, 7 Oct 2015 21:13:15 +0000 (21:13 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 7 Oct 2015 21:13:15 +0000 (21:13 +0000)
The __CxxFrameHandler3 tables for 32-bit are supposed to hold stack
offsets relative to EBP, not ESP. I blindly updated the win-catchpad.ll
test case, and immediately noticed that 32-bit catching stopped working.

While I'm at it, move the frame index to frame offset WinEH table logic
out of PEI.  PEI shouldn't have to know about WinEHFuncInfo. I realized
we can calculate frame index offsets just fine from the table printer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249618 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/WinEHFuncInfo.h
lib/CodeGen/AsmPrinter/WinException.cpp
lib/CodeGen/AsmPrinter/WinException.h
lib/CodeGen/PrologEpilogInserter.cpp
test/CodeGen/X86/win-catchpad.ll

index 11591a85d28525a02d8e4f1b16f64edcfb645303..773931ff7cd5bfb09463dae425f821b84097c907 100644 (file)
@@ -147,7 +147,6 @@ struct WinEHHandlerType {
   /// index, and after PEI, becomes a raw offset.
   union {
     const AllocaInst *Alloca;
-    int FrameOffset;
     int FrameIndex;
   } CatchObj = {};
   GlobalVariable *TypeDescriptor;
@@ -180,7 +179,6 @@ struct WinEHFuncInfo {
   SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap;
   SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap;
   int UnwindHelpFrameIdx = INT_MAX;
-  int UnwindHelpFrameOffset = -1;
 
   int getLastStateNumber() const { return UnwindMap.size() - 1; }
 
index bc2c9ee635cfb7a56c415c7f41e1a74402f9ca85..f672f93a3ee4f4f46787855697b5a00d81aa36c7 100644 (file)
@@ -38,6 +38,7 @@
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
 using namespace llvm;
 
 WinException::WinException(AsmPrinter *A) : EHStreamer(A) {
@@ -292,6 +293,14 @@ const MCExpr *WinException::getLabelPlusOne(MCSymbol *Label) {
                                  Asm->OutContext);
 }
 
+int WinException::getFrameIndexOffset(int FrameIndex) {
+  const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
+  unsigned UnusedReg;
+  if (Asm->MAI->usesWindowsCFI())
+    return TFI.getFrameIndexReferenceFromSP(*Asm->MF, FrameIndex, UnusedReg);
+  return TFI.getFrameIndexReference(*Asm->MF, FrameIndex, UnusedReg);
+}
+
 namespace {
 /// Information describing an invoke range.
 struct InvokeRange {
@@ -599,6 +608,10 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
     emitEHRegistrationOffsetLabel(FuncInfo, FuncLinkageName);
   }
 
+  int UnwindHelpOffset = 0;
+  if (Asm->MAI->usesWindowsCFI())
+    UnwindHelpOffset = getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx);
+
   MCSymbol *UnwindMapXData = nullptr;
   MCSymbol *TryBlockMapXData = nullptr;
   MCSymbol *IPToStateXData = nullptr;
@@ -637,7 +650,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
   OS.EmitIntValue(IPToStateTable.size(), 4);           // IPMapEntries
   OS.EmitValue(create32bitRef(IPToStateXData), 4);     // IPToStateMap
   if (Asm->MAI->usesWindowsCFI())
-    OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp
+    OS.EmitIntValue(UnwindHelpOffset, 4);              // UnwindHelp
   OS.EmitIntValue(0, 4);                               // ESTypeList
   OS.EmitIntValue(1, 4);                               // EHFlags
 
@@ -714,8 +727,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
                   FuncLinkageName, HT.CatchObjRecoverIdx);
           FrameAllocOffsetRef = MCSymbolRefExpr::create(
               FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
-        } else if (HT.CatchObj.FrameOffset != INT_MAX) {
-          int Offset = HT.CatchObj.FrameOffset;
+        } else if (HT.CatchObj.FrameIndex != INT_MAX) {
+          int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex);
           // For 32-bit, the catch object offset is relative to the end of the
           // EH registration node. For 64-bit, it's relative to SP at the end of
           // the prologue.
index bf1724f60f7ab1d5933650e692b5968be4b13453..5c853349d2e17b921886e867f0a711d4a7cd2abb 100644 (file)
@@ -63,6 +63,12 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
   const MCExpr *create32bitRef(const Value *V);
   const MCExpr *getLabelPlusOne(MCSymbol *Label);
 
+  /// Gets the offset that we should use in a table for a stack object with the
+  /// given index. For targets using CFI (Win64, etc), this is relative to the
+  /// established SP at the end of the prologue. For targets without CFI (Win32
+  /// only), it is relative to the frame pointer.
+  int getFrameIndexOffset(int FrameIndex);
+
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
index 495da5c07d11e91ee05ba9609fdf19d6c93ca0cd..fab56bcfe85c9f81c06984c50cf3ffff46c753b7 100644 (file)
@@ -807,28 +807,6 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
   const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
   if (!TFI.needsFrameIndexResolution(Fn)) return;
 
-  MachineModuleInfo &MMI = Fn.getMMI();
-  const Function *F = Fn.getFunction();
-  const Function *ParentF = MMI.getWinEHParent(F);
-  unsigned FrameReg;
-  if (F == ParentF) {
-    WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn.getFunction());
-    // FIXME: This should be unconditional but we have bugs in the preparation
-    // pass.
-    if (FuncInfo.UnwindHelpFrameIdx != INT_MAX)
-      FuncInfo.UnwindHelpFrameOffset = TFI.getFrameIndexReferenceFromSP(
-          Fn, FuncInfo.UnwindHelpFrameIdx, FrameReg);
-    for (WinEHTryBlockMapEntry &TBME : FuncInfo.TryBlockMap) {
-      for (WinEHHandlerType &H : TBME.HandlerArray) {
-        if (H.CatchObj.FrameIndex == INT_MAX)
-          H.CatchObj.FrameOffset = INT_MAX;
-        else
-          H.CatchObj.FrameOffset = TFI.getFrameIndexReferenceFromSP(
-              Fn, H.CatchObj.FrameIndex, FrameReg);
-      }
-    }
-  }
-
   // Store SPAdj at exit of a basic block.
   SmallVector<int, 8> SPState;
   SPState.resize(Fn.getNumBlockIDs());
index 67875f2306033530408b4a9986fcd1c8846b90c5..78a8fcfc8f4bcab16ed397f9de6a779f5fcaac28 100644 (file)
@@ -120,7 +120,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X86: $handlerMap$0$try_catch_catch:
 ; X86-NEXT:   .long   0
 ; X86-NEXT:   .long   "??_R0H@8"
-; X86-NEXT:   .long   24
+; X86-NEXT:   .long   -20
 ; X86-NEXT:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"
 ; X86-NEXT:   .long   64
 ; X86-NEXT:   .long   0