Skip to content

Commit 5d9247f

Browse files
author
git apple-llvm automerger
committed
Merge commit 'f5d575722570' from swift/release/5.5 into swift/main
2 parents 2ed88e2 + f5d5757 commit 5d9247f

File tree

6 files changed

+83
-16
lines changed

6 files changed

+83
-16
lines changed

llvm/lib/CodeGen/SjLjEHPrepare.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,12 @@ bool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) {
472472

473473
// Finally, for any returns from this function, if this function contains an
474474
// invoke, add a call to unregister the function context.
475-
for (ReturnInst *Return : Returns)
476-
CallInst::Create(UnregisterFn, FuncCtx, "", Return);
475+
for (ReturnInst *Return : Returns) {
476+
Instruction *InsertPoint = Return;
477+
if (CallInst *CI = Return->getParent()->getTerminatingMustTailCall())
478+
InsertPoint = CI;
479+
CallInst::Create(UnregisterFn, FuncCtx, "", InsertPoint);
480+
}
477481

478482
return true;
479483
}

llvm/lib/Support/OptimizedStructLayout.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ llvm::performOptimizedStructLayout(MutableArrayRef<Field> Fields) {
350350
Optional<uint64_t> EndOffset) -> bool {
351351
assert(Queue->Head);
352352
assert(StartOffset == alignTo(LastEnd, Queue->Alignment));
353+
assert(!EndOffset || StartOffset < *EndOffset);
353354

354355
// Figure out the maximum size that a field can be, and ignore this
355356
// queue if there's nothing in it that small.
@@ -372,6 +373,7 @@ llvm::performOptimizedStructLayout(MutableArrayRef<Field> Fields) {
372373
// Helper function to find the "best" flexible-offset field according
373374
// to the criteria described above.
374375
auto tryAddBestField = [&](Optional<uint64_t> BeforeOffset) -> bool {
376+
assert(!BeforeOffset || LastEnd < *BeforeOffset);
375377
auto QueueB = FlexibleFieldsByAlignment.begin();
376378
auto QueueE = FlexibleFieldsByAlignment.end();
377379

@@ -403,9 +405,12 @@ llvm::performOptimizedStructLayout(MutableArrayRef<Field> Fields) {
403405
return false;
404406

405407
// Otherwise, scan backwards to find the most-aligned queue that
406-
// still has minimal leading padding after LastEnd.
408+
// still has minimal leading padding after LastEnd. If that
409+
// minimal padding is already at or past the end point, we're done.
407410
--FirstQueueToSearch;
408411
Offset = alignTo(LastEnd, FirstQueueToSearch->Alignment);
412+
if (BeforeOffset && Offset >= *BeforeOffset)
413+
return false;
409414
while (FirstQueueToSearch != QueueB &&
410415
Offset == alignTo(LastEnd, FirstQueueToSearch[-1].Alignment))
411416
--FirstQueueToSearch;
@@ -415,6 +420,7 @@ llvm::performOptimizedStructLayout(MutableArrayRef<Field> Fields) {
415420
// Phase 1: fill the gaps between fixed-offset fields with the best
416421
// flexible-offset field that fits.
417422
for (auto I = Fields.begin(); I != FirstFlexible; ++I) {
423+
assert(LastEnd <= I->Offset);
418424
while (LastEnd != I->Offset) {
419425
if (!tryAddBestField(I->Offset))
420426
break;

llvm/lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,19 +1134,16 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
11341134
// The aligned reloads from area DPRCS2 are not inserted here.
11351135
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
11361136
continue;
1137-
11381137
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
1139-
!isCmseEntry && !isTrap && STI.hasV5TOps()) {
1140-
if (MBB.succ_empty()) {
1141-
Reg = ARM::PC;
1142-
// Fold the return instruction into the LDM.
1143-
DeleteRet = true;
1144-
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
1145-
// We 'restore' LR into PC so it is not live out of the return block:
1146-
// Clear Restored bit.
1147-
Info.setRestored(false);
1148-
} else
1149-
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
1138+
!isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 &&
1139+
STI.hasV5TOps() && MBB.succ_empty()) {
1140+
Reg = ARM::PC;
1141+
// Fold the return instruction into the LDM.
1142+
DeleteRet = true;
1143+
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
1144+
// We 'restore' LR into PC so it is not live out of the return block:
1145+
// Clear Restored bit.
1146+
Info.setRestored(false);
11501147
}
11511148

11521149
// If NoGap is true, pop consecutive registers and then leave the rest

llvm/test/CodeGen/ARM/tailcc-call.ll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,15 @@ define tailcc void @fromtail_toC() {
191191
call void @Ccallee_stack4([4 x i32] undef, i32 42)
192192
ret void
193193
}
194+
195+
; Don't try to return by popping pc if there's stack to reclaim.
196+
define tailcc void @notail_stackclean([4 x i32], i32) {
197+
; COMMON-LABEL: notail_stackclean:
198+
; COMMON: pop {r7, lr}
199+
; COMMON: add sp, #8
200+
; COMMON: bx lr
201+
202+
203+
call void @callee_stack0()
204+
ret void
205+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39439.
2+
; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -filetype asm -o - %s -verify-machineinstrs=0 | FileCheck %s
3+
4+
declare void @_Z20function_that_throwsv()
5+
declare i32 @__gxx_personality_sj0(...)
6+
declare i8* @__cxa_begin_catch(i8*)
7+
declare void @__cxa_end_catch()
8+
declare void @_callee();
9+
10+
define void @_Z8functionv() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
11+
entry:
12+
invoke void @_Z20function_that_throwsv()
13+
to label %try.cont unwind label %lpad
14+
15+
lpad:
16+
%0 = landingpad { i8*, i32 }
17+
catch i8* null
18+
%1 = extractvalue { i8*, i32 } %0, 0
19+
%2 = tail call i8* @__cxa_begin_catch(i8* %1)
20+
tail call void @__cxa_end_catch()
21+
br label %try.cont
22+
23+
try.cont:
24+
musttail call void @_callee();
25+
ret void
26+
}
27+
28+
; CHECK-LABEL: __Z8functionv:
29+
; CHECK: calll __Unwind_SjLj_Unregister
30+
; CHECK-NOT: {{.*}}:
31+
; CHECK: jmp __callee

llvm/unittests/Support/OptimizedStructLayoutTest.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,21 @@ TEST(OptimizedStructLayoutTest, GardenPath) {
129129
.flexible(2, 2, 42)
130130
.flexible(2, 2, 48)
131131
.verify(50, 4);
132-
}
132+
}
133+
134+
// PR 51131
135+
TEST(OptimizedStructLayoutTest, HighAlignment) {
136+
// Handle the case where a flexible field has such a high alignment
137+
// requirement that aligning LastEnd to it gives an offset past the
138+
// end of the gap before the next fixed-alignment field.
139+
LayoutTest()
140+
.fixed(8, 8, 0)
141+
.fixed(8, 8, 8)
142+
.fixed(64, 64, 64)
143+
.flexible(1, 1, 16)
144+
.flexible(1, 1, 17)
145+
.flexible(4, 128, 128)
146+
.flexible(1, 1, 18)
147+
.flexible(1, 1, 19)
148+
.verify(132, 128);
149+
}

0 commit comments

Comments
 (0)