Bug type: hang
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp: Negator::Negate
Negator::Negator
Negator::visitImpl
Negator::~Negator
Issue title: InstCombine gets stuck when sinking negation
Labels: llvm:instcombine
llvm:hang
Reported by: dtcxzyw

Minimal reproducer (It looks over-reduced): https://godbolt.org/z/9zj5K8seP
```
; opt -passes=instcombine test.ll -S -debug
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

define i32 @func_112() {
entry:
  br label %for.cond

for.cond:                                         ; preds = %for.cond, %entry
  %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
  %conv5 = trunc i32 %l_139.0 to i8
  %call6 = sub i8 0, %conv5
  %conv7 = zext i8 %call6 to i32
  %0 = shl nuw i32 %conv7, 24
  br label %for.cond
}
```

```
INSTCOMBINE ITERATION #1 on func_112
ADD:   br label %for.cond
ADD:   %0 = shl nuw i32 %conv7, 24
ADD:   %conv7 = zext i8 %call6 to i32
ADD:   %call6 = sub i8 0, %conv5
ADD:   %conv5 = trunc i32 %l_139.0 to i8
ADD:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
ADD:   br label %for.cond
IC: Visiting:   br label %for.cond
IC: Visiting:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
IC: Visiting:   %conv5 = trunc i32 %l_139.0 to i8
IC: Visiting:   %call6 = sub i8 0, %conv5
Negator: attempting to sink negation into   %conv5 = trunc i32 %l_139.0 to i8
Negator: successfully sunk negation into   %conv5 = trunc i32 %l_139.0 to i8
         NEW:   %conv5.neg = trunc i32 %l_139.0.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg = mul i32 %conv7, -16777216
ADD DEFERRED:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
IC: Old =   %call6 = sub i8 0, %conv5
    New =   <badref> = add i8 %conv5.neg, 0
ADD:   %call6 = add i8 %conv5.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5
ADD DEFERRED:   %conv5 = trunc i32 %l_139.0 to i8
IC: ERASE   %conv5 = trunc i32 %l_139.0 to i8
ADD DEFERRED:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
IC: ERASE   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
ADD DEFERRED:   %0 = shl nuw i32 %conv7, 24
IC: ERASE   %0 = shl nuw i32 %conv7, 24
ADD DEFERRED:   %conv7 = zext i8 %call6 to i32
ADD:   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD:   %.neg = mul i32 %conv7, -16777216
IC: Visiting:   %.neg = mul i32 %conv7, -16777216
Negator: attempting to sink negation into   %conv7 = zext i8 %call6 to i32
Negator: failed to sink negation into   %conv7 = zext i8 %call6 to i32
ADD DEFERRED:   %call6.neg = sub i8 0, %call6
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
IC: Old =   %.neg = mul i32 %conv7, -16777216
    New =   <badref> = shl i32 %call6.neg.z, 24
ADD:   %.neg = shl i32 %call6.neg.z, 24
IC: ERASE   %0 = mul i32 %conv7, -16777216
ADD DEFERRED:   %conv7 = zext i8 %call6 to i32
IC: ERASE   %conv7 = zext i8 %call6 to i32
ADD DEFERRED:   %call6 = add i8 %conv5.neg, 0
ADD:   %call6.neg.z = zext i8 %call6.neg to i32
ADD:   %call6.neg = sub i8 0, %call6
IC: Visiting:   %call6.neg = sub i8 0, %call6
IC: Old =   %call6.neg = sub i8 0, %call6
    New =   <badref> = sub i8 0, %conv5.neg
ADD:   %call6.neg = sub i8 0, %conv5.neg
IC: ERASE   %0 = sub i8 0, %call6
ADD DEFERRED:   %call6 = add i8 %conv5.neg, 0
IC: ERASE   %call6 = add i8 %conv5.neg, 0
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD DEFERRED:   %call6.neg = sub i8 0, %conv5.neg
IC: Visiting:   %call6.neg = sub i8 0, %conv5.neg
Negator: attempting to sink negation into   %conv5.neg = trunc i32 %l_139.0.neg to i8
Negator: successfully sunk negation into   %conv5.neg = trunc i32 %l_139.0.neg to i8
         NEW:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg.neg = mul i32 %call6.neg.z, -16777216
ADD DEFERRED:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
IC: Old =   %call6.neg = sub i8 0, %conv5.neg
    New =   <badref> = add i8 %conv5.neg.neg, 0
ADD:   %call6.neg = add i8 %conv5.neg.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5.neg
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
IC: ERASE   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD DEFERRED:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
IC: ERASE   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD DEFERRED:   %.neg = shl i32 %call6.neg.z, 24
IC: ERASE   %.neg = shl i32 %call6.neg.z, 24
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
ADD:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD:   %.neg.neg = mul i32 %call6.neg.z, -16777216
IC: Visiting:   %.neg.neg = mul i32 %call6.neg.z, -16777216
Negator: attempting to sink negation into   %call6.neg.z = zext i8 %call6.neg to i32
Negator: failed to sink negation into   %call6.neg.z = zext i8 %call6.neg to i32
ADD DEFERRED:   %call6.neg.neg = sub i8 0, %call6.neg
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
IC: Old =   %.neg.neg = mul i32 %call6.neg.z, -16777216
    New =   <badref> = shl i32 %call6.neg.neg.z, 24
ADD:   %.neg.neg = shl i32 %call6.neg.neg.z, 24
IC: ERASE   %0 = mul i32 %call6.neg.z, -16777216
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
IC: ERASE   %call6.neg.z = zext i8 %call6.neg to i32
ADD DEFERRED:   %call6.neg = add i8 %conv5.neg.neg, 0
ADD:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD:   %call6.neg.neg = sub i8 0, %call6.neg
IC: Visiting:   %call6.neg.neg = sub i8 0, %call6.neg
IC: Old =   %call6.neg.neg = sub i8 0, %call6.neg
    New =   <badref> = sub i8 0, %conv5.neg.neg
ADD:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
IC: ERASE   %0 = sub i8 0, %call6.neg
ADD DEFERRED:   %call6.neg = add i8 %conv5.neg.neg, 0
IC: ERASE   %call6.neg = add i8 %conv5.neg.neg, 0
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD DEFERRED:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
IC: Visiting:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
Negator: attempting to sink negation into   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
Negator: successfully sunk negation into   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
         NEW:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
ADD DEFERRED:   %l_139.0.neg.neg.neg = phi i32 [ -1, %entry ], [ %.neg.neg.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
IC: Old =   %call6.neg.neg = sub i8 0, %conv5.neg.neg
    New =   <badref> = add i8 %conv5.neg.neg.neg, 0
ADD:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5.neg.neg
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
IC: ERASE   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD DEFERRED:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
IC: ERASE   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD DEFERRED:   %.neg.neg = shl i32 %call6.neg.neg.z, 24
IC: ERASE   %.neg.neg = shl i32 %call6.neg.neg.z, 24
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
ADD:   %l_139.0.neg.neg.neg = phi i32 [ -1, %entry ], [ %.neg.neg.neg, %for.cond ]
ADD:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
IC: Visiting:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
Negator: attempting to sink negation into   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
Negator: failed to sink negation into   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD DEFERRED:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
ADD DEFERRED:   %call6.neg.neg.neg.z = zext i8 %call6.neg.neg.neg to i32
IC: Old =   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
    New =   <badref> = shl i32 %call6.neg.neg.neg.z, 24
ADD:   %.neg.neg.neg = shl i32 %call6.neg.neg.neg.z, 24
IC: ERASE   %0 = mul i32 %call6.neg.neg.z, -16777216
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
IC: ERASE   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD DEFERRED:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
ADD:   %call6.neg.neg.neg.z = zext i8 %call6.neg.neg.neg to i32
ADD:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
IC: Visiting:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
IC: Old =   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
    New =   <badref> = sub i8 0, %conv5.neg.neg.neg
ADD:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
IC: ERASE   %0 = sub i8 0, %call6.neg.neg
ADD DEFERRED:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
IC: ERASE   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
ADD DEFERRED:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
ADD DEFERRED:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
IC: Visiting:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
Negator: attempting to sink negation into   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
Negator: successfully sunk negation into   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
         NEW:   %conv5.neg.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg.neg to i8
...
```


Fix patch:
commit 48ae61470104e9d7a8be5beb8739c24f52cc33c0
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Sat Aug 17 16:48:29 2024 +0800

    [InstCombine] Avoid infinite loop when negating phi nodes (#104581)
    
    Closes https://github.com/llvm/llvm-project/issues/96012
    
    ---------
    
    Co-authored-by: Nikita Popov <github@npopov.com>

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 16f1c3ba15eb..a0f2399972b5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -780,11 +780,14 @@ class Negator final {
   using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
   BuilderTy Builder;
 
+  const DominatorTree &DT;
+
   const bool IsTrulyNegation;
 
   SmallDenseMap<Value *, Value *> NegationsCache;
 
-  Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation);
+  Negator(LLVMContext &C, const DataLayout &DL, const DominatorTree &DT,
+          bool IsTrulyNegation);
 
 #if LLVM_ENABLE_STATS
   unsigned NumValuesVisitedInThisNegator = 0;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index 2dd1db6a4a75..92293ef40146 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -90,13 +90,14 @@ static cl::opt<unsigned>
                     cl::desc("What is the maximal lookup depth when trying to "
                              "check for viability of negation sinking."));
 
-Negator::Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation_)
+Negator::Negator(LLVMContext &C, const DataLayout &DL, const DominatorTree &DT_,
+                 bool IsTrulyNegation_)
     : Builder(C, TargetFolder(DL),
               IRBuilderCallbackInserter([&](Instruction *I) {
                 ++NegatorNumInstructionsCreatedTotal;
                 NewInstructions.push_back(I);
               })),
-      IsTrulyNegation(IsTrulyNegation_) {}
+      DT(DT_), IsTrulyNegation(IsTrulyNegation_) {}
 
 #if LLVM_ENABLE_STATS
 Negator::~Negator() {
@@ -309,6 +310,9 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
     auto *PHI = cast<PHINode>(I);
     SmallVector<Value *, 4> NegatedIncomingValues(PHI->getNumOperands());
     for (auto I : zip(PHI->incoming_values(), NegatedIncomingValues)) {
+      // Don't negate indvars to avoid infinite loops.
+      if (DT.dominates(PHI->getParent(), std::get<0>(I)))
+        return nullptr;
       if (!(std::get<1>(I) =
                 negate(std::get<0>(I), IsNSW, Depth + 1))) // Early return.
         return nullptr;
@@ -537,7 +541,8 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
   if (!NegatorEnabled || !DebugCounter::shouldExecute(NegatorCounter))
     return nullptr;
 
-  Negator N(Root->getContext(), IC.getDataLayout(), LHSIsZero);
+  Negator N(Root->getContext(), IC.getDataLayout(), IC.getDominatorTree(),
+            LHSIsZero);
   std::optional<Result> Res = N.run(Root, IsNSW);
   if (!Res) { // Negation failed.
     LLVM_DEBUG(dbgs() << "Negator: failed to sink negation into " << *Root


Regression tests:
file: llvm/test/Transforms/InstCombine/pr96012.ll
commands: opt -S -passes=instcombine < %s
tests: test_name: <module>
test_body: 
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"

; Make sure we don't hang here.
define i32 @pr96012() {
;
entry:
  br label %for.cond

for.cond:
  %indvar = phi i32 [ 1, %entry ], [ %shl, %for.cond ]
  %conv1 = trunc i32 %indvar to i8
  %neg = sub i8 0, %conv1
  %conv2 = zext i8 %neg to i32
  %shl = shl nuw i32 %conv2, 24
  br label %for.cond
}