Bug type: miscompilation
Component: IR
Bug location: llvm/lib/IR/Operator.cpp: Operator::hasPoisonGeneratingFlags
Issue title: [InstCombine] `samesign` flag should be dropped
Labels: miscompilation
llvm:ir
Reported by: dtcxzyw

Reproducer:
```
define i1 @src(i32 %In) {
  %c1 = icmp samesign sgt i32 %In, -1
  %c2 = icmp samesign eq i32 %In, 1
  %V = select i1 %c1, i1 %c2, i1 false
  ret i1 %V
}

define i1 @tgt(i32 %In) {
  %c2 = icmp samesign eq i32 %In, 1
  ret i1 %c2
}
```

We should check this flag in `Operator::hasPoisonGeneratingFlags`.



Fix patch:
commit 9b7491e8669126180253480821d5addde34874d0
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Tue Oct 15 23:07:16 2024 +0800

    [IR] Add support for `samesign` in `Operator::hasPoisonGeneratingFlags` (#112358)
    
    Fix https://github.com/llvm/llvm-project/issues/112356.

diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index f93ff8f6fc8a..199eb4d90f55 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -50,6 +50,8 @@ bool Operator::hasPoisonGeneratingFlags() const {
     if (auto *NNI = dyn_cast<PossiblyNonNegInst>(this))
       return NNI->hasNonNeg();
     return false;
+  case Instruction::ICmp:
+    return cast<ICmpInst>(this)->hasSameSign();
   default:
     if (const auto *FP = dyn_cast<FPMathOperator>(this))
       return FP->hasNoNaNs() || FP->hasNoInfs();


Regression tests:
file: llvm/test/Transforms/InstCombine/icmp.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: icmp_samesign_logical_or
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @icmp_samesign_logical_or(i32 %In) {
  %c1 = icmp samesign slt i32 %In, 0
  %c2 = icmp samesign ne i32 %In, 1
  %V = select i1 %c1, i1 true, i1 %c2
  ret i1 %V
}

test_name: icmp_and_inv_pow2_or_zero_ne_0
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #0

define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) {
  %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
  %cond = icmp ult i32 %popcnt, 2
  call void @llvm.assume(i1 %cond)
  %inv = xor i32 %B, -1
  %and = and i32 %A, %inv
  %cmp = icmp ne i32 %and, 0
  ret i1 %cmp
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.ctpop.i32(i32) #1

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: icmp_samesign_logical_and
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @icmp_samesign_logical_and(i32 %In) {
  %c1 = icmp samesign sgt i32 %In, -1
  %c2 = icmp samesign eq i32 %In, 1
  %V = select i1 %c1, i1 %c2, i1 false
  ret i1 %V
}