llvm.org GIT mirror llvm / a671f7f
Fix libcall expansion creating DAG nodes with invalid type post type legalization. If we are lowering a libcall after legalization, we'll split the return type into a pair of legal values. Patch by Jatin Bhateja and Eli Friedman. Differential Revision: https://reviews.llvm.org/D34240 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307207 91177308-0d34-0410-b5e6-96231b3b80d8 Vadim Chugunov 2 years ago
4 changed file(s) with 54 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
28262826 // TargetLowering::LowerCall that perform tail call conversions.
28272827 bool IsTailCall = false;
28282828
2829 // Is Call lowering done post SelectionDAG type legalization.
2830 bool IsPostTypeLegalization = false;
2831
28292832 unsigned NumFixedArgs = -1;
28302833 CallingConv::ID CallConv = CallingConv::C;
28312834 SDValue Callee;
29452948
29462949 CallLoweringInfo &setIsPatchPoint(bool Value = true) {
29472950 IsPatchPoint = Value;
2951 return *this;
2952 }
2953
2954 CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
2955 IsPostTypeLegalization = Value;
29482956 return *this;
29492957 }
29502958
19901990 std::move(Args))
19911991 .setTailCall(isTailCall)
19921992 .setSExtResult(isSigned)
1993 .setZExtResult(!isSigned);
1993 .setZExtResult(!isSigned)
1994 .setIsPostTypeLegalization(true);
19941995
19951996 std::pair CallInfo = TLI.LowerCallTo(CLI);
19961997
20282029 .setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
20292030 std::move(Args))
20302031 .setSExtResult(isSigned)
2031 .setZExtResult(!isSigned);
2032 .setZExtResult(!isSigned)
2033 .setIsPostTypeLegalization(true);
20322034
20332035 std::pair CallInfo = TLI.LowerCallTo(CLI);
20342036
35643566 SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
35653567 Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
35663568 }
3567 BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
3568 DAG.getIntPtrConstant(0, dl));
3569 TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
3570 DAG.getIntPtrConstant(1, dl));
3571 // Ret is a node with an illegal type. Because such things are not
3572 // generally permitted during this phase of legalization, make sure the
3573 // node has no more uses. The above EXTRACT_ELEMENT nodes should have been
3574 // folded.
3575 assert(Ret->use_empty() &&
3576 "Unexpected uses of illegally type from expanded lib call.");
3569 assert(Ret.getOpcode() == ISD::MERGE_VALUES &&
3570 "Ret value is a collection of constituent nodes holding result.");
3571 BottomHalf = Ret.getOperand(0);
3572 TopHalf = Ret.getOperand(1);
35773573 }
35783574
35793575 if (isSigned) {
78417841 auto &DL = CLI.DAG.getDataLayout();
78427842 ComputeValueVTs(*this, DL, CLI.RetTy, RetTys, &Offsets);
78437843
7844 if (CLI.IsPostTypeLegalization) {
7845 // If we are lowering a libcall after legalization, split the return type.
7846 SmallVector OldRetTys = std::move(RetTys);
7847 SmallVector OldOffsets = std::move(Offsets);
7848 for (size_t i = 0, e = OldRetTys.size(); i != e; ++i) {
7849 EVT RetVT = OldRetTys[i];
7850 uint64_t Offset = OldOffsets[i];
7851 MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), RetVT);
7852 unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), RetVT);
7853 unsigned RegisterVTSize = RegisterVT.getSizeInBits();
7854 RetTys.append(NumRegs, RegisterVT);
7855 for (unsigned j = 0; j != NumRegs; ++j)
7856 Offsets.push_back(Offset + j * RegisterVTSize);
7857 }
7858 }
7859
78447860 SmallVector Outs;
78457861 GetReturnInfo(CLI.RetTy, getReturnAttrs(CLI), Outs, *this, DL);
78467862
79237939 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
79247940 SmallVector ValueVTs;
79257941 ComputeValueVTs(*this, DL, Args[i].Ty, ValueVTs);
7942 // FIXME: Split arguments if CLI.IsPostTypeLegalization
79267943 Type *FinalType = Args[i].Ty;
79277944 if (Args[i].IsByVal)
79287945 FinalType = cast(Args[i].Ty)->getElementType();
0 ; RUN: llc < %s -asm-verbose=false | FileCheck %s
1 ; Test that UMULO works correctly on 64-bit operands.
2 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
3 target triple = "wasm32-unknown-emscripten"
4
5 ; CHECK-LABEL: _ZN4core3num21_$LT$impl$u20$u64$GT$15overflowing_mul17h07be88b4cbac028fE:
6 ; CHECK: __multi3
7 ; Function Attrs: inlinehint
8 define void @"_ZN4core3num21_$LT$impl$u20$u64$GT$15overflowing_mul17h07be88b4cbac028fE"(i64, i64) unnamed_addr #0 {
9 start:
10 %2 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %0, i64 %1)
11 %3 = extractvalue { i64, i1 } %2, 0
12 store i64 %3, i64* undef
13 unreachable
14 }
15
16 ; Function Attrs: nounwind readnone speculatable
17 declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64) #1
18
19 attributes #0 = { inlinehint }
20 attributes #1 = { nounwind readnone speculatable }