@@ -1380,7 +1380,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1380
1380
// After all vararg is processed, 'VAOffset' holds the size of the
1381
1381
// vararg byte array.
1382
1382
1383
- SDValue VADeclareParam; // vararg byte array
1383
+ SDValue VADeclareParam = SDValue (); // vararg byte array
1384
1384
const unsigned FirstVAArg = CLI.NumFixedArgs ; // position of first variadic
1385
1385
unsigned VAOffset = 0 ; // current offset in the param array
1386
1386
@@ -1583,8 +1583,6 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1583
1583
VAOffset += TypeSize;
1584
1584
}
1585
1585
1586
- GlobalAddressSDNode *Func = dyn_cast<GlobalAddressSDNode>(Callee.getNode ());
1587
-
1588
1586
// Handle Result
1589
1587
if (!Ins.empty ()) {
1590
1588
const SDValue RetSymbol = DAG.getExternalSymbol (" retval0" , MVT::i32 );
@@ -1597,10 +1595,9 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1597
1595
}
1598
1596
}
1599
1597
1600
- const bool HasVAArgs = CLI.IsVarArg && (CLI.Args .size () > CLI.NumFixedArgs );
1601
1598
// Set the size of the vararg param byte array if the callee is a variadic
1602
1599
// function and the variadic part is not empty.
1603
- if (HasVAArgs ) {
1600
+ if (VADeclareParam ) {
1604
1601
SDValue DeclareParamOps[] = {VADeclareParam.getOperand (0 ),
1605
1602
VADeclareParam.getOperand (1 ),
1606
1603
VADeclareParam.getOperand (2 ), GetI32 (VAOffset),
@@ -1609,6 +1606,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1609
1606
VADeclareParam->getVTList (), DeclareParamOps);
1610
1607
}
1611
1608
1609
+ const auto *Func = dyn_cast<GlobalAddressSDNode>(Callee.getNode ());
1612
1610
// If the type of the callsite does not match that of the function, convert
1613
1611
// the callsite to an indirect call.
1614
1612
const bool ConvertToIndirectCall = shouldConvertToIndirectCall (CB, Func);
@@ -1638,6 +1636,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1638
1636
// instruction.
1639
1637
// The prototype is embedded in a string and put as the operand for a
1640
1638
// CallPrototype SDNode which will print out to the value of the string.
1639
+ const bool HasVAArgs = CLI.IsVarArg && (CLI.Args .size () > CLI.NumFixedArgs );
1641
1640
std::string Proto =
1642
1641
getPrototype (DL, RetTy, Args, CLI.Outs ,
1643
1642
HasVAArgs ? std::optional (FirstVAArg) : std::nullopt, *CB,
@@ -5540,6 +5539,15 @@ static SDValue combineADDRSPACECAST(SDNode *N,
5540
5539
return SDValue ();
5541
5540
}
5542
5541
5542
+ // During call lowering we wrap the return values in a ProxyReg node which depend
5543
+ // on the chain value produced by the completed call. This ensures that the
5544
+ // full call is emitted in cases where libcalls are used to legalize operations.
5545
+ // To improve the functioning of other DAG combines we pull all operations we
5546
+ // can through one of these nodes, ensuring that the ProxyReg directly wraps a
5547
+ // load. That is:
5548
+ //
5549
+ // (ProxyReg (zext (load retval0))) => (zext (ProxyReg (load retval0)))
5550
+ //
5543
5551
static SDValue sinkProxyReg (SDValue R, SDValue Chain,
5544
5552
TargetLowering::DAGCombinerInfo &DCI) {
5545
5553
switch (R.getOpcode ()) {
@@ -5593,6 +5601,8 @@ static SDValue combineProxyReg(SDNode *N,
5593
5601
SDValue Chain = N->getOperand (0 );
5594
5602
SDValue Reg = N->getOperand (1 );
5595
5603
5604
+ // If the ProxyReg is not wrapping a load, try to pull the operations through
5605
+ // the ProxyReg.
5596
5606
if (Reg.getOpcode () != ISD::LOAD) {
5597
5607
if (SDValue V = sinkProxyReg (Reg, Chain, DCI))
5598
5608
return V;
0 commit comments