[llvm] fuzz1 (PR #173702)

Justin Lebar via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 26 21:24:30 PST 2025


https://github.com/jlebar updated https://github.com/llvm/llvm-project/pull/173702

>From 4b08107f6377459989072458fbcd1c059384a5a9 Mon Sep 17 00:00:00 2001
From: Justin Lebar <justin.lebar at gmail.com>
Date: Sat, 20 Dec 2025 23:15:16 -0500
Subject: [PATCH] [InstCombine] Guard foldICmpSRemConstant against zero
 divisors

instcombine can create srem X, 0 or icmp ult X, 0 mid-pass when
operands fold to zero, which trips assertions in foldICmpSRemConstant.
Bail out on zero divisors / zero ULT constants instead of asserting,
and add a regression test from the minimized reproducer.

This was found by a fuzzer I'm working on.  The high-level design is to
randomly generate LLVM IR, run a pass on it, and then run the original
and new IR through the interpreter.  They should produce the same
results.  Right now I'm only fuzzing instcombine.
---
 .../InstCombine/InstCombineCompares.cpp          |  8 ++++----
 .../Transforms/InstCombine/srem-zero-icmp-ult.ll | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/Transforms/InstCombine/srem-zero-icmp-ult.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7f1ced9505b9b..d23712597ff49 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2668,17 +2668,17 @@ Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
     const APInt *DivisorC;
     if (!match(SRem->getOperand(1), m_APInt(DivisorC)))
       return nullptr;
+    if (DivisorC->isZero())
+      return nullptr;
 
     APInt NormalizedC = C;
     if (Pred == ICmpInst::ICMP_ULT) {
-      assert(!NormalizedC.isZero() &&
-             "ult X, 0 should have been simplified already.");
+      if (NormalizedC.isZero())
+        return nullptr;
       --NormalizedC;
     }
     if (C.isNegative())
       NormalizedC.flipAllBits();
-    assert(!DivisorC->isZero() &&
-           "srem X, 0 should have been simplified already.");
     if (!NormalizedC.uge(DivisorC->abs() - 1))
       return nullptr;
 
diff --git a/llvm/test/Transforms/InstCombine/srem-zero-icmp-ult.ll b/llvm/test/Transforms/InstCombine/srem-zero-icmp-ult.ll
new file mode 100644
index 0000000000000..e0d0658deaadb
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/srem-zero-icmp-ult.ll
@@ -0,0 +1,16 @@
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+define i64 @f(i1 %c) {
+entry:
+  %0 = select i1 %c, i64 3, i64 0
+  %1 = trunc i64 %0 to i8
+  %2 = sdiv i8 -1, %1
+  %3 = srem i8 -1, %2
+  %4 = icmp ult i8 %1, %3
+  %5 = zext i1 %4 to i64
+  %6 = select i1 false, i64 %0, i64 %5
+  ret i64 %6
+}
+
+; CHECK-LABEL: @f(
+; CHECK: ret i64 poison



More information about the llvm-commits mailing list