llvm.org GIT mirror llvm / 6ee91ac
[PPC] Claim stack frame before storing into it, if no red zone is present Unlike PPC64, PPC32/SVRV4 does not have red zone. In the absence of it there is no guarantee that this part of the stack will not be modified by any interrupt. To avoid this, make sure to claim the stack frame first before storing into it. This fixes https://llvm.org/bugs/show_bug.cgi?id=26519. Differential Revision: https://reviews.llvm.org/D24093 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280705 91177308-0d34-0410-b5e6-96231b3b80d8 Krzysztof Parzyszek 3 years ago
6 changed file(s) with 121 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
671671 bool IsLargeFrame = !isInt<16>(NegFrameSize);
672672 MachineFrameInfo &MFI = MF.getFrameInfo();
673673 unsigned MaxAlign = MFI.getMaxAlignment();
674
675 return IsLargeFrame && HasBP && MaxAlign > 1;
674 bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
675
676 return (IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1;
676677 }
677678
678679 bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
741742 // Do we have a frame pointer and/or base pointer for this function?
742743 bool HasFP = hasFP(MF);
743744 bool HasBP = RegInfo->hasBasePointer(MF);
745 bool HasRedZone = isPPC64 || !isSVR4ABI;
744746
745747 unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1;
746748 unsigned BPReg = RegInfo->getBaseRegister(MF);
875877 MIB.addReg(MustSaveCRs[i], CrState);
876878 }
877879
878 if (HasFP)
879 // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
880 BuildMI(MBB, MBBI, dl, StoreInst)
881 .addReg(FPReg)
882 .addImm(FPOffset)
883 .addReg(SPReg);
884
885 if (FI->usesPICBase())
886 // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
887 BuildMI(MBB, MBBI, dl, StoreInst)
888 .addReg(PPC::R30)
889 .addImm(PBPOffset)
890 .addReg(SPReg);
891
892 if (HasBP)
893 // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
894 BuildMI(MBB, MBBI, dl, StoreInst)
895 .addReg(BPReg)
896 .addImm(BPOffset)
897 .addReg(SPReg);
880 if (HasRedZone) {
881 if (HasFP)
882 BuildMI(MBB, MBBI, dl, StoreInst)
883 .addReg(FPReg)
884 .addImm(FPOffset)
885 .addReg(SPReg);
886 if (FI->usesPICBase())
887 BuildMI(MBB, MBBI, dl, StoreInst)
888 .addReg(PPC::R30)
889 .addImm(PBPOffset)
890 .addReg(SPReg);
891 if (HasBP)
892 BuildMI(MBB, MBBI, dl, StoreInst)
893 .addReg(BPReg)
894 .addImm(BPOffset)
895 .addReg(SPReg);
896 }
898897
899898 if (MustSaveLR)
900 // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
901899 BuildMI(MBB, MBBI, dl, StoreInst)
902900 .addReg(ScratchReg, getKillRegState(true))
903901 .addImm(LROffset)
904902 .addReg(SPReg);
905903
906904 if (MustSaveCR &&
907 !(SingleScratchReg && MustSaveLR)) // will only occur for PPC64
905 !(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64
906 assert(HasRedZone && "A red zone is always available on PPC64");
908907 BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8))
909908 .addReg(TempReg, getKillRegState(true))
910909 .addImm(8)
911910 .addReg(SPReg);
911 }
912912
913913 // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
914 if (!FrameSize) return;
914 if (!FrameSize)
915 return;
915916
916917 // Adjust stack pointer: r1 += NegFrameSize.
917918 // If there is a preferred stack alignment, align R1 now
918919
919 if (HasBP) {
920 if (HasBP && HasRedZone) {
920921 // Save a copy of r1 as the base pointer.
921922 BuildMI(MBB, MBBI, dl, OrInst, BPReg)
922923 .addReg(SPReg)
923924 .addReg(SPReg);
924925 }
926
927 // Have we generated a STUX instruction to claim stack frame? If so,
928 // the frame size will be placed in ScratchReg.
929 bool HasSTUX = false;
925930
926931 // This condition must be kept in sync with canUseAsPrologue.
927932 if (HasBP && MaxAlign > 1) {
951956 .addReg(ScratchReg, RegState::Kill)
952957 .addReg(TempReg, RegState::Kill);
953958 }
959
954960 BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
955961 .addReg(SPReg, RegState::Kill)
956962 .addReg(SPReg)
957963 .addReg(ScratchReg);
964 HasSTUX = true;
958965
959966 } else if (!isLargeFrame) {
960967 BuildMI(MBB, MBBI, dl, StoreUpdtInst, SPReg)
972979 .addReg(SPReg, RegState::Kill)
973980 .addReg(SPReg)
974981 .addReg(ScratchReg);
982 HasSTUX = true;
983 }
984
985 if (!HasRedZone) {
986 assert(!isPPC64 && "A red zone is always available on PPC64");
987 if (HasSTUX) {
988 // The frame size is in ScratchReg, and the SPReg has been advanced
989 // (downwards) by the frame size: SPReg = old SPReg + ScratchReg.
990 // Set ScratchReg to the original SPReg: ScratchReg = SPReg - ScratchReg.
991 BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
992 .addReg(ScratchReg, RegState::Kill)
993 .addReg(SPReg);
994
995 // Now that the stack frame has been allocated, save all the necessary
996 // registers using ScratchReg as the base address.
997 if (HasFP)
998 BuildMI(MBB, MBBI, dl, StoreInst)
999 .addReg(FPReg)
1000 .addImm(FPOffset)
1001 .addReg(ScratchReg);
1002 if (FI->usesPICBase())
1003 BuildMI(MBB, MBBI, dl, StoreInst)
1004 .addReg(PPC::R30)
1005 .addImm(PBPOffset)
1006 .addReg(ScratchReg);
1007 if (HasBP) {
1008 BuildMI(MBB, MBBI, dl, StoreInst)
1009 .addReg(BPReg)
1010 .addImm(BPOffset)
1011 .addReg(ScratchReg);
1012 BuildMI(MBB, MBBI, dl, OrInst, BPReg)
1013 .addReg(ScratchReg, RegState::Kill)
1014 .addReg(ScratchReg);
1015 }
1016 } else {
1017 // The frame size is a known 16-bit constant (fitting in the immediate
1018 // field of STWU). To be here we have to be compiling for PPC32.
1019 // Since the SPReg has been decreased by FrameSize, add it back to each
1020 // offset.
1021 if (HasFP)
1022 BuildMI(MBB, MBBI, dl, StoreInst)
1023 .addReg(FPReg)
1024 .addImm(FrameSize + FPOffset)
1025 .addReg(SPReg);
1026 if (FI->usesPICBase())
1027 BuildMI(MBB, MBBI, dl, StoreInst)
1028 .addReg(PPC::R30)
1029 .addImm(FrameSize + PBPOffset)
1030 .addReg(SPReg);
1031 if (HasBP) {
1032 BuildMI(MBB, MBBI, dl, StoreInst)
1033 .addReg(BPReg)
1034 .addImm(FrameSize + BPOffset)
1035 .addReg(SPReg);
1036 BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), BPReg)
1037 .addReg(SPReg)
1038 .addImm(FrameSize);
1039 }
1040 }
9751041 }
9761042
9771043 // Add Call Frame Information for the instructions we generated above.
1313 ret i32 %1
1414 }
1515
16 ; PPC32: stw 31, -4(1)
16 ; PPC32-LABEL: test_cr2:
1717 ; PPC32: stwu 1, -32(1)
18 ; PPC32: stw 31, 28(1)
1819 ; PPC32: mfcr 12
1920 ; PPC32-NEXT: stw 12, 24(31)
2021 ; PPC32: lwz 12, 24(31)
4243 ret i32 %1
4344 }
4445
45 ; PPC32: stw 31, -4(1)
46 ; PPC32-LABEL: test_cr234:
4647 ; PPC32: stwu 1, -32(1)
48 ; PPC32: stw 31, 28(1)
4749 ; PPC32: mfcr 12
4850 ; PPC32-NEXT: stw 12, 24(31)
4951 ; PPC32: lwz 12, 24(31)
3030 ; LINUX-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}}
3131 ; LINUX-FP-NEXT: .cfi_startproc
3232 ; LINUX-FP-NEXT: {{^}}#
33 ; LINUX-FP-NEXT: stw 31, -4(1)
3433 ; LINUX-FP-NEXT: stwu 1, -16(1)
34 ; LINUX-FP-NEXT: stw 31, 12(1)
3535 ; LINUX-FP-NEXT: {{^}}.L{{.*}}:{{$}}
3636 ; LINUX-FP-NEXT: .cfi_def_cfa_offset 16
3737 ; LINUX-FP-NEXT: {{^}}.L{{.*}}:{{$}}
1414 ; LARGE-BSS: [[POFF:\.L[0-9]+\$poff]]:
1515 ; LARGE-BSS-NEXT: .long .LTOC-[[PB:\.L[0-9]+\$pb]]
1616 ; LARGE-BSS-NEXT: foo:
17 ; LARGE-BSS: stw 30, -8(1)
17 ; LARGE-BSS: stwu 1, -32(1)
18 ; LARGE-BSS: stw 30, 24(1)
1819 ; LARGE-BSS: bl [[PB]]
1920 ; LARGE-BSS-NEXT: [[PB]]:
2021 ; LARGE-BSS: mflr 30
1212 !llvm.module.flags = !{!0}
1313 !0 = !{i32 1, !"PIC Level", i32 1}
1414 ; SMALL-BSS-LABEL:foo:
15 ; SMALL-BSS: stw 30, -8(1)
1615 ; SMALL-BSS: stwu 1, -32(1)
16 ; SMALL-BSS: stw 30, 24(1)
1717 ; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4
1818 ; SMALL-BSS: mflr 30
1919 ; SMALL-BSS-DAG: stw {{[0-9]+}}, 8(1)
7676 ; CHECK-FP: blr
7777
7878 ; CHECK-32-LABEL: @goo
79 ; CHECK-32-DAG: mflr {{[0-9]+}}
79 ; CHECK-32-DAG: mflr [[LR:[0-9]+]]
8080 ; CHECK-32-DAG: clrlwi [[REG:[0-9]+]], 1, 27
81 ; CHECK-32-DAG: stw 30, -8(1)
82 ; CHECK-32-DAG: mr 30, 1
83 ; CHECK-32-DAG: stw 0, 4(1)
81 ; CHECK-32-DAG: stw [[LR]], 4(1)
8482 ; CHECK-32-DAG: subfic 0, [[REG]], -64
8583 ; CHECK-32: stwux 1, 1, 0
84 ; CHECK-32: subf 0, 0, 1
85 ; CHECK-32: stw 30, -8(0)
86 ; CHECK-32: mr 30, 0
8687
8788 ; CHECK-32-PIC-LABEL: @goo
88 ; CHECK-32-PIC-DAG: mflr {{[0-9]+}}
89 ; CHECK-32-PIC-DAG: mflr [[LR:[0-9]+]]
8990 ; CHECK-32-PIC-DAG: clrlwi [[REG:[0-9]+]], 1, 27
90 ; CHECK-32-PIC-DAG: stw 29, -12(1)
91 ; CHECK-32-PIC-DAG: mr 29, 1
92 ; CHECK-32-PIC-DAG: stw 0, 4(1)
91 ; CHECK-32-PIC-DAG: stw [[LR]], 4(1)
9392 ; CHECK-32-PIC-DAG: subfic 0, [[REG]], -64
9493 ; CHECK-32-PIC: stwux 1, 1, 0
94 ; CHECK-32-PIC: subf 0, 0, 1
95 ; CHECK-32-PIC: stw 29, -12(0)
96 ; CHECK-32-PIC-DAG: mr 29, 0
9597
9698 ; The large-frame-size case.
9799 define void @hoo(%struct.s* byval nocapture readonly %a) {
129131
130132 ; CHECK-32-DAG: lis [[REG1:[0-9]+]], -13
131133 ; CHECK-32-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
132 ; CHECK-32-DAG: mflr {{[0-9]+}}
134 ; CHECK-32-DAG: mflr [[LR:[0-9]+]]
133135 ; CHECK-32-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
134 ; CHECK-32-DAG: stw 30, -8(1)
135 ; CHECK-32-DAG: mr 30, 1
136 ; CHECK-32-DAG: stw 0, 4(1)
136 ; CHECK-32-DAG: stw [[LR]], 4(1)
137137 ; CHECK-32-DAG: subfc 0, [[REG3]], [[REG2]]
138 ; CHECK-32: stwux 1, 1, 0
138 ; CHECK-32: stwux 1, 1, 0
139 ; CHECK-32: subf 0, 0, 1
140 ; CHECK-32-DAG: stw 31, -4(0)
141 ; CHECK-32-DAG: stw 30, -8(0)
142 ; CHECK-32: mr 30, 0
139143
140144 ; CHECK-32: blr
141145
145149 ; CHECK-32-PIC-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
146150 ; CHECK-32-PIC-DAG: mflr {{[0-9]+}}
147151 ; CHECK-32-PIC-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
148 ; CHECK-32-PIC-DAG: stw 29, -12(1)
149 ; CHECK-32-PIC-DAG: mr 29, 1
150152 ; CHECK-32-PIC-DAG: stw 0, 4(1)
151153 ; CHECK-32-PIC-DAG: subfc 0, [[REG3]], [[REG2]]
152 ; CHECK-32: stwux 1, 1, 0
154 ; CHECK-32-PIC: stwux 1, 1, 0
155 ; CHECK-32-PIC: stw 29, -12(0)
156 ; CHECK-32-PIC: subf 0, 0, 1
157 ; CHECK-32-PIC: mr 29, 0
153158
154159 ; CHECK-32: blr
155160