@@ -1429,6 +1429,30 @@ struct LegalizeWGSLEntryPointContext
1429
1429
}
1430
1430
}
1431
1431
1432
+ void legalizeFunc (IRFunc* func)
1433
+ {
1434
+ // Insert casts to convert integer return types
1435
+ auto funcReturnType = func->getResultType ();
1436
+ if (isIntegralType (funcReturnType))
1437
+ {
1438
+ for (auto block : func->getBlocks ())
1439
+ {
1440
+ if (auto returnInst = as<IRReturn>(block->getTerminator ()))
1441
+ {
1442
+ auto returnedValue = returnInst->getOperand (0 );
1443
+ auto returnedValueType = returnedValue->getDataType ();
1444
+ if (isIntegralType (returnedValueType))
1445
+ {
1446
+ IRBuilder builder (returnInst);
1447
+ builder.setInsertBefore (returnInst);
1448
+ auto newOp = builder.emitCast (funcReturnType, returnedValue);
1449
+ builder.replaceOperand (returnInst->getOperands (), newOp);
1450
+ }
1451
+ }
1452
+ }
1453
+ }
1454
+ }
1455
+
1432
1456
void legalizeSwitch (IRSwitch* switchInst)
1433
1457
{
1434
1458
// WGSL Requires all switch statements to contain a default case.
@@ -1491,6 +1515,28 @@ struct LegalizeWGSLEntryPointContext
1491
1515
inst->getOperand (0 ));
1492
1516
builder.replaceOperand (inst->getOperands (), newLhs);
1493
1517
}
1518
+ else if (
1519
+ isIntegralType (inst->getOperand (0 )->getDataType ()) &&
1520
+ isIntegralType (inst->getOperand (1 )->getDataType ()))
1521
+ {
1522
+ // If integer operands differ in signedness, convert the signed one to unsigned.
1523
+ // We're assuming that the cases where this is bad have already been caught by
1524
+ // common validation checks.
1525
+ IntInfo opIntInfo[2 ] = {
1526
+ getIntTypeInfo (inst->getOperand (0 )->getDataType ()),
1527
+ getIntTypeInfo (inst->getOperand (1 )->getDataType ())};
1528
+ if (opIntInfo[0 ].isSigned != opIntInfo[1 ].isSigned )
1529
+ {
1530
+ int signedOpIndex = (int )opIntInfo[1 ].isSigned ;
1531
+ opIntInfo[signedOpIndex].isSigned = false ;
1532
+ IRBuilder builder (inst);
1533
+ builder.setInsertBefore (inst);
1534
+ auto newOp = builder.emitCast (
1535
+ builder.getType (getIntTypeOpFromInfo (opIntInfo[signedOpIndex])),
1536
+ inst->getOperand (signedOpIndex));
1537
+ builder.replaceOperand (inst->getOperands () + signedOpIndex, newOp);
1538
+ }
1539
+ }
1494
1540
}
1495
1541
1496
1542
void processInst (IRInst* inst)
@@ -1529,6 +1575,9 @@ struct LegalizeWGSLEntryPointContext
1529
1575
legalizeBinaryOp (inst);
1530
1576
break ;
1531
1577
1578
+ case kIROp_Func :
1579
+ legalizeFunc (static_cast <IRFunc*>(inst));
1580
+ [[fallthrough]];
1532
1581
default :
1533
1582
for (auto child : inst->getModifiableChildren ())
1534
1583
{
0 commit comments