@@ -1405,7 +1405,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
14051405 // After all vararg is processed, 'VAOffset' holds the size of the
14061406 // vararg byte array.
14071407
1408- SDValue VADeclareParam; // vararg byte array
1408+ SDValue VADeclareParam = SDValue (); // vararg byte array
14091409 const unsigned FirstVAArg = CLI.NumFixedArgs ; // position of first variadic
14101410 unsigned VAOffset = 0 ; // current offset in the param array
14111411
@@ -1608,8 +1608,6 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
16081608 VAOffset += TypeSize;
16091609 }
16101610
1611- GlobalAddressSDNode *Func = dyn_cast<GlobalAddressSDNode>(Callee.getNode ());
1612-
16131611 // Handle Result
16141612 if (!Ins.empty ()) {
16151613 const SDValue RetSymbol = DAG.getExternalSymbol (" retval0" , MVT::i32 );
@@ -1622,10 +1620,9 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
16221620 }
16231621 }
16241622
1625- const bool HasVAArgs = CLI.IsVarArg && (CLI.Args .size () > CLI.NumFixedArgs );
16261623 // Set the size of the vararg param byte array if the callee is a variadic
16271624 // function and the variadic part is not empty.
1628- if (HasVAArgs ) {
1625+ if (VADeclareParam ) {
16291626 SDValue DeclareParamOps[] = {VADeclareParam.getOperand (0 ),
16301627 VADeclareParam.getOperand (1 ),
16311628 VADeclareParam.getOperand (2 ), GetI32 (VAOffset),
@@ -1634,6 +1631,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
16341631 VADeclareParam->getVTList (), DeclareParamOps);
16351632 }
16361633
1634+ const auto *Func = dyn_cast<GlobalAddressSDNode>(Callee.getNode ());
16371635 // If the type of the callsite does not match that of the function, convert
16381636 // the callsite to an indirect call.
16391637 const bool ConvertToIndirectCall = shouldConvertToIndirectCall (CB, Func);
@@ -1663,6 +1661,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
16631661 // instruction.
16641662 // The prototype is embedded in a string and put as the operand for a
16651663 // CallPrototype SDNode which will print out to the value of the string.
1664+ const bool HasVAArgs = CLI.IsVarArg && (CLI.Args .size () > CLI.NumFixedArgs );
16661665 std::string Proto =
16671666 getPrototype (DL, RetTy, Args, CLI.Outs ,
16681667 HasVAArgs ? std::optional (FirstVAArg) : std::nullopt , *CB,
@@ -5732,6 +5731,15 @@ static SDValue combinePRMT(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
57325731}
57335732
57345733
5734+ // During call lowering we wrap the return values in a ProxyReg node which
5735+ // depend on the chain value produced by the completed call. This ensures that
5736+ // the full call is emitted in cases where libcalls are used to legalize
5737+ // operations. To improve the functioning of other DAG combines we pull all
5738+ // operations we can through one of these nodes, ensuring that the ProxyReg
5739+ // directly wraps a load. That is:
5740+ //
5741+ // (ProxyReg (zext (load retval0))) => (zext (ProxyReg (load retval0)))
5742+ //
57355743static SDValue sinkProxyReg (SDValue R, SDValue Chain,
57365744 TargetLowering::DAGCombinerInfo &DCI) {
57375745 switch (R.getOpcode ()) {
@@ -5785,6 +5793,8 @@ static SDValue combineProxyReg(SDNode *N,
57855793 SDValue Chain = N->getOperand (0 );
57865794 SDValue Reg = N->getOperand (1 );
57875795
5796+ // If the ProxyReg is not wrapping a load, try to pull the operations through
5797+ // the ProxyReg.
57885798 if (Reg.getOpcode () != ISD::LOAD) {
57895799 if (SDValue V = sinkProxyReg (Reg, Chain, DCI))
57905800 return V;
0 commit comments