Skip to content

Commit 03e8fd6

Browse files
authored
Revert "[WebAssembly][FastISel] Fold i64 extension chains into widened loads" (#188306)
Reverts #187934 Breaks bots.
1 parent 5928fc4 commit 03e8fd6

File tree

2 files changed

+165
-266
lines changed

2 files changed

+165
-266
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

Lines changed: 73 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,117 +1284,89 @@ bool WebAssemblyFastISel::selectBitCast(const Instruction *I) {
12841284
return true;
12851285
}
12861286

1287-
static unsigned getSExtLoadOpcode(unsigned LoadSize, bool I64Result, bool A64) {
1288-
if (I64Result) {
1289-
switch (LoadSize) {
1290-
default:
1291-
return WebAssembly::INSTRUCTION_LIST_END;
1292-
case 8:
1293-
return A64 ? WebAssembly::LOAD8_S_I64_A64 : WebAssembly::LOAD8_S_I64_A32;
1294-
case 16:
1295-
return A64 ? WebAssembly::LOAD16_S_I64_A64
1296-
: WebAssembly::LOAD16_S_I64_A32;
1297-
case 32:
1298-
return A64 ? WebAssembly::LOAD32_S_I64_A64
1299-
: WebAssembly::LOAD32_S_I64_A32;
1300-
}
1301-
}
1302-
1303-
switch (LoadSize) {
1304-
default:
1305-
return WebAssembly::INSTRUCTION_LIST_END;
1306-
case 8:
1307-
return A64 ? WebAssembly::LOAD8_S_I32_A64 : WebAssembly::LOAD8_S_I32_A32;
1308-
case 16:
1309-
return A64 ? WebAssembly::LOAD16_S_I32_A64 : WebAssembly::LOAD16_S_I32_A32;
1310-
}
1311-
}
1312-
1313-
static unsigned getZExtLoadOpcode(unsigned LoadSize, bool I64Result, bool A64) {
1314-
if (I64Result) {
1315-
switch (LoadSize) {
1316-
default:
1317-
return WebAssembly::INSTRUCTION_LIST_END;
1318-
case 8:
1319-
return A64 ? WebAssembly::LOAD8_U_I64_A64 : WebAssembly::LOAD8_U_I64_A32;
1320-
case 16:
1321-
return A64 ? WebAssembly::LOAD16_U_I64_A64
1322-
: WebAssembly::LOAD16_U_I64_A32;
1323-
case 32:
1324-
return A64 ? WebAssembly::LOAD32_U_I64_A64
1325-
: WebAssembly::LOAD32_U_I64_A32;
1326-
}
1327-
}
1328-
1329-
switch (LoadSize) {
1330-
default:
1331-
return WebAssembly::INSTRUCTION_LIST_END;
1332-
case 8:
1333-
return A64 ? WebAssembly::LOAD8_U_I32_A64 : WebAssembly::LOAD8_U_I32_A32;
1334-
case 16:
1335-
return A64 ? WebAssembly::LOAD16_U_I32_A64 : WebAssembly::LOAD16_U_I32_A32;
1336-
}
1337-
}
1338-
1339-
static bool isFoldableSExtOpcode(unsigned Opc) {
1287+
static unsigned getSExtLoadOpcode(unsigned Opc, bool A64) {
13401288
switch (Opc) {
13411289
default:
1342-
return false;
1290+
return WebAssembly::INSTRUCTION_LIST_END;
13431291
case WebAssembly::I32_EXTEND8_S_I32:
1292+
Opc = A64 ? WebAssembly::LOAD8_S_I32_A64 : WebAssembly::LOAD8_S_I32_A32;
1293+
break;
13441294
case WebAssembly::I32_EXTEND16_S_I32:
1295+
Opc = A64 ? WebAssembly::LOAD16_S_I32_A64 : WebAssembly::LOAD16_S_I32_A32;
1296+
break;
13451297
case WebAssembly::I64_EXTEND8_S_I64:
1298+
Opc = A64 ? WebAssembly::LOAD8_S_I64_A64 : WebAssembly::LOAD8_S_I64_A32;
1299+
break;
13461300
case WebAssembly::I64_EXTEND16_S_I64:
1301+
Opc = A64 ? WebAssembly::LOAD16_S_I64_A64 : WebAssembly::LOAD16_S_I64_A32;
1302+
break;
13471303
case WebAssembly::I64_EXTEND32_S_I64:
13481304
case WebAssembly::I64_EXTEND_S_I32:
1349-
return true;
1305+
Opc = A64 ? WebAssembly::LOAD32_S_I64_A64 : WebAssembly::LOAD32_S_I64_A32;
1306+
break;
13501307
}
1308+
1309+
return Opc;
13511310
}
13521311

1353-
static bool isI64SExtResult(unsigned Opc) {
1354-
switch (Opc) {
1355-
default:
1356-
llvm_unreachable("unexpected opcode");
1357-
case WebAssembly::I32_EXTEND8_S_I32:
1358-
case WebAssembly::I32_EXTEND16_S_I32:
1359-
return false;
1360-
case WebAssembly::I64_EXTEND8_S_I64:
1361-
case WebAssembly::I64_EXTEND16_S_I64:
1362-
case WebAssembly::I64_EXTEND32_S_I64:
1363-
case WebAssembly::I64_EXTEND_S_I32:
1364-
return true;
1312+
static unsigned getZExtLoadOpcodeFromAnd(MachineInstr *MI,
1313+
MachineRegisterInfo &MRI,
1314+
const LoadInst *LI, bool A64) {
1315+
uint64_t Mask = 0;
1316+
bool IsConstant = false;
1317+
for (unsigned I = 1; I <= 2; ++I) {
1318+
Register Reg = MI->getOperand(I).getReg();
1319+
MachineInstr *DefMI = MRI.getUniqueVRegDef(Reg);
1320+
if (DefMI && (DefMI->getOpcode() == WebAssembly::CONST_I32 ||
1321+
DefMI->getOpcode() == WebAssembly::CONST_I64)) {
1322+
Mask = DefMI->getOperand(1).getImm();
1323+
IsConstant = true;
1324+
break;
1325+
}
13651326
}
1366-
}
13671327

1368-
static unsigned getFoldedLoadOpcode(MachineInstr *MI, MachineRegisterInfo &MRI,
1369-
const LoadInst *LI, bool A64) {
1370-
unsigned Opc = MI->getOpcode();
1328+
if (!IsConstant)
1329+
return WebAssembly::INSTRUCTION_LIST_END;
1330+
1331+
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1332+
if (Mask != llvm::maskTrailingOnes<uint64_t>(LoadSize))
1333+
return WebAssembly::INSTRUCTION_LIST_END;
13711334

1372-
if (isFoldableSExtOpcode(Opc)) {
1373-
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1374-
return getSExtLoadOpcode(LoadSize, isI64SExtResult(Opc), A64);
1335+
if (MI->getOpcode() == WebAssembly::AND_I32) {
1336+
if (LoadSize == 8)
1337+
return A64 ? WebAssembly::LOAD8_U_I32_A64 : WebAssembly::LOAD8_U_I32_A32;
1338+
if (LoadSize == 16)
1339+
return A64 ? WebAssembly::LOAD16_U_I32_A64
1340+
: WebAssembly::LOAD16_U_I32_A32;
1341+
} else if (MI->getOpcode() == WebAssembly::AND_I64) {
1342+
if (LoadSize == 8)
1343+
return A64 ? WebAssembly::LOAD8_U_I64_A64 : WebAssembly::LOAD8_U_I64_A32;
1344+
if (LoadSize == 16)
1345+
return A64 ? WebAssembly::LOAD16_U_I64_A64
1346+
: WebAssembly::LOAD16_U_I64_A32;
1347+
if (LoadSize == 32)
1348+
return A64 ? WebAssembly::LOAD32_U_I64_A64
1349+
: WebAssembly::LOAD32_U_I64_A32;
13751350
}
13761351

13771352
return WebAssembly::INSTRUCTION_LIST_END;
13781353
}
13791354

1380-
static unsigned getFoldedI64LoadOpcode(Register DestReg, const LoadInst *LI,
1381-
MachineRegisterInfo &MRI, bool A64,
1382-
MachineInstr *&OuterUserMI,
1383-
unsigned NarrowOpc) {
1384-
if (!MRI.hasOneNonDBGUse(DestReg))
1385-
return NarrowOpc;
1386-
1387-
MachineInstr *UserMI = &*MRI.use_instr_nodbg_begin(DestReg);
1388-
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1389-
switch (UserMI->getOpcode()) {
1390-
case WebAssembly::I64_EXTEND_U_I32:
1391-
OuterUserMI = UserMI;
1392-
return getZExtLoadOpcode(LoadSize, /*I64Result=*/true, A64);
1355+
static unsigned getFoldedLoadOpcode(MachineInstr *MI, MachineRegisterInfo &MRI,
1356+
const LoadInst *LI, bool A64) {
1357+
switch (MI->getOpcode()) {
1358+
case WebAssembly::I32_EXTEND8_S_I32:
1359+
case WebAssembly::I32_EXTEND16_S_I32:
1360+
case WebAssembly::I64_EXTEND8_S_I64:
1361+
case WebAssembly::I64_EXTEND16_S_I64:
1362+
case WebAssembly::I64_EXTEND32_S_I64:
13931363
case WebAssembly::I64_EXTEND_S_I32:
1394-
OuterUserMI = UserMI;
1395-
return getSExtLoadOpcode(LoadSize, /*I64Result=*/true, A64);
1364+
return getSExtLoadOpcode(MI->getOpcode(), A64);
1365+
case WebAssembly::AND_I32:
1366+
case WebAssembly::AND_I64:
1367+
return getZExtLoadOpcodeFromAnd(MI, MRI, LI, A64);
13961368
default:
1397-
return NarrowOpc;
1369+
return WebAssembly::INSTRUCTION_LIST_END;
13981370
}
13991371
}
14001372

@@ -1407,8 +1379,7 @@ static unsigned getFoldedI64LoadOpcode(Register DestReg, const LoadInst *LI,
14071379
/// size (32 - LoadBitWidth).
14081380
static unsigned matchFoldableShift(MachineInstr *MI, const LoadInst *LI,
14091381
MachineRegisterInfo &MRI, bool A64,
1410-
MachineInstr *&UserMI,
1411-
MachineInstr *&OuterUserMI) {
1382+
MachineInstr *&UserMI) {
14121383
unsigned Opc = MI->getOpcode();
14131384
unsigned NewOpc = WebAssembly::INSTRUCTION_LIST_END;
14141385
if (Opc != WebAssembly::SHL_I32)
@@ -1439,104 +1410,13 @@ static unsigned matchFoldableShift(MachineInstr *MI, const LoadInst *LI,
14391410
if (!IsExpectedConst(ShlAmtDef) || !IsExpectedConst(ShrAmtDef))
14401411
return NewOpc;
14411412

1442-
unsigned LoadSize = LoadTy->getIntegerBitWidth();
1443-
unsigned NarrowOpc = getSExtLoadOpcode(LoadSize, /*I64Result=*/false, A64);
1444-
if (NarrowOpc == WebAssembly::INSTRUCTION_LIST_END)
1445-
return WebAssembly::INSTRUCTION_LIST_END;
1446-
1447-
return getFoldedI64LoadOpcode(UserMI->getOperand(0).getReg(), LI, MRI, A64,
1448-
OuterUserMI, NarrowOpc);
1449-
}
1450-
1451-
static unsigned matchFoldableSExtFromPromotedI32(MachineInstr *MI,
1452-
const LoadInst *LI,
1453-
MachineRegisterInfo &MRI,
1454-
bool A64,
1455-
MachineInstr *&UserMI) {
1456-
if (MI->getOpcode() != WebAssembly::I64_EXTEND_U_I32)
1457-
return WebAssembly::INSTRUCTION_LIST_END;
1458-
1459-
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1460-
Register DestReg = MI->getOperand(0).getReg();
1461-
if (!MRI.hasOneNonDBGUse(DestReg))
1462-
return WebAssembly::INSTRUCTION_LIST_END;
1463-
1464-
UserMI = &*MRI.use_instr_nodbg_begin(DestReg);
1465-
switch (UserMI->getOpcode()) {
1466-
default:
1467-
return WebAssembly::INSTRUCTION_LIST_END;
1468-
case WebAssembly::I64_EXTEND8_S_I64:
1469-
if (LoadSize != 8)
1470-
return WebAssembly::INSTRUCTION_LIST_END;
1471-
return getSExtLoadOpcode(LoadSize, true, A64);
1472-
case WebAssembly::I64_EXTEND16_S_I64:
1473-
if (LoadSize != 16)
1474-
return WebAssembly::INSTRUCTION_LIST_END;
1475-
return getSExtLoadOpcode(LoadSize, true, A64);
1476-
}
1477-
}
1478-
1479-
static unsigned matchFoldableCopyToI64Ext(MachineInstr *MI, const LoadInst *LI,
1480-
MachineRegisterInfo &MRI, bool A64,
1481-
MachineInstr *&OuterUserMI) {
1482-
if (MI->getOpcode() != WebAssembly::COPY)
1483-
return WebAssembly::INSTRUCTION_LIST_END;
1413+
if (LoadTy->isIntegerTy(8))
1414+
NewOpc = A64 ? WebAssembly::LOAD8_S_I32_A64 : WebAssembly::LOAD8_S_I32_A32;
1415+
else if (LoadTy->isIntegerTy(16))
1416+
NewOpc =
1417+
A64 ? WebAssembly::LOAD16_S_I32_A64 : WebAssembly::LOAD16_S_I32_A32;
14841418

1485-
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1486-
if (LoadSize != 32)
1487-
return WebAssembly::INSTRUCTION_LIST_END;
1488-
1489-
Register CopyDst = MI->getOperand(0).getReg();
1490-
if (!MRI.hasOneNonDBGUse(CopyDst))
1491-
return WebAssembly::INSTRUCTION_LIST_END;
1492-
1493-
OuterUserMI = &*MRI.use_instr_nodbg_begin(CopyDst);
1494-
switch (OuterUserMI->getOpcode()) {
1495-
default:
1496-
return WebAssembly::INSTRUCTION_LIST_END;
1497-
case WebAssembly::I64_EXTEND_U_I32:
1498-
return getZExtLoadOpcode(LoadSize, true, A64);
1499-
case WebAssembly::I64_EXTEND_S_I32:
1500-
return getSExtLoadOpcode(LoadSize, true, A64);
1501-
}
1502-
}
1503-
1504-
static unsigned matchFoldableAnd(MachineInstr *MI, const LoadInst *LI,
1505-
MachineRegisterInfo &MRI, bool A64,
1506-
MachineInstr *&OuterUserMI) {
1507-
if (MI->getOpcode() != WebAssembly::AND_I32 &&
1508-
MI->getOpcode() != WebAssembly::AND_I64)
1509-
return WebAssembly::INSTRUCTION_LIST_END;
1510-
1511-
uint64_t Mask = 0;
1512-
bool IsConstant = false;
1513-
for (unsigned I = 1; I <= 2; ++I) {
1514-
Register Reg = MI->getOperand(I).getReg();
1515-
MachineInstr *DefMI = MRI.getUniqueVRegDef(Reg);
1516-
if (DefMI && (DefMI->getOpcode() == WebAssembly::CONST_I32 ||
1517-
DefMI->getOpcode() == WebAssembly::CONST_I64)) {
1518-
Mask = DefMI->getOperand(1).getImm();
1519-
IsConstant = true;
1520-
break;
1521-
}
1522-
}
1523-
1524-
if (!IsConstant)
1525-
return WebAssembly::INSTRUCTION_LIST_END;
1526-
1527-
unsigned LoadSize = LI->getType()->getPrimitiveSizeInBits();
1528-
if (Mask != llvm::maskTrailingOnes<uint64_t>(LoadSize))
1529-
return WebAssembly::INSTRUCTION_LIST_END;
1530-
1531-
if (MI->getOpcode() == WebAssembly::AND_I64)
1532-
return getZExtLoadOpcode(LoadSize, /*I64Result=*/true, A64);
1533-
1534-
unsigned NarrowOpc = getZExtLoadOpcode(LoadSize, /*I64Result=*/false, A64);
1535-
if (NarrowOpc == WebAssembly::INSTRUCTION_LIST_END)
1536-
return WebAssembly::INSTRUCTION_LIST_END;
1537-
1538-
return getFoldedI64LoadOpcode(MI->getOperand(0).getReg(), LI, MRI, A64,
1539-
OuterUserMI, NarrowOpc);
1419+
return NewOpc;
15401420
}
15411421

15421422
bool WebAssemblyFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
@@ -1545,39 +1425,20 @@ bool WebAssemblyFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
15451425
MachineRegisterInfo &MRI = FuncInfo.MF->getRegInfo();
15461426
Register ResultReg;
15471427
MachineInstr *UserMI = nullptr;
1548-
MachineInstr *OuterUserMI = nullptr;
1549-
unsigned NewOpc = WebAssembly::INSTRUCTION_LIST_END;
1550-
if ((NewOpc = matchFoldableSExtFromPromotedI32(MI, LI, MRI, A64, UserMI)) !=
1428+
unsigned NewOpc;
1429+
if ((NewOpc = getFoldedLoadOpcode(MI, MRI, LI, A64)) !=
15511430
WebAssembly::INSTRUCTION_LIST_END) {
1552-
ResultReg = UserMI->getOperand(0).getReg();
1553-
} else if ((NewOpc =
1554-
matchFoldableCopyToI64Ext(MI, LI, MRI, A64, OuterUserMI)) !=
1555-
WebAssembly::INSTRUCTION_LIST_END) {
1556-
ResultReg = OuterUserMI->getOperand(0).getReg();
1557-
} else if ((NewOpc = matchFoldableAnd(MI, LI, MRI, A64, OuterUserMI)) !=
1558-
WebAssembly::INSTRUCTION_LIST_END) {
1559-
ResultReg = OuterUserMI ? OuterUserMI->getOperand(0).getReg()
1560-
: MI->getOperand(0).getReg();
1561-
} else if ((NewOpc = getFoldedLoadOpcode(MI, MRI, LI, A64)) !=
1562-
WebAssembly::INSTRUCTION_LIST_END) {
15631431
ResultReg = MI->getOperand(0).getReg();
1564-
} else if ((NewOpc =
1565-
matchFoldableShift(MI, LI, MRI, A64, UserMI, OuterUserMI)) !=
1432+
} else if ((NewOpc = matchFoldableShift(MI, LI, MRI, A64, UserMI)) !=
15661433
WebAssembly::INSTRUCTION_LIST_END) {
1567-
ResultReg = OuterUserMI ? OuterUserMI->getOperand(0).getReg()
1568-
: UserMI->getOperand(0).getReg();
1434+
ResultReg = UserMI->getOperand(0).getReg();
15691435
} else {
15701436
return false;
15711437
}
15721438

15731439
if (!emitLoad(ResultReg, NewOpc, LI))
15741440
return false;
15751441

1576-
if (OuterUserMI) {
1577-
MachineBasicBlock::iterator OuterIter(OuterUserMI);
1578-
removeDeadCode(OuterIter, std::next(OuterIter));
1579-
}
1580-
15811442
if (UserMI) {
15821443
MachineBasicBlock::iterator UserIter(UserMI);
15831444
removeDeadCode(UserIter, std::next(UserIter));

0 commit comments

Comments
 (0)