[llvm] WebAssembly: Use LibcallLoweringInfo (PR #176804)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 19 11:23:14 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/176804

Query libcalls through analysis instead of the TargetLowering
copy. This could be nicer by parsing the libcall name and checking
against the LibcallImpl, but that's probably slower for such a specific
case (alternatively, ExternalSymbol should support encoding as a LibcallImpl).

>From 7e18edcd4eae01e8c1e4e6bc627fd34dd409b937 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 19 Jan 2026 20:06:49 +0100
Subject: [PATCH] WebAssembly: Use LibcallLoweringInfo

Query libcalls through analysis instead of the TargetLowering
copy. This could be nicer by parsing the libcall name and checking
against the LibcallImpl, but that's probably slower for such a specific
case (alternatively, ExternalSymbol should support encoding as a LibcallImpl).
---
 .../WebAssemblyMemIntrinsicResults.cpp        | 54 +++++++++++++------
 .../WebAssembly/WebAssemblyPeephole.cpp       | 28 +++++++---
 2 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
index 2f861cae69598..74bba7339cab0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
@@ -62,12 +62,21 @@ class WebAssemblyMemIntrinsicResults final : public MachineFunctionPass {
     AU.addPreserved<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addRequired<TargetLibraryInfoWrapperPass>();
+    AU.addRequired<LibcallLoweringInfoWrapper>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
 private:
+  MachineDominatorTree *MDT;
+  LiveIntervals *LIS;
+  const TargetLibraryInfo *LibInfo;
+
+  StringRef MemcpyName, MemmoveName, MemsetName;
+
+  bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
+                    const MachineRegisterInfo &MRI) const;
 };
 } // end anonymous namespace
 
@@ -145,24 +154,24 @@ static bool replaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI,
   return Changed;
 }
 
-static bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
-                         const MachineRegisterInfo &MRI,
-                         MachineDominatorTree &MDT, LiveIntervals &LIS,
-                         const WebAssemblyTargetLowering &TLI,
-                         const TargetLibraryInfo &LibInfo) {
+bool WebAssemblyMemIntrinsicResults::optimizeCall(
+    MachineBasicBlock &MBB, MachineInstr &MI,
+    const MachineRegisterInfo &MRI) const {
   MachineOperand &Op1 = MI.getOperand(1);
   if (!Op1.isSymbol())
     return false;
 
   StringRef Name(Op1.getSymbolName());
-  bool CallReturnsInput = Name == TLI.getLibcallName(RTLIB::MEMCPY) ||
-                          Name == TLI.getLibcallName(RTLIB::MEMMOVE) ||
-                          Name == TLI.getLibcallName(RTLIB::MEMSET);
+
+  // TODO: Could generalize by parsing to LibcallImpl and checking signature
+  // attributes
+  bool CallReturnsInput =
+      Name == MemcpyName || Name == MemmoveName || Name == MemsetName;
   if (!CallReturnsInput)
     return false;
 
   LibFunc Func;
-  if (!LibInfo.getLibFunc(Name, Func))
+  if (!LibInfo->getLibFunc(Name, Func))
     return false;
 
   Register FromReg = MI.getOperand(2).getReg();
@@ -170,7 +179,7 @@ static bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
   if (MRI.getRegClass(FromReg) != MRI.getRegClass(ToReg))
     report_fatal_error("Memory Intrinsic results: call to builtin function "
                        "with wrong signature, from/to mismatch");
-  return replaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT, LIS);
+  return replaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, *MDT, *LIS);
 }
 
 bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
@@ -180,12 +189,23 @@ bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
   });
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  const WebAssemblyTargetLowering &TLI =
-      *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
-  const auto &LibInfo =
-      getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
-  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+  MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  const WebAssemblySubtarget &Subtarget =
+      MF.getSubtarget<WebAssemblySubtarget>();
+  LibInfo =
+      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
+  const LibcallLoweringInfo &Libcalls =
+      getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+          *MF.getFunction().getParent(), Subtarget);
+
+  MemcpyName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
+      Libcalls.getLibcallImpl(RTLIB::MEMCPY));
+  MemmoveName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
+      Libcalls.getLibcallImpl(RTLIB::MEMMOVE));
+  MemsetName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
+      Libcalls.getLibcallImpl(RTLIB::MEMSET));
+
   bool Changed = false;
 
   // We don't preserve SSA form.
@@ -201,7 +221,7 @@ bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
       default:
         break;
       case WebAssembly::CALL:
-        Changed |= optimizeCall(MBB, MI, MRI, MDT, LIS, TLI, LibInfo);
+        Changed |= optimizeCall(MBB, MI, MRI);
         break;
       }
   }
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
index 6e2d566d9b486..d7ae32b061e67 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
@@ -38,6 +38,7 @@ class WebAssemblyPeephole final : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
     AU.addRequired<TargetLibraryInfoWrapperPass>();
+    AU.addRequired<LibcallLoweringInfoWrapper>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
@@ -117,11 +118,28 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
-  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-  const WebAssemblyTargetLowering &TLI =
-      *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
+  const WebAssemblySubtarget &Subtarget =
+      MF.getSubtarget<WebAssemblySubtarget>();
+  const auto &TII = *Subtarget.getInstrInfo();
   auto &LibInfo =
       getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
+
+  const LibcallLoweringInfo &LibcallLowering =
+      getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+          *MF.getFunction().getParent(), Subtarget);
+
+  RTLIB::LibcallImpl MemcpyImpl = LibcallLowering.getLibcallImpl(RTLIB::MEMCPY);
+  RTLIB::LibcallImpl MemmoveImpl =
+      LibcallLowering.getLibcallImpl(RTLIB::MEMMOVE);
+  RTLIB::LibcallImpl MemsetImpl = LibcallLowering.getLibcallImpl(RTLIB::MEMSET);
+
+  StringRef MemcpyName =
+      RTLIB::RuntimeLibcallsInfo::getLibcallImplName(MemcpyImpl);
+  StringRef MemmoveName =
+      RTLIB::RuntimeLibcallsInfo::getLibcallImplName(MemmoveImpl);
+  StringRef MemsetName =
+      RTLIB::RuntimeLibcallsInfo::getLibcallImplName(MemsetImpl);
+
   bool Changed = false;
 
   for (auto &MBB : MF)
@@ -133,9 +151,7 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
         MachineOperand &Op1 = MI.getOperand(1);
         if (Op1.isSymbol()) {
           StringRef Name(Op1.getSymbolName());
-          if (Name == TLI.getLibcallName(RTLIB::MEMCPY) ||
-              Name == TLI.getLibcallName(RTLIB::MEMMOVE) ||
-              Name == TLI.getLibcallName(RTLIB::MEMSET)) {
+          if (Name == MemcpyName || Name == MemmoveName || Name == MemsetName) {
             LibFunc Func;
             if (LibInfo.getLibFunc(Name, Func)) {
               const auto &Op2 = MI.getOperand(2);



More information about the llvm-commits mailing list