[llvm] [WebAssembly][GlobalISel] Implement pointer and memory ops. (PR #206885)

Demetrius Kanios via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 4 01:08:32 PDT 2026


================
@@ -165,6 +199,94 @@ bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
     I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
     return RBI.constrainGenericRegister(DefReg, *DefRC, MRI) != nullptr;
   }
+  case G_PTRTOINT: {
+    bool PtrIsI64 = MRI.getType(I.getOperand(1).getReg()).getSizeInBits() == 64;
+
+    I.setDesc(
+        TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
+    constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+    return true;
+  }
+  case G_INTTOPTR: {
+    bool PtrIsI64 = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() == 64;
+
+    I.setDesc(
+        TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
+    constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+    return true;
+  }
+  case G_PTRMASK: {
+    bool PtrIsI64 = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() == 64;
+
+    I.setDesc(TII.get(PtrIsI64 ? WebAssembly::AND_I64 : WebAssembly::AND_I32));
+    constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+    return true;
+  }
+  case G_GLOBAL_VALUE: {
+    assert(I.getOperand(1).getTargetFlags() == 0 &&
+           "Unexpected target flags on generic G_GLOBAL_VALUE instruction");
+
+    unsigned OperandFlags = 0;
+    const llvm::GlobalValue *GV = I.getOperand(1).getGlobal();
+    LLT PtrTy = MRI.getType(I.getOperand(0).getReg());
+    bool PtrIsI64 = PtrTy.getSizeInBits() == 64;
+
+    if (TLI.isPositionIndependent()) {
+      if (TM.shouldAssumeDSOLocal(GV)) {
+        const char *BaseName;
+        if (GV->getValueType()->isFunctionTy()) {
+          BaseName = MF.createExternalSymbolName("__table_base");
+          OperandFlags = WebAssemblyII::MO_TABLE_BASE_REL;
+        } else {
+          BaseName = MF.createExternalSymbolName("__memory_base");
+          OperandFlags = WebAssemblyII::MO_MEMORY_BASE_REL;
+        }
+        MachineIRBuilder B(I);
+
+        Register MemBase = MRI.createVirtualRegister(
+            PtrIsI64 ? &WebAssembly::I64RegClass : &WebAssembly::I32RegClass);
+        MRI.setType(MemBase, PtrTy);
----------------
QuantumSegfault wrote:

Okay, I moved it.

But it doesn't seem any better.

I haven't seen any target do things this way. Even targets that do have "Wrapper" and use it in the DAG, simply handle `G_GLOBAL_VALUE` like I did originally (in the instruction selector).

And this affords us very little combiner opportunities anyway. The only generic MI we can introduce is the `G_PTR_ADD`. Everything else is target-specific (even if we inline `G_Wrapper`, we can't use e.g. `G_CONSTANT` because we need to attach the globaladdr as the operand).

And I tried doing more with tablegen, but all the patterns rely on matching against `texternalsym` or `tglobaladdr`, neither of which are supported by the importer.

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


More information about the llvm-commits mailing list