[PATCH] 128-bit ABI for x86_64-w64-mingw32 incorrectly generated
Jameson Nash
vtjnash at gmail.com
Sat Apr 19 23:14:36 PDT 2014
move logic to TargetLowering::LowerCallTo
this significantly simplifies the change, while moving it to a more sensible location
http://reviews.llvm.org/D1998
CHANGE SINCE LAST DIFF
http://reviews.llvm.org/D1998?vs=8668&id=8673#toc
Files:
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
test/CodeGen/X86/mod128.ll
Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/ConstantFolding.h"
@@ -6989,10 +6990,26 @@
/// migrated to using LowerCall, this hook should be integrated into SDISel.
std::pair<SDValue, SDValue>
TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
+ Triple Trip(CLI.DAG.getTarget().getTargetTriple());
+ int Win64 = Trip.isArch64Bit() && Trip.isOSMSVCRT();
+
// Handle the incoming return values from the call.
CLI.Ins.clear();
SmallVector<EVT, 4> RetTys;
ComputeValueVTs(*this, CLI.RetTy, RetTys);
+ bool ret_m128 = false; EVT RetVT_m128;
+ if (Win64 && RetTys.size() == 1) {
+ EVT VT = RetTys[0];
+ if ((VT.isFloatingPoint() || VT.isInteger()) && VT.getSizeInBits() == 128) {
+ // change the return type to something llvm can represent, that
+ // we know will end up in the xmm0 register. we will patch up the
+ // return type later in this function
+ RetTys[0] = static_cast<EVT>(MVT::v2i64);
+ CLI.IsTailCall = false;
+ ret_m128 = true;
+ RetVT_m128 = VT;
+ }
+ }
for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
EVT VT = RetTys[I];
MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), VT);
@@ -7018,7 +7035,22 @@
ArgListTy &Args = CLI.Args;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
SmallVector<EVT, 4> ValueVTs;
- ComputeValueVTs(*this, Args[i].Ty, ValueVTs);
+ TargetLowering::ArgListEntry Entry = Args[i];
+ if (Win64 && Entry.Node.getValueType().getSizeInBits() > 64) {
+ SDValue StackPtr = CLI.DAG.CreateStackTemporary(Entry.Node.getValueType(), 16);
+ int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
+ MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(SPFI);
+ // Emit a store to the stack slot.
+ CLI.Chain = CLI.DAG.getStore(CLI.Chain, CLI.DL, Entry.Node, StackPtr, PtrInfo,
+ false, false, 16);
+ Entry.Node = StackPtr;
+ Entry.Ty = PointerType::get(Entry.Ty,0);
+ Entry.isSExt = false;
+ Entry.isZExt = false;
+ Args[i] = Entry;
+ CLI.IsTailCall = false;
+ }
+ ComputeValueVTs(*this, Entry.Ty, ValueVTs);
for (unsigned Value = 0, NumValues = ValueVTs.size();
Value != NumValues; ++Value) {
EVT VT = ValueVTs[Value];
@@ -7160,6 +7192,8 @@
SDValue Res = CLI.DAG.getNode(ISD::MERGE_VALUES, CLI.DL,
CLI.DAG.getVTList(&RetTys[0], RetTys.size()),
&ReturnValues[0], ReturnValues.size());
+ if (ret_m128)
+ Res = CLI.DAG.getNode(ISD::BITCAST, CLI.DL, RetVT_m128, Res);
return std::make_pair(Res, CLI.Chain);
}
Index: test/CodeGen/X86/mod128.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/mod128.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64
+; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64
+
+define i128 @mod128(i128 %x) nounwind {
+ ; X86-64: movl $3, %edx
+ ; X86-64: xorl %ecx, %ecx
+ ; X86-64: callq __modti3
+
+ ; WIN64-NOT: movl $3, %r8d
+ ; WIN64-NOT: xorl %r9d, %r9d
+ ; WIN64: callq __modti3
+
+ %1 = srem i128 %x, 3
+ ret i128 %1
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1998.4.patch
Type: text/x-patch
Size: 3734 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140419/a27415a8/attachment.bin>
More information about the llvm-commits
mailing list