[llvm] [Transforms] Copy nsw if it is present on the neg (PR #81496)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 12 08:23:21 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: AtariDreams (AtariDreams)

<details>
<summary>Changes</summary>

This is safe to do, as tests have shown.

Proof:
https://godbolt.org/z/T3fdvK7b9
https://alive2.llvm.org/ce/z/4oHEXy

---
Full diff: https://github.com/llvm/llvm-project/pull/81496.diff


1 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+14-6) 


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 56d1259e955196..164d32b6361d29 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1559,14 +1559,22 @@ 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))))
-      return replaceOperand(*II, 0, X);
-    if (match(IIOperand, m_Select(m_Value(), m_Value(X), m_Neg(m_Deferred(X)))))
-      return replaceOperand(*II, 0, X);
-    if (match(IIOperand, m_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X))))
+    if (match(IIOperand, m_Neg(m_Value(X))) ||
+        match(IIOperand,
+              m_Select(m_Value(), m_Value(X), m_Neg(m_Deferred(X)))) ||
+        match(IIOperand,
+              m_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X)))) {
+      // Check if the negation has the nsw flag
+      if (auto *NegInst = dyn_cast<Instruction>(IIOperand)) {
+        if (NegInst->hasNoSignedWrap()) {
+          // Create a new abs instruction with the nsw flag
+          auto *AbsInst = cast<IntrinsicInst>(II);
+          AbsInst->setHasNoSignedWrap(true);
+        }
+      }
       return replaceOperand(*II, 0, X);
+    }
 
     if (std::optional<bool> Known =
             getKnownSignOrZero(IIOperand, II, DL, &AC, &DT)) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/81496


More information about the llvm-commits mailing list