[llvm] [InstCombine] Fold abs(X, false) --> abs(X, true) If X != INT_MIN (PR #219527)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 10:10:09 PDT 2026


https://github.com/tadeuszjt updated https://github.com/llvm/llvm-project/pull/219527

>From b47afbe69f001f153f06b8f90d66704009f66e54 Mon Sep 17 00:00:00 2001
From: Tadeusz Tomoszek <tadeuszjt at protonmail.com>
Date: Fri, 28 Aug 2026 18:14:32 +0200
Subject: [PATCH] [InstCombine] Fold abs(X, false) --> abs(X, true) If X !=
 INT_MIN

---
 .../InstCombine/InstCombineCalls.cpp          | 13 ++++++++++
 .../Transforms/InstCombine/abs-intrinsic.ll   | 25 +++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 1402c12f2025f..e8a3b9157116c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2216,6 +2216,19 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
                               {XY, II->getArgOperand(1)});
     }
 
+    // abs(x, false) -> abs(x, true) if x != INT_MIN
+    if (!IntMinIsPoison) {
+      if (auto *IntTy = dyn_cast<IntegerType>(IIOperand->getType())) {
+        unsigned BitWidth = IntTy->getBitWidth();
+        Constant *IntMin =
+            ConstantInt::get(IntTy, APInt::getSignedMinValue(BitWidth));
+
+        if (isKnownNonEqual(IIOperand, IntMin, SQ.getWithInstruction(II)))
+          return CallInst::Create(II->getCalledFunction(),
+                                  {IIOperand, Builder.getTrue()});
+      }
+    }
+
     if (std::optional<bool> Known =
             getKnownSignOrZero(IIOperand, SQ.getWithInstruction(II))) {
       // abs(x) -> x if x >= 0 (include abs(x-y) --> x - y where x >= y)
diff --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
index f93d0b366ef11..a76f4f0e67406 100644
--- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
@@ -1199,3 +1199,28 @@ define i1 @abs_cmp_ugt_poison_multiuse(i32 %x) {
   %cmp = icmp ugt i32 %x.abs, 31
   ret i1 %cmp
 }
+
+define i8 @abs_no_poison_ne_int_min(i8 %x) {
+; CHECK-LABEL: @abs_no_poison_ne_int_min(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
+; CHECK-NEXT:    ret i8 [[ABS]]
+;
+  %cmp = icmp ne i8 %x, -128
+  call void @llvm.assume(i1 %cmp)
+  %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
+  ret i8 %abs
+}
+
+define i1 @abs_no_poison_ne_int_min_eq_fold(i32 %x) {
+; CHECK-LABEL: @abs_no_poison_ne_int_min_eq_fold(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %x1 = or i32 %x, 1
+  %abs = call i32 @llvm.abs.i32(i32 %x1, i1 false)
+  %cmp = icmp eq i32 %abs, %x1
+  ret i1 %cmp
+}
+



More information about the llvm-commits mailing list