[llvm] [ExpandMemCmp][RISCV] Expand memcmp/bcmp for aligned pointers on strict-align targets (PR #209738)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 06:01:12 PDT 2026


================
@@ -860,6 +870,37 @@ static bool expandMemCmp(CallInst *CI, const TargetTransformInfo *TTI,
   if (!OptForSize && MaxLoadsPerMemcmp.getNumOccurrences())
     Options.MaxNumLoads = MaxLoadsPerMemcmp;
 
+  // Keep only the load sizes the target can actually access given the
+  // statically known common alignment of both pointers: either the access is
+  // naturally aligned, or the target allows a misaligned access of that width.
+  // This lets strict-alignment targets expand compares whose pointers happen to
+  // be sufficiently aligned, while still falling back to the libcall when no
+  // load size fits. Because the greedy load sequence only places a load of size
+  // S at an offset that is a multiple of S, a load that does not exceed the
+  // base alignment is guaranteed to be naturally aligned.
+  //
+  // Note we query whether the access is *allowed*, not whether it is *fast*:
+  // this matches the historical behavior of forming unaligned loads whenever
+  // the target permits them, so it is a no-op for targets that allow unaligned
+  // access even when it is slow.
+  const Align LhsAlign = getMemCmpArgAlignment(CI, 0, *DL);
+  const Align RhsAlign = getMemCmpArgAlignment(CI, 1, *DL);
+  const Align MinAlign = std::min(LhsAlign, RhsAlign);
+  LLVMContext &Context = CI->getContext();
+  unsigned AS = CI->getArgOperand(0)->getType()->getPointerAddressSpace();
+  llvm::erase_if(Options.LoadSizes, [&](unsigned LoadSize) {
+    if (MinAlign >= LoadSize)
+      return false;
+    return !TTI->allowsMisalignedMemoryAccesses(Context, LoadSize * 8, AS,
+                                                MinAlign);
+  });
+  // Byte loads are naturally aligned for any pointer, so at least the 1-byte
+  // size normally survives and remains useful for small compares: the number
+  // of loads is bounded by MaxNumLoads, and larger compares that would need
+  // too many byte loads fall back to the libcall in MemCmpExpansion.
----------------
lukel97 wrote:

Nit, is the comment above related to the loadsizes check below? Is the check below not just because we can end up erasing all the load sizes and then MemCmpExpansion constructor below will assert?

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


More information about the llvm-commits mailing list