Skip to content

Commit 613a2a1

Browse files
authored
[AArch64][PAC] Protect the entire function if pac-ret+leaf is requested (#140895)
Normally, pac-ret hardening is emitted as part of function prologues and epilogues, thus it is affected by the shrink-wrapping optimization. As protecting LR when it is spilled to the stack is already handled by regular -mbranch-protection=pac-ret option, it is reasonable to assume that pac-ret+leaf option means the user wants to apply pac-ret hardening to as much code as possible. For that reason, if pac-ret+leaf hardening mode is requested, this patch moves the emission of PAUTH_PROLOGUE (or PAUTH_EPILOGUE) pseudos from emitPrologue (emitEpilogue) methods of the AArch64FrameLowering class to processFunctionBeforeFrameIndicesReplaced. This change does not currently affect targets that emit WinCFI unwind information. This commit only affects where LR is signed and authenticated, but does not otherwise prevents the shrink-wrapping optimization. Moreover, without "+leaf" modifier PAUTH_(PROLOGUE|EPILOGUE) pseudos respect the shrink-wrapping optimization just as any other prologue/epilogue code.
1 parent e7c9f29 commit 613a2a1

File tree

6 files changed

+201
-26
lines changed

6 files changed

+201
-26
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,16 @@ static bool needsWinCFI(const MachineFunction &MF) {
11821182
F.needsUnwindTableEntry();
11831183
}
11841184

1185+
static bool shouldSignReturnAddressEverywhere(const MachineFunction &MF) {
1186+
// FIXME: With WinCFI, extra care should be taken to place SEH_PACSignLR
1187+
// and SEH_EpilogEnd instructions in the correct order.
1188+
if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())
1189+
return false;
1190+
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
1191+
bool SignReturnAddressAll = AFI->shouldSignReturnAddress(/*SpillsLR=*/false);
1192+
return SignReturnAddressAll;
1193+
}
1194+
11851195
bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
11861196
MachineFunction &MF, uint64_t StackBumpBytes) const {
11871197
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
@@ -1780,6 +1790,39 @@ static void getLivePhysRegsUpTo(MachineInstr &MI, const TargetRegisterInfo &TRI,
17801790
}
17811791
#endif
17821792

1793+
void AArch64FrameLowering::emitPacRetPlusLeafHardening(
1794+
MachineFunction &MF) const {
1795+
const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1796+
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1797+
1798+
auto EmitSignRA = [&](MachineBasicBlock &MBB) {
1799+
DebugLoc DL; // Set debug location to unknown.
1800+
MachineBasicBlock::iterator MBBI = MBB.begin();
1801+
1802+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1803+
.setMIFlag(MachineInstr::FrameSetup);
1804+
};
1805+
1806+
auto EmitAuthRA = [&](MachineBasicBlock &MBB) {
1807+
DebugLoc DL;
1808+
MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
1809+
if (MBBI != MBB.end())
1810+
DL = MBBI->getDebugLoc();
1811+
1812+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_EPILOGUE))
1813+
.setMIFlag(MachineInstr::FrameDestroy);
1814+
};
1815+
1816+
// This should be in sync with PEIImpl::calculateSaveRestoreBlocks.
1817+
EmitSignRA(MF.front());
1818+
for (MachineBasicBlock &MBB : MF) {
1819+
if (MBB.isEHFuncletEntry())
1820+
EmitSignRA(MBB);
1821+
if (MBB.isReturnBlock())
1822+
EmitAuthRA(MBB);
1823+
}
1824+
}
1825+
17831826
void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
17841827
MachineBasicBlock &MBB) const {
17851828
MachineBasicBlock::iterator MBBI = MBB.begin();
@@ -1849,17 +1892,21 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
18491892
DebugLoc DL;
18501893

18511894
const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
1852-
if (MFnI.needsShadowCallStackPrologueEpilogue(MF))
1853-
emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI,
1854-
MFnI.needsDwarfUnwindInfo(MF));
1855-
18561895
if (MFnI.shouldSignReturnAddress(MF)) {
1857-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1858-
.setMIFlag(MachineInstr::FrameSetup);
1896+
// If pac-ret+leaf is in effect, PAUTH_PROLOGUE pseudo instructions
1897+
// are inserted by emitPacRetPlusLeafHardening().
1898+
if (!shouldSignReturnAddressEverywhere(MF)) {
1899+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1900+
.setMIFlag(MachineInstr::FrameSetup);
1901+
}
18591902
if (NeedsWinCFI)
18601903
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
18611904
}
18621905

1906+
if (MFnI.needsShadowCallStackPrologueEpilogue(MF))
1907+
emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI,
1908+
MFnI.needsDwarfUnwindInfo(MF));
1909+
18631910
if (EmitCFI && MFnI.isMTETagged()) {
18641911
BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED))
18651912
.setMIFlag(MachineInstr::FrameSetup);
@@ -2413,17 +2460,21 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
24132460
MachineBasicBlock::iterator EpilogStartI = MBB.end();
24142461

24152462
auto FinishingTouches = make_scope_exit([&]() {
2416-
if (AFI->shouldSignReturnAddress(MF)) {
2417-
BuildMI(MBB, MBB.getFirstTerminator(), DL,
2418-
TII->get(AArch64::PAUTH_EPILOGUE))
2419-
.setMIFlag(MachineInstr::FrameDestroy);
2420-
if (NeedsWinCFI)
2421-
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
2422-
}
24232463
if (AFI->needsShadowCallStackPrologueEpilogue(MF))
24242464
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL);
24252465
if (EmitCFI)
24262466
emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator());
2467+
if (AFI->shouldSignReturnAddress(MF)) {
2468+
// If pac-ret+leaf is in effect, PAUTH_EPILOGUE pseudo instructions
2469+
// are inserted by emitPacRetPlusLeafHardening().
2470+
if (!shouldSignReturnAddressEverywhere(MF)) {
2471+
BuildMI(MBB, MBB.getFirstTerminator(), DL,
2472+
TII->get(AArch64::PAUTH_EPILOGUE))
2473+
.setMIFlag(MachineInstr::FrameDestroy);
2474+
}
2475+
if (NeedsWinCFI)
2476+
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
2477+
}
24272478
if (HasWinCFI) {
24282479
BuildMI(MBB, MBB.getFirstTerminator(), DL,
24292480
TII->get(AArch64::SEH_EpilogEnd))
@@ -5230,6 +5281,13 @@ void AArch64FrameLowering::processFunctionBeforeFrameIndicesReplaced(
52305281
else if (StackTaggingMergeSetTag)
52315282
II = tryMergeAdjacentSTG(II, this, RS);
52325283
}
5284+
5285+
// By the time this method is called, most of the prologue/epilogue code is
5286+
// already emitted, whether its location was affected by the shrink-wrapping
5287+
// optimization or not.
5288+
if (!MF.getFunction().hasFnAttribute(Attribute::Naked) &&
5289+
shouldSignReturnAddressEverywhere(MF))
5290+
emitPacRetPlusLeafHardening(MF);
52335291
}
52345292

52355293
/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ class AArch64FrameLowering : public TargetFrameLowering {
3636
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
3737
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
3838

39+
/// Harden the entire function with pac-ret.
40+
///
41+
/// If pac-ret+leaf is requested, we want to harden as much code as possible.
42+
/// This function inserts pac-ret hardening at the points where prologue and
43+
/// epilogue are traditionally inserted, ignoring possible shrink-wrapping
44+
/// optimization.
45+
void emitPacRetPlusLeafHardening(MachineFunction &MF) const;
46+
3947
bool enableCFIFixup(const MachineFunction &MF) const override;
4048

4149
bool enableFullCFIFixup(const MachineFunction &MF) const override;

llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,19 @@ define hidden noundef i32 @baz_async(i32 noundef %a) #0 uwtable(async) {
7474
; CHECK-V8A-NEXT: bl _Z3bari
7575
; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
7676
; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
77+
; CHECK-V8A-NEXT: .cfi_restore w30
7778
; CHECK-V8A-NEXT: hint #29
7879
; CHECK-V8A-NEXT: .cfi_negate_ra_state
79-
; CHECK-V8A-NEXT: .cfi_restore w30
8080
; CHECK-V8A-NEXT: b _Z3bari
8181
; CHECK-V8A-NEXT: .LBB1_2: // %if.else
8282
; CHECK-V8A-NEXT: .cfi_restore_state
8383
; CHECK-V8A-NEXT: bl _Z4quuxi
8484
; CHECK-V8A-NEXT: add w0, w0, #1
8585
; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
8686
; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
87+
; CHECK-V8A-NEXT: .cfi_restore w30
8788
; CHECK-V8A-NEXT: hint #29
8889
; CHECK-V8A-NEXT: .cfi_negate_ra_state
89-
; CHECK-V8A-NEXT: .cfi_restore w30
9090
; CHECK-V8A-NEXT: ret
9191
;
9292
; CHECK-V83A-LABEL: baz_async:
@@ -103,9 +103,9 @@ define hidden noundef i32 @baz_async(i32 noundef %a) #0 uwtable(async) {
103103
; CHECK-V83A-NEXT: bl _Z3bari
104104
; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
105105
; CHECK-V83A-NEXT: .cfi_def_cfa_offset 0
106+
; CHECK-V83A-NEXT: .cfi_restore w30
106107
; CHECK-V83A-NEXT: autiasp
107108
; CHECK-V83A-NEXT: .cfi_negate_ra_state
108-
; CHECK-V83A-NEXT: .cfi_restore w30
109109
; CHECK-V83A-NEXT: b _Z3bari
110110
; CHECK-V83A-NEXT: .LBB1_2: // %if.else
111111
; CHECK-V83A-NEXT: .cfi_restore_state

llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,40 +256,40 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re
256256
define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18" {
257257
; CHECK-LABEL: non_leaf_scs:
258258
; CHECK: // %bb.0:
259-
; CHECK-NEXT: str x30, [x18], #8
260-
; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
261259
; CHECK-NEXT: hint #39
262260
; CHECK-NEXT: .cfi_negate_ra_state_with_pc
263261
; CHECK-NEXT: .Ltmp4:
264262
; CHECK-NEXT: paciasp
263+
; CHECK-NEXT: str x30, [x18], #8
264+
; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
265265
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
266266
; CHECK-NEXT: .cfi_def_cfa_offset 16
267267
; CHECK-NEXT: .cfi_offset w30, -16
268268
; CHECK-NEXT: bl foo
269269
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
270+
; CHECK-NEXT: ldr x30, [x18, #-8]!
270271
; CHECK-NEXT: adrp x16, .Ltmp4
271272
; CHECK-NEXT: add x16, x16, :lo12:.Ltmp4
272273
; CHECK-NEXT: hint #39
273274
; CHECK-NEXT: autiasp
274-
; CHECK-NEXT: ldr x30, [x18, #-8]!
275275
; CHECK-NEXT: ret
276276
;
277277
; PAUTHLR-LABEL: non_leaf_scs:
278278
; PAUTHLR: // %bb.0:
279-
; PAUTHLR-NEXT: str x30, [x18], #8
280-
; PAUTHLR-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
281279
; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc
282280
; PAUTHLR-NEXT: .Ltmp4:
283281
; PAUTHLR-NEXT: paciasppc
282+
; PAUTHLR-NEXT: str x30, [x18], #8
283+
; PAUTHLR-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
284284
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
285285
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
286286
; PAUTHLR-NEXT: .cfi_offset w30, -16
287287
; PAUTHLR-NEXT: bl foo
288288
; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
289+
; PAUTHLR-NEXT: ldr x30, [x18, #-8]!
289290
; PAUTHLR-NEXT: adrp x16, .Ltmp4
290291
; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp4
291292
; PAUTHLR-NEXT: autiasppc .Ltmp4
292-
; PAUTHLR-NEXT: ldr x30, [x18, #-8]!
293293
; PAUTHLR-NEXT: ret
294294
%call = call i32 @foo(i32 %x)
295295
ret i32 %call

llvm/test/CodeGen/AArch64/sign-return-address-tailcall.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ define i32 @tailcall_two_branches(i1 %0) "sign-return-address"="all" {
156156
; COMMON: str x30, [sp, #-16]!
157157
; COMMON: bl callee2
158158
; COMMON: ldr x30, [sp], #16
159-
; COMMON-NEXT: [[AUTIASP]]
160159
; COMMON-NEXT: .[[ELSE]]:
160+
; COMMON-NEXT: [[AUTIASP]]
161161

162162
; LDR-NEXT: ldr w16, [x30]
163163
;

llvm/test/CodeGen/AArch64/sign-return-address.ll

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,22 +133,131 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
133133
define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18" {
134134
; CHECK-LABEL: non_leaf_scs:
135135
; CHECK: // %bb.0:
136-
; CHECK-NEXT: str x30, [x18], #8
137-
; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
138136
; CHECK-NEXT: paciasp
139137
; CHECK-NEXT: .cfi_negate_ra_state
138+
; CHECK-NEXT: str x30, [x18], #8
139+
; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
140140
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
141141
; CHECK-NEXT: .cfi_def_cfa_offset 16
142142
; CHECK-NEXT: .cfi_offset w30, -16
143143
; CHECK-NEXT: bl foo
144144
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
145-
; CHECK-NEXT: autiasp
146145
; CHECK-NEXT: ldr x30, [x18, #-8]!
146+
; CHECK-NEXT: autiasp
147147
; CHECK-NEXT: ret
148148
%call = call i32 @foo(i32 %x)
149149
ret i32 %call
150150
}
151151

152+
@var = dso_local global i64 0
153+
154+
; By default, pac-ret hardening respects shrink-wrapping optimization.
155+
define void @shrink_wrap_sign_non_leaf(i32 %x, i32 %cond) "sign-return-address"="non-leaf" uwtable(async) {
156+
; COMPAT-LABEL: shrink_wrap_sign_non_leaf:
157+
; COMPAT: // %bb.0: // %entry
158+
; COMPAT-NEXT: cbnz w1, .LBB8_2
159+
; COMPAT-NEXT: // %bb.1: // %if.then
160+
; COMPAT-NEXT: hint #25
161+
; COMPAT-NEXT: .cfi_negate_ra_state
162+
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
163+
; COMPAT-NEXT: .cfi_def_cfa_offset 16
164+
; COMPAT-NEXT: .cfi_offset w30, -16
165+
; COMPAT-NEXT: bl foo
166+
; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
167+
; COMPAT-NEXT: .cfi_def_cfa_offset 0
168+
; COMPAT-NEXT: .cfi_restore w30
169+
; COMPAT-NEXT: hint #29
170+
; COMPAT-NEXT: .cfi_negate_ra_state
171+
; COMPAT-NEXT: .LBB8_2: // %exit
172+
; COMPAT-NEXT: adrp x8, var
173+
; COMPAT-NEXT: mov w9, #42 // =0x2a
174+
; COMPAT-NEXT: str x9, [x8, :lo12:var]
175+
; COMPAT-NEXT: ret
176+
;
177+
; V83A-LABEL: shrink_wrap_sign_non_leaf:
178+
; V83A: // %bb.0: // %entry
179+
; V83A-NEXT: cbnz w1, .LBB8_2
180+
; V83A-NEXT: // %bb.1: // %if.then
181+
; V83A-NEXT: paciasp
182+
; V83A-NEXT: .cfi_negate_ra_state
183+
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
184+
; V83A-NEXT: .cfi_def_cfa_offset 16
185+
; V83A-NEXT: .cfi_offset w30, -16
186+
; V83A-NEXT: bl foo
187+
; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
188+
; V83A-NEXT: .cfi_def_cfa_offset 0
189+
; V83A-NEXT: .cfi_restore w30
190+
; V83A-NEXT: autiasp
191+
; V83A-NEXT: .cfi_negate_ra_state
192+
; V83A-NEXT: .LBB8_2: // %exit
193+
; V83A-NEXT: adrp x8, var
194+
; V83A-NEXT: mov w9, #42 // =0x2a
195+
; V83A-NEXT: str x9, [x8, :lo12:var]
196+
; V83A-NEXT: ret
197+
entry:
198+
%cond.bool = icmp eq i32 %cond, 0
199+
br i1 %cond.bool, label %if.then, label %exit
200+
if.then:
201+
%call = call i32 @foo(i32 %x)
202+
br label %exit
203+
exit:
204+
store i64 42, ptr @var
205+
ret void
206+
}
207+
208+
; When "+leaf" is specified to harden everything, pac-ret hardens the entire
209+
; function, ignoring shrink-wrapping.
210+
define void @shrink_wrap_sign_all(i32 %x, i32 %cond) "sign-return-address"="all" uwtable(async) {
211+
; COMPAT-LABEL: shrink_wrap_sign_all:
212+
; COMPAT: // %bb.0: // %entry
213+
; COMPAT-NEXT: hint #25
214+
; COMPAT-NEXT: .cfi_negate_ra_state
215+
; COMPAT-NEXT: cbnz w1, .LBB9_2
216+
; COMPAT-NEXT: // %bb.1: // %if.then
217+
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
218+
; COMPAT-NEXT: .cfi_def_cfa_offset 16
219+
; COMPAT-NEXT: .cfi_offset w30, -16
220+
; COMPAT-NEXT: bl foo
221+
; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
222+
; COMPAT-NEXT: .cfi_def_cfa_offset 0
223+
; COMPAT-NEXT: .cfi_restore w30
224+
; COMPAT-NEXT: .LBB9_2: // %exit
225+
; COMPAT-NEXT: adrp x8, var
226+
; COMPAT-NEXT: mov w9, #42 // =0x2a
227+
; COMPAT-NEXT: str x9, [x8, :lo12:var]
228+
; COMPAT-NEXT: hint #29
229+
; COMPAT-NEXT: .cfi_negate_ra_state
230+
; COMPAT-NEXT: ret
231+
;
232+
; V83A-LABEL: shrink_wrap_sign_all:
233+
; V83A: // %bb.0: // %entry
234+
; V83A-NEXT: paciasp
235+
; V83A-NEXT: .cfi_negate_ra_state
236+
; V83A-NEXT: cbnz w1, .LBB9_2
237+
; V83A-NEXT: // %bb.1: // %if.then
238+
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
239+
; V83A-NEXT: .cfi_def_cfa_offset 16
240+
; V83A-NEXT: .cfi_offset w30, -16
241+
; V83A-NEXT: bl foo
242+
; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
243+
; V83A-NEXT: .cfi_def_cfa_offset 0
244+
; V83A-NEXT: .cfi_restore w30
245+
; V83A-NEXT: .LBB9_2: // %exit
246+
; V83A-NEXT: adrp x8, var
247+
; V83A-NEXT: mov w9, #42 // =0x2a
248+
; V83A-NEXT: str x9, [x8, :lo12:var]
249+
; V83A-NEXT: retaa
250+
entry:
251+
%cond.bool = icmp eq i32 %cond, 0
252+
br i1 %cond.bool, label %if.then, label %exit
253+
if.then:
254+
%call = call i32 @foo(i32 %x)
255+
br label %exit
256+
exit:
257+
store i64 42, ptr @var
258+
ret void
259+
}
260+
152261
define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
153262
; CHECK-LABEL: leaf_sign_all_v83:
154263
; CHECK: // %bb.0:

0 commit comments

Comments
 (0)