diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1047,6 +1047,9 @@ return false; // Must be an invoke or callbr. } + // Keep track if we constant folded the condition in this invocation. + bool ConstantFolded = false; + // Run constant folding to see if we can reduce the condition to a simple // constant. if (Instruction *I = dyn_cast(Condition)) { @@ -1057,6 +1060,7 @@ if (isInstructionTriviallyDead(I, TLI)) I->eraseFromParent(); Condition = SimpleVal; + ConstantFolded = true; } } @@ -1107,7 +1111,7 @@ // FIXME: Unify this with code below. if (ProcessThreadableEdges(Condition, BB, Preference, Terminator)) return true; - return false; + return ConstantFolded; } if (CmpInst *CondCmp = dyn_cast(CondInst)) { diff --git a/llvm/test/Transforms/JumpThreading/constant-fold-status.ll b/llvm/test/Transforms/JumpThreading/constant-fold-status.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/JumpThreading/constant-fold-status.ll @@ -0,0 +1,28 @@ +; RUN: opt -jump-threading < %s -S -o - | FileCheck %s + +; Reproducer for PR47297. + +; The pass did previously not report a correct Modified status in the case +; where a terminator's condition was successfully constant folded, but there +; were no other transformations done. This was caught by the pass return +; status check that is hidden under EXPENSIVE_CHECKS. + +; CHECK-LABEL: entry: +; CHECK-NEXT: br i1 icmp eq (i32 ptrtoint (i16* @a to i32), i32 0), label %overflow, label %cont + +@a = internal global i16 0 + +define void @foo(i16 %d) { +entry: + %.not = icmp eq i16 zext (i1 icmp ne (i32 ptrtoint (i16* @a to i32), i32 0) to i16), 0 + br i1 %.not, label %overflow, label %cont + +overflow: ; preds = %entry + call void @bar() + br label %cont + +cont: ; preds = %overflow, %entry + ret void +} + +declare void @bar()