From 57d54664d6ca4b779c1a7dae17871a93cc10dedc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Jun 2018 03:18:38 +0000 Subject: [PATCH] [WebAssembly] Fix lowering of varargs functions with non-legal fixed arguments. CallLoweringInfo's NumFixedArgs field gives the number of fixed arguments before legalization. The ISD::OutputArg "Outs" array holds legalized arguments, so when indexing into it to find the non-fixed arguemn, we need to use the number of arguments after legalization. Fixes PR37934. llvm-svn: 335576 --- .../WebAssembly/WebAssemblyISelLowering.cpp | 5 +++-- test/CodeGen/WebAssembly/varargs.ll | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 52b1e18c8a4..633af3e8752 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -487,6 +487,7 @@ SDValue WebAssemblyTargetLowering::LowerCall( SmallVectorImpl &Outs = CLI.Outs; SmallVectorImpl &OutVals = CLI.OutVals; + unsigned NumFixedArgs = 0; for (unsigned i = 0; i < Outs.size(); ++i) { const ISD::OutputArg &Out = Outs[i]; SDValue &OutVal = OutVals[i]; @@ -512,11 +513,11 @@ SDValue WebAssemblyTargetLowering::LowerCall( /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo()); OutVal = FINode; } + // Count the number of fixed args *after* legalization. + NumFixedArgs += Out.IsFixed; } bool IsVarArg = CLI.IsVarArg; - unsigned NumFixedArgs = CLI.NumFixedArgs; - auto PtrVT = getPointerTy(Layout); // Analyze operands of the call, assigning locations to each operand. diff --git a/test/CodeGen/WebAssembly/varargs.ll b/test/CodeGen/WebAssembly/varargs.ll index acd35c3b4a9..0e26ab4959b 100644 --- a/test/CodeGen/WebAssembly/varargs.ll +++ b/test/CodeGen/WebAssembly/varargs.ll @@ -143,6 +143,27 @@ bb1: ret void } +; Test a call to a varargs function with a non-legal fixed argument. + +declare void @callee_with_nonlegal_fixed(fp128, ...) nounwind + +; CHECK-LABEL: call_nonlegal_fixed: +; CHECK: i64.const $push[[L0:[0-9]+]]=, 0 +; CHECK: i64.const $push[[L1:[0-9]+]]=, 0 +; CHECK: i32.const $push[[L2:[0-9]+]]=, 0 +; CHECK: call callee_with_nonlegal_fixed@FUNCTION, $pop[[L0]], $pop[[L1]], $pop[[L2]]{{$}} +define void @call_nonlegal_fixed() nounwind { + call void (fp128, ...) @callee_with_nonlegal_fixed(fp128 0xL00000000000000000000000000000000) + ret void +} + +; Test a definition a varargs function with a non-legal fixed argument. + +; CHECK-LABEL: nonlegal_fixed: +; CHECK-NEXT: .param i64, i64, i32{{$}} +define void @nonlegal_fixed(fp128 %x, ...) nounwind { + ret void +} declare void @llvm.va_start(i8*) declare void @llvm.va_end(i8*)