Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp: Negator::visitImpl
Issue title: [InstCombine] `nsw` flag should be dropped in Negator
Labels: miscompilation
llvm:instcombine
Reported by: dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/ZFF_QK
```
define i8 @src(i8 %x, i8 %y, i1 %c) {
  %t0 = sub nsw i8 0, %x
  %t1 = select i1 %c, i8 %t0, i8 %x
  %t2 = sub i8 %y, %t1
  ret i8 %t2
}

define i8 @tgt(i8 %x, i8 %y, i1 %c) {
  %t0 = sub nsw i8 0, %x
  %1 = select i1 %c, i8 %x, i8 %t0
  %t2 = add i8 %1, %y
  ret i8 %t2
}
```
```
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
i8 %x = #x80 (128, -128)
i8 %y = #x00 (0)
i1 %c = #x0 (0)

Source:
i8 %t0 = poison
i8 %t1 = #x80 (128, -128)
i8 %t2 = #x80 (128, -128)

Target:
i8 %t0 = poison
i8 %#1 = poison
i8 %t2 = poison
Source value: #x80 (128, -128)
Target value: poison
```

Comments: author: AZero13
body: Is this an issue in 19.x or just main?
author: AZero13
body: Confirmed this issue exists in 19.x

Fix patch:
commit ff07df6620c32571c7e13ff96ec7976c63ed0ab8
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Fri Nov 8 16:20:04 2024 +0800

    [InstCombine] Drop nsw in negation of select (#112893)
    
    Closes https://github.com/llvm/llvm-project/issues/112666 and
    https://github.com/llvm/llvm-project/issues/114181.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index 9bd848552615..2210336d92bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -333,6 +333,17 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
       NewSelect->swapValues();
       // Don't swap prof metadata, we didn't change the branch behavior.
       NewSelect->setName(I->getName() + ".neg");
+      // Poison-generating flags should be dropped
+      Value *TV = NewSelect->getTrueValue();
+      Value *FV = NewSelect->getFalseValue();
+      if (match(TV, m_Neg(m_Specific(FV))))
+        cast<Instruction>(TV)->dropPoisonGeneratingFlags();
+      else if (match(FV, m_Neg(m_Specific(TV))))
+        cast<Instruction>(FV)->dropPoisonGeneratingFlags();
+      else {
+        cast<Instruction>(TV)->dropPoisonGeneratingFlags();
+        cast<Instruction>(FV)->dropPoisonGeneratingFlags();
+      }
       Builder.Insert(NewSelect);
       return NewSelect;
     }


Regression tests:
file: llvm/test/Transforms/InstCombine/sub-of-negatible.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: negate_select_of_op_vs_negated_op_nsw_commuted
test_body: define i8 @negate_select_of_op_vs_negated_op_nsw_commuted(i8 %x, i8 %y, i1 %c) {
  %t0 = sub nsw i8 0, %x
  %t1 = select i1 %c, i8 %x, i8 %t0
  %t2 = sub i8 %y, %t1
  ret i8 %t2
}

test_name: negate_select_of_op_vs_negated_op_nsw
test_body: define i8 @negate_select_of_op_vs_negated_op_nsw(i8 %x, i8 %y, i1 %c) {
  %t0 = sub nsw i8 0, %x
  %t1 = select i1 %c, i8 %t0, i8 %x
  %t2 = sub i8 %y, %t1
  ret i8 %t2
}

test_name: dont_negate_ordinary_select
test_body: define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {
  %t0 = select i1 %c, i8 %x, i8 %y
  %t1 = sub i8 %z, %t0
  ret i8 %t1
}

test_name: negate_select_of_op_vs_negated_op_nsw_xyyx
test_body: define i8 @negate_select_of_op_vs_negated_op_nsw_xyyx(i8 %x, i8 %y, i8 %z, i1 %c) {
  %sub1 = sub nsw i8 %x, %y
  %sub2 = sub nsw i8 %y, %x
  %t1 = select i1 %c, i8 %sub1, i8 %sub2
  %t2 = sub i8 %z, %t1
  ret i8 %t2
}

test_name: negate_select_of_op_vs_negated_op
test_body: declare void @use8(i8)

define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) {
  %t0 = sub i8 0, %x
  call void @use8(i8 %t0)
  %t1 = select i1 %c, i8 %t0, i8 %x, !prof !0
  %t2 = sub i8 %y, %t1
  ret i8 %t2
}

!0 = !{!"branch_weights", i32 40, i32 1}