[llvm] [WebAssembly][FastISel] Emit signed loads for sext of i8/i16/i32 (PR #182333)

Demetrius Kanios via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 21 00:29:31 PST 2026


================
@@ -1323,6 +1354,16 @@ bool WebAssemblyFastISel::selectLoad(const Instruction *I) {
 
   addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Load));
 
+  if (FoldExt) {
+    unsigned ExtReg = lookUpRegForValue(Ext);
+    if (ExtReg) {
+      if (MachineInstr *ExtMI = MRI.getUniqueVRegDef(ExtReg)) {
+        MRI.replaceRegWith(ExtReg, ResultReg);
+        ExtMI->eraseFromParent();
+      }
+    }
+    updateValueMap(Ext, ResultReg);
+  }
----------------
QuantumSegfault wrote:

Okay, so FastISel currently works bottom-up. We start at the bottoms of blocks, and iterate backwards selecting instructions before their uses. This means the `sext` will ALWAYS be selected first.

But take a look at this:

https://github.com/llvm/llvm-project/blob/7c6159660d97c634965bc387b1267519989b3800/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp#L1823-L1849

It looks like there is a better(?) way to do this folding? Instead of changing anything in here, you could override the `FastISel::tryToFoldLoadIntoMI` hook to handle folding of any instruction (after it has been selected; so we get things like ANDs, shifts, Wasm sext instructions, I32 => I64 extends, and I64 => I32 truncates). Seems the general pattern to check the legality of the desired load, generate it, then run `removeDeadCode` to remove the now dead MI we just folded.

https://github.com/llvm/llvm-project/pull/182333


More information about the llvm-commits mailing list