[llvm] [AggressiveInstCombine] Guard memset with length in [0, 1] (PR #213240)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 00:21:50 PDT 2026


================
@@ -2462,6 +2464,41 @@ static bool foldMulHigh(Instruction &I) {
   return false;
 }
 
+/// Guard a memset whose nonconstant length is known to be in [0, 1].
+/// Inserts a conditional branch around the memset and specialises the
+/// executed path to a one-byte store.
+static bool foldMemSetZeroOrOneLength(Instruction &I, const DataLayout &DL,
+                                      TargetLibraryInfo &TLI,
+                                      AssumptionCache &AC, DominatorTree &DT,
+                                      bool &MadeCFGChange) {
+  auto *MI = dyn_cast<MemSetInst>(&I);
+  if (!MI || isa<ConstantInt>(MI->getLength()))
+    return false;
+
+  SimplifyQuery SQ(DL, &TLI, &DT, &AC, nullptr, /*UseInstrInfo=*/true);
+  KnownBits KnownLen =
+      computeKnownBits(MI->getLength(), SQ.getWithInstruction(MI));
+  if (!KnownLen.getMaxValue().isOne())
+    return false;
+
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+  IRBuilder<> B(MI);
+  Value *IsNonZero = B.CreateIsNotNull(MI->getLength(), "memset.notzero");
+  Instruction *ThenTerm = SplitBlockAndInsertIfThen(
+      IsNonZero, MI->getIterator(), /*Unreachable=*/false,
+      /*BranchWeights=*/nullptr, &DTU);
+  MI->moveBefore(ThenTerm->getIterator());
----------------
nikic wrote:

No need to move if we're going to erase it right away. Can pass ThenTerm to StoreBuilder instead.

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


More information about the llvm-commits mailing list