[llvm] [InstCombine] Infer exact division from a known-zero remainder (PR #221509)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 5 20:10:02 PDT 2026


================
@@ -0,0 +1,682 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+declare void @llvm.assume(i1 noundef)
+declare i32 @llvm.abs.i32(i32, i1 immarg)
+declare i1 @func_bool()
+declare void @func1()
+declare void @func2()
+
+define i32 @udiv_exact_assume(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @udiv_exact_assume(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[REM]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_ZERO]])
+; CHECK-NEXT:    [[QUOT:%.*]] = udiv exact i32 [[X]], [[Y]]
+; CHECK-NEXT:    ret i32 [[QUOT]]
+;
+  %rem = urem i32 %x, %y
+  %is.zero = icmp eq i32 %rem, 0
+  call void @llvm.assume(i1 %is.zero)
+  %quot = udiv i32 %x, %y
+  ret i32 %quot
+}
+
+define i32 @sdiv_exact_assume(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @sdiv_exact_assume(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[REM]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_ZERO]])
+; CHECK-NEXT:    [[QUOT:%.*]] = sdiv exact i32 [[X]], [[Y]]
+; CHECK-NEXT:    ret i32 [[QUOT]]
+;
+  %rem = srem i32 %x, %y
+  %is.zero = icmp eq i32 %rem, 0
+  call void @llvm.assume(i1 %is.zero)
+  %quot = sdiv i32 %x, %y
+  ret i32 %quot
+}
+
+; TODO: The following unconditional assumption makes the earlier division exact.
+define i32 @udiv_exact_assume_after_division(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @udiv_exact_assume_after_division(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[REM]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_ZERO]])
+; CHECK-NEXT:    ret i32 [[QUOT]]
+;
+  %quot = udiv i32 %x, %y
+  %rem = urem i32 %x, %y
+  %is.zero = icmp eq i32 %rem, 0
+  call void @llvm.assume(i1 %is.zero)
+  ret i32 %quot
+}
+
+; TODO: Sinking revisits the division before the dominating condition is added
+; to the cache, so inferring exact requires another InstCombine iteration.
+define i32 @udiv_exact_assume_after_division_unreachable(i32 %x, i32 %y) "instcombine-no-verify-fixpoint" {
----------------
ZERICO2005 wrote:

There was a fix for this, but I decided it was out of scope for this PR:
https://github.com/llvm/llvm-project/commit/280f129ec3ed64b2f9a539b466b7c008f5cdc8c7#diff-0ffb024c6c026c4b93507d08e6d24dccf98980023130781164b71586bc747f2dR6159-R6163

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


More information about the llvm-commits mailing list