aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/InstSimplify
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstSimplify')
-rw-r--r--test/Transforms/InstSimplify/2010-12-20-Distribute.ll62
-rw-r--r--test/Transforms/InstSimplify/apint-or.ll37
-rw-r--r--test/Transforms/InstSimplify/ashr-nop.ll10
-rw-r--r--test/Transforms/InstSimplify/compare.ll230
-rw-r--r--test/Transforms/InstSimplify/dead-code-removal.ll15
-rw-r--r--test/Transforms/InstSimplify/undef.ll7
-rw-r--r--test/Transforms/InstSimplify/vector_gep.ll49
7 files changed, 347 insertions, 63 deletions
diff --git a/test/Transforms/InstSimplify/2010-12-20-Distribute.ll b/test/Transforms/InstSimplify/2010-12-20-Distribute.ll
deleted file mode 100644
index 9ea0a5e10708..000000000000
--- a/test/Transforms/InstSimplify/2010-12-20-Distribute.ll
+++ /dev/null
@@ -1,62 +0,0 @@
-; RUN: opt < %s -instsimplify -S | FileCheck %s
-
-define i32 @factorize(i32 %x, i32 %y) {
-; CHECK-LABEL: @factorize(
-; (X | 1) & (X | 2) -> X | (1 & 2) -> X
- %l = or i32 %x, 1
- %r = or i32 %x, 2
- %z = and i32 %l, %r
- ret i32 %z
-; CHECK: ret i32 %x
-}
-
-define i32 @factorize2(i32 %x) {
-; CHECK-LABEL: @factorize2(
-; 3*X - 2*X -> X
- %l = mul i32 3, %x
- %r = mul i32 2, %x
- %z = sub i32 %l, %r
- ret i32 %z
-; CHECK: ret i32 %x
-}
-
-define i32 @factorize3(i32 %x, i32 %a, i32 %b) {
-; CHECK-LABEL: @factorize3(
-; (X | (A|B)) & (X | B) -> X | ((A|B) & B) -> X | B
- %aORb = or i32 %a, %b
- %l = or i32 %x, %aORb
- %r = or i32 %x, %b
- %z = and i32 %l, %r
- ret i32 %z
-; CHECK: ret i32 %r
-}
-
-define i32 @factorize4(i32 %x, i32 %y) {
-; CHECK-LABEL: @factorize4(
- %sh = shl i32 %y, 1
- %ml = mul i32 %sh, %x
- %mr = mul i32 %x, %y
- %s = sub i32 %ml, %mr
- ret i32 %s
-; CHECK: ret i32 %mr
-}
-
-define i32 @factorize5(i32 %x, i32 %y) {
-; CHECK-LABEL: @factorize5(
- %sh = mul i32 %y, 2
- %ml = mul i32 %sh, %x
- %mr = mul i32 %x, %y
- %s = sub i32 %ml, %mr
- ret i32 %s
-; CHECK: ret i32 %mr
-}
-
-define i32 @expand(i32 %x) {
-; CHECK-LABEL: @expand(
-; ((X & 1) | 2) & 1 -> ((X & 1) & 1) | (2 & 1) -> (X & 1) | 0 -> X & 1
- %a = and i32 %x, 1
- %b = or i32 %a, 2
- %c = and i32 %b, 1
- ret i32 %c
-; CHECK: ret i32 %a
-}
diff --git a/test/Transforms/InstSimplify/apint-or.ll b/test/Transforms/InstSimplify/apint-or.ll
new file mode 100644
index 000000000000..5d314db7133d
--- /dev/null
+++ b/test/Transforms/InstSimplify/apint-or.ll
@@ -0,0 +1,37 @@
+; RUN: opt < %s -instsimplify -S | not grep or
+
+; Test the case where integer BitWidth <= 64 && BitWidth % 2 != 0.
+define i39 @test1(i39 %V, i39 %M) {
+ ;; If we have: ((V + N) & C1) | (V & C2)
+ ;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
+ ;; replace with V+N.
+ %C1 = xor i39 274877906943, -1 ;; C2 = 274877906943
+ %N = and i39 %M, 274877906944
+ %A = add i39 %V, %N
+ %B = and i39 %A, %C1
+ %D = and i39 %V, 274877906943
+ %R = or i39 %B, %D
+ ret i39 %R
+; CHECK-LABEL @test1
+; CHECK-NEXT: and {{.*}}, -274877906944
+; CHECK-NEXT: add
+; CHECK-NEXT: ret
+}
+
+; Test the case where Integer BitWidth > 64 && BitWidth <= 1024.
+define i399 @test2(i399 %V, i399 %M) {
+ ;; If we have: ((V + N) & C1) | (V & C2)
+ ;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
+ ;; replace with V+N.
+ %C1 = xor i399 274877906943, -1 ;; C2 = 274877906943
+ %N = and i399 %M, 18446742974197923840
+ %A = add i399 %V, %N
+ %B = and i399 %A, %C1
+ %D = and i399 %V, 274877906943
+ %R = or i399 %B, %D
+ ret i399 %R
+; CHECK-LABEL @test2
+; CHECK-NEXT: and {{.*}}, 18446742974197923840
+; CHECK-NEXT: add
+; CHECK-NEXT: ret
+}
diff --git a/test/Transforms/InstSimplify/ashr-nop.ll b/test/Transforms/InstSimplify/ashr-nop.ll
new file mode 100644
index 000000000000..0914d725e40d
--- /dev/null
+++ b/test/Transforms/InstSimplify/ashr-nop.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+; CHECK-LABEL: @foo
+; CHECK-NOT: ashr
+define i32 @foo(i32 %x) {
+ %o = and i32 %x, 1
+ %n = add i32 %o, -1
+ %t = ashr i32 %n, 17
+ ret i32 %t
+}
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index abb38695e710..94872d35bb97 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -739,3 +739,233 @@ define i1 @non_inbounds_gep_compare2(i64* %a) {
ret i1 %cmp
; CHECK-NEXT: ret i1 true
}
+
+define <4 x i8> @vectorselectfold(<4 x i8> %a, <4 x i8> %b) {
+ %false = icmp ne <4 x i8> zeroinitializer, zeroinitializer
+ %sel = select <4 x i1> %false, <4 x i8> %a, <4 x i8> %b
+ ret <4 x i8> %sel
+
+; CHECK-LABEL: @vectorselectfold
+; CHECK-NEXT: ret <4 x i8> %b
+}
+
+define <4 x i8> @vectorselectfold2(<4 x i8> %a, <4 x i8> %b) {
+ %true = icmp eq <4 x i8> zeroinitializer, zeroinitializer
+ %sel = select <4 x i1> %true, <4 x i8> %a, <4 x i8> %b
+ ret <4 x i8> %sel
+
+; CHECK-LABEL: @vectorselectfold
+; CHECK-NEXT: ret <4 x i8> %a
+}
+
+define i1 @compare_always_true_slt(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp slt i32 %2, 1
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_true_slt
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @compare_always_true_sle(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp sle i32 %2, 0
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_true_sle
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @compare_always_false_sgt(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp sgt i32 %2, 0
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_false_sgt
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @compare_always_false_sge(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp sge i32 %2, 1
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_false_sge
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @compare_always_false_eq(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp eq i32 %2, 1
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_false_eq
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @compare_always_false_ne(i16 %a) {
+ %1 = zext i16 %a to i32
+ %2 = sub nsw i32 0, %1
+ %3 = icmp ne i32 %2, 1
+ ret i1 %3
+
+; CHECK-LABEL: @compare_always_false_ne
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @compare_dividend(i32 %a) {
+ %div = sdiv i32 2, %a
+ %cmp = icmp eq i32 %div, 3
+ ret i1 %cmp
+
+; CHECK-LABEL: @compare_dividend
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @lshr_ugt_false(i32 %a) {
+ %shr = lshr i32 1, %a
+ %cmp = icmp ugt i32 %shr, 1
+ ret i1 %cmp
+; CHECK-LABEL: @lshr_ugt_false
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @exact_lshr_ugt_false(i32 %a) {
+ %shr = lshr exact i32 30, %a
+ %cmp = icmp ult i32 %shr, 15
+ ret i1 %cmp
+; CHECK-LABEL: @exact_lshr_ugt_false
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @lshr_sgt_false(i32 %a) {
+ %shr = lshr i32 1, %a
+ %cmp = icmp sgt i32 %shr, 1
+ ret i1 %cmp
+; CHECK-LABEL: @lshr_sgt_false
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @ashr_sgt_false(i32 %a) {
+ %shr = ashr i32 -30, %a
+ %cmp = icmp sgt i32 %shr, -1
+ ret i1 %cmp
+; CHECK-LABEL: @ashr_sgt_false
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @exact_ashr_sgt_false(i32 %a) {
+ %shr = ashr exact i32 -30, %a
+ %cmp = icmp sgt i32 %shr, -15
+ ret i1 %cmp
+; CHECK-LABEL: @exact_ashr_sgt_false
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @nonnull_arg(i32* nonnull %i) {
+ %cmp = icmp eq i32* %i, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_arg
+; CHECK: ret i1 false
+}
+
+define i1 @nonnull_deref_arg(i32* dereferenceable(4) %i) {
+ %cmp = icmp eq i32* %i, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_deref_arg
+; CHECK: ret i1 false
+}
+
+define i1 @nonnull_deref_as_arg(i32 addrspace(1)* dereferenceable(4) %i) {
+ %cmp = icmp eq i32 addrspace(1)* %i, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_deref_as_arg
+; CHECK: icmp
+; CHECK ret
+}
+
+declare nonnull i32* @returns_nonnull_helper()
+define i1 @returns_nonnull() {
+ %call = call nonnull i32* @returns_nonnull_helper()
+ %cmp = icmp eq i32* %call, null
+ ret i1 %cmp
+; CHECK-LABEL: @returns_nonnull
+; CHECK: ret i1 false
+}
+
+declare dereferenceable(4) i32* @returns_nonnull_deref_helper()
+define i1 @returns_nonnull_deref() {
+ %call = call dereferenceable(4) i32* @returns_nonnull_deref_helper()
+ %cmp = icmp eq i32* %call, null
+ ret i1 %cmp
+; CHECK-LABEL: @returns_nonnull_deref
+; CHECK: ret i1 false
+}
+
+declare dereferenceable(4) i32 addrspace(1)* @returns_nonnull_deref_as_helper()
+define i1 @returns_nonnull_as_deref() {
+ %call = call dereferenceable(4) i32 addrspace(1)* @returns_nonnull_deref_as_helper()
+ %cmp = icmp eq i32 addrspace(1)* %call, null
+ ret i1 %cmp
+; CHECK-LABEL: @returns_nonnull_as_deref
+; CHECK: icmp
+; CHECK: ret
+}
+
+; If a bit is known to be zero for A and known to be one for B,
+; then A and B cannot be equal.
+define i1 @icmp_eq_const(i32 %a) nounwind {
+ %b = mul nsw i32 %a, -2
+ %c = icmp eq i32 %b, 1
+ ret i1 %c
+
+; CHECK-LABEL: @icmp_eq_const
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @icmp_ne_const(i32 %a) nounwind {
+ %b = mul nsw i32 %a, -2
+ %c = icmp ne i32 %b, 1
+ ret i1 %c
+
+; CHECK-LABEL: @icmp_ne_const
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @icmp_sdiv_int_min(i32 %a) {
+ %div = sdiv i32 -2147483648, %a
+ %cmp = icmp ne i32 %div, -1073741824
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_sdiv_int_min
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 -2147483648, %a
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[DIV]], -1073741824
+; CHECK-NEXT: ret i1 [[CMP]]
+}
+
+define i1 @icmp_sdiv_pr20288(i64 %a) {
+ %div = sdiv i64 %a, -8589934592
+ %cmp = icmp ne i64 %div, 1073741824
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_sdiv_pr20288
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 %a, -8589934592
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824
+; CHECK-NEXT: ret i1 [[CMP]]
+}
+
+define i1 @icmp_sdiv_neg1(i64 %a) {
+ %div = sdiv i64 %a, -1
+ %cmp = icmp ne i64 %div, 1073741824
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_sdiv_neg1
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 %a, -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824
+; CHECK-NEXT: ret i1 [[CMP]]
+}
diff --git a/test/Transforms/InstSimplify/dead-code-removal.ll b/test/Transforms/InstSimplify/dead-code-removal.ll
new file mode 100644
index 000000000000..e181f3b60d5b
--- /dev/null
+++ b/test/Transforms/InstSimplify/dead-code-removal.ll
@@ -0,0 +1,15 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+
+define void @foo() nounwind {
+ br i1 undef, label %1, label %4
+
+; <label>:1 ; preds = %1, %0
+; CHECK-NOT: phi
+; CHECK-NOT: sub
+ %2 = phi i32 [ %3, %1 ], [ undef, %0 ]
+ %3 = sub i32 0, undef
+ br label %1
+
+; <label>:4 ; preds = %0
+ ret void
+}
diff --git a/test/Transforms/InstSimplify/undef.ll b/test/Transforms/InstSimplify/undef.ll
index 23cd50f92b40..181c2efa2dc0 100644
--- a/test/Transforms/InstSimplify/undef.ll
+++ b/test/Transforms/InstSimplify/undef.ll
@@ -153,3 +153,10 @@ define i64 @test18(i64 %a) {
%r = call i64 (i64)* undef(i64 %a)
ret i64 %r
}
+
+; CHECK-LABEL: @test19
+; CHECK: ret <4 x i8> undef
+define <4 x i8> @test19(<4 x i8> %a) {
+ %b = shl <4 x i8> %a, <i8 8, i8 9, i8 undef, i8 -1>
+ ret <4 x i8> %b
+}
diff --git a/test/Transforms/InstSimplify/vector_gep.ll b/test/Transforms/InstSimplify/vector_gep.ll
index 5ac1ddef64f8..17814637b3dd 100644
--- a/test/Transforms/InstSimplify/vector_gep.ll
+++ b/test/Transforms/InstSimplify/vector_gep.ll
@@ -1,4 +1,7 @@
-;RUN: opt -instsimplify -disable-output < %s
+; RUN: opt -S -instsimplify < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
declare void @helper(<2 x i8*>)
define void @test(<2 x i8*> %a) {
%A = getelementptr <2 x i8*> %a, <2 x i32> <i32 0, i32 0>
@@ -6,3 +9,47 @@ define void @test(<2 x i8*> %a) {
ret void
}
+define <4 x i8*> @test1(<4 x i8*> %a) {
+ %gep = getelementptr <4 x i8*> %a, <4 x i32> zeroinitializer
+ ret <4 x i8*> %gep
+
+; CHECK-LABEL: @test1
+; CHECK-NEXT: ret <4 x i8*> %a
+}
+
+define <4 x i8*> @test2(<4 x i8*> %a) {
+ %gep = getelementptr <4 x i8*> %a
+ ret <4 x i8*> %gep
+
+; CHECK-LABEL: @test2
+; CHECK-NEXT: ret <4 x i8*> %a
+}
+
+%struct = type { double, float }
+
+define <4 x float*> @test3() {
+ %gep = getelementptr <4 x %struct*> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x float*> %gep
+
+; CHECK-LABEL: @test3
+; CHECK-NEXT: ret <4 x float*> undef
+}
+
+%struct.empty = type { }
+
+define <4 x %struct.empty*> @test4(<4 x %struct.empty*> %a) {
+ %gep = getelementptr <4 x %struct.empty*> %a, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x %struct.empty*> %gep
+
+; CHECK-LABEL: @test4
+; CHECK-NEXT: ret <4 x %struct.empty*> %a
+}
+
+define <4 x i8*> @test5() {
+ %c = inttoptr <4 x i64> <i64 1, i64 2, i64 3, i64 4> to <4 x i8*>
+ %gep = getelementptr <4 x i8*> %c, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x i8*> %gep
+
+; CHECK-LABEL: @test5
+; CHECK-NEXT: ret <4 x i8*> getelementptr (<4 x i8*> <i8* inttoptr (i64 1 to i8*), i8* inttoptr (i64 2 to i8*), i8* inttoptr (i64 3 to i8*), i8* inttoptr (i64 4 to i8*)>, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+}