Bug type: crash
Component: LazyValueInfo
Bug location: llvm/lib/Analysis/LazyValueInfo.cpp: LazyValueInfoImpl::getEdgeValueLocal
Issue title: [CVP] Assertion `getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"' failed.
Labels: crash-on-valid
llvm:analysis
generated by fuzzer
Reported by: dtcxzyw

Reproducer: https://godbolt.org/z/3anEc1bnb
```
; bin/opt -passes=correlated-propagation 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"

@g_228 = external global [3 x i8]

define i16 @func_219() {
entry:
  %0 = trunc i64 0 to i16
  %exitcond = icmp eq i64 0, sub (i64 0, i64 ptrtoint (ptr @g_228 to i64))
  br i1 %exitcond, label %lbl_1093.loopexit, label %for.cond373.preheader

for.cond373.preheader:                            ; preds = %entry
  br label %lbl_1093.loopexit

lbl_1093.loopexit:                                ; preds = %for.cond373.preheader, %entry
  %storemerge.lcssa = phi i16 [ %0, %entry ], [ 0, %for.cond373.preheader ]
  ret i16 %storemerge.lcssa
}
```
```
opt: /root/llvm-project/llvm/include/llvm/IR/Instructions.h:2718: void llvm::PHINode::setIncomingValue(unsigned int, llvm::Value*): Assertion `getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -passes=correlated-propagation <source>
1.	Running pass "function(correlated-propagation)" on module "<source>"
2.	Running pass "correlated-propagation" on function "func_219"
 #0 0x00000000058f05c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x58f05c8)
 #1 0x00000000058ed474 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x0000739263c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x0000739263c969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x0000739263c42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x0000739263c287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x0000739263c2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x0000739263c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x000000000452f3c5 runImpl(llvm::Function&, llvm::LazyValueInfo*, llvm::DominatorTree*, llvm::SimplifyQuery const&) CorrelatedValuePropagation.cpp:0:0
 #9 0x000000000452f5cb llvm::CorrelatedValuePropagationPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x452f5cb)
#10 0x0000000002f5c97e llvm::detail::PassModel<llvm::Function, llvm::CorrelatedValuePropagationPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2f5c97e)
#11 0x00000000056d7b01 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56d7b01)
#12 0x0000000000eecc6e llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xeecc6e)
#13 0x00000000056d606a llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56d606a)
#14 0x000000000097366e llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x97366e)
#15 0x00000000056d5a21 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56d5a21)
#16 0x000000000097d77a llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x97d77a)
#17 0x00000000009719c7 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9719c7)
#18 0x0000739263c29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#19 0x0000739263c29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#20 0x0000000000968ad5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x968ad5)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```



Fix patch:
commit d62776d03323e709abb8e4734e0ae36f76dba815
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Wed Oct 1 14:20:10 2025 +0800

    [LVI] Handle constant value lattice in `getEdgeValueLocal` (#161410)
    
    Closes https://github.com/llvm/llvm-project/issues/161367.
    
    In https://github.com/llvm/llvm-project/pull/157614, we ignored cases
    where OpLatticeVal might be a constant or notconstant. Directly
    returning the result causes a type mismatch. I apologize for the
    oversight in the previous code review.
    
    This patch applies the cast op to constants. For notconstant value
    lattices, I'd leave it as a todo (it is similar to the constant case,
    except for trunc without nsw/nuw).

diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 6fb28072afe4..0e5bc481383a 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1632,19 +1632,25 @@ LazyValueInfoImpl::getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
                 *getValueFromCondition(Usr->getOperand(0), Condition,
                                        isTrueDest, /*UseBlockValue*/ false);
 
-            if (!OpLatticeVal.isConstantRange())
-              return OpLatticeVal;
+            if (OpLatticeVal.isConstantRange()) {
+              const unsigned ResultBitWidth =
+                  Usr->getType()->getScalarSizeInBits();
+              if (auto *Trunc = dyn_cast<TruncInst>(Usr))
+                return ValueLatticeElement::getRange(
+                    OpLatticeVal.getConstantRange().truncate(
+                        ResultBitWidth, Trunc->getNoWrapKind()));
 
-            const unsigned ResultBitWidth =
-                Usr->getType()->getScalarSizeInBits();
-            if (auto *Trunc = dyn_cast<TruncInst>(Usr))
               return ValueLatticeElement::getRange(
-                  OpLatticeVal.getConstantRange().truncate(
-                      ResultBitWidth, Trunc->getNoWrapKind()));
-
-            return ValueLatticeElement::getRange(
-                OpLatticeVal.getConstantRange().castOp(
-                    cast<CastInst>(Usr)->getOpcode(), ResultBitWidth));
+                  OpLatticeVal.getConstantRange().castOp(
+                      cast<CastInst>(Usr)->getOpcode(), ResultBitWidth));
+            }
+            if (OpLatticeVal.isConstant()) {
+              Constant *C = OpLatticeVal.getConstant();
+              if (auto *CastC = ConstantFoldCastOperand(
+                      cast<CastInst>(Usr)->getOpcode(), C, Usr->getType(), DL))
+                return ValueLatticeElement::get(CastC);
+            }
+            return ValueLatticeElement::getOverdefined();
           } else {
             // If one of Val's operand has an inferred value, we may be able to
             // infer the value of Val.


Regression tests:
file: llvm/test/Transforms/CorrelatedValuePropagation/pr161367.ll
commands: opt < %s -passes=correlated-propagation -S
tests: test_name: <module>
test_body: 
; Make sure that we apply trunc to the edge value of %x.
@g = external global i8

define i16 @pr161367(i64 %x) {
;
entry:
  %trunc = trunc i64 %x to i16
  %exitcond = icmp eq i64 %x, sub (i64 0, i64 ptrtoint (ptr @g to i64))
  br i1 %exitcond, label %exit, label %else

else:
  br label %exit

exit:
  %ret = phi i16 [ %trunc, %entry ], [ 0, %else ]
  ret i16 %ret
}