[llvm] [InstCombine] Limit (icmp eq/ne (and (add A, Addend), Msk), C) fold to one use of and (PR #172858)

Vladimir Radosavljevic via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 18 06:31:04 PST 2025


https://github.com/vladimirradosavljevic created https://github.com/llvm/llvm-project/pull/172858

If the and has multiple uses, the fold can increase the instruction count.

>From 87d8df4f090542a99d8814b6718470b0f3c7fca3 Mon Sep 17 00:00:00 2001
From: Vladimir Radosavljevic <vr at matterlabs.dev>
Date: Thu, 18 Dec 2025 15:27:47 +0100
Subject: [PATCH 1/2] [InstCombine] NFC: Add pre-commit test

---
 .../test/Transforms/InstCombine/and-compare.ll | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/and-compare.ll b/llvm/test/Transforms/InstCombine/and-compare.ll
index 3a59aca0fa8e1..df92e940dcc58 100644
--- a/llvm/test/Transforms/InstCombine/and-compare.ll
+++ b/llvm/test/Transforms/InstCombine/and-compare.ll
@@ -280,3 +280,21 @@ entry:
   %cmp = icmp ne i8 %and, 16
   ret i1 %cmp
 }
+
+define i1 @test_ne_11_and_15_add_10_multiuse(i8 %a) {
+; CHECK-LABEL: @test_ne_11_and_15_add_10_multiuse(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[A:%.*]], 10
+; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ADD]], 15
+; CHECK-NEXT:    call void @use.i8(i8 [[AND]])
+; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A]], 15
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP0]], 1
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %add = add i8 %a, 10
+  %and = and i8 %add, 15
+  call void @use.i8(i8 %and)
+  %cmp = icmp ne i8 %and, 11
+  ret i1 %cmp
+}

>From 19d0d2ee365979ea48d5319e0a569d4b9cb3da78 Mon Sep 17 00:00:00 2001
From: Vladimir Radosavljevic <vr at matterlabs.dev>
Date: Thu, 18 Dec 2025 15:28:37 +0100
Subject: [PATCH 2/2] [InstCombine] Limit (icmp eq/ne (and (add A, Addend),
 Msk), C) fold to one use of and

If the and has multiple uses, the fold can increase the
instruction count.
---
 llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 4 ++--
 llvm/test/Transforms/InstCombine/and-compare.ll         | 3 +--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 616cb04be9dbc..99f20261dcfa9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2005,8 +2005,8 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
   {
     Value *A;
     const APInt *Addend, *Msk;
-    if (match(And, m_And(m_OneUse(m_Add(m_Value(A), m_APInt(Addend))),
-                         m_LowBitMask(Msk))) &&
+    if (match(And, m_OneUse(m_And(m_OneUse(m_Add(m_Value(A), m_APInt(Addend))),
+                                  m_LowBitMask(Msk)))) &&
         C.ule(*Msk)) {
       APInt NewComperand = (C - *Addend) & *Msk;
       Value *MaskA = Builder.CreateAnd(A, ConstantInt::get(A->getType(), *Msk));
diff --git a/llvm/test/Transforms/InstCombine/and-compare.ll b/llvm/test/Transforms/InstCombine/and-compare.ll
index df92e940dcc58..ae5be9dc47ec6 100644
--- a/llvm/test/Transforms/InstCombine/and-compare.ll
+++ b/llvm/test/Transforms/InstCombine/and-compare.ll
@@ -287,8 +287,7 @@ define i1 @test_ne_11_and_15_add_10_multiuse(i8 %a) {
 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[A:%.*]], 10
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ADD]], 15
 ; CHECK-NEXT:    call void @use.i8(i8 [[AND]])
-; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A]], 15
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP0]], 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], 11
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
 entry:



More information about the llvm-commits mailing list