dtcxzyw/llvm-apr-benchmark huggingface dataset:
Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp: foldFCmpFSubIntoFCmp
Issue title: [InstCombine] `ninf` should not be propagated when folding `fcmp pred, x - y, 0` to `fcmp pred, x, y`
Labels: miscompilation
llvm:instcombine
floating-point
generated by fuzzer
Reported by: dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/ZHW6-B
```
; bin/opt -passes=instcombine test.ll -S
define i1 @src1(float %x, float %y) {
  %fs = fsub float %x, %y
  %cmp = fcmp ninf ule float %fs, 0.000000e+00
  ret i1 %cmp
}
```
```
=>
define i1 @src1(float %x, float %y) {
#0:
  %cmp = fcmp ninf ule float %x, %y
  ret i1 %cmp
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
float %x = #x7f800000 (+oo)
float %y = #x7f800080 (SNaN)

Source:
float %fs = #xffc00003 (QNaN)
i1 %cmp = #x1 (1)

Target:
i1 %cmp = poison
Source value: #x1 (1)
Target value: poison
```



Fix patch:
commit 0b7129afccc8e79fb88bb686466211f3bcad142e
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Fri Oct 3 01:44:03 2025 +0800

    [InstCombine] Fix FMF propagation in `foldFCmpFSubIntoFCmp` (#161539)
    
    Proof: https://alive2.llvm.org/ce/z/orSP-S
    Closes https://github.com/llvm/llvm-project/issues/161525.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index e4cb457499ef..60da48e1d95d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8527,6 +8527,9 @@ static Instruction *foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI,
             DenormalMode::getIEEE()) {
       CI.replaceOperand(I, 0, X);
       CI.replaceOperand(I, 1, Y);
+      I.setHasNoInfs(LHSI->hasNoInfs());
+      if (LHSI->hasNoNaNs())
+        I.setHasNoNaNs(true);
       return &I;
     }
     break;


Regression tests:
file: llvm/test/Transforms/InstCombine/fcmp.ll
commands: opt -S -passes=instcombine < %s
tests: test_name: fcmp_ninf_ule_fsub_const
test_body: define i1 @fcmp_ninf_ule_fsub_const(float %x, float %y) {
  %fs = fsub float %x, %y
  %cmp = fcmp ninf ule float %fs, 0.000000e+00
  ret i1 %cmp
}

test_name: fcmp_ule_fsub_ninf_const
test_body: define i1 @fcmp_ule_fsub_ninf_const(float %x, float %y) {
  %fs = fsub ninf float %x, %y
  %cmp = fcmp ule float %fs, 0.000000e+00
  ret i1 %cmp
}

test_name: fcmp_ule_fsub_nnan_const
test_body: define i1 @fcmp_ule_fsub_nnan_const(float %x, float %y) {
  %fs = fsub nnan float %x, %y
  %cmp = fcmp ule float %fs, 0.000000e+00
  ret i1 %cmp
}

test_name: fcmp_nnan_ule_fsub_const
test_body: define i1 @fcmp_nnan_ule_fsub_const(float %x, float %y) {
  %fs = fsub float %x, %y
  %cmp = fcmp nnan ule float %fs, 0.000000e+00
  ret i1 %cmp
}

test_name: fcmp_ugt_fsub_const
test_body: define i1 @fcmp_ugt_fsub_const(float %x, float %y) {
  %fs = fsub float %x, %y
  %cmp = fcmp ugt float %fs, 0.000000e+00
  ret i1 %cmp
}

test_name: fcmp_ule_fsub_const
test_body: define i1 @fcmp_ule_fsub_const(float %x, float %y) {
  %fs = fsub float %x, %y
  %cmp = fcmp ule float %fs, 0.000000e+00
  ret i1 %cmp
}
Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: areAllOperandsReplacedByCopyableData
Issue title: [SLP] Assertion `all_of(Bundles, [](const ScheduleBundle *Bundle) { return Bundle->isScheduled(); }) && "must be scheduled at this point"' failed.
Labels: llvm:SLPVectorizer
crash-on-valid
Reported by: fhahn

The following input triggers an assertion with `-p slp-vectorizer` on current `main`:
https://llvm.godbolt.org/z/xsTTooc64

```
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx15.0.0"

define void @crash(ptr %output) #0 {
entry:
  %arrayidx.2.i = getelementptr i8, ptr %output, i64 8
  %0 = load i32, ptr %output, align 4
  %arrayidx.3.i = getelementptr i8, ptr %output, i64 12
  %1 = load i32, ptr %arrayidx.3.i, align 4
  %xor7 = xor i32 -1, %0
  %or.i = tail call i32 @llvm.fshl.i32(i32 %xor7, i32 0, i32 2)
  %or.i11 = tail call i32 @llvm.fshl.i32(i32 %1, i32 %1, i32 2)
  store i32 %or.i, ptr %arrayidx.2.i, align 4
  store i32 %or.i11, ptr %arrayidx.3.i, align 4
  ret void
}

declare i32 @llvm.fshl.i32(i32, i32, i32) #1

attributes #0 = { "target-cpu"="skylake-avx512" }
``

Comments: author: fhahn
body: cc @alexey-bataev 

Fix patch:
commit e6b0be376412bf0599f6e75aa5e67f95cd36b411
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Sun Oct 19 11:29:14 2025 -0700

    [SLP]Correctly calculate number of copyable operands
    
    The compiler shall not check for overflow of the number of copyable
    operands counter, otherwise non-copyable operand can be counted as
    copyable and lead to a compiler crash.
    
    Fixes #164164

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 9cd52da1ce1c..048a3e691fe5 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -5343,7 +5343,7 @@ private:
             unsigned &OpCnt =
                 OrderedEntriesCount.try_emplace(TE, 0).first->getSecond();
             EdgeInfo EI(TE, U.getOperandNo());
-            if (!getScheduleCopyableData(EI, Op) && OpCnt < NumOps)
+            if (!getScheduleCopyableData(EI, Op))
               continue;
             // Found copyable operand - continue.
             ++OpCnt;


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/num-uses-for-copyable-elements.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-apple-macosx15.0.0  -mcpu=skylake-avx512 -S < %s
tests: test_name: <module>
test_body: 
define void @test(ptr %output) {
;
entry:
  %arrayidx.2.i = getelementptr i8, ptr %output, i64 8
  %0 = load i32, ptr %output, align 4
  %arrayidx.3.i = getelementptr i8, ptr %output, i64 12
  %1 = load i32, ptr %arrayidx.3.i, align 4
  %xor7 = xor i32 -1, %0
  %or.i = tail call i32 @llvm.fshl.i32(i32 %xor7, i32 0, i32 2)
  %or.i11 = tail call i32 @llvm.fshl.i32(i32 %1, i32 %1, i32 2)
  store i32 %or.i, ptr %arrayidx.2.i, align 4
  store i32 %or.i11, ptr %arrayidx.3.i, align 4
  ret void
}

declare i32 @llvm.fshl.i32(i32, i32, i32)
Bug type: miscompilation
Component: VectorCombine
Bug location: llvm/lib/Transforms/Vectorize/VectorCombine.cpp: VectorCombine::foldShuffleOfBinops
Issue title: VectorCombine transform leading to srem by poison
Labels: miscompilation
vectorizers
Reported by: regehr

https://alive2.llvm.org/ce/z/HRAkAK

this:
```llvm
define <4 x i32> @f(<4 x i32> %0, <4 x i32> %1) {
  %3 = srem <4 x i32> %1, %0
  %4 = srem <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %0
  %5 = shufflevector <4 x i32> %3, <4 x i32> %4, <4 x i32> <i32 0, i32 poison, i32 6, i32 3>
  ret <4 x i32> %5
}
```
is getting vector-combined to this:
```llvm
define <4 x i32> @f(<4 x i32> %0, <4 x i32> %1) {
  %3 = shufflevector <4 x i32> %1, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 0, i32 poison, i32 6, i32 3>
  %4 = shufflevector <4 x i32> %0, <4 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 2, i32 3>
  %5 = srem <4 x i32> %3, %4
  ret <4 x i32> %5
}
```

but that poison in lane 1 is now problematic, this gives us full UB when it hits the srem

cc @nunoplopes @hatsunespica


Comments: author: RKSimon
body: I'll take a look at this

Fix patch:
commit 4cc9c6d98dfef90d1ffa69977d13ffa2894a10f7
Author: Simon Pilgrim <llvm-dev@redking.me.uk>
Date:   Mon Apr 22 09:00:20 2024 +0100

    [VectorCombine] foldShuffleOfBinops - don't fold shuffle(divrem(x,y),divrem(z,w)) if mask contains poison
    
    Fixes #89390

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 4918cee1fa82..f23b10540338 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1405,6 +1405,11 @@ bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
       B0->getOpcode() != B1->getOpcode() || B0->getType() != VecTy)
     return false;
 
+  // Don't introduce poison into div/rem.
+  if (any_of(Mask, [](int M) { return M == PoisonMaskElem; }) &&
+      B0->isIntDivRem())
+    return false;
+
   // Try to replace a binop with a shuffle if the shuffle is not costly.
   // The new shuffle will choose from a single, common operand, so it may be
   // cheaper than the existing two-operand shuffle.


Regression tests:
file: llvm/test/Transforms/VectorCombine/X86/shuffle-of-binops.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: shuf_and_v16i16_yy_expensive_shuf
test_body: define <16 x i16> @shuf_and_v16i16_yy_expensive_shuf(<16 x i16> %x, <16 x i16> %y, <16 x i16> %z) {
  %b0 = and <16 x i16> %x, %y
  %b1 = and <16 x i16> %y, %z
  %r = shufflevector <16 x i16> %b0, <16 x i16> %b1, <16 x i32> <i32 15, i32 22, i32 25, i32 13, i32 28, i32 0, i32 poison, i32 3, i32 0, i32 30, i32 3, i32 7, i32 9, i32 19, i32 2, i32 22>
  ret <16 x i16> %r
}

test_name: shuf_srem_v4i32_poison
test_body: define <4 x i32> @shuf_srem_v4i32_poison(<4 x i32> %a0, <4 x i32> %a1) {
  %srem0 = srem <4 x i32> %a1, %a0
  %srem1 = srem <4 x i32> splat (i32 1), %a0
  %r = shufflevector <4 x i32> %srem0, <4 x i32> %srem1, <4 x i32> <i32 0, i32 poison, i32 6, i32 3>
  ret <4 x i32> %r
}
Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: SLPVectorizerPass::vectorizeCmpInsts
Issue title: [SLP] Assertion `detail::isPresent(Val) && "dyn_cast on a non-existent value"' failed.
Labels: llvm:SLPVectorizer
crash-on-valid
Reported by: DianQK

This IR crashes on SLP: https://llvm.godbolt.org/z/8oar4o4d1

```llvm
define void @foo() {
bb:
  br label %bb1

bb1:                                              ; preds = %bb3, %bb
  %i = phi i32 [ %i26, %bb3 ], [ 0, %bb ]
  %i2 = phi i32 [ %i24, %bb3 ], [ 0, %bb ]
  br label %bb3

bb3:                                              ; preds = %bb1
  %i4 = zext i32 %i2 to i64
  %i5 = mul i64 %i4, 0
  %i10 = or i64 0, %i5
  %i11 = trunc i64 %i10 to i32
  %i12 = and i32 %i11, 0
  %i13 = zext i32 %i to i64
  %i14 = mul i64 %i13, 0
  %i19 = or i64 0, %i14
  %i20 = trunc i64 %i19 to i32
  %i21 = and i32 %i20, 0
  %i22 = or i32 %i12, %i21
  %i23 = icmp ult i32 %i22, 0
  %i24 = select i1 %i23, i32 0, i32 0
  %i25 = icmp ult i32 0, 0
  %i26 = select i1 %i25, i32 0, i32 0
  br label %bb1
}
```


Fix patch:
commit e7a4d78ad328d02bf515b2fa4af8b2c188a6a636
Author: DianQK <dianqk@dianqk.net>
Date:   Thu Dec 19 06:21:57 2024 +0800

    [SLP] Check if instructions exist after vectorization (#120434)
    
    Fixes #120433.

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index d967813075bb..88049897b29a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -21148,8 +21148,11 @@ bool SLPVectorizerPass::vectorizeCmpInsts(iterator_range<ItT> CmpInsts,
     if (R.isDeleted(I))
       continue;
     for (Value *Op : I->operands())
-      if (auto *RootOp = dyn_cast<Instruction>(Op))
+      if (auto *RootOp = dyn_cast<Instruction>(Op)) {
         Changed |= vectorizeRootInstruction(nullptr, RootOp, BB, R);
+        if (R.isDeleted(I))
+          break;
+      }
   }
   // Try to vectorize operands as vector bundles.
   for (CmpInst *I : CmpInsts) {


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/slp-deleted-inst.ll
commands: opt -S -passes=slp-vectorizer < %s
tests: test_name: foo
test_body: define void @foo() {
bb:
  br label %bb1

bb1:                                              ; preds = %bb3, %bb
  %i = phi i32 [ %i26, %bb3 ], [ 0, %bb ]
  %i2 = phi i32 [ %i24, %bb3 ], [ 0, %bb ]
  br label %bb3

bb3:                                              ; preds = %bb1
  %i4 = zext i32 %i2 to i64
  %i5 = mul i64 %i4, 0
  %i10 = or i64 0, %i5
  %i11 = trunc i64 %i10 to i32
  %i12 = and i32 %i11, 0
  %i13 = zext i32 %i to i64
  %i14 = mul i64 %i13, 0
  %i19 = or i64 0, %i14
  %i20 = trunc i64 %i19 to i32
  %i21 = and i32 %i20, 0
  %i22 = or i32 %i12, %i21
  %i23 = icmp ult i32 %i22, 0
  %i24 = select i1 %i23, i32 0, i32 0
  %i25 = icmp ult i32 0, 0
  %i26 = select i1 %i25, i32 0, i32 0
  br label %bb1
}
Bug type: crash
Component: InductiveRangeCheckElimination
Bug location: llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp: InductiveRangeCheck::parseRangeCheckICmp
Issue title: Assertion in Scalar Evolution when running IRCE
Labels: llvm:SCEV
crash-on-valid
Reported by: gbaraldi

The following IR crashes with 
```llvm
define void @foo() {
top:
  br label %L3

L3:                                               ; preds = %L13, %top
  %value_phi = phi ptr [ null, %top ], [ %0, %L13 ]
  %0 = getelementptr i8, ptr %value_phi, i64 8
  %.not = icmp ule ptr %value_phi, null
  br i1 %.not, label %L13, label %L15

L13:                                              ; preds = %L3
  br label %L3

L15:                                              ; preds = %L3
  ret void
}
```

`opt --passes=irce` 

https://godbolt.org/z/1sbvaT7r1 


Fix patch:
commit 22da5a6e34ed6146752b24d9156a678b50fddaef
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Fri Apr 26 16:25:33 2024 +0800

    [IRCE] Skip icmp ptr in `InductiveRangeCheck::parseRangeCheckICmp` (#89967)
    
    Fixes https://github.com/llvm/llvm-project/issues/89959.

diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index 9df28747570c..104e8ceb7967 100644
--- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -279,6 +279,9 @@ bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
   Value *LHS = ICI->getOperand(0);
   Value *RHS = ICI->getOperand(1);
 
+  if (!LHS->getType()->isIntegerTy())
+    return false;
+
   // Canonicalize to the `Index Pred Invariant` comparison
   if (IsLoopInvariant(LHS)) {
     std::swap(LHS, RHS);


Regression tests:
file: llvm/test/Transforms/IRCE/pr89959.ll
commands: opt -passes=irce -S < %s 2>&1
tests: test_name: <module>
test_body: 
; Make sure we don't crash.
define void @pr89959() {
;
top:
  br label %L3

L3:
  %value_phi = phi ptr [ null, %top ], [ %0, %L13 ]
  %0 = getelementptr i8, ptr %value_phi, i64 8
  %.not = icmp ule ptr %value_phi, null
  br i1 %.not, label %L13, label %L15

L13:
  br label %L3

L15:
  ret void
}
Bug type: crash
Component: AggressiveInstCombine
Bug location: llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp: mergeConsecutivePartStores
Issue title: [AggressiveInstCombine] Invalid trunc creation in store merge optimization
Labels: crash
llvm:instcombine
Reported by: nikic

```llvm
target triple = "x86_64-unknown-linux-gnu"

define void @test(i56 %arg, ptr %p) {
  %lo = trunc i56 %arg to i32
  store i32 %lo, ptr %p, align 4
  %shr = lshr i56 %arg, 32
  %hi = trunc i56 %shr to i32
  %p.4 = getelementptr i8, ptr %p, i64 4
  store i32 %hi, ptr %p.4, align 4
  ret void
}
```

> opt: /home/npopov/repos/llvm-project/llvm/lib/IR/Instructions.cpp:3043: static CastInst *llvm::CastInst::Create(Instruction::CastOps, Value *, Type *, const Twine &, InsertPosition): Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' failed.



Fix patch:
commit 4167b285e228ee1cfff77f30eee66cbc7b4dd3db
Author: Nikita Popov <npopov@redhat.com>
Date:   Thu Feb 12 14:41:00 2026 +0100

    [AggressiveInstCombine] Create zext during store merge (#181125)
    
    The top extracted value can include shifted-in zero bits. In that case
    we should emit a zext before the new store.
    
    Fixes https://github.com/llvm/llvm-project/issues/181117.

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 3341368208c2..797fabde3f25 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -915,7 +915,7 @@ static bool mergeConsecutivePartStores(ArrayRef<PartStore> Parts,
   Value *Val = First.Val;
   if (First.ValOffset != 0)
     Val = Builder.CreateLShr(Val, First.ValOffset);
-  Val = Builder.CreateTrunc(Val, NewTy);
+  Val = Builder.CreateZExtOrTrunc(Val, NewTy);
   StoreInst *Store = Builder.CreateAlignedStore(
       Val, First.Store->getPointerOperand(), First.Store->getAlign());
 


Regression tests:
file: llvm/test/Transforms/AggressiveInstCombine/X86/store-merge.ll
commands: opt -S -passes=aggressive-instcombine -mtriple=x86_64-unknown-linux-gnu < %s
tests: test_name: test_store_same_parts_twice
test_body: define void @test_store_same_parts_twice(i32 %x, ptr %p) {
  %x.0 = trunc i32 %x to i8
  store i8 %x.0, ptr %p, align 1
  %shr.1 = lshr i32 %x, 8
  %x.1 = trunc i32 %shr.1 to i8
  %gep.1 = getelementptr i8, ptr %p, i64 1
  store i8 %x.1, ptr %gep.1, align 1
  %gep.2 = getelementptr i8, ptr %p, i64 2
  store i8 %x.0, ptr %gep.2, align 1
  %gep.3 = getelementptr i8, ptr %p, i64 3
  store i8 %x.1, ptr %gep.3, align 1
  ret void
}

test_name: test_zext_store
test_body: define void @test_zext_store(i56 %arg, ptr %p) {
  %lo = trunc i56 %arg to i32
  store i32 %lo, ptr %p, align 4
  %shr = lshr i56 %arg, 32
  %hi = trunc i56 %shr to i32
  %p.4 = getelementptr i8, ptr %p, i64 4
  store i32 %hi, ptr %p.4, align 4
  ret void
}
Bug type: crash
Component: LoopStrengthReduce
Bug location: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp: ReduceLoopStrength
Issue title: [LSR] crashed on "asserting value handle still pointed to this value!"
Labels: llvm:crash
llvm:transforms
Reported by: coderchenlin

https://godbolt.org/z/MWWcGdxT5
LSR crashed when deleting dead PHIs 

Comments: author: coderchenlin
body: I will give a resolution to fix it later.
author: coderchenlin
body:  #84777 For this case, I think we should not set the value with nullptr when the value's uses are not empty.   
author: nikic
body: Reduced:
```llvm
define i64 @test() {
bb:
  br label %bb1

bb1:
  %phi = phi i8 [ %zext6, %bb5 ], [ 0, %bb ]
  br label %bb2

bb2:
  %phi3 = phi i8 [ %add, %bb2 ], [ %phi, %bb1 ]
  %phi4 = phi i32 [ 0, %bb2 ], [ 1, %bb1 ]
  %add = add i8 %phi3, 1
  br i1 true, label %bb5, label %bb2

bb5:
  %zext = zext i8 %add to i32
  %icmp = icmp sge i32 %phi4, 0
  %zext6 = zext i1 %icmp to i8
  br label %bb1
}
```

Fix patch:
commit beba307c5bc206168bdea3b893e02ea31579fe62
Author: Nikita Popov <npopov@redhat.com>
Date:   Tue Mar 12 16:23:25 2024 +0100

    [LSR] Clear SCEVExpander before deleting phi nodes
    
    Fixes https://github.com/llvm/llvm-project/issues/84709.

diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 8b078ddc4e74..c4e1a0db8b32 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -6971,6 +6971,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
     Rewriter.setDebugType(DEBUG_TYPE);
 #endif
     unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &TTI);
+    Rewriter.clear();
     if (numFolded) {
       Changed = true;
       RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts, &TLI,
@@ -6989,6 +6990,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
     SCEVExpander Rewriter(SE, DL, "lsr", true);
     int Rewrites = rewriteLoopExitValues(L, &LI, &TLI, &SE, &TTI, Rewriter, &DT,
                                          UnusedIndVarInLoop, DeadInsts);
+    Rewriter.clear();
     if (Rewrites) {
       Changed = true;
       RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts, &TLI,


Regression tests:
file: llvm/test/Transforms/LoopStrengthReduce/pr84709.ll
commands: opt -S -passes=loop-reduce < %s
tests: test_name: test
test_body: define i64 @test() {
bb:
  br label %bb1

bb1:                                              ; preds = %bb5, %bb
  %phi = phi i8 [ %zext6, %bb5 ], [ 0, %bb ]
  br label %bb2

bb2:                                              ; preds = %bb2, %bb1
  %phi3 = phi i8 [ %add, %bb2 ], [ %phi, %bb1 ]
  %phi4 = phi i32 [ 0, %bb2 ], [ 1, %bb1 ]
  %add = add i8 %phi3, 1
  br i1 true, label %bb5, label %bb2

bb5:                                              ; preds = %bb2
  %zext = zext i8 %add to i32
  %icmp = icmp sge i32 %phi4, 0
  %zext6 = zext i1 %icmp to i8
  br label %bb1
}
Bug type: miscompilation
Component: Float2Int
Bug location: llvm/lib/Transforms/Scalar/Float2Int.cpp: Float2IntPass::calcRange
Issue title: [Float2Int] Miscompilation at O3
Labels: miscompilation
floating-point
llvm:transforms
generated by fuzzer
Reported by: dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/u3J86e
```
; bin/opt -passes=float2int test.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i1 @src() {
entry:
  %0 = fadd float 0xC5AAD8ABE0000000, 0xC57E819700000000
  %1 = fcmp one float %0, 0.000000e+00
  ret i1 %1
}
```
```
=>
define i1 @src() {
entry:
  ret i1 0
}
Transformation doesn't verify!

ERROR: Value mismatch

NOTE: The counterexample is unique.

Example:

Source:
float %#0 = #xed7546f6 (-4744350869734834488282710016)
i1 %#1 = #x1 (1)

Target:
Source value: #x1 (1)
Target value: #x0 (0)
```
llvm version: cf35502dd569d842a860696650a783f896db0648


Fix patch:
commit edd8b29667716101ed026baf3aa4befb37ac132a
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Thu Nov 13 20:54:32 2025 +0800

    [Float2Int] Make sure the CFP can be represented in the integer type (#167699)
    
    When `convertToInteger` fails, the integer result is undefined. In this
    case, we cannot use it in the subsequent steps.
    Close https://github.com/llvm/llvm-project/issues/167627.

diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index 14686ce8c2ab..37822cf05f14 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -237,10 +237,14 @@ std::optional<ConstantRange> Float2IntPass::calcRange(Instruction *I) {
       // OK, it's representable. Now get it.
       APSInt Int(MaxIntegerBW+1, false);
       bool Exact;
-      CF->getValueAPF().convertToInteger(Int,
-                                         APFloat::rmNearestTiesToEven,
-                                         &Exact);
-      OpRanges.push_back(ConstantRange(Int));
+      APFloat::opStatus Status = CF->getValueAPF().convertToInteger(
+          Int, APFloat::rmNearestTiesToEven, &Exact);
+      // Although the round above is loseless, we still need to check if the
+      // floating-point value can be represented in the integer type.
+      if (Status == APFloat::opOK || Status == APFloat::opInexact)
+        OpRanges.push_back(ConstantRange(Int));
+      else
+        return badRange();
     } else {
       llvm_unreachable("Should have already marked this as badRange!");
     }


Regression tests:
file: llvm/test/Transforms/Float2Int/pr167627.ll
commands: opt -S -passes=float2int < %s
tests: test_name: pr167627
test_body: define i1 @pr167627() {
entry:
  %fadd = fadd float 0xC5AAD8ABE0000000, 0xC57E819700000000
  %cmp = fcmp one float %fadd, 0.000000e+00
  ret i1 %cmp
}