@@ -974,8 +974,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
974
974
FlatSymbolRefAttr callee, ValueRange args) {
975
975
assert (callee && " expected non-null callee in direct call builder" );
976
976
build (builder, state, results,
977
- TypeAttr::get ( getLLVMFuncType (builder. getContext (), results , args)) ,
978
- callee, args, /* fastmathFlags= */ nullptr , /* branch_weights=*/ nullptr ,
977
+ /* callee_type= */ nullptr , callee , args, /* fastmathFlags= */ nullptr ,
978
+ /* branch_weights=*/ nullptr ,
979
979
/* CConv=*/ nullptr , /* TailCallKind=*/ nullptr ,
980
980
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
981
981
/* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
@@ -996,17 +996,21 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
996
996
void CallOp::build (OpBuilder &builder, OperationState &state,
997
997
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
998
998
ValueRange args) {
999
- build (builder, state, getCallOpResultTypes (calleeType),
1000
- TypeAttr::get (calleeType), callee, args, /* fastmathFlags=*/ nullptr ,
999
+ auto varArgCalleeType =
1000
+ calleeType.isVarArg () ? TypeAttr::get (calleeType) : nullptr ;
1001
+ build (builder, state, getCallOpResultTypes (calleeType), varArgCalleeType,
1002
+ callee, args, /* fastmathFlags=*/ nullptr ,
1001
1003
/* branch_weights=*/ nullptr , /* CConv=*/ nullptr ,
1002
1004
/* TailCallKind=*/ nullptr , /* access_groups=*/ nullptr ,
1003
1005
/* alias_scopes=*/ nullptr , /* noalias_scopes=*/ nullptr , /* tbaa=*/ nullptr );
1004
1006
}
1005
1007
1006
1008
void CallOp::build (OpBuilder &builder, OperationState &state,
1007
1009
LLVMFunctionType calleeType, ValueRange args) {
1008
- build (builder, state, getCallOpResultTypes (calleeType),
1009
- TypeAttr::get (calleeType), /* callee=*/ nullptr , args,
1010
+ auto varArgCalleeType =
1011
+ calleeType.isVarArg () ? TypeAttr::get (calleeType) : nullptr ;
1012
+ build (builder, state, getCallOpResultTypes (calleeType), varArgCalleeType,
1013
+ /* callee=*/ nullptr , args,
1010
1014
/* fastmathFlags=*/ nullptr , /* branch_weights=*/ nullptr ,
1011
1015
/* CConv=*/ nullptr , /* TailCallKind=*/ nullptr ,
1012
1016
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
@@ -1016,8 +1020,10 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
1016
1020
void CallOp::build (OpBuilder &builder, OperationState &state, LLVMFuncOp func,
1017
1021
ValueRange args) {
1018
1022
auto calleeType = func.getFunctionType ();
1019
- build (builder, state, getCallOpResultTypes (calleeType),
1020
- TypeAttr::get (calleeType), SymbolRefAttr::get (func), args,
1023
+ auto varArgCalleeType =
1024
+ calleeType.isVarArg () ? TypeAttr::get (calleeType) : nullptr ;
1025
+ build (builder, state, getCallOpResultTypes (calleeType), varArgCalleeType,
1026
+ SymbolRefAttr::get (func), args,
1021
1027
/* fastmathFlags=*/ nullptr , /* branch_weights=*/ nullptr ,
1022
1028
/* CConv=*/ nullptr , /* TailCallKind=*/ nullptr ,
1023
1029
/* access_groups=*/ nullptr , /* alias_scopes=*/ nullptr ,
@@ -1080,6 +1086,11 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
1080
1086
if (getNumResults () > 1 )
1081
1087
return emitOpError (" must have 0 or 1 result" );
1082
1088
1089
+ // If the callee type attribute is present, it must be variadic.
1090
+ if (std::optional<LLVMFunctionType> calleeType = getCalleeType ())
1091
+ if (!calleeType->isVarArg ())
1092
+ return emitOpError (" expected variadic callee type attribute" );
1093
+
1083
1094
// Type for the callee, we'll get it differently depending if it is a direct
1084
1095
// or indirect call.
1085
1096
Type fnType;
@@ -1168,14 +1179,6 @@ void CallOp::print(OpAsmPrinter &p) {
1168
1179
auto callee = getCallee ();
1169
1180
bool isDirect = callee.has_value ();
1170
1181
1171
- LLVMFunctionType calleeType;
1172
- bool isVarArg = false ;
1173
-
1174
- if (std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType ()) {
1175
- calleeType = *optionalCalleeType;
1176
- isVarArg = calleeType.isVarArg ();
1177
- }
1178
-
1179
1182
p << ' ' ;
1180
1183
1181
1184
// Print calling convention.
@@ -1195,8 +1198,9 @@ void CallOp::print(OpAsmPrinter &p) {
1195
1198
auto args = getOperands ().drop_front (isDirect ? 0 : 1 );
1196
1199
p << ' (' << args << ' )' ;
1197
1200
1198
- if (isVarArg)
1199
- p << " vararg(" << calleeType << " )" ;
1201
+ // Print the callee type if the call is variadic.
1202
+ if (std::optional<LLVMFunctionType> calleeType = getCalleeType ())
1203
+ p << " vararg(" << *calleeType << " )" ;
1200
1204
1201
1205
p.printOptionalAttrDict (processFMFAttr ((*this )->getAttrs ()),
1202
1206
{getCConvAttrName (), " callee" , " callee_type" ,
@@ -1333,27 +1337,30 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
1333
1337
ValueRange ops, Block *normal , ValueRange normalOps,
1334
1338
Block *unwind, ValueRange unwindOps) {
1335
1339
auto calleeType = func.getFunctionType ();
1336
- build (builder, state, getCallOpResultTypes (calleeType),
1337
- TypeAttr::get (calleeType), SymbolRefAttr::get (func), ops, normalOps,
1338
- unwindOps, nullptr , nullptr , normal , unwind);
1340
+ auto varArgCalleeType =
1341
+ calleeType.isVarArg () ? TypeAttr::get (calleeType) : nullptr ;
1342
+ build (builder, state, getCallOpResultTypes (calleeType), varArgCalleeType,
1343
+ SymbolRefAttr::get (func), ops, normalOps, unwindOps, nullptr , nullptr ,
1344
+ normal , unwind);
1339
1345
}
1340
1346
1341
1347
void InvokeOp::build (OpBuilder &builder, OperationState &state, TypeRange tys,
1342
1348
FlatSymbolRefAttr callee, ValueRange ops, Block *normal ,
1343
1349
ValueRange normalOps, Block *unwind,
1344
1350
ValueRange unwindOps) {
1345
1351
build (builder, state, tys,
1346
- TypeAttr::get ( getLLVMFuncType (builder. getContext (), tys , ops)), callee ,
1347
- ops, normalOps, unwindOps, nullptr , nullptr , normal , unwind);
1352
+ /* callee_type= */ nullptr , callee , ops, normalOps, unwindOps, nullptr ,
1353
+ nullptr , normal , unwind);
1348
1354
}
1349
1355
1350
1356
void InvokeOp::build (OpBuilder &builder, OperationState &state,
1351
1357
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
1352
1358
ValueRange ops, Block *normal , ValueRange normalOps,
1353
1359
Block *unwind, ValueRange unwindOps) {
1354
- build (builder, state, getCallOpResultTypes (calleeType),
1355
- TypeAttr::get (calleeType), callee, ops, normalOps, unwindOps, nullptr ,
1356
- nullptr , normal , unwind);
1360
+ auto varArgCalleeType =
1361
+ calleeType.isVarArg () ? TypeAttr::get (calleeType) : nullptr ;
1362
+ build (builder, state, getCallOpResultTypes (calleeType), varArgCalleeType,
1363
+ callee, ops, normalOps, unwindOps, nullptr , nullptr , normal , unwind);
1357
1364
}
1358
1365
1359
1366
SuccessorOperands InvokeOp::getSuccessorOperands (unsigned index) {
@@ -1393,6 +1400,11 @@ LogicalResult InvokeOp::verify() {
1393
1400
if (getNumResults () > 1 )
1394
1401
return emitOpError (" must have 0 or 1 result" );
1395
1402
1403
+ // If the callee type attribute is present, it must be variadic.
1404
+ if (std::optional<LLVMFunctionType> calleeType = getCalleeType ())
1405
+ if (!calleeType->isVarArg ())
1406
+ return emitOpError (" expected variadic callee type attribute" );
1407
+
1396
1408
Block *unwindDest = getUnwindDest ();
1397
1409
if (unwindDest->empty ())
1398
1410
return emitError (" must have at least one operation in unwind destination" );
@@ -1409,14 +1421,6 @@ void InvokeOp::print(OpAsmPrinter &p) {
1409
1421
auto callee = getCallee ();
1410
1422
bool isDirect = callee.has_value ();
1411
1423
1412
- LLVMFunctionType calleeType;
1413
- bool isVarArg = false ;
1414
-
1415
- if (std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType ()) {
1416
- calleeType = *optionalCalleeType;
1417
- isVarArg = calleeType.isVarArg ();
1418
- }
1419
-
1420
1424
p << ' ' ;
1421
1425
1422
1426
// Print calling convention.
@@ -1435,8 +1439,9 @@ void InvokeOp::print(OpAsmPrinter &p) {
1435
1439
p << " unwind " ;
1436
1440
p.printSuccessorAndUseList (getUnwindDest (), getUnwindDestOperands ());
1437
1441
1438
- if (isVarArg)
1439
- p << " vararg(" << calleeType << " )" ;
1442
+ // Print the callee type if the invoke is variadic.
1443
+ if (std::optional<LLVMFunctionType> calleeType = getCalleeType ())
1444
+ p << " vararg(" << *calleeType << " )" ;
1440
1445
1441
1446
p.printOptionalAttrDict ((*this )->getAttrs (),
1442
1447
{InvokeOp::getOperandSegmentSizeAttr (), " callee" ,
0 commit comments