llvm.org GIT mirror llvm / e6c5643
This patch solves a problem with passing varargs parameters under the PPC64 ELF ABI. A varargs parameter consisting of a single-precision floating-point value, or of a single-element aggregate containing a single-precision floating-point value, must be passed in the low-order (rightmost) four bytes of the doubleword stack slot reserved for that parameter. If there are GPR protocol registers remaining, the parameter must also be mirrored in the low-order four bytes of the reserved GPR. Prior to this patch, such parameters were being passed in the high-order four bytes of the stack slot and the mirrored GPR. The patch adds a new test case to verify the correct code generation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166968 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Schmidt 7 years ago
2 changed file(s) with 34 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
37503750 RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
37513751
37523752 if (isVarArg) {
3753 SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff,
3753 // A single float or an aggregate containing only a single float
3754 // must be passed right-justified in the stack doubleword, and
3755 // in the GPR, if one is available.
3756 SDValue StoreOff;
3757 if (Arg.getValueType().getSimpleVT().SimpleTy == MVT::f32) {
3758 SDValue ConstFour = DAG.getConstant(4, PtrOff.getValueType());
3759 StoreOff = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, ConstFour);
3760 } else
3761 StoreOff = PtrOff;
3762
3763 SDValue Store = DAG.getStore(Chain, dl, Arg, StoreOff,
37543764 MachinePointerInfo(), false, false, 0);
37553765 MemOpChains.push_back(Store);
37563766
0 ; RUN: llc -mcpu=pwr7 -O0 < %s | FileCheck %s
1
2 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
3 target triple = "powerpc64-unknown-linux-gnu"
4
5 %struct.Sf1 = type { float }
6
7 define void @foo(float inreg %s.coerce) nounwind {
8 entry:
9 %s = alloca %struct.Sf1, align 4
10 %coerce.dive = getelementptr %struct.Sf1* %s, i32 0, i32 0
11 store float %s.coerce, float* %coerce.dive, align 1
12 %coerce.dive1 = getelementptr %struct.Sf1* %s, i32 0, i32 0
13 %0 = load float* %coerce.dive1, align 1
14 call void (i32, ...)* @testvaSf1(i32 1, float inreg %0)
15 ret void
16 }
17
18 ; CHECK: stfs {{[0-9]+}}, 60(1)
19 ; CHECK: ld 4, 56(1)
20 ; CHECK: bl
21
22 declare void @testvaSf1(i32, ...)