[llvm] [InstCombine] Add optimization to combine adds through zext nneg, and add testcase (PR #157723)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 9 10:47:50 PDT 2025


https://github.com/Aethezz updated https://github.com/llvm/llvm-project/pull/157723

>From 0e8a5fd5b05517159b0df102913086d6e4bb2390 Mon Sep 17 00:00:00 2001
From: Aethezz <ellisonlao999 at gmail.com>
Date: Tue, 9 Sep 2025 13:20:22 -0400
Subject: [PATCH] Combine adds through zext nneg, and add testcase

---
 .../InstCombine/InstCombineAddSub.cpp           | 17 +++++++++++++++++
 llvm/test/Transforms/InstCombine/zext.ll        | 11 +++++++++++
 2 files changed, 28 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d934638c15e75..f4a2ab5377a34 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1910,6 +1910,23 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I))
     return Res;
 
+  // Combine adds through zext nneg:
+  // (zext nneg (X + C1)) + C2 --> zext X if C1 + C2 == 0
+  {
+    Value *X;
+    const APInt *C1, *C2;
+    if (match(&I, m_c_Add(m_NNegZExt(m_Add(m_Value(X), m_APInt(C1))),
+                          m_APInt(C2)))) {
+      // Check if the constants cancel out (C1 + C2 == 0)
+      APInt Sum = C1->sext(C2->getBitWidth()) + *C2;
+      if (Sum.isZero()) {
+        // The add inside the zext and the outer add cancel out
+        Value *NewZExt = Builder.CreateZExt(X, I.getType());
+        return replaceInstUsesWith(I, NewZExt);
+      }
+    }
+  }
+
   // Re-enqueue users of the induction variable of add recurrence if we infer
   // new nuw/nsw flags.
   if (Changed) {
diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll
index e4d18e9395219..15aa2aaec430a 100644
--- a/llvm/test/Transforms/InstCombine/zext.ll
+++ b/llvm/test/Transforms/InstCombine/zext.ll
@@ -976,3 +976,14 @@ entry:
   %res = zext nneg i2 %x to i32
   ret i32 %res
 }
+
+define i32 @zext_nneg_add_cancel(i8 %arg) {
+; CHECK-LABEL: @zext_nneg_add_cancel(
+; CHECK-NEXT:    [[ADD2:%.*]] = zext i8 [[ARG:%.*]] to i32
+; CHECK-NEXT:    ret i32 [[ADD2]]
+;
+  %add = add i8 %arg, -2
+  %zext = zext nneg i8 %add to i32
+  %add2 = add i32 %zext, 2
+  ret i32 %add2
+}
\ No newline at end of file



More information about the llvm-commits mailing list