llvm.org GIT mirror llvm / c8f5d43
LLVM-1163: AAPCS-VFP violation when CPRC allocated to stack According to the AAPCS, when a CPRC is allocated to the stack, all other VFP registers should be marked as unavailable. I have also modified the rules for allocating non-CPRCs to the stack, to make it more explicit that all GPRs must be made unavailable. I cannot think of a case where the old version would produce incorrect answers, so there is no test for this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200970 91177308-0d34-0410-b5e6-96231b3b80d8 Oliver Stannard 6 years ago
5 changed file(s) with 69 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
347347 return AllocateStack(Size, Align);
348348 }
349349
350 /// Version of AllocateStack with list of extra registers to be shadowed.
351 /// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
352 unsigned AllocateStack(unsigned Size, unsigned Align,
353 const uint16_t *ShadowRegs, unsigned NumShadowRegs) {
354 for (unsigned i = 0; i < NumShadowRegs; ++i)
355 MarkAllocated(ShadowRegs[i]);
356 return AllocateStack(Size, Align);
357 }
358
350359 // HandleByVal - Allocate a stack slot large enough to pass an argument by
351360 // value. The size and alignment information of the argument is encoded in its
352361 // parameter attribute.
8888 int Align = align;
8989 }
9090
91 /// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a register
92 /// to be shadowed.
93 class CCAssignToStackWithShadow :
94 CCAssignToStack {
95 Register ShadowReg = reg;
91 /// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of
92 /// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this
93 /// shadows ALL of the registers in shadowList.
94 class CCAssignToStackWithShadow
95 int align,
96 list shadowList> : CCAction {
97 int Size = size;
98 int Align = align;
99 list ShadowRegList = shadowList;
96100 }
97101
98102 /// CCPassByVal - This action always matches: it assigns the value to a stack
113113 CCIfType<[i32], CCIf<"ArgFlags.getOrigAlign() != 8",
114114 CCAssignToReg<[R0, R1, R2, R3]>>>,
115115
116 CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, R3>>>,
117 CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
118 CCIfType<[f64], CCAssignToStack<8, 8>>,
119 CCIfType<[v2f64], CCAssignToStack<16, 8>>
116 CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, [R0, R1, R2, R3]>>>,
117 CCIfType<[i32], CCAssignToStackWithShadow<4, 4, [R0, R1, R2, R3]>>,
118 CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
119 CCIfType<[f64], CCAssignToStackWithShadow<8, 8, [Q0, Q1, Q2, Q3]>>,
120 CCIfType<[v2f64], CCAssignToStackWithShadow<16, 8, [Q0, Q1, Q2, Q3]>>
120121 ]>;
121122
122123 def RetCC_ARM_AAPCS_Common : CallingConv<[
0 ; RUN: llc < %s -o - -filetype=asm | FileCheck %s
1
2 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
3 target triple = "armv8-none--eabi"
4
5 ; CHECK-LABEL: fn1:
6 define arm_aapcs_vfpcc float @fn1(double %a, double %b, double %c, double %d, double %e, double %f, double %g, float %h, double %i, float %j) {
7 ret float %j
8 ; CHECK: vldr s0, [sp, #8]
9 }
10
11 ; CHECK-LABEL: fn2:
12 define arm_aapcs_vfpcc float @fn2(double %a, double %b, double %c, double %d, double %e, double %f, float %h, <4 x float> %i, float %j) {
13 ret float %j
14 ; CHECK: vldr s0, [sp, #16]
15 }
16
17 ; CHECK-LABEL: fn3:
18 define arm_aapcs_vfpcc float @fn3(float %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, float %j) #0 {
19 ret float %j
20 ; CHECK: vldr s0, [sp, #8]
21 }
184184 else
185185 O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
186186 "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
187 if (Action->isSubClassOf("CCAssignToStackWithShadow"))
188 O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
189187 O << ");\n" << IndentStr
190188 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
189 << Counter << ", LocVT, LocInfo));\n";
190 O << IndentStr << "return false;\n";
191 } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
192 int Size = Action->getValueAsInt("Size");
193 int Align = Action->getValueAsInt("Align");
194 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
195
196 unsigned ShadowRegListNumber = ++Counter;
197
198 O << IndentStr << "static const uint16_t ShadowRegList"
199 << ShadowRegListNumber << "[] = {\n";
200 O << IndentStr << " ";
201 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
202 if (i != 0) O << ", ";
203 O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
204 }
205 O << "\n" << IndentStr << "};\n";
206
207 O << IndentStr << "unsigned Offset" << ++Counter
208 << " = State.AllocateStack("
209 << Size << ", " << Align << ", "
210 << "ShadowRegList" << ShadowRegListNumber << ", "
211 << ShadowRegList->getSize() << ");\n";
212 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
191213 << Counter << ", LocVT, LocInfo));\n";
192214 O << IndentStr << "return false;\n";
193215 } else if (Action->isSubClassOf("CCPromoteToType")) {