Hello, I am trying to figure out, what vrp propagation does in llvm. I tried this program: #include <stdio.h> int main() { int s = 0; int j = 0; for (int i = 0; i < 100; i++) { j = j+i+1; s+=j; } return (s+j); } And got this under optimized version ( I don't want everything to be eliminated) define i32 @main() #0 { entry: br label %for.body for.body: ; preds = %for.body, %entry %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] %s.02 = phi i32 [ 0, %entry ], [ %add2, %for.body ] %j.01 = phi i32 [ 0, %entry ], [ %add1, %for.body ] %add = add nsw i32 %j.01, %i.03 %add1 = add nsw i32 %add, 1 %add2 = add nsw i32 %s.02, %add1 %inc = add nsw i32 %i.03, 1 %cmp = icmp slt i32 %i.03, 99 br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body %add3 = add nsw i32 %add2, %add1 ret i32 %add3 } the value range pass was not able to determine any size, even of the induction variable, is it a correct behavior? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170807/4f222a8b/attachment.html>
I am trying to print it like this (maybe here is smth wrong?) LazyValueInfo &LV = getAnalysis<LazyValueInfoWrapperPass>().getLVI(); DominatorTree &DT getAnalysis<DominatorTreeWrapperPass>().getDomTree(); LV.printLVI(F, DT, llvm::outs()); for (BasicBlock &BB : F) { for (Instruction &I : BB) { if (Value* v = dyn_cast<Value>(&I)) if (v->getType()->isIntegerTy()) { ConstantRange r = LV.getConstantRange(v, &BB, &I); I.dump(); printf("LOWER VALUE : %llu\n",r.getLower().getRawData()); printf("UPPER VALUE : %llu\n",r.getUpper().getRawData()); } } } 2017-08-07 11:12 GMT+02:00 Anastasiya Ruzhanskaya < anastasiya.ruzhanskaya at frtk.ru>:> Hello, > I am trying to figure out, what vrp propagation does in llvm. I tried this > program: > #include <stdio.h> > > int main() { > int s = 0; > int j = 0; > for (int i = 0; i < 100; i++) { > j = j+i+1; > s+=j; > } > return (s+j); > } > > And got this under optimized version ( I don't want everything to be > eliminated) > define i32 @main() #0 { > entry: > br label %for.body > > for.body: ; preds = %for.body, > %entry > %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] > %s.02 = phi i32 [ 0, %entry ], [ %add2, %for.body ] > %j.01 = phi i32 [ 0, %entry ], [ %add1, %for.body ] > %add = add nsw i32 %j.01, %i.03 > %add1 = add nsw i32 %add, 1 > %add2 = add nsw i32 %s.02, %add1 > %inc = add nsw i32 %i.03, 1 > %cmp = icmp slt i32 %i.03, 99 > br i1 %cmp, label %for.body, label %for.end > > for.end: ; preds = %for.body > %add3 = add nsw i32 %add2, %add1 > ret i32 %add3 > } > > > the value range pass was not able to determine any size, even of the > induction variable, is it a correct behavior? >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170807/b182e169/attachment.html>
On Mon, Aug 7, 2017 at 2:14 AM, Anastasiya Ruzhanskaya via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I am trying to print it like this (maybe here is smth wrong?) > > > LazyValueInfo &LV = getAnalysis<LazyValueInfoWrapperPass>().getLVI(); > DominatorTree &DT > getAnalysis<DominatorTreeWrapperPass>().getDomTree(); > LV.printLVI(F, DT, llvm::outs());The value analysis in llvm is lazy (hence, LVI), so you're trying to print an empty cache, I guess.> for (BasicBlock &BB : F) { > for (Instruction &I : BB) { > if (Value* v = dyn_cast<Value>(&I)) > if (v->getType()->isIntegerTy()) { > ConstantRange r = LV.getConstantRange(v, &BB, &I); > I.dump(); > printf("LOWER VALUE : %llu\n",r.getLower().getRawData()); > printf("UPPER VALUE : %llu\n",r.getUpper().getRawData()); > } > }About your other question, "the value range pass was not able to determine any size, even of the induction variable, is it a correct behavior?". Yes, returning a conservative answer is always correct, but not optimal. As reference, a more sophisticated range analysis finds the following ranges for your IR: [0, +inf] %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] [0, +inf] %s.02 = phi i32 [ 0, %entry ], [ %add2, %for.body ] [0, +inf] %j.01 = phi i32 [ 0, %entry ], [ %add1, %for.body ] [0, +inf] %add = add nsw i32 %j.01, %i.03 [1, +inf] %add1 = add nsw i32 %add, 1 [1, +inf] %add2 = add nsw i32 %s.02, %add1 [1, +inf] %inc = add nsw i32 %i.03, 1 [2, +inf] %add3 = add nsw i32 %add2, %add1 -- Davide