Bug type: miscompilation
Component: SimplifyIndVar
Bug location: llvm/lib/Transforms/Utils/SimplifyIndVar.cpp: WidenIV::widenWithVariantUse
Issue title: [IndVarSimplify] Miscompilation at -O3
Labels: miscompilation
llvm:transforms
Reported by: dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/fvxiS3
```
; bin/opt -passes=indvars 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 void @src(ptr %p) {
entry:
  br label %for.body21

for.body21:
  %storemerge629 = phi i8 [ -12, %entry ], [ %dec, %for.body21 ]
  %conv29 = sext i8 %storemerge629 to i16
  %conv1.i = sext i8 %storemerge629 to i16
  %add.i = add i16 %conv29, %conv1.i
  %conv55 = zext i16 %add.i to i32
  store i32 %conv55, ptr %p, align 4
  %dec = add i8 %storemerge629, 1
  br i1 false, label %for.body21, label %for.end234

for.end234:
  ret void
}
```
Output:
```
define void @tgt(ptr %p) {
  br label %for.body21

for.body21:                                       ; preds = %for.body21, %entry
  store i32 131048, ptr %p, align 4
  br i1 false, label %for.body21, label %for.end234

for.end234:                                       ; preds = %for.body21
  ret void
}
```
`store i32 131048, ptr @g_150, align 4` should be `store i32 65512, ptr @g_150, align 4`
llvm version: f819f46284f2a79790038e1f6649172789734ae8



Fix patch:
commit d14acb78065bdd331019924feaaef52e5e744529
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Fri Apr 11 09:03:06 2025 +0800

    [IndVarSimplify] Handle the case where both operands are the same when widening IV (#135207)
    
    `WidenIV::widenWithVariantUse` assumes that exactly one of the binop
    operands is the IV to be widened. This miscompilation happens when it
    tries to sign-extend the "NonIV" operand while the IV is zero-extended.
    Closes https://github.com/llvm/llvm-project/issues/135182.

diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 7b9c5c77cbe9..5a76bec01765 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -1743,6 +1743,9 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
     // TODO: Support case for NarrowDef = NarrowUse->getOperand(1).
     if (NarrowUse->getOperand(0) != NarrowDef)
       return false;
+    // We cannot use a different extend kind for the same operand.
+    if (NarrowUse->getOperand(1) == NarrowDef)
+      return false;
     if (!SE->isKnownNegative(RHS))
       return false;
     bool ProvedSubNUW = SE->isKnownPredicateAt(ICmpInst::ICMP_UGE, LHS,


Regression tests:
file: llvm/test/Transforms/IndVarSimplify/pr135182.ll
commands: opt -S -passes=indvars < %s
tests: test_name: pr135182
test_body: 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"

define i32 @pr135182() {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %indvar = phi i16 [ -12, %entry ], [ %indvar.next, %for.body ]
  %add = add i16 %indvar, %indvar
  %ext = zext i16 %add to i32
  %indvar.next = add i16 %indvar, 1
  br i1 false, label %for.body, label %for.end

for.end:                                          ; preds = %for.body
  ret i32 %ext
}