[llvm] [InstCombine] Propagate neg `nsw` when folding `abs(-x)` to `abs(x)` (PR #150460)
Pedro Lobo via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 09:54:06 PDT 2025
https://github.com/pedroclobo created https://github.com/llvm/llvm-project/pull/150460
We can propagate the nsw in the neg to abs, as `-x` is only poison if x == INT_MIN.
>From e1dd8e1aacb2bd1eed0a2b3efee43ac0fcd8f6c1 Mon Sep 17 00:00:00 2001
From: Pedro Lobo <pedro.lobo at tecnico.ulisboa.pt>
Date: Thu, 24 Jul 2025 17:40:11 +0100
Subject: [PATCH] [InstCombine] Propagate neg `nsw` when folding `abs(-x)` to
`abs(x)`
We can propagate the nsw in the neg to abs, as `-x` is only poison if
x == INT_MIN.
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 6 ++++--
llvm/test/Transforms/InstCombine/abs-intrinsic.ll | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index d88bc2c4901c7..1b78acea62bd6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1830,10 +1830,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
bool IntMinIsPoison = cast<Constant>(II->getArgOperand(1))->isOneValue();
// abs(-x) -> abs(x)
- // TODO: Copy nsw if it was present on the neg?
Value *X;
- if (match(IIOperand, m_Neg(m_Value(X))))
+ if (match(IIOperand, m_Neg(m_Value(X)))) {
+ if (cast<Instruction>(IIOperand)->hasNoSignedWrap() || IntMinIsPoison)
+ replaceOperand(*II, 1, Builder.getTrue());
return replaceOperand(*II, 0, X);
+ }
if (match(IIOperand, m_c_Select(m_Neg(m_Value(X)), m_Deferred(X))))
return replaceOperand(*II, 0, X);
diff --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
index 022d60d2f501b..d32f0e4690502 100644
--- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
@@ -229,7 +229,7 @@ define i32 @abs_of_neg(i32 %x) {
define <4 x i32> @abs_of_neg_vec(<4 x i32> %x) {
; CHECK-LABEL: @abs_of_neg_vec(
-; CHECK-NEXT: [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
+; CHECK-NEXT: [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 true)
; CHECK-NEXT: ret <4 x i32> [[B]]
;
%a = sub nsw <4 x i32> zeroinitializer, %x
More information about the llvm-commits
mailing list