[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