Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 6f2104a

Browse files
committed
[PowerPC] Fix the calling convention for i1 arguments on PPC32
Summary: Integer types smaller than i32 must be extended to i32 by default. The feature "crbits" introduced at r202451 handles i1 as a special case, but it did not extend properly. The caller was, therefore, passing i1 stack arguments by writing 0/1 to the first byte of the 4-byte stack object and callee was reading the first byte for the value. "crbits" is enabled if the optimization level is greater than 1, which is very common in "release builds". Such discrepancies with ABI specification also introduces potential incompatibility with programs or libraries built with other compilers e.g. GCC. Fixes PR38661 Reviewers: hfinkel, cuviper Subscribers: sylvestre.ledru, glaubitz, nagisa, nemanjai, kbarton, llvm-commits Differential Revision: https://reviews.llvm.org/D51108
1 parent 5a081f0 commit 6f2104a

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,9 +3510,14 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
35103510
// Argument stored in memory.
35113511
assert(VA.isMemLoc());
35123512

3513+
// Get the extended size of the argument type in stack
35133514
unsigned ArgSize = VA.getLocVT().getStoreSize();
3514-
int FI = MFI.CreateFixedObject(ArgSize, VA.getLocMemOffset(),
3515-
isImmutable);
3515+
// Get the actual size of the argument type
3516+
unsigned ObjSize = VA.getValVT().getStoreSize();
3517+
unsigned ArgOffset = VA.getLocMemOffset();
3518+
// Stack objects in PPC32 are right justified.
3519+
ArgOffset += ArgSize - ObjSize;
3520+
int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, isImmutable);
35163521

35173522
// Create load nodes to retrieve arguments from the stack.
35183523
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
@@ -5467,10 +5472,15 @@ SDValue PPCTargetLowering::LowerCall_32SVR4(
54675472
Arg = PtrOff;
54685473
}
54695474

5470-
if (VA.isRegLoc()) {
5471-
if (Arg.getValueType() == MVT::i1)
5472-
Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Arg);
5475+
// When useCRBits() is true, there can be i1 arguments.
5476+
// It is because getRegisterType(MVT::i1) => MVT::i1,
5477+
// and for other integer types getRegisterType() => MVT::i32.
5478+
// Extend i1 and ensure callee will get i32.
5479+
if (Arg.getValueType() == MVT::i1)
5480+
Arg = DAG.getNode(Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
5481+
dl, MVT::i32, Arg);
54735482

5483+
if (VA.isRegLoc()) {
54745484
seenFloatArg |= VA.getLocVT().isFloatingPoint();
54755485
// Put argument in a physical register.
54765486
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: llc -verify-machineinstrs < %s -mcpu=ppc32 -mattr=+crbits | FileCheck %s
2+
target triple = "powerpc-unknown-linux-gnu"
3+
4+
define void @check_callee(
5+
i32, i32, i32, i32,
6+
i32, i32, i32, i32,
7+
i1 zeroext %s1
8+
) {
9+
call void @check_caller(
10+
i32 9, i32 9, i32 9, i32 9,
11+
i32 9, i32 9, i32 9, i32 9,
12+
i1 zeroext %s1)
13+
ret void
14+
}
15+
16+
; CHECK-LABEL: @check_callee
17+
; CHECK: lbz {{[0-9]+}}, 27(1)
18+
; CHECK: stw {{[0-9]+}}, 8(1)
19+
20+
declare void @check_caller(
21+
i32, i32, i32, i32,
22+
i32, i32, i32, i32,
23+
i1 zeroext
24+
)

0 commit comments

Comments
 (0)