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

Backport some wasm fixes #98

Merged
merged 2 commits into from
Nov 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -2589,6 +2589,9 @@ class TargetLowering : public TargetLoweringBase {
// TargetLowering::LowerCall that perform tail call conversions.
bool IsTailCall;

// Is Call lowering done post SelectionDAG type legalization.
bool IsPostTypeLegalization = false;

unsigned NumFixedArgs;
CallingConv::ID CallConv;
SDValue Callee;
Expand Down Expand Up @@ -2714,6 +2717,11 @@ class TargetLowering : public TargetLoweringBase {
return *this;
}

CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
IsPostTypeLegalization = Value;
return *this;
}

ArgListTy &getArgs() {
return Args;
}
Expand Down
20 changes: 8 additions & 12 deletions lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
std::move(Args))
.setTailCall(isTailCall)
.setSExtResult(isSigned)
.setZExtResult(!isSigned);
.setZExtResult(!isSigned)
.setIsPostTypeLegalization(true);

std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);

Expand Down Expand Up @@ -1979,7 +1980,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, EVT RetVT,
.setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
std::move(Args))
.setSExtResult(isSigned)
.setZExtResult(!isSigned);
.setZExtResult(!isSigned)
.setIsPostTypeLegalization(true);

std::pair<SDValue,SDValue> CallInfo = TLI.LowerCallTo(CLI);

Expand Down Expand Up @@ -3525,16 +3527,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
}
BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
DAG.getIntPtrConstant(0, dl));
TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
DAG.getIntPtrConstant(1, dl));
// Ret is a node with an illegal type. Because such things are not
// generally permitted during this phase of legalization, make sure the
// node has no more uses. The above EXTRACT_ELEMENT nodes should have been
// folded.
assert(Ret->use_empty() &&
"Unexpected uses of illegally type from expanded lib call.");
assert(Ret.getOpcode() == ISD::MERGE_VALUES &&
"Ret value is a collection of constituent nodes holding result.");
BottomHalf = Ret.getOperand(0);
TopHalf = Ret.getOperand(1);
}

if (isSigned) {
Expand Down
17 changes: 17 additions & 0 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7658,6 +7658,22 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
auto &DL = CLI.DAG.getDataLayout();
ComputeValueVTs(*this, DL, CLI.RetTy, RetTys, &Offsets);

if (CLI.IsPostTypeLegalization) {
// If we are lowering a libcall after legalization, split the return type.
SmallVector<EVT, 4> OldRetTys = std::move(RetTys);
SmallVector<uint64_t, 4> OldOffsets = std::move(Offsets);
for (size_t i = 0, e = OldRetTys.size(); i != e; ++i) {
EVT RetVT = OldRetTys[i];
uint64_t Offset = OldOffsets[i];
MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), RetVT);
unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), RetVT);
unsigned RegisterVTByteSZ = RegisterVT.getSizeInBits() / 8;
RetTys.append(NumRegs, RegisterVT);
for (unsigned j = 0; j != NumRegs; ++j)
Offsets.push_back(Offset + j * RegisterVTByteSZ);
}
}

SmallVector<ISD::OutputArg, 4> Outs;
GetReturnInfo(CLI.RetTy, getReturnAttrs(CLI), Outs, *this, DL);

Expand Down Expand Up @@ -7738,6 +7754,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
SmallVector<EVT, 4> ValueVTs;
ComputeValueVTs(*this, DL, Args[i].Ty, ValueVTs);
// FIXME: Split arguments if CLI.IsPostTypeLegalization
Type *FinalType = Args[i].Ty;
if (Args[i].isByVal)
FinalType = cast<PointerType>(Args[i].Ty)->getElementType();
Expand Down
32 changes: 32 additions & 0 deletions test/CodeGen/WebAssembly/umulo-i64.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
; RUN: llc < %s -asm-verbose=false | FileCheck %s
; Test that UMULO works correctly on 64-bit operands.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"

; CHECK-LABEL: _ZN4core3num21_$LT$impl$u20$u64$GT$15overflowing_mul17h07be88b4cbac028fE:
; CHECK: __multi3
; Function Attrs: inlinehint
define void @"_ZN4core3num21_$LT$impl$u20$u64$GT$15overflowing_mul17h07be88b4cbac028fE"(i64, i64) unnamed_addr #0 {
start:
%2 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %0, i64 %1)
%3 = extractvalue { i64, i1 } %2, 0
store i64 %3, i64* undef
unreachable
}

; Function Attrs: nounwind readnone speculatable
declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64) #1

attributes #0 = { inlinehint }
attributes #1 = { nounwind readnone speculatable }

; CHECK-LABEL: wut:
; CHECK: call __multi3@FUNCTION, $2, $0, $pop0, $1, $pop10
; CHECK: i64.load $0=, 8($2)
define i1 @wut(i64, i64) {
start:
%2 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %0, i64 %1)
%3 = extractvalue { i64, i1 } %2, 1
ret i1 %3
}