Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 61f25da

Browse files
committed
[ARM][CMSE] Clear the secure fp-registers when using softfp abi.
When expanding the non-secure call instruction we are emiting code to clear the secure floating-point registers only if the targeted architecture has floating-point support. The potential problem is when the source code containing non-secure calls are built with -mfloat-abi=soft but some other part of the system has been built with -mfloat-abi=softfp (soft and softfp are compatible as they use the same procedure calling standard). In this case floating-point registers could leak to non-secure state as the non-secure won't have cleared them assuming no floating point has been used. Differential Revision: https://reviews.llvm.org/D109153
1 parent 054e331 commit 61f25da

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,16 +1333,14 @@ void ARMExpandPseudo::CMSESaveClearFPRegs(
13331333
const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
13341334
if (STI->hasV8_1MMainlineOps())
13351335
CMSESaveClearFPRegsV81(MBB, MBBI, DL, LiveRegs);
1336-
else
1336+
else if (STI->hasV8MMainlineOps())
13371337
CMSESaveClearFPRegsV8(MBB, MBBI, DL, LiveRegs, ScratchRegs);
13381338
}
13391339

13401340
// Save and clear FP registers if present
13411341
void ARMExpandPseudo::CMSESaveClearFPRegsV8(
13421342
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
13431343
const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
1344-
if (!STI->hasFPRegs())
1345-
return;
13461344

13471345
// Store an available register for FPSCR clearing
13481346
assert(!ScratchRegs.empty());
@@ -1396,7 +1394,11 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8(
13961394

13971395
bool passesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
13981396

1399-
// Lazy store all fp registers to the stack
1397+
if (passesFPReg)
1398+
assert(STI->hasFPRegs() && "Subtarget needs fpregs");
1399+
1400+
// Lazy store all fp registers to the stack.
1401+
// This executes as NOP in the absence of floating-point support.
14001402
MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM))
14011403
.addReg(ARM::SP)
14021404
.add(predOps(ARMCC::AL));
@@ -1524,15 +1526,13 @@ void ARMExpandPseudo::CMSERestoreFPRegs(
15241526
SmallVectorImpl<unsigned> &AvailableRegs) {
15251527
if (STI->hasV8_1MMainlineOps())
15261528
CMSERestoreFPRegsV81(MBB, MBBI, DL, AvailableRegs);
1527-
else
1529+
else if (STI->hasV8MMainlineOps())
15281530
CMSERestoreFPRegsV8(MBB, MBBI, DL, AvailableRegs);
15291531
}
15301532

15311533
void ARMExpandPseudo::CMSERestoreFPRegsV8(
15321534
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
15331535
SmallVectorImpl<unsigned> &AvailableRegs) {
1534-
if (!STI->hasFPRegs())
1535-
return;
15361536

15371537
// Use AvailableRegs to store the fp regs
15381538
std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
@@ -1574,6 +1574,11 @@ void ARMExpandPseudo::CMSERestoreFPRegsV8(
15741574
}
15751575
}
15761576

1577+
bool returnsFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
1578+
1579+
if (returnsFPReg)
1580+
assert(STI->hasFPRegs() && "Subtarget needs fpregs");
1581+
15771582
// Push FP regs that cannot be restored via normal registers on the stack
15781583
for (unsigned Reg : NonclearedFPRegs) {
15791584
if (ARM::DPR_VFP2RegClass.contains(Reg))
@@ -1588,7 +1593,8 @@ void ARMExpandPseudo::CMSERestoreFPRegsV8(
15881593
.add(predOps(ARMCC::AL));
15891594
}
15901595

1591-
// Lazy load fp regs from stack
1596+
// Lazy load fp regs from stack.
1597+
// This executes as NOP in the absence of floating-point support.
15921598
BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
15931599
.addReg(ARM::SP)
15941600
.add(predOps(ARMCC::AL));

llvm/test/CodeGen/ARM/cmse-clear.ll

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ define i32 @ns_call(i32 (i32)* nocapture %fptr) #2 {
166166
; CHECK-8M-SOFT-NEXT: movs r0, #10
167167
; CHECK-8M-SOFT-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
168168
; CHECK-8M-SOFT-NEXT: bic r1, r1, #1
169-
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
169+
; CHECK-8M-SOFT-NEXT: sub sp, #136
170+
; CHECK-8M-SOFT-NEXT: vlstm sp
170171
; CHECK-8M-SOFT-NEXT: mov r2, r1
171172
; CHECK-8M-SOFT-NEXT: mov r3, r1
172173
; CHECK-8M-SOFT-NEXT: mov r4, r1
@@ -178,7 +179,10 @@ define i32 @ns_call(i32 (i32)* nocapture %fptr) #2 {
178179
; CHECK-8M-SOFT-NEXT: mov r10, r1
179180
; CHECK-8M-SOFT-NEXT: mov r11, r1
180181
; CHECK-8M-SOFT-NEXT: mov r12, r1
182+
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
181183
; CHECK-8M-SOFT-NEXT: blxns r1
184+
; CHECK-8M-SOFT-NEXT: vlldm sp
185+
; CHECK-8M-SOFT-NEXT: add sp, #136
182186
; CHECK-8M-SOFT-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
183187
; CHECK-8M-SOFT-NEXT: pop {r7, pc}
184188
;
@@ -291,7 +295,8 @@ define i32 @ns_tail_call(i32 (i32)* nocapture %fptr) #4 {
291295
; CHECK-8M-SOFT-NEXT: movs r0, #10
292296
; CHECK-8M-SOFT-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
293297
; CHECK-8M-SOFT-NEXT: bic r1, r1, #1
294-
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
298+
; CHECK-8M-SOFT-NEXT: sub sp, #136
299+
; CHECK-8M-SOFT-NEXT: vlstm sp
295300
; CHECK-8M-SOFT-NEXT: mov r2, r1
296301
; CHECK-8M-SOFT-NEXT: mov r3, r1
297302
; CHECK-8M-SOFT-NEXT: mov r4, r1
@@ -303,7 +308,10 @@ define i32 @ns_tail_call(i32 (i32)* nocapture %fptr) #4 {
303308
; CHECK-8M-SOFT-NEXT: mov r10, r1
304309
; CHECK-8M-SOFT-NEXT: mov r11, r1
305310
; CHECK-8M-SOFT-NEXT: mov r12, r1
311+
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
306312
; CHECK-8M-SOFT-NEXT: blxns r1
313+
; CHECK-8M-SOFT-NEXT: vlldm sp
314+
; CHECK-8M-SOFT-NEXT: add sp, #136
307315
; CHECK-8M-SOFT-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
308316
; CHECK-8M-SOFT-NEXT: pop {r7, pc}
309317
;
@@ -423,7 +431,8 @@ define void (i32, i32, i32, i32)* @ns_tail_call_many_args(void (i32, i32, i32, i
423431
; CHECK-8M-SOFT-NEXT: mov r2, r12
424432
; CHECK-8M-SOFT-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
425433
; CHECK-8M-SOFT-NEXT: bic r4, r4, #1
426-
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r4
434+
; CHECK-8M-SOFT-NEXT: sub sp, #136
435+
; CHECK-8M-SOFT-NEXT: vlstm sp
427436
; CHECK-8M-SOFT-NEXT: mov r5, r4
428437
; CHECK-8M-SOFT-NEXT: mov r6, r4
429438
; CHECK-8M-SOFT-NEXT: mov r7, r4
@@ -432,7 +441,10 @@ define void (i32, i32, i32, i32)* @ns_tail_call_many_args(void (i32, i32, i32, i
432441
; CHECK-8M-SOFT-NEXT: mov r10, r4
433442
; CHECK-8M-SOFT-NEXT: mov r11, r4
434443
; CHECK-8M-SOFT-NEXT: mov r12, r4
444+
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r4
435445
; CHECK-8M-SOFT-NEXT: blxns r4
446+
; CHECK-8M-SOFT-NEXT: vlldm sp
447+
; CHECK-8M-SOFT-NEXT: add sp, #136
436448
; CHECK-8M-SOFT-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
437449
; CHECK-8M-SOFT-NEXT: mov r0, r4
438450
; CHECK-8M-SOFT-NEXT: pop {r4, pc}
@@ -554,7 +566,8 @@ define i32 @ns_call_void(i32 %reg0, i32 ()* nocapture %fptr) #8 {
554566
; CHECK-8M-SOFT-NEXT: push {r7, lr}
555567
; CHECK-8M-SOFT-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
556568
; CHECK-8M-SOFT-NEXT: bic r1, r1, #1
557-
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
569+
; CHECK-8M-SOFT-NEXT: sub sp, #136
570+
; CHECK-8M-SOFT-NEXT: vlstm sp
558571
; CHECK-8M-SOFT-NEXT: mov r0, r1
559572
; CHECK-8M-SOFT-NEXT: mov r2, r1
560573
; CHECK-8M-SOFT-NEXT: mov r3, r1
@@ -567,7 +580,10 @@ define i32 @ns_call_void(i32 %reg0, i32 ()* nocapture %fptr) #8 {
567580
; CHECK-8M-SOFT-NEXT: mov r10, r1
568581
; CHECK-8M-SOFT-NEXT: mov r11, r1
569582
; CHECK-8M-SOFT-NEXT: mov r12, r1
583+
; CHECK-8M-SOFT-NEXT: msr apsr_nzcvqg, r1
570584
; CHECK-8M-SOFT-NEXT: blxns r1
585+
; CHECK-8M-SOFT-NEXT: vlldm sp
586+
; CHECK-8M-SOFT-NEXT: add sp, #136
571587
; CHECK-8M-SOFT-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
572588
; CHECK-8M-SOFT-NEXT: pop {r7, pc}
573589
;

llvm/test/CodeGen/ARM/cmse.ll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ define void @func1(void ()* nocapture %fptr) #0 {
6161
; CHECK-8M-NEXT: push {r7, lr}
6262
; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
6363
; CHECK-8M-NEXT: bic r0, r0, #1
64-
; CHECK-8M-NEXT: msr apsr_nzcvq, r0
64+
; CHECK-8M-NEXT: sub sp, #136
65+
; CHECK-8M-NEXT: vlstm sp
6566
; CHECK-8M-NEXT: mov r1, r0
6667
; CHECK-8M-NEXT: mov r2, r0
6768
; CHECK-8M-NEXT: mov r3, r0
@@ -74,7 +75,10 @@ define void @func1(void ()* nocapture %fptr) #0 {
7475
; CHECK-8M-NEXT: mov r10, r0
7576
; CHECK-8M-NEXT: mov r11, r0
7677
; CHECK-8M-NEXT: mov r12, r0
78+
; CHECK-8M-NEXT: msr apsr_nzcvq, r0
7779
; CHECK-8M-NEXT: blxns r0
80+
; CHECK-8M-NEXT: vlldm sp
81+
; CHECK-8M-NEXT: add sp, #136
7882
; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
7983
; CHECK-8M-NEXT: pop.w {r7, lr}
8084
; CHECK-8M-NEXT: mov r0, lr
@@ -152,7 +156,8 @@ define void @func2(void ()* nocapture %fptr) #2 {
152156
; CHECK-8M-NEXT: push {r7, lr}
153157
; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
154158
; CHECK-8M-NEXT: bic r0, r0, #1
155-
; CHECK-8M-NEXT: msr apsr_nzcvq, r0
159+
; CHECK-8M-NEXT: sub sp, #136
160+
; CHECK-8M-NEXT: vlstm sp
156161
; CHECK-8M-NEXT: mov r1, r0
157162
; CHECK-8M-NEXT: mov r2, r0
158163
; CHECK-8M-NEXT: mov r3, r0
@@ -165,7 +170,10 @@ define void @func2(void ()* nocapture %fptr) #2 {
165170
; CHECK-8M-NEXT: mov r10, r0
166171
; CHECK-8M-NEXT: mov r11, r0
167172
; CHECK-8M-NEXT: mov r12, r0
173+
; CHECK-8M-NEXT: msr apsr_nzcvq, r0
168174
; CHECK-8M-NEXT: blxns r0
175+
; CHECK-8M-NEXT: vlldm sp
176+
; CHECK-8M-NEXT: add sp, #136
169177
; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
170178
; CHECK-8M-NEXT: pop {r7, pc}
171179
;

0 commit comments

Comments
 (0)