llvm.org GIT mirror llvm / beb38b4
Merging r355136: ------------------------------------------------------------------------ r355136 | efriedma | 2019-02-28 21:38:45 +0100 (Thu, 28 Feb 2019) | 12 lines [AArch64] [Windows] Don't skip constructing UnwindHelp. In certain cases, the first non-frame-setup instruction in a function is a branch. For example, it could be a cbz on an argument. Make sure we correctly allocate the UnwindHelp, and find an appropriate register to use to initialize it. Fixes https://bugs.llvm.org/show_bug.cgi?id=40184 Differential Revision: https://reviews.llvm.org/D58752 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@355313 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 5 months ago
3 changed file(s) with 46 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
21072107 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
21082108 ++MBBI;
21092109
2110 if (MBBI->isTerminator())
2111 return;
2112
21132110 // Create an UnwindHelp object.
21142111 int UnwindHelpFI =
21152112 MFI.CreateStackObject(/*size*/8, /*alignment*/16, false);
21172114 // We need to store -2 into the UnwindHelp object at the start of the
21182115 // function.
21192116 DebugLoc DL;
2120 RS->enterBasicBlock(MBB);
2121 unsigned DstReg = RS->scavengeRegister(&AArch64::GPR64RegClass, MBBI, 0);
2117 RS->enterBasicBlockEnd(MBB);
2118 RS->backward(std::prev(MBBI));
2119 unsigned DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
2120 assert(DstReg && "There must be a free register after frame setup");
21222121 BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);
21232122 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi))
21242123 .addReg(DstReg, getKillRegState(true))
0 ; RUN: llc < %s | FileCheck %s
1
2 ; Make sure the prologue is sane. (Doesn't need to exactly match this,
3 ; but the original issue only reproduced if the cbz was immediately
4 ; after the frame setup.)
5
6 ; CHECK: sub sp, sp, #32
7 ; CHECK-NEXT: stp x29, x30, [sp, #16]
8 ; CHECK-NEXT: add x29, sp, #16
9 ; CHECK-NEXT: orr x1, xzr, #0xfffffffffffffffe
10 ; CHECK-NEXT: stur x1, [x29, #-16]
11 ; CHECK-NEXT: cbz w0, .LBB0_2
12
13 target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
14 target triple = "aarch64-unknown-windows-msvc19.11.0"
15
16 ; Function Attrs: uwtable
17 define dso_local void @"?f@@YAXH@Z"(i32 %x) local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
18 entry:
19 %cmp = icmp eq i32 %x, 0
20 br i1 %cmp, label %try.cont, label %if.then
21
22 if.then: ; preds = %entry
23 invoke void @"?g@@YAXXZ"()
24 to label %try.cont unwind label %catch.dispatch
25
26 catch.dispatch: ; preds = %if.then
27 %0 = catchswitch within none [label %catch] unwind to caller
28
29 catch: ; preds = %catch.dispatch
30 %1 = catchpad within %0 [i8* null, i32 64, i8* null]
31 catchret from %1 to label %try.cont
32
33 try.cont: ; preds = %entry, %if.then, %catch
34 ret void
35 }
36
37 declare dso_local void @"?g@@YAXXZ"() local_unnamed_addr #1
38
39 declare dso_local i32 @__CxxFrameHandler3(...)
2121 ; CHECK: add x29, sp, #32
2222 ; CHECK: sub sp, sp, #624
2323 ; CHECK: mov x19, sp
24 ; CHECK: orr x1, xzr, #0xfffffffffffffffe
25 ; CHECK: stur x1, [x19]
24 ; CHECK: orr x0, xzr, #0xfffffffffffffffe
25 ; CHECK: stur x0, [x19]
2626
2727 ; Now check that x is stored at fp - 20. We check that this is the same
2828 ; location accessed from the funclet to retrieve x.