mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
[WinEH] Update WinEHFuncInfo if StackColoring merges allocas
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
This commit is contained in:
parent
7203e500c0
commit
204e31b7ab
@ -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");
|
||||
|
@ -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);
|
||||
|
53
test/CodeGen/X86/catchpad-lifetime.ll
Normal file
53
test/CodeGen/X86/catchpad-lifetime.ll
Normal file
@ -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 }
|
Loading…
Reference in New Issue
Block a user