This patch teaches IndVarSimplify to add nuw and nsw to certain kinds
authorSanjoy Das <sanjoy@playingwithpointers.com>
Tue, 6 Jan 2015 19:02:56 +0000 (19:02 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Tue, 6 Jan 2015 19:02:56 +0000 (19:02 +0000)
commit31123d4529758c6066a143219646e2be9a8abddd
tree8876b1c2dff6bef23030714a725411e75c166717
parent63d0449f11af353422bd7b1af024d5f10e31d049
This patch teaches IndVarSimplify to add nuw and nsw to certain kinds
of operations that provably don't overflow. For example, we can prove
%civ.inc below does not sign-overflow. With this change,
IndVarSimplify changes %civ.inc to an add nsw.

  define i32 @foo(i32* %array, i32* %length_ptr, i32 %init) {
   entry:
    %length = load i32* %length_ptr, !range !0
    %len.sub.1 = sub i32 %length, 1
    %upper = icmp slt i32 %init, %len.sub.1
    br i1 %upper, label %loop, label %exit

   loop:
    %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
    %civ.inc = add i32 %civ, 1
    %cmp = icmp slt i32 %civ.inc, %length
    br i1 %cmp, label %latch, label %break

   latch:
    store i32 0, i32* %array
    %check = icmp slt i32 %civ.inc, %len.sub.1
    br i1 %check, label %loop, label %break

   break:
    ret i32 %civ.inc

   exit:
    ret i32 42
  }

Differential Revision: http://reviews.llvm.org/D6748

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225282 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/Utils/SimplifyIndVar.cpp
test/Transforms/BBVectorize/loop1.ll
test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
test/Transforms/IndVarSimplify/strengthen-overflow.ll [new file with mode: 0644]