diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-01-06 19:02:56 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-01-06 19:02:56 +0000 |
commit | 7c0ce26614af63cf450fecf44c7ed088d7fb3b06 (patch) | |
tree | 7a882cbd0ad8f96c1e3199953368e6cd6d49290c /llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll | |
parent | 4e781371d11a1b773ac8e90706129daf9f1f0621 (diff) | |
download | bcm5719-llvm-7c0ce26614af63cf450fecf44c7ed088d7fb3b06.tar.gz bcm5719-llvm-7c0ce26614af63cf450fecf44c7ed088d7fb3b06.zip |
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
llvm-svn: 225282
Diffstat (limited to 'llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll')
-rw-r--r-- | llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll new file mode 100644 index 00000000000..07e489e0338 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll @@ -0,0 +1,214 @@ +; RUN: opt < %s -indvars -S | FileCheck %s + +define i32 @test.signed.add.0(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.signed.add.0 + entry: + %upper = icmp slt i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = add i32 %civ, 1 +; CHECK: %civ.inc = add nsw 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, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.signed.add.1(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.signed.add.1 + entry: + %upper = icmp sle i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = add i32 %civ, 1 +; CHECK: %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, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.signed.sub.0(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.signed.sub.0 + entry: + %upper = icmp sgt i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = sub i32 %civ, 1 +; CHECK: %civ.inc = sub nsw 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 sgt i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.signed.sub.1(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.signed.sub.1 + entry: + %upper = icmp sgt i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = sub i32 %civ, 1 +; CHECK: %civ.inc = sub 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 sge i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.unsigned.add.0(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.unsigned.add.0 + entry: + %upper = icmp ult i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = add i32 %civ, 1 +; CHECK: %civ.inc = add nuw 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 ult i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.unsigned.add.1(i32* %array, i32 %length, i32 %init) { +; CHECK-LABEL: @test.unsigned.add.1 + entry: + %upper = icmp ule i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = add i32 %civ, 1 +; CHECK: %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 ult i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.unsigned.sub.0(i32* %array, i32* %length_ptr, i32 %init) { +; CHECK-LABEL: @test.unsigned.sub.0 + entry: + %length = load i32* %length_ptr, !range !0 + %upper = icmp ult i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = sub i32 %civ, 2 +; CHECK: %civ.inc = sub nuw i32 %civ, 2 + %cmp = icmp slt i32 %civ.inc, %length + br i1 %cmp, label %latch, label %break + + latch: + store i32 0, i32* %array + %check = icmp ult i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +define i32 @test.unsigned.sub.1(i32* %array, i32* %length_ptr, i32 %init) { +; CHECK-LABEL: @test.unsigned.sub.1 + entry: + %length = load i32* %length_ptr, !range !1 + %upper = icmp ult i32 %init, %length + br i1 %upper, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ] + %civ.inc = sub i32 %civ, 2 +; CHECK: %civ.inc = sub i32 %civ, 2 + %cmp = icmp slt i32 %civ.inc, %length + br i1 %cmp, label %latch, label %break + + latch: + store i32 0, i32* %array + %check = icmp ult i32 %civ.inc, %length + br i1 %check, label %loop, label %break + + break: + ret i32 %civ.inc + + exit: + ret i32 42 +} + +!0 = !{i32 0, i32 2} +!1 = !{i32 0, i32 42} |