[llvm] [Instcombine] Ensure simplifyValueKnownNonZero adds instrs in dominance order. (PR #173703)

Justin Lebar via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 27 11:45:03 PST 2025


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

>From b162182b26255d5ef3d38042f92c4db02e9090d1 Mon Sep 17 00:00:00 2001
From: Justin Lebar <justin.lebar at gmail.com>
Date: Mon, 22 Dec 2025 16:53:48 -0500
Subject: [PATCH 1/4] [Instcombine] Ensure simplifyValueKnownNonZero adds
 instrs in dominance order.

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.
---
 .../Transforms/InstCombine/InstCombineMulDivRem.cpp | 10 ++++++++++
 .../InstCombine/instcombine-dominance-fixup.ll      | 13 +++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index a9aacc707cc20..09f8d3cba64a2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -51,6 +51,16 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
   // code.
   if (!V->hasOneUse()) return nullptr;
 
+  // This helper can rewrite an instruction (including its operands) even when
+  // IC.Builder is currently set to the instruction being visited (e.g. a
+  // divide/remainder using V as a non-zero divisor). Ensure that any IR we
+  // create is inserted before the value we are about to rewrite, so it
+  // dominates all uses.
+  IRBuilderBase::InsertPointGuard Guard(IC.Builder);
+  if (auto *VI = dyn_cast<Instruction>(V))
+    if (VI->getParent())
+      IC.Builder.SetInsertPoint(VI);
+
   bool MadeChange = false;
 
   // ((1 << A) >>u B) --> (1 << (A-B))
diff --git a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
new file mode 100644
index 0000000000000..c5109055c189d
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
@@ -0,0 +1,13 @@
+; NOTE: This test ensures InstCombine preserves dominance even when it
+; reorders shifts through SimplifyDemandedBits/log2 folding.
+;
+; RUN: opt -passes=instcombine,verify -disable-output %s
+
+define i64 @f(i64 %0, i64 %1) {
+entry:
+  %2 = shl nuw i64 1, %1
+  %3 = lshr exact i64 %2, 1
+  %4 = shl nuw i64 %3, %1
+  %5 = srem i64 %0, %4
+  ret i64 %5
+}

>From 6aae42c617c8c02551d50255fda234a712ff587d Mon Sep 17 00:00:00 2001
From: Justin Lebar <justin.lebar at gmail.com>
Date: Sat, 27 Dec 2025 13:37:10 -0500
Subject: [PATCH 2/4] [InstCombine] Address dominance fixup review feedback

---
 .../InstCombine/InstCombineMulDivRem.cpp      | 20 ++++++-----------
 .../instcombine-dominance-fixup.ll            | 22 +++++++++++++------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 09f8d3cba64a2..ca8d2c3cee518 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -51,16 +51,6 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
   // code.
   if (!V->hasOneUse()) return nullptr;
 
-  // This helper can rewrite an instruction (including its operands) even when
-  // IC.Builder is currently set to the instruction being visited (e.g. a
-  // divide/remainder using V as a non-zero divisor). Ensure that any IR we
-  // create is inserted before the value we are about to rewrite, so it
-  // dominates all uses.
-  IRBuilderBase::InsertPointGuard Guard(IC.Builder);
-  if (auto *VI = dyn_cast<Instruction>(V))
-    if (VI->getParent())
-      IC.Builder.SetInsertPoint(VI);
-
   bool MadeChange = false;
 
   // ((1 << A) >>u B) --> (1 << (A-B))
@@ -79,9 +69,13 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
       IC.isKnownToBeAPowerOfTwo(I->getOperand(0), false, &CxtI)) {
     // We know that this is an exact/nuw shift and that the input is a
     // non-zero context as well.
-    if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC, CxtI)) {
-      IC.replaceOperand(*I, 0, V2);
-      MadeChange = true;
+    {
+      IRBuilderBase::InsertPointGuard Guard(IC.Builder);
+      IC.Builder.SetInsertPoint(I);
+      if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC, CxtI)) {
+        IC.replaceOperand(*I, 0, V2);
+        MadeChange = true;
+      }
     }
 
     if (I->getOpcode() == Instruction::LShr && !I->isExact()) {
diff --git a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
index c5109055c189d..2d716779b1433 100644
--- a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
+++ b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
@@ -1,13 +1,21 @@
 ; NOTE: This test ensures InstCombine preserves dominance even when it
 ; reorders shifts through SimplifyDemandedBits/log2 folding.
 ;
-; RUN: opt -passes=instcombine,verify -disable-output %s
+; RUN: opt -passes=instcombine,instnamer < %s | FileCheck %s
 
-define i64 @f(i64 %0, i64 %1) {
+define i64 @f(i64 %arg0, i64 %arg1) {
+; CHECK-LABEL: define i64 @f(
+; CHECK-SAME: i64 [[ARG0:%[^,]+]], i64 [[ARG1:%[^)]+]])
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SHL:%[^ ]+]] = shl nuw i64 1, [[ARG1]]
+; CHECK-NEXT:    [[LSHR:%[^ ]+]] = lshr exact i64 [[SHL]], 1
+; CHECK-NEXT:    [[SHL2:%[^ ]+]] = shl nuw i64 [[LSHR]], [[ARG1]]
+; CHECK-NEXT:    [[SREM:%[^ ]+]] = srem i64 [[ARG0]], [[SHL2]]
+; CHECK-NEXT:    ret i64 [[SREM]]
 entry:
-  %2 = shl nuw i64 1, %1
-  %3 = lshr exact i64 %2, 1
-  %4 = shl nuw i64 %3, %1
-  %5 = srem i64 %0, %4
-  ret i64 %5
+  %shl = shl nuw i64 1, %arg1
+  %lshr = lshr exact i64 %shl, 1
+  %shl2 = shl nuw i64 %lshr, %arg1
+  %srem = srem i64 %arg0, %shl2
+  ret i64 %srem
 }

>From c9e2eda50fdf65f85756e2210406576d33eaf775 Mon Sep 17 00:00:00 2001
From: Justin Lebar <justin.lebar at gmail.com>
Date: Sat, 27 Dec 2025 13:44:18 -0500
Subject: [PATCH 3/4] [InstCombine] Update dominance fixup checks

---
 .../InstCombine/instcombine-dominance-fixup.ll   | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
index 2d716779b1433..7fe4e6eb1e812 100644
--- a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
+++ b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
@@ -1,17 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; NOTE: This test ensures InstCombine preserves dominance even when it
 ; reorders shifts through SimplifyDemandedBits/log2 folding.
 ;
-; RUN: opt -passes=instcombine,instnamer < %s | FileCheck %s
+; RUN: opt -passes=instcombine,instnamer -S < %s | FileCheck %s
 
 define i64 @f(i64 %arg0, i64 %arg1) {
 ; CHECK-LABEL: define i64 @f(
-; CHECK-SAME: i64 [[ARG0:%[^,]+]], i64 [[ARG1:%[^)]+]])
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[SHL:%[^ ]+]] = shl nuw i64 1, [[ARG1]]
-; CHECK-NEXT:    [[LSHR:%[^ ]+]] = lshr exact i64 [[SHL]], 1
-; CHECK-NEXT:    [[SHL2:%[^ ]+]] = shl nuw i64 [[LSHR]], [[ARG1]]
-; CHECK-NEXT:    [[SREM:%[^ ]+]] = srem i64 [[ARG0]], [[SHL2]]
+; CHECK-SAME: i64 [[ARG0:%.*]], i64 [[ARG1:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[I:%.*]] = add i64 [[ARG1]], -1
+; CHECK-NEXT:    [[I1:%.*]] = shl nuw i64 1, [[I]]
+; CHECK-NEXT:    [[SHL2:%.*]] = shl nuw i64 [[I1]], [[ARG1]]
+; CHECK-NEXT:    [[SREM:%.*]] = srem i64 [[ARG0]], [[SHL2]]
 ; CHECK-NEXT:    ret i64 [[SREM]]
+;
 entry:
   %shl = shl nuw i64 1, %arg1
   %lshr = lshr exact i64 %shl, 1

>From db182bb1bc8cba71b7749d7ab31e4ab968e17717 Mon Sep 17 00:00:00 2001
From: Justin Lebar <justin.lebar at gmail.com>
Date: Sat, 27 Dec 2025 14:22:28 -0500
Subject: [PATCH 4/4] [InstCombine] Drop instnamer from dominance test

---
 llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
index 7fe4e6eb1e812..c374ef2fc9a53 100644
--- a/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
+++ b/llvm/test/Transforms/InstCombine/instcombine-dominance-fixup.ll
@@ -2,7 +2,7 @@
 ; NOTE: This test ensures InstCombine preserves dominance even when it
 ; reorders shifts through SimplifyDemandedBits/log2 folding.
 ;
-; RUN: opt -passes=instcombine,instnamer -S < %s | FileCheck %s
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
 
 define i64 @f(i64 %arg0, i64 %arg1) {
 ; CHECK-LABEL: define i64 @f(



More information about the llvm-commits mailing list