diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 2f9236bb977fc92b949ed869b2854abbf107e542..1db4d410a467811928f15de621db7ed87688b6bb 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1429,6 +1429,7 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( // Use ScratchRegs to store the fp regs std::vector> ClearedFPRegs; std::vector NonclearedFPRegs; + bool ReturnsFPReg = false; for (const MachineOperand &Op : MBBI->operands()) { if (Op.isReg() && Op.isUse()) { Register Reg = Op.getReg(); @@ -1463,14 +1464,51 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( NonclearedFPRegs.push_back(Reg); } } + } else if (Op.isReg() && Op.isDef()) { + Register Reg = Op.getReg(); + if (ARM::SPRRegClass.contains(Reg) || ARM::DPRRegClass.contains(Reg) || + ARM::QPRRegClass.contains(Reg)) + ReturnsFPReg = true; } } - bool passesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty()); + bool PassesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty()); - if (passesFPReg) + if (PassesFPReg || ReturnsFPReg) assert(STI->hasFPRegs() && "Subtarget needs fpregs"); + // CVE-2024-7883 + // + // The VLLDM/VLSTM instructions set up lazy state preservation, but they + // execute as NOPs if the FP register file is not considered to contain + // secure data, represented by the CONTROL_S.SFPA bit. This means that the + // state of CONTROL_S.SFPA must be the same when these two instructions are + // executed. That might not be the case if we haven't used any FP + // instructions before the VLSTM, so CONTROL_S.SFPA is clear, but do have one + // before the VLLDM, which sets it.. + // + // If we can't prove that SFPA will be the same for the VLSTM and VLLDM, we + // execute a "vmov s0, s0" instruction before the VLSTM to ensure that + // CONTROL_S.SFPA is set for both. + // + // That can only happen for callees which take no FP arguments (or we'd have + // inserted a VMOV above) and which return values in FP regs (so that we need + // to use a VMOV to back-up the return value before the VLLDM). It also can't + // happen if the call is dominated by other existing floating-point + // instructions, but we don't currently check for that case. + // + // These conditions mean that we only emit this instruction when using the + // hard-float ABI, which means we can assume that FP instructions are + // available, and don't need to make it conditional like we do for the + // CVE-2021-35465 workaround. + if (ReturnsFPReg && !PassesFPReg) { + bool S0Dead = !LiveRegs.contains(ARM::S0); + BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVS)) + .addReg(ARM::S0, RegState::Define | getDeadRegState(S0Dead)) + .addReg(ARM::S0, getUndefRegState(S0Dead)) + .add(predOps(ARMCC::AL)); + } + // Lazy store all fp registers to the stack. // This executes as NOP in the absence of floating-point support. MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM)) @@ -1525,7 +1563,7 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( } // restore FPSCR from stack and clear bits 0-4, 7, 28-31 // The other bits are program global according to the AAPCS - if (passesFPReg) { + if (PassesFPReg) { BuildMI(MBB, MBBI, DL, TII->get(ARM::tLDRspi), SpareReg) .addReg(ARM::SP) .addImm(0x10) diff --git a/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll b/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll index 606859db0a0ea8eb3aff7c2ae0470a7e342cdd0a..f97fc51a0c4575057ed9448675cb05822ea37b2b 100644 --- a/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll +++ b/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll @@ -187,7 +187,7 @@ define float @f2(ptr nocapture %fptr) #2 { ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: ldr r1, [sp, #64] ; CHECK-8M-NEXT: bic r1, r1, #159 @@ -207,7 +207,7 @@ define float @f2(ptr nocapture %fptr) #2 { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -245,7 +245,7 @@ define double @d2(ptr nocapture %fptr) #2 { ; CHECK-8M-LE-NEXT: bic r0, r0, #1 ; CHECK-8M-LE-NEXT: sub sp, #136 ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 -; CHECK-8M-LE-NEXT: vlstm sp +; CHECK-8M-LE-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 ; CHECK-8M-LE-NEXT: ldr r1, [sp, #64] ; CHECK-8M-LE-NEXT: bic r1, r1, #159 @@ -264,7 +264,7 @@ define double @d2(ptr nocapture %fptr) #2 { ; CHECK-8M-LE-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-LE-NEXT: blxns r0 ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 -; CHECK-8M-LE-NEXT: vlldm sp +; CHECK-8M-LE-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 ; CHECK-8M-LE-NEXT: add sp, #136 ; CHECK-8M-LE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -283,7 +283,7 @@ define double @d2(ptr nocapture %fptr) #2 { ; CHECK-8M-BE-NEXT: bic r0, r0, #1 ; CHECK-8M-BE-NEXT: sub sp, #136 ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 -; CHECK-8M-BE-NEXT: vlstm sp +; CHECK-8M-BE-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 ; CHECK-8M-BE-NEXT: ldr r1, [sp, #64] ; CHECK-8M-BE-NEXT: bic r1, r1, #159 @@ -302,7 +302,7 @@ define double @d2(ptr nocapture %fptr) #2 { ; CHECK-8M-BE-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-BE-NEXT: blxns r0 ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 -; CHECK-8M-BE-NEXT: vlldm sp +; CHECK-8M-BE-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 ; CHECK-8M-BE-NEXT: add sp, #136 ; CHECK-8M-BE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -368,7 +368,7 @@ define float @f3(ptr nocapture %fptr) #4 { ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: ldr r1, [sp, #64] ; CHECK-8M-NEXT: bic r1, r1, #159 @@ -388,7 +388,7 @@ define float @f3(ptr nocapture %fptr) #4 { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -426,7 +426,7 @@ define double @d3(ptr nocapture %fptr) #4 { ; CHECK-8M-LE-NEXT: bic r0, r0, #1 ; CHECK-8M-LE-NEXT: sub sp, #136 ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 -; CHECK-8M-LE-NEXT: vlstm sp +; CHECK-8M-LE-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 ; CHECK-8M-LE-NEXT: ldr r1, [sp, #64] ; CHECK-8M-LE-NEXT: bic r1, r1, #159 @@ -445,7 +445,7 @@ define double @d3(ptr nocapture %fptr) #4 { ; CHECK-8M-LE-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-LE-NEXT: blxns r0 ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 -; CHECK-8M-LE-NEXT: vlldm sp +; CHECK-8M-LE-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 ; CHECK-8M-LE-NEXT: add sp, #136 ; CHECK-8M-LE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -464,7 +464,7 @@ define double @d3(ptr nocapture %fptr) #4 { ; CHECK-8M-BE-NEXT: bic r0, r0, #1 ; CHECK-8M-BE-NEXT: sub sp, #136 ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 -; CHECK-8M-BE-NEXT: vlstm sp +; CHECK-8M-BE-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 ; CHECK-8M-BE-NEXT: ldr r1, [sp, #64] ; CHECK-8M-BE-NEXT: bic r1, r1, #159 @@ -483,7 +483,7 @@ define double @d3(ptr nocapture %fptr) #4 { ; CHECK-8M-BE-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-BE-NEXT: blxns r0 ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 -; CHECK-8M-BE-NEXT: vlldm sp +; CHECK-8M-BE-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 ; CHECK-8M-BE-NEXT: add sp, #136 ; CHECK-8M-BE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -547,8 +547,9 @@ define float @f4(ptr nocapture %fptr) #6 { ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vmov.f32 s0, s0 ; CHECK-8M-NEXT: mov r1, r0 +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: mov r2, r0 ; CHECK-8M-NEXT: mov r3, r0 ; CHECK-8M-NEXT: mov r4, r0 @@ -563,7 +564,7 @@ define float @f4(ptr nocapture %fptr) #6 { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -598,8 +599,9 @@ define double @d4(ptr nocapture %fptr) #6 { ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vmov.f32 s0, s0 ; CHECK-8M-NEXT: mov r1, r0 +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: mov r2, r0 ; CHECK-8M-NEXT: mov r3, r0 ; CHECK-8M-NEXT: mov r4, r0 @@ -614,7 +616,7 @@ define double @d4(ptr nocapture %fptr) #6 { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r11, r12, d0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov d0, r11, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -649,7 +651,7 @@ define void @fd(ptr %f, float %a, double %b) #8 { ; CHECK-8M-NEXT: vmov r12, s0 ; CHECK-8M-NEXT: mov r2, r0 ; CHECK-8M-NEXT: vmov r10, r11, d1 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: vmov d1, r10, r11 ; CHECK-8M-NEXT: ldr r1, [sp, #64] @@ -666,7 +668,7 @@ define void @fd(ptr %f, float %a, double %b) #8 { ; CHECK-8M-NEXT: mov r9, r0 ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: pop {r7, pc} @@ -708,7 +710,7 @@ define void @fdff(ptr %f, float %a, double %b, float %c, float %d) #8 { ; CHECK-8M-NEXT: vmov r9, s1 ; CHECK-8M-NEXT: mov r4, r0 ; CHECK-8M-NEXT: vmov r8, s4 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: vmov d1, r10, r11 ; CHECK-8M-NEXT: vmov s1, r9 @@ -723,7 +725,7 @@ define void @fdff(ptr %f, float %a, double %b, float %c, float %d) #8 { ; CHECK-8M-NEXT: mov r7, r0 ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: pop {r7, pc} @@ -765,7 +767,7 @@ define void @fidififid(ptr %fu, float %a, i32 %b, double %c, i32 %d, float %e, i ; CHECK-8M-NEXT: vmov r8, s1 ; CHECK-8M-NEXT: vmov r7, s4 ; CHECK-8M-NEXT: vmov r5, r6, d3 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r11 ; CHECK-8M-NEXT: vmov d1, r9, r10 ; CHECK-8M-NEXT: vmov s1, r8 @@ -778,7 +780,7 @@ define void @fidififid(ptr %fu, float %a, i32 %b, double %c, i32 %d, float %e, i ; CHECK-8M-NEXT: mov r4, r12 ; CHECK-8M-NEXT: msr apsr_nzcvqg, r12 ; CHECK-8M-NEXT: blxns r12 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: pop {r7, pc} @@ -897,7 +899,7 @@ define half @h2(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: ldr r1, [sp, #64] ; CHECK-8M-NEXT: bic r1, r1, #159 @@ -917,7 +919,7 @@ define half @h2(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -976,7 +978,7 @@ define half @h3(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: ldr r1, [sp, #64] ; CHECK-8M-NEXT: bic r1, r1, #159 @@ -996,7 +998,7 @@ define half @h3(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -1053,8 +1055,9 @@ define half @h4(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vmov.f32 s0, s0 ; CHECK-8M-NEXT: mov r1, r0 +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: mov r2, r0 ; CHECK-8M-NEXT: mov r3, r0 ; CHECK-8M-NEXT: mov r4, r0 @@ -1069,7 +1072,7 @@ define half @h4(ptr nocapture %hptr) nounwind { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -1176,7 +1179,7 @@ define half @h1_arg(ptr nocapture %hptr, half %harg) nounwind { ; CHECK-8M-NEXT: bic r0, r0, #1 ; CHECK-8M-NEXT: sub sp, #136 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlstm sp +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: ldr r1, [sp, #64] ; CHECK-8M-NEXT: bic r1, r1, #159 @@ -1196,7 +1199,7 @@ define half @h1_arg(ptr nocapture %hptr, half %harg) nounwind { ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ; CHECK-8M-NEXT: blxns r0 ; CHECK-8M-NEXT: vmov r12, s0 -; CHECK-8M-NEXT: vlldm sp +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ; CHECK-8M-NEXT: vmov s0, r12 ; CHECK-8M-NEXT: add sp, #136 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} @@ -1241,3 +1244,100 @@ entry: ret half %call } +define float @float_return_undef_arg(ptr nocapture %fptr) #6 { +; CHECK-8M-LABEL: float_return_undef_arg: +; CHECK-8M: @ %bb.0: @ %entry +; CHECK-8M-NEXT: push {r7, lr} +; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-8M-NEXT: bic r0, r0, #1 +; CHECK-8M-NEXT: sub sp, #136 +; CHECK-8M-NEXT: vmov.f32 s0, s0 +; CHECK-8M-NEXT: mov r1, r0 +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} +; CHECK-8M-NEXT: mov r2, r0 +; CHECK-8M-NEXT: mov r3, r0 +; CHECK-8M-NEXT: mov r4, r0 +; CHECK-8M-NEXT: mov r5, r0 +; CHECK-8M-NEXT: mov r6, r0 +; CHECK-8M-NEXT: mov r7, r0 +; CHECK-8M-NEXT: mov r8, r0 +; CHECK-8M-NEXT: mov r9, r0 +; CHECK-8M-NEXT: mov r10, r0 +; CHECK-8M-NEXT: mov r11, r0 +; CHECK-8M-NEXT: mov r12, r0 +; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 +; CHECK-8M-NEXT: blxns r0 +; CHECK-8M-NEXT: vmov r12, s0 +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} +; CHECK-8M-NEXT: vmov s0, r12 +; CHECK-8M-NEXT: add sp, #136 +; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-8M-NEXT: pop {r7, pc} +; +; CHECK-81M-LABEL: float_return_undef_arg: +; CHECK-81M: @ %bb.0: @ %entry +; CHECK-81M-NEXT: push {r7, lr} +; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-81M-NEXT: bic r0, r0, #1 +; CHECK-81M-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} +; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr} +; CHECK-81M-NEXT: vstr fpcxts, [sp, #-8]! +; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr} +; CHECK-81M-NEXT: blxns r0 +; CHECK-81M-NEXT: vldr fpcxts, [sp], #8 +; CHECK-81M-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} +; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-81M-NEXT: pop {r7, pc} +entry: + %call = call float %fptr(i32 undef) #7 + ret float %call +} + +define float @float_return_poison_arg(ptr nocapture %fptr) #6 { +; CHECK-8M-LABEL: float_return_poison_arg: +; CHECK-8M: @ %bb.0: @ %entry +; CHECK-8M-NEXT: push {r7, lr} +; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-8M-NEXT: bic r0, r0, #1 +; CHECK-8M-NEXT: sub sp, #136 +; CHECK-8M-NEXT: vmov.f32 s0, s0 +; CHECK-8M-NEXT: mov r1, r0 +; CHECK-8M-NEXT: vlstm sp, {d0 - d15} +; CHECK-8M-NEXT: mov r2, r0 +; CHECK-8M-NEXT: mov r3, r0 +; CHECK-8M-NEXT: mov r4, r0 +; CHECK-8M-NEXT: mov r5, r0 +; CHECK-8M-NEXT: mov r6, r0 +; CHECK-8M-NEXT: mov r7, r0 +; CHECK-8M-NEXT: mov r8, r0 +; CHECK-8M-NEXT: mov r9, r0 +; CHECK-8M-NEXT: mov r10, r0 +; CHECK-8M-NEXT: mov r11, r0 +; CHECK-8M-NEXT: mov r12, r0 +; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 +; CHECK-8M-NEXT: blxns r0 +; CHECK-8M-NEXT: vmov r12, s0 +; CHECK-8M-NEXT: vlldm sp, {d0 - d15} +; CHECK-8M-NEXT: vmov s0, r12 +; CHECK-8M-NEXT: add sp, #136 +; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-8M-NEXT: pop {r7, pc} +; +; CHECK-81M-LABEL: float_return_poison_arg: +; CHECK-81M: @ %bb.0: @ %entry +; CHECK-81M-NEXT: push {r7, lr} +; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-81M-NEXT: bic r0, r0, #1 +; CHECK-81M-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} +; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr} +; CHECK-81M-NEXT: vstr fpcxts, [sp, #-8]! +; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr} +; CHECK-81M-NEXT: blxns r0 +; CHECK-81M-NEXT: vldr fpcxts, [sp], #8 +; CHECK-81M-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} +; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +; CHECK-81M-NEXT: pop {r7, pc} +entry: + %call = call float %fptr(i32 poison) #7 + ret float %call +} diff --git a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir index 2bc4288884f192518f3c68ba45925240266979c6..416cf3a53c9b5f42735d1fdac888e462e5b8bde1 100644 --- a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir +++ b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir @@ -89,6 +89,7 @@ body: | # CHECK: $sp = t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5, $r6, undef $r7, $r8, $r9, $r10, $r11 # CHECK-NEXT: $r0 = t2BICri $r0, 1, 14 /* CC::al */, $noreg, $noreg # CHECK-NEXT: $sp = tSUBspi $sp, 34, 14 /* CC::al */, $noreg +# CHECK-NEXT: dead $s0 = VMOVS undef $s0, 14 /* CC::al */, $noreg # CHECK-NEXT: VLSTM $sp, 14 /* CC::al */, $noreg, implicit undef $vpr, implicit undef $fpscr, implicit undef $fpscr_nzcv, implicit undef $q0, implicit undef $q1, implicit undef $q2, implicit undef $q3, implicit undef $q4, implicit undef $q5, implicit undef $q6, implicit undef $q7 # CHECK-NEXT: $r1 = tMOVr $r0, 14 /* CC::al */, $noreg # CHECK-NEXT: $r2 = tMOVr $r0, 14 /* CC::al */, $noreg