From d5db2cdb22ab302acbb6e1a066e791f25dc612de Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 2 Jan 2024 10:55:59 +0100 Subject: [PATCH] [LVI] Don't push both binop operands at once If one of the binop operands depends on the other, this may end up evaluating them in the wrong order, producing sub-optimal results. Make sure that only one unevaluated operand gets pushed per iteration. Fixes https://github.com/llvm/llvm-project/issues/76705. --- llvm/lib/Analysis/LazyValueInfo.cpp | 6 ++++-- llvm/test/Transforms/CorrelatedValuePropagation/basic.ll | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index f7d87716482278..c94e29cabc3fe0 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -976,9 +976,11 @@ LazyValueInfoImpl::solveBlockValueBinaryOpImpl( // lets us pick up facts from expressions like "and i32 (call i32 // @foo()), 32" std::optional LHSRes = getRangeFor(I->getOperand(0), I, BB); + if (!LHSRes) + return std::nullopt; + std::optional RHSRes = getRangeFor(I->getOperand(1), I, BB); - if (!LHSRes || !RHSRes) - // More work to do before applying this transfer rule. + if (!RHSRes) return std::nullopt; const ConstantRange &LHSRange = *LHSRes; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll index 7b9375784dae82..6227a5c822b107 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -1915,8 +1915,7 @@ define i1 @binop_eval_order(i32 %x) { ; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[X:%.*]], 1 ; CHECK-NEXT: [[B:%.*]] = add nuw nsw i32 [[A]], 1 ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i32 [[A]], [[B]] -; CHECK-NEXT: [[D:%.*]] = icmp ugt i32 [[C]], 2 -; CHECK-NEXT: ret i1 [[D]] +; CHECK-NEXT: ret i1 true ; %a = add nuw nsw i32 %x, 1 %b = add nuw nsw i32 %a, 1