From 6669f253d582f3de896737001f8e67c84bab5b0e Mon Sep 17 00:00:00 2001 From: Artur Pilipenko Date: Fri, 12 Aug 2016 10:14:11 +0000 Subject: [PATCH] [LVI] Take range metadata into account while calculating icmp condition constraints Take range metadata into account for conditions like this: %length = load i32, i32* %length_ptr, !range !{i32 0, i32 2147483647} %cmp = icmp ult i32 %a, %length This is a common pattern for range checks where the length of the array is dynamically loaded. Reviewed By: sanjoy Differential Revision: https://reviews.llvm.org/D23267 llvm-svn: 278496 --- llvm/lib/Analysis/LazyValueInfo.cpp | 3 +++ .../test/Transforms/CorrelatedValuePropagation/add.ll | 19 +++++++++++++++++++ .../Transforms/CorrelatedValuePropagation/range.ll | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index c5c9027..8c09010 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1211,6 +1211,9 @@ static LVILatticeVal getValueFromICmpCondition(Value *Val, ICmpInst *ICI, /*isFullSet=*/true); if (ConstantInt *CI = dyn_cast(RHS)) RHSRange = ConstantRange(CI->getValue()); + else if (Instruction *I = dyn_cast(RHS)) + if (auto *Ranges = I->getMetadata(LLVMContext::MD_range)) + RHSRange = getConstantRangeFromMetadata(*Ranges); // If we're interested in the false dest, invert the condition CmpInst::Predicate Pred = diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/add.ll b/llvm/test/Transforms/CorrelatedValuePropagation/add.ll index ae7a2c2..4b436ff 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/add.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/add.ll @@ -193,3 +193,22 @@ bb: exit: ret void } + +@limit = external global i32 +; CHECK-LABEL: @test11( +define i32 @test11(i32* %p, i32 %i) { + %limit = load i32, i32* %p, !range !{i32 0, i32 2147483647} + %within.1 = icmp ugt i32 %limit, %i + %i.plus.7 = add i32 %i, 7 + %within.2 = icmp ugt i32 %limit, %i.plus.7 + %within = and i1 %within.1, %within.2 + br i1 %within, label %then, label %else + +then: +; CHECK: %i.plus.6 = add nuw nsw i32 %i, 6 + %i.plus.6 = add i32 %i, 6 + ret i32 %i.plus.6 + +else: + ret i32 0 +} diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll index dac6ce4..216b7f3 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll @@ -445,3 +445,20 @@ then: else: ret i1 false } + +@limit = external global i32 +define i1 @test15(i32 %a) { +; CHECK-LABEL: @test15( +; CHECK: then: +; CHECK-NEXT: ret i1 false + %limit = load i32, i32* @limit, !range !{i32 0, i32 256} + %cmp = icmp ult i32 %a, %limit + br i1 %cmp, label %then, label %else + +then: + %result = icmp eq i32 %a, 255 + ret i1 %result + +else: + ret i1 false +} -- 2.7.4