dtcxzyw/llvm-apr-benchmark huggingface dataset:
Bug type: hang
Component: VectorCombine
Bug location: llvm/lib/Transforms/Vectorize/VectorCombine.cpp: VectorCombine::scalarizeLoadExtract
Issue title: [VectorCombine] scalarizeLoadExtract - infinite loop if we scalarize a dead extract waiting to be erased
Labels: release:backport
vectorizers
hang
Reported by: RKSimon

Reduced test case:

```ll
define void @infinite_loop(ptr %p0) {
  %load = load <4 x float>, ptr %p0, align 8
  %shuffle0 = shufflevector <4 x float> zeroinitializer, <4 x float> %load, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
  %shuffle1 = shufflevector <4 x float> %shuffle0, <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 4, i32 poison, i32 poison>
  %extract = extractelement <4 x float> %load, i64 1
  ret void
}
```

scalarizeLoadExtract iterates across all users of a load, and doesn't account for possible orders in the worklist that prevent unused instructions that use the load from being erased afterward.

Fix incoming


Fix patch:
commit 5ddf40fa78705384966c22da78e12134df7bd723
Author: Simon Pilgrim <llvm-dev@redking.me.uk>
Date:   Sat Mar 1 16:54:22 2025 +0000

    [VectorCombine] scalarizeLoadExtract - don't create scalar loads if any extract is waiting to be erased (#129375)
    
    If any extract is waiting to be erased, then bail out as this will distort the cost calculation and possibly lead to infinite loops.
    
    Fixes #129373

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index bb4e1c0f67e7..2e8458e2cd03 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1579,6 +1579,11 @@ bool VectorCombine::scalarizeLoadExtract(Instruction &I) {
     if (!UI || UI->getParent() != LI->getParent())
       return false;
 
+    // If any extract is waiting to be erased, then bail out as this will
+    // distort the cost calculation and possibly lead to infinite loops.
+    if (UI->use_empty())
+      return false;
+
     // Check if any instruction between the load and the extract may modify
     // memory.
     if (LastCheckedInst->comesBefore(UI)) {


Regression tests:
file: llvm/test/Transforms/VectorCombine/X86/load-extractelement-scalarization.ll
commands: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2
opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2
tests: test_name: multiple_extract
test_body: define void @multiple_extract(ptr %p) {
  %vp = load ptr, ptr %p, align 8
  %v = load <2 x i32>, ptr %vp, align 16
  %e0 = extractelement <2 x i32> %v, i64 0
  %e1 = extractelement <2 x i32> %v, i64 1
  store i32 %e0, ptr %p, align 4
  %p1 = getelementptr inbounds nuw i8, ptr %p, i64 4
  store i32 %e1, ptr %p1, align 4
  ret void
}

test_name: unused_extract
test_body: define void @unused_extract(ptr %p) {
  %load = load <4 x float>, ptr %p, align 8
  %shuffle0 = shufflevector <4 x float> zeroinitializer, <4 x float> %load, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
  %shuffle1 = shufflevector <4 x float> %shuffle0, <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 4, i32 poison, i32 poison>
  %extract = extractelement <4 x float> %load, i64 1
  ret void
}
Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp: foldSelectWithSRem
Issue title: miscompile of vanilla integer code by InstCombine
Labels: miscompilation
llvm:instcombine
Reported by: regehr

https://alive2.llvm.org/ce/z/jRfVLr

this function:
```llvm
define i8 @f(i8 %0, i8 %1) {
  %3 = icmp slt i8 %1, 0
  %4 = shl i8 1, %0
  %5 = srem i8 1, %4
  %6 = add i8 %5, %4
  %7 = select i1 %3, i8 %6, i8 %5
  ret i8 %7
}
```
is getting mis-optimized to:
```llvm
define i8 @f(i8 %0, i8 %1) {
  %3 = icmp ne i8 %0, 0
  %4 = zext i1 %3 to i8
  ret i8 %4
}
```
here I'll just give Alive's work:
```
Example:
i8 %#0 = #x00 (0)
i8 %#1 = #xff (255, -1)

Source:
i1 %#3 = #x1 (1)
i8 %#4 = #x01 (1)
i8 %#5 = #x00 (0)
i8 %#6 = #x01 (1)
i8 %#7 = #x01 (1)

Target:
i1 %#3 = #x0 (0)
i8 %#4 = #x00 (0)
Source value: #x01 (1)
Target value: #x00 (0)
```

cc @nunoplopes @hatsunespica


Fix patch:
commit 6309440c218778db027306826993e484eab2be17
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Sun Apr 21 22:41:32 2024 +0800

     [InstCombine] Fix unexpected overwriting in `foldSelectWithSRem` (#89539)
    
    Fixes #89516

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 0262af28068b..73600206a55c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2720,7 +2720,7 @@ static Instruction *foldSelectWithSRem(SelectInst &SI, InstCombinerImpl &IC,
   // %cnd = icmp slt i32 %rem, 0
   // %add = add i32 %rem, %n
   // %sel = select i1 %cnd, i32 %add, i32 %rem
-  if (match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
+  if (match(TrueVal, m_Add(m_Specific(RemRes), m_Value(Remainder))) &&
       match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) &&
       IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) &&
       FalseVal == RemRes)


Regression tests:
file: llvm/test/Transforms/InstCombine/select-divrem.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: rem_euclid_pow2_false_arm_folded
test_body: define i32 @rem_euclid_pow2_false_arm_folded(i32 %n) {
  %rem = srem i32 %n, 2
  %nonneg = icmp sge i32 %rem, 0
  %res = select i1 %nonneg, i32 %rem, i32 1
  ret i32 %res
}

test_name: pr89516
test_body: define i8 @pr89516(i8 %n, i8 %x) {
  %cond = icmp slt i8 %x, 0
  %pow2 = shl nuw i8 1, %n
  %srem = srem i8 1, %pow2
  %add = add nuw i8 %srem, %pow2
  %res = select i1 %cond, i8 %add, i8 %srem
  ret i8 %res
}
Bug type: crash
Component: FunctionAttrs
Bug location: llvm/lib/Transforms/IPO/FunctionAttrs.cpp: getArgumentAccessInfo
Issue title: FunctionAttrs: Assertion `isOrder edRanges(RangesRef)' failed.
Labels: ipo
crash
Reported by: aeubanks

```
$ cat /tmp/f.ll
define i32 @f(ptr %arg, ptr %arg2) {
  store ptr %arg, ptr %arg2
  %getelementptr = getelementptr float, ptr %arg, i64 2305843009213693951
  %load = load i32, ptr %getelementptr, align 4
  ret i32 %load
}
$ opt -p function-attrs /tmp/f.ll -disable-output
opt: ../../llvm/include/llvm/IR/ConstantRangeList.h:36: llvm::ConstantRangeList::ConstantRangeList(ArrayRef<ConstantRange>): Assertion `isOrder
edRanges(RangesRef)' failed.
```


Fix patch:
commit 0547e84181ff10b24d6363bbfc97f168fe245397
Author: Arthur Eubanks <aeubanks@google.com>
Date:   Wed Apr 23 15:56:24 2025 -0700

    [FunctionAttrs] Bail if initializes range overflows 64-bit signed int (#137053)
    
    Otherwise the range doesn't make sense since we interpret it as signed.
    
    Fixes #134115

diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index bbfed2ac2c09..74e8a849803d 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -661,8 +661,13 @@ ArgumentAccessInfo getArgumentAccessInfo(const Instruction *I,
     auto TypeSize = DL.getTypeStoreSize(Ty);
     if (!TypeSize.isScalable() && Offset) {
       int64_t Size = TypeSize.getFixedValue();
-      return ConstantRange(APInt(64, *Offset, true),
-                           APInt(64, *Offset + Size, true));
+      APInt Low(64, *Offset, true);
+      bool Overflow;
+      APInt High = Low.sadd_ov(APInt(64, Size, true), Overflow);
+      // Bail if the range overflows signed 64-bit int.
+      if (Overflow)
+        return std::nullopt;
+      return ConstantRange(Low, High);
     }
     return std::nullopt;
   };


Regression tests:
file: llvm/test/Transforms/FunctionAttrs/initializes.ll
commands: opt -passes=function-attrs -S < %s
tests: test_name: memset_offset_1_size_0
test_body: define void @memset_offset_1_size_0(ptr %dst, ptr %src) {
  %dst.1 = getelementptr inbounds i8, ptr %dst, i64 1
  call void @llvm.memmove.p0.p0.i64(ptr %dst.1, ptr %src, i64 0, i1 false)
  ret void
}

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memmove.p0.p0.i64(ptr writeonly captures(none), ptr readonly captures(none), i64, i1 immarg) #0

attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }

test_name: range_overflows_signed_64_bit_int
test_body: define void @range_overflows_signed_64_bit_int(ptr %arg) {
  %getelementptr = getelementptr i8, ptr %arg, i64 9223372036854775804
  store i32 0, ptr %getelementptr, align 4
  ret void
}
Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp: InstCombinerImpl::visitFreeze
Issue title: [InstCombine] Miscompilation when removing freezes
Labels: miscompilation
llvm:instcombine
generated by fuzzer
Reported by: dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/3napog
```
define i64 @src(i1 %cond) {
  %1 = freeze i64 poison
  %2 = freeze i64 poison
  %ret = select i1 %cond, i64 %1, i64 %2
  ret i64 %ret
}

define i64 @tgt(i1 %cond) {
  ret i64 poison
}
```
llvm version: 69586331e868cef99fbcea74a061bd44f57c1904



Fix patch:
commit 73d9974c91413f5a6dbe6f76f4b73ad226b6276b
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Wed Oct 1 22:02:30 2025 +0800

    [InstCombine] Avoid self-replacing in `getUndefReplacement` (#161500)
    
    Self-replacing has a different meaning in InstCombine. It will replace
    all uses with poison.
    Closes https://github.com/llvm/llvm-project/issues/161492.

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index ff063f929347..5d2d79e42093 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5212,7 +5212,7 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
       else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value())))
         V = ConstantInt::getTrue(Ty);
       else if (match(U, m_c_Select(m_Specific(&I), m_Value(V)))) {
-        if (!isGuaranteedNotToBeUndefOrPoison(V, &AC, &I, &DT))
+        if (V == &I || !isGuaranteedNotToBeUndefOrPoison(V, &AC, &I, &DT))
           V = NullValue;
       } else if (auto *PHI = dyn_cast<PHINode>(U)) {
         if (Value *MaybeV = pickCommonConstantFromPHI(*PHI))
@@ -5225,6 +5225,7 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
         BestValue = NullValue;
     }
     assert(BestValue && "Must have at least one use");
+    assert(BestValue != &I && "Cannot replace with itself");
     return BestValue;
   };
 


Regression tests:
file: llvm/test/Transforms/InstCombine/freeze.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: pr161492_2
test_body: define i64 @pr161492_2(i1 %cond) {
  %fr = freeze i64 poison
  %ret = select i1 %cond, i64 %fr, i64 %fr
  ret i64 %ret
}

test_name: pr161492_1
test_body: define i64 @pr161492_1(i1 %cond) {
  %fr1 = freeze i64 poison
  %fr2 = freeze i64 poison
  %ret = select i1 %cond, i64 %fr1, i64 %fr2
  ret i64 %ret
}

test_name: freeze_ptrmask_nonnull
test_body: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare ptr @llvm.ptrmask.p0.i64(ptr, i64) #0

define ptr @freeze_ptrmask_nonnull(ptr %p, i64 noundef %m) {
  %mask = call nonnull ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
  %fr = freeze ptr %mask
  ret ptr %fr
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
Bug type: hang
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp: InstCombinerImpl::commonShiftTransforms
Issue title: [InstCombine] Infinite loop when combining two `shl` instructions
Labels: llvm:instcombine
llvm:hang
Reported by: momo5502

The following sample triggers an infinite loop in instcombine:

```
@c = external constant i8
@c2 = external constant i8

define i16 @testfunc() {
entry:
  %0 = shl i64 1, ptrtoint (ptr @c2 to i64)
  %1 = shl i64 %0, ptrtoint (ptr @c to i64)
  %2 = inttoptr i64 %1 to ptr
  %3 = load i16, ptr %2, align 1
  ret i16 %3
}
```

https://godbolt.org/z/WP6YvGjPq


Comments: author: momo5502
body: I have a potential fix and will create a PR soon

Fix patch:
commit 27eaa8a40ef338bea611f693fa8e810b1fc8d78d
Author: Maurice Heumann <MauriceHeumann@gmail.com>
Date:   Thu Dec 5 16:57:27 2024 +0100

    [InstCombine] Prevent infinite loop with two shifts (#118806)
    
    The following pattern: `(C2 << X) << C1` will usually be transformed
    into `(C2 << C1) << X`, essentially swapping `X` and `C1`.
    
    However, this should only be done when `C1` is an immediate constant,
    otherwise thiscan lead to both constants being swapped forever.
    
    This fixes #118798.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 10c3ccdb2243..d511e79e3e48 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -427,7 +427,8 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
       if (Instruction *R = FoldOpIntoSelect(I, SI))
         return R;
 
-  if (Constant *CUI = dyn_cast<Constant>(Op1))
+  Constant *CUI;
+  if (match(Op1, m_ImmConstant(CUI)))
     if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
       return Res;
 


Regression tests:
file: llvm/test/Transforms/InstCombine/shl-twice-constant.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: testfunc
test_body: @c = external constant i8
@c2 = external constant i8

define i64 @testfunc() {
  %shl1 = shl i64 1, ptrtoint (ptr @c2 to i64)
  %shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
  ret i64 %shl2
}
Bug type: crash
Component: PredicateInfo
Bug location: llvm/lib/Transforms/Utils/PredicateInfo.cpp: PredicateInfoBuilder::convertUsesToDFSOrdered
Issue title: ipsccp -> llvm.lifetime.start/end can only be used on alloca or poison
Labels: crash-on-valid
llvm:transforms
Reported by: bjope

Running ipsccp pass on IR like this
```
define void @foo() {
  %g = alloca [4 x i16], align 1
  %.not1 = icmp eq ptr %g, inttoptr (i16 -1 to ptr)
  br i1 %.not1, label %for.end35.us.lr.ph, label %for.cond5

for.end35.us.lr.ph:                               ; preds = %entry
  br label %for.end35.us

for.end35.us:                                     ; preds = %for.end35.us, %for.end35.us.lr.ph
  call void @llvm.lifetime.start.p0(ptr %g)
  br label %for.end35.us

for.cond5:                                        ; preds = %entry
  ret void
}
```
results in
```
lvm.lifetime.start/end can only be used on alloca or poison
  call void @llvm.lifetime.start.p0(ptr inttoptr (i16 -1 to ptr))
LLVM ERROR: Broken module found, compilation aborted!
```
See https://godbolt.org/z/jo9zqrP1x

Comments: author: XChy
body: Maybe we should prevent replacing alloca with constant at `SCCPSolver::tryToReplaceWithConstant`?
author: bjope
body: > Maybe we should prevent replacing alloca with constant at `SCCPSolver::tryToReplaceWithConstant`?

In this case I think problem happens earlier, already when introducing an ssa.copy.

Fix patch:
commit ab323eb0c6b2ed8814c4516d4bce179d55372a5a
Author: Nikita Popov <npopov@redhat.com>
Date:   Tue Aug 12 12:53:39 2025 +0200

    [SCCP][PredicateInfo] Do not predicate argument of lifetime intrinsic
    
    Replacing the argument with a no-op bitcast violates a verifier
    constraint, even if only temporarily. Any replacement based on it
    would result in a violation even after the copy has been removed.
    
    Fixes https://github.com/llvm/llvm-project/issues/153013.

diff --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 38a312a3715c..13c7ad2927d1 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -291,6 +291,11 @@ void PredicateInfoBuilder::convertUsesToDFSOrdered(
     Value *Op, SmallVectorImpl<ValueDFS> &DFSOrderedSet) {
   for (auto &U : Op->uses()) {
     if (auto *I = dyn_cast<Instruction>(U.getUser())) {
+      // Lifetime intrinsics must work directly on alloca, do not replace them
+      // with a predicated copy.
+      if (I->isLifetimeStartOrEnd())
+        continue;
+
       ValueDFS VD;
       // Put the phi node uses in the incoming block.
       BasicBlock *IBlock;


Regression tests:
file: llvm/test/Transforms/SCCP/lifetime.ll
commands: opt -S -passes=ipsccp < %s
tests: test_name: <module>
test_body: 
define void @test() {
;
  %a = alloca [4 x i16]
  %cmp = icmp eq ptr %a, inttoptr (i64 -1 to ptr)
  br i1 %cmp, label %if, label %exit

if:
  call void @llvm.lifetime.start.p0(ptr %a)
  br label %exit

exit:
  ret void
}
Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::getEntryCost
Issue title: [SLP] crash after 8ff233f
Labels: llvm:SLPVectorizer
crash-on-valid
Reported by: JonPsson1

8ff233f "[SLP]Correctly detect minnum/maxnum patterns for select/cmp operations on floats." seems to have introduced a problem when building SPEC on SystemZ.

opt  -mtriple=s390x-linux-gnu -mcpu=z16 -O3 ./tc_slp.ll -o /dev/null
opt: /home/ijonpan/llvm-project/llvm/include/llvm/IR/DerivedTypes.h:704: llvm::Type* llvm::Type::getWithNewBitWidth(unsigned int) const: Assertion `isIntOrIntVectorTy() && "Original type expected to be a vector of integers or a scalar integer."' failed.
...
#15 0x000000000519c8f8 llvm::slpvectorizer::BoUpSLP::getEntryCost

[tc_slp.ll.tar.gz](https://github.com/user-attachments/files/16337301/tc_slp.ll.tar.gz)



Fix patch:
commit 3cb82f49dc990dc20a765856c0e126193992fe44
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Mon Jul 22 12:45:28 2024 -0700

    [SLP]Fix PR99899: Use canonical type instead of original vector of ptr.
    
    Use adjusted canonical integer type instead of the original ptr type to
    fix the crash in the TTI.
    Fixes https://github.com/llvm/llvm-project/issues/99899

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 667c4eb311c2..cca9eeebaa53 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -9699,7 +9699,8 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
           CanonicalType = CanonicalType->getWithNewType(IntegerType::get(
               CanonicalType->getContext(),
               DL->getTypeSizeInBits(CanonicalType->getScalarType())));
-        IntrinsicCostAttributes CostAttrs(MinMaxID, VecTy, {VecTy, VecTy});
+        IntrinsicCostAttributes CostAttrs(MinMaxID, CanonicalType,
+                                          {CanonicalType, CanonicalType});
         InstructionCost IntrinsicCost =
             TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
         // If the selects are the only uses of the compares, they will be


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/SystemZ/cmp-ptr-minmax.ll
commands: opt -S --passes=slp-vectorizer -mtriple=s390x-unknown-linux-gnu -mcpu=z16 -slp-threshold=-10 < %s
tests: test_name: <module>
test_body: 
define i1 @test(i64 %0, i64 %1, ptr %2) {
;
entry:
  %gep44 = getelementptr i8, ptr null, i64 %0
  %gep45 = getelementptr i8, ptr null, i64 %1
  %4 = icmp ult ptr %gep44, %gep45
  %umin = select i1 %4, ptr %gep44, ptr %gep45
  %gep48 = getelementptr i8, ptr null, i64 %0
  %gep49 = getelementptr i8, ptr null, i64 %1
  %5 = icmp ult ptr %gep48, %gep49
  %umin50 = select i1 %5, ptr %gep48, ptr %gep49
  %b095 = icmp ult ptr %umin, %2
  %b196 = icmp ult ptr %umin50, %2
  %res = and i1 %b095, %b196
  ret i1 %res
}
Bug type: miscompilation
Component: ValueTracking
Bug location: llvm/lib/Analysis/ValueTracking.cpp: isImpliedCondICmps
Issue title: [ValueTracking] miscompile in samesign compare
Labels: miscompilation
llvm:analysis
Reported by: DianQK

#122590 and #122700 miscompile the following code:

```llvm
define i1 @src(i8 %L0, i8 %L1, i1 %V) {
  %LHS = icmp samesign ugt i8 %L0, %L1
  %R0 = sub nsw i8 %L0, %L1
  %RHS = icmp ult i8 %R0, -1
  br i1 %LHS, label %LHS_true, label %LHS_false

LHS_true:
  br label %EXIT

LHS_false:
  br label %EXIT

EXIT:
  %RET = phi i1 [ %RHS, %LHS_true ], [ %V, %LHS_false ]
  ret i1 %RET
}
```

`%RHS` should be 1: https://alive2.llvm.org/ce/z/RscAzy.


Fix patch:
commit c546b5317c518987a5f45dd4c4d25321a955c758
Author: DianQK <dianqk@dianqk.net>
Date:   Fri Jan 24 23:02:50 2025 +0800

    [ValueTracking] Pass changed predicate `SignedLPred` to `isImpliedByMatchingCmp` (#124271)
    
    Fixes #124267.
    
    Since we are using the new predicate, we should also update the
    parameters of `isImpliedByMatchingCmp`.

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 264fedd6b66b..eba728c7c8c3 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9494,7 +9494,7 @@ isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0,
        SignedLPred == ICmpInst::ICMP_SGE) &&
       match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) {
     if (match(R1, m_NonPositive()) &&
-        ICmpInst::isImpliedByMatchingCmp(LPred, RPred) == false)
+        ICmpInst::isImpliedByMatchingCmp(SignedLPred, RPred) == false)
       return false;
   }
 
@@ -9504,7 +9504,7 @@ isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0,
        SignedLPred == ICmpInst::ICMP_SLE) &&
       match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) {
     if (match(R1, m_NonNegative()) &&
-        ICmpInst::isImpliedByMatchingCmp(LPred, RPred) == true)
+        ICmpInst::isImpliedByMatchingCmp(SignedLPred, RPred) == true)
       return true;
   }
 


Regression tests:
file: llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
commands: opt -passes=instsimplify -S %s
tests: test_name: gt_sub_nsw_ult
test_body: define i1 @gt_sub_nsw_ult(i8 %L0, i8 %L1, i1 %V) {
  %LHS = icmp samesign ugt i8 %L0, %L1
  br i1 %LHS, label %LHS_true, label %LHS_false

LHS_true:                                         ; preds = %0
  %R0 = sub nsw i8 %L0, %L1
  %RHS = icmp ult i8 %R0, -1
  ret i1 %RHS

LHS_false:                                        ; preds = %0
  ret i1 %V
}

test_name: lt_sub_nsw_ult
test_body: define i1 @lt_sub_nsw_ult(i8 %L0, i8 %L1, i1 %V) {
  %LHS = icmp samesign ult i8 %L0, %L1
  br i1 %LHS, label %LHS_true, label %LHS_false

LHS_true:                                         ; preds = %0
  %R0 = sub nsw i8 %L0, %L1
  %RHS = icmp ult i8 %R0, 1
  ret i1 %RHS

LHS_false:                                        ; preds = %0
  ret i1 %V
}