[llvm] InstCombine: Add general sext/zext abs fold pattern (PR #209573)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 10:49:22 PDT 2026


https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/209573

https://alive2.llvm.org/ce/z/vwCeNM

>From 5a7e92edc727800935dba998fe0d9d3579b15723 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Tue, 14 Jul 2026 13:48:57 -0400
Subject: [PATCH] InstCombine: Add general sext/zext abs fold pattern

https://alive2.llvm.org/ce/z/vwCeNM
---
 .../Transforms/InstCombine/InstCombineAddSub.cpp    |  8 ++++++++
 llvm/test/Transforms/InstCombine/abs-1.ll           | 13 +++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 6770b4c0e2da6..15b6b5388a7d8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1748,6 +1748,14 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
       A->getType()->isIntOrIntVectorTy(1))
     return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
+  // (A ^ sext(B)) + zext(B) --> B ? -A : A
+  if (match(&I, m_c_Add(m_OneUse(m_c_Xor(m_Value(A), m_SExt(m_Value(B)))),
+                        m_ZExt(m_Deferred(B)))) &&
+      B->getType()->isIntOrIntVectorTy(1)) {
+    Value *NegA = Builder.CreateNeg(A, "", I.hasNoSignedWrap());
+    return SelectInst::Create(B, NegA, A);
+  }
+
   // sext(A < B) + zext(A > B) => ucmp/scmp(A, B)
   CmpPredicate LTPred, GTPred;
   if (match(&I,
diff --git a/llvm/test/Transforms/InstCombine/abs-1.ll b/llvm/test/Transforms/InstCombine/abs-1.ll
index fd67fc3421498..ed1b40467a5ad 100644
--- a/llvm/test/Transforms/InstCombine/abs-1.ll
+++ b/llvm/test/Transforms/InstCombine/abs-1.ll
@@ -989,3 +989,16 @@ define <2 x i32> @abs_unary_shuffle_ops(<2 x i32> %x) {
   %r = call <2 x i32> @llvm.abs(<2 x i32> %a, i1 false)
   ret <2 x i32> %r
 }
+
+define i32 @test_arbitrary_cmp(i32 %A, i1 %cmp) {
+; CHECK-LABEL: @test_arbitrary_cmp(
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[A:%.*]]
+; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[CMP:%.*]], i32 [[TMP1]], i32 [[A]]
+; CHECK-NEXT:    ret i32 [[ADD]]
+;
+  %sext = sext i1 %cmp to i32
+  %xor = xor i32 %A, %sext
+  %zext = zext i1 %cmp to i32
+  %add = add i32 %xor, %zext
+  ret i32 %add
+}



More information about the llvm-commits mailing list