[WinEH] Update WinEHFuncInfo if StackColoring merges allocas
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 08:03:55 +0000 (08:03 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 08:03:55 +0000 (08:03 +0000)
Windows EH keeping track of which frame index corresponds to a catchpad
in order to inform the runtime where the catch parameter should be
initialized.  LLVM's optimizations are able to prove that the memory
used by the catch parameter can be reused with another memory
optimization, changing it's frame index.

We need to keep WinEHFuncInfo up to date with respect to this or we will
miscompile/assert.

This fixes PR26069.

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

lib/CodeGen/StackColoring.cpp
lib/CodeGen/WinEHPrepare.cpp
test/CodeGen/X86/catchpad-lifetime.ll [new file with mode: 0644]

index 3541b33a8441f42a6c52b7124faf64477a67631d..d0c0cf777028be7b91b37d24d6e67e6474981e8c 100644 (file)
@@ -43,6 +43,7 @@
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/StackProtector.h"
+#include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
@@ -570,6 +571,12 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
       }
     }
 
+  if (WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo())
+    for (WinEHTryBlockMapEntry &TBME : EHInfo->TryBlockMap)
+      for (WinEHHandlerType &H : TBME.HandlerArray)
+        if (SlotRemap.count(H.CatchObj.FrameIndex))
+          H.CatchObj.FrameIndex = SlotRemap[H.CatchObj.FrameIndex];
+
   DEBUG(dbgs()<<"Fixed "<<FixedMemOp<<" machine memory operands.\n");
   DEBUG(dbgs()<<"Fixed "<<FixedDbg<<" debug locations.\n");
   DEBUG(dbgs()<<"Fixed "<<FixedInstr<<" machine instructions.\n");
index f112b1bb3b973812658da3700288d15bacb012b7..886c5f6070c118eec1b62e83cc7795d9fbd17043 100644 (file)
@@ -144,10 +144,11 @@ static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
       HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
     HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
     HT.Handler = CPI->getParent();
-    if (isa<ConstantPointerNull>(CPI->getArgOperand(2)))
-      HT.CatchObj.Alloca = nullptr;
+    if (auto *AI =
+            dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
+      HT.CatchObj.Alloca = AI;
     else
-      HT.CatchObj.Alloca = cast<AllocaInst>(CPI->getArgOperand(2));
+      HT.CatchObj.Alloca = nullptr;
     TBME.HandlerArray.push_back(HT);
   }
   FuncInfo.TryBlockMap.push_back(TBME);
diff --git a/test/CodeGen/X86/catchpad-lifetime.ll b/test/CodeGen/X86/catchpad-lifetime.ll
new file mode 100644 (file)
index 0000000..38fc981
--- /dev/null
@@ -0,0 +1,53 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "x86_64-pc-windows-msvc"
+
+declare void @throw()
+
+declare i32 @__CxxFrameHandler3(...)
+
+define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  %alloca2 = alloca i8*, align 4
+  %alloca1 = alloca i8*, align 4
+  store volatile i8* null, i8** %alloca1
+  invoke void @throw()
+          to label %unreachable unwind label %catch.dispatch
+
+; CHECK-LABEL: test1:
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: callq throw
+
+catch.dispatch:                                   ; preds = %entry
+  %cs = catchswitch within none [label %catch.pad] unwind to caller
+
+catch.pad:                                        ; preds = %catch.dispatch
+  %cp = catchpad within %cs [i8* null, i32 0, i8** %alloca1]
+  store volatile i8* null, i8** %alloca1
+  %bc1 = bitcast i8** %alloca1 to i8*
+  call void @llvm.lifetime.end(i64 4, i8* nonnull %bc1)
+  %bc2 = bitcast i8** %alloca2 to i8*
+  call void @llvm.lifetime.start(i64 4, i8* %bc2)
+  store volatile i8* null, i8** %alloca1
+  unreachable
+
+; CHECK-LABEL: "?catch$2@?0?test1@4HA"
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: ud2
+
+unreachable:                                      ; preds = %entry
+  unreachable
+}
+
+; CHECK-LABEL: $cppxdata$test1:
+; CHECK: .long   32                      # CatchObjOffset
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start(i64, i8* nocapture) #0
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture) #0
+
+attributes #0 = { argmemonly nounwind }