https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/135543
Backport bb9580a02b393683ff0b6c360df684f33c715a1f Requested by: @dtcxzyw >From aa784fdf7baffcff8ae1c4f5c353632828aa00a4 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng <dtcxzyw2...@gmail.com> Date: Sun, 13 Apr 2025 20:22:48 +0800 Subject: [PATCH] [SCEV] Use ashr to adjust constant multipliers (#135534) SCEV converts "-2 *nsw (i32 V)" into "2148473647 *nsw (i32 V)". But we cannot preserve the nsw flag when the constant multiplier is negative. This patch changes lshr to ashr so that we can preserve both nsw and nuw flags. Alive2 proof: https://alive2.llvm.org/ce/z/LZVSEa Closes https://github.com/llvm/llvm-project/issues/135531. (cherry picked from commit bb9580a02b393683ff0b6c360df684f33c715a1f) --- llvm/lib/Analysis/ScalarEvolution.cpp | 2 +- .../test/Analysis/ScalarEvolution/pr135531.ll | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Analysis/ScalarEvolution/pr135531.ll diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index b8069df4e6598..36fe036aa9e9f 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -7854,7 +7854,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { unsigned GCD = std::min(MulZeros, TZ); APInt DivAmt = APInt::getOneBitSet(BitWidth, TZ - GCD); SmallVector<const SCEV*, 4> MulOps; - MulOps.push_back(getConstant(OpC->getAPInt().lshr(GCD))); + MulOps.push_back(getConstant(OpC->getAPInt().ashr(GCD))); append_range(MulOps, LHSMul->operands().drop_front()); auto *NewMul = getMulExpr(MulOps, LHSMul->getNoWrapFlags()); ShiftedLHS = getUDivExpr(NewMul, getConstant(DivAmt)); diff --git a/llvm/test/Analysis/ScalarEvolution/pr135531.ll b/llvm/test/Analysis/ScalarEvolution/pr135531.ll new file mode 100644 index 0000000000000..e172d56d3a515 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/pr135531.ll @@ -0,0 +1,19 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -disable-output -passes='print<scalar-evolution>' < %s 2>&1 | FileCheck %s + +define i32 @pr135511(i32 %x) { +; CHECK-LABEL: 'pr135511' +; CHECK-NEXT: Classifying expressions for: @pr135511 +; CHECK-NEXT: %and = and i32 %x, 16382 +; CHECK-NEXT: --> (2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nuw><nsw> U: [0,16383) S: [0,16383) +; CHECK-NEXT: %neg = sub nsw i32 0, %and +; CHECK-NEXT: --> (-2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nsw> U: [0,-1) S: [-16382,1) +; CHECK-NEXT: %res = and i32 %neg, 268431360 +; CHECK-NEXT: --> (4096 * (zext i16 (trunc i32 ((-1 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nsw> /u 2048) to i16) to i32))<nuw><nsw> U: [0,268431361) S: [0,268431361) +; CHECK-NEXT: Determining loop execution counts for: @pr135511 +; + %and = and i32 %x, 16382 + %neg = sub nsw i32 0, %and + %res = and i32 %neg, 268431360 + ret i32 %res +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits