Successfully identified regression in *llvm* in CI configuration tcwg_bmk_llvm_tx1/llvm-release-aarch64-spec2k6-O3. So far, this commit has regressed CI configurations: - tcwg_bmk_llvm_tx1/llvm-release-aarch64-spec2k6-O3
Culprit: <cut> commit 445db89b537e5397a2d4b08e79751edb845b2c2a Author: Nikita Popov nikita.ppv@gmail.com Date: Sun Sep 20 21:07:52 2020 +0200
[LVI] Get value range from mask comparison
InstCombine likes to canonicalize comparisons of the form X == C || X == C+1 into (X & -2) == C'. Make sure LVI can still recover the value range from this. Can of course also be useful for proper mask comparisons.
For the sake of clarity, the implementation goes through KnownBits to compute the range. </cut>
Results regressed to (for first_bad == 445db89b537e5397a2d4b08e79751edb845b2c2a) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O3 -- artifacts/build-445db89b537e5397a2d4b08e79751edb845b2c2a/results_id: 1 # 400.perlbench,perlbench_base.default regressed by 103
from (for last_good == 91af6a78d00f731826ff2eb81c9a9281b1d21388) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O3 -- artifacts/build-91af6a78d00f731826ff2eb81c9a9281b1d21388/results_id: 1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... Results ID of last_good: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-release-aarch64-spec2k6-O3/880 Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... Results ID of first_bad: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-release-aarch64-spec2k6-O3/890 Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-...
Configuration details:
Reproduce builds: <cut> mkdir investigate-llvm-445db89b537e5397a2d4b08e79751edb845b2c2a cd investigate-llvm-445db89b537e5397a2d4b08e79751edb845b2c2a
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
cd llvm
# Reproduce first_bad build git checkout --detach 445db89b537e5397a2d4b08e79751edb845b2c2a ../artifacts/test.sh
# Reproduce last_good build git checkout --detach 91af6a78d00f731826ff2eb81c9a9281b1d21388 ../artifacts/test.sh
cd .. </cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/c...
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-... Build log: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-release-...
Full commit (up to 1000 lines): <cut> commit 445db89b537e5397a2d4b08e79751edb845b2c2a Author: Nikita Popov nikita.ppv@gmail.com Date: Sun Sep 20 21:07:52 2020 +0200
[LVI] Get value range from mask comparison
InstCombine likes to canonicalize comparisons of the form X == C || X == C+1 into (X & -2) == C'. Make sure LVI can still recover the value range from this. Can of course also be useful for proper mask comparisons.
For the sake of clarity, the implementation goes through KnownBits to compute the range. --- llvm/lib/Analysis/LazyValueInfo.cpp | 14 ++++++++++++++ .../test/Transforms/CorrelatedValuePropagation/icmp.ll | 18 ++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 4e9505a12cb8..cc364fc93337 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -36,6 +36,7 @@ #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/KnownBits.h" #include "llvm/Support/raw_ostream.h" #include <map> using namespace llvm; @@ -1145,6 +1146,19 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI, if (matchICmpOperand(Offset, RHS, Val, SwappedPred)) return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
+ // If (Val & Mask) == C then all the masked bits are known and we can compute + // a value range based on that. + const APInt *Mask, *C; + if (EdgePred == ICmpInst::ICMP_EQ && + match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) && + match(RHS, m_APInt(C))) { + KnownBits Known; + Known.Zero = ~*C & *Mask; + Known.One = *C & *Mask; + return ValueLatticeElement::getRange( + ConstantRange::fromKnownBits(Known, /*IsSigned*/ false)); + } + return ValueLatticeElement::getOverdefined(); }
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll index 76d8e0d00f70..cdc5140b6548 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll @@ -995,14 +995,10 @@ define void @test_icmp_mask_two_values(i32 %a) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 10 -; CHECK-NEXT: call void @check1(i1 [[CMP2]]) -; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], 11 -; CHECK-NEXT: call void @check1(i1 [[CMP3]]) -; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 10 -; CHECK-NEXT: call void @check1(i1 [[CMP4]]) -; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[A]], 11 -; CHECK-NEXT: call void @check1(i1 [[CMP5]]) +; CHECK-NEXT: call void @check1(i1 true) +; CHECK-NEXT: call void @check1(i1 true) +; CHECK-NEXT: call void @check1(i1 false) +; CHECK-NEXT: call void @check1(i1 false) ; CHECK-NEXT: ret void ; CHECK: if.false: ; CHECK-NEXT: ret void @@ -1032,8 +1028,7 @@ define void @test_icmp_mask_bit_set(i32 %a) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 32 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 32 -; CHECK-NEXT: call void @check1(i1 [[CMP2]]) +; CHECK-NEXT: call void @check1(i1 true) ; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[A]], 33 ; CHECK-NEXT: call void @check1(i1 [[CMP3]]) ; CHECK-NEXT: ret void @@ -1061,8 +1056,7 @@ define void @test_icmp_mask_bit_unset(i32 %a) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: -; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[A]], -33 -; CHECK-NEXT: call void @check1(i1 [[CMP2]]) +; CHECK-NEXT: call void @check1(i1 true) ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], -34 ; CHECK-NEXT: call void @check1(i1 [[CMP3]]) ; CHECK-NEXT: ret void </cut>