[llvm] r342288 - [PowerPC] Fix the calling convention for i1 arguments on PPC32

Lion Yang via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 14 14:26:05 PDT 2018


Author: lionnatsu
Date: Fri Sep 14 14:26:05 2018
New Revision: 342288

URL: http://llvm.org/viewvc/llvm-project?rev=342288&view=rev
Log:
[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

Added:
    llvm/trunk/test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=342288&r1=342287&r2=342288&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Sep 14 14:26:05 2018
@@ -3511,9 +3511,14 @@ SDValue PPCTargetLowering::LowerFormalAr
       // Argument stored in memory.
       assert(VA.isMemLoc());
 
+      // Get the extended size of the argument type in stack
       unsigned ArgSize = VA.getLocVT().getStoreSize();
-      int FI = MFI.CreateFixedObject(ArgSize, VA.getLocMemOffset(),
-                                     isImmutable);
+      // Get the actual size of the argument type
+      unsigned ObjSize = VA.getValVT().getStoreSize();
+      unsigned ArgOffset = VA.getLocMemOffset();
+      // Stack objects in PPC32 are right justified.
+      ArgOffset += ArgSize - ObjSize;
+      int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, isImmutable);
 
       // Create load nodes to retrieve arguments from the stack.
       SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
@@ -5468,10 +5473,15 @@ SDValue PPCTargetLowering::LowerCall_32S
       Arg = PtrOff;
     }
 
-    if (VA.isRegLoc()) {
-      if (Arg.getValueType() == MVT::i1)
-        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Arg);
+    // When useCRBits() is true, there can be i1 arguments.
+    // It is because getRegisterType(MVT::i1) => MVT::i1,
+    // and for other integer types getRegisterType() => MVT::i32.
+    // Extend i1 and ensure callee will get i32.
+    if (Arg.getValueType() == MVT::i1)
+      Arg = DAG.getNode(Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+                        dl, MVT::i32, Arg);
 
+    if (VA.isRegLoc()) {
       seenFloatArg |= VA.getLocVT().isFloatingPoint();
       // Put argument in a physical register.
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));

Added: llvm/trunk/test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll?rev=342288&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll Fri Sep 14 14:26:05 2018
@@ -0,0 +1,24 @@
+; RUN: llc -verify-machineinstrs < %s -mcpu=ppc32 -mattr=+crbits | FileCheck %s
+target triple = "powerpc-unknown-linux-gnu"
+
+define void @check_callee(
+  i32, i32, i32, i32,
+  i32, i32, i32, i32,
+  i1 zeroext %s1
+) {
+  call void @check_caller(
+    i32 9, i32 9, i32 9, i32 9,
+    i32 9, i32 9, i32 9, i32 9,
+    i1 zeroext %s1)
+  ret void
+}
+
+; CHECK-LABEL: @check_callee
+; CHECK: lbz {{[0-9]+}}, 27(1)
+; CHECK: stw {{[0-9]+}}, 8(1)
+
+declare void @check_caller(
+  i32, i32, i32, i32,
+  i32, i32, i32, i32,
+  i1 zeroext
+)




More information about the llvm-commits mailing list