From 3512bcc2e9ab06b0ae2cab78744550b515e54184 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 12 Aug 2024 15:18:32 +0200 Subject: [PATCH] [SCEV] Fix incorrect extension in computeConstantDifference() The Mul factor was zero-extended here, resulting in incorrect results for integers larger than 64-bit. As we currently only multiply by 1 or -1, just split this into two cases -- there's no need for a full multiplication here. Fixes https://github.com/llvm/llvm-project/issues/102597. --- llvm/lib/Analysis/ScalarEvolution.cpp | 11 ++++++++--- llvm/test/Transforms/IndVarSimplify/pr102597.ll | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 9ecdcbe2c5decf..318a9d773dc2e1 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -11961,9 +11961,14 @@ ScalarEvolution::computeConstantDifference(const SCEV *More, const SCEV *Less) { SmallDenseMap Multiplicity; APInt Diff(BW, 0); auto Add = [&](const SCEV *S, int Mul) { - if (auto *C = dyn_cast(S)) - Diff += C->getAPInt() * Mul; - else + if (auto *C = dyn_cast(S)) { + if (Mul == 1) { + Diff += C->getAPInt(); + } else { + assert(Mul == -1); + Diff -= C->getAPInt(); + } + } else Multiplicity[S] += Mul; }; auto Decompose = [&](const SCEV *S, int Mul) { diff --git a/llvm/test/Transforms/IndVarSimplify/pr102597.ll b/llvm/test/Transforms/IndVarSimplify/pr102597.ll index 2bb00da0aaf112..9de614524444db 100644 --- a/llvm/test/Transforms/IndVarSimplify/pr102597.ll +++ b/llvm/test/Transforms/IndVarSimplify/pr102597.ll @@ -1,14 +1,15 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -passes=indvars < %s | FileCheck %s -; FIXME: This is a miscompile. +; The %tobool condition should not be optimized away. define void @test() { ; CHECK-LABEL: define void @test() { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: ; CHECK-NEXT: [[IV:%.*]] = phi i128 [ 3, %[[ENTRY]] ], [ [[IV_DEC:%.*]], %[[LOOP_LATCH:.*]] ] -; CHECK-NEXT: br i1 true, label %[[LOOP_LATCH]], label %[[IF:.*]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i128 [[IV]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label %[[LOOP_LATCH]], label %[[IF:.*]] ; CHECK: [[IF]]: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label %[[LOOP_LATCH]]