aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstSimplify
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-04 19:51:48 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-12-04 19:51:48 +0000
commita21bbdfad461e957fa42ac9d6860ddc9de2da3e9 (patch)
tree8d32ff2094b47e15a8def30d62fd7dee6e009de3 /test/Transforms/InstSimplify
parent6b8c6a5088c221af2b25065b8b6b8b0fec8a116f (diff)
parent876d6995443e99d13696f3941c3a789a4daa7c7a (diff)
downloadexternal_llvm-a21bbdfad461e957fa42ac9d6860ddc9de2da3e9.zip
external_llvm-a21bbdfad461e957fa42ac9d6860ddc9de2da3e9.tar.gz
external_llvm-a21bbdfad461e957fa42ac9d6860ddc9de2da3e9.tar.bz2
am 876d6995: Merge "Update aosp/master LLVM for rebase to r222494."
* commit '876d6995443e99d13696f3941c3a789a4daa7c7a': Update aosp/master LLVM for rebase to r222494.
Diffstat (limited to 'test/Transforms/InstSimplify')
-rw-r--r--test/Transforms/InstSimplify/AndOrXor.ll128
-rw-r--r--test/Transforms/InstSimplify/assume.ll13
-rw-r--r--test/Transforms/InstSimplify/compare.ll191
-rw-r--r--test/Transforms/InstSimplify/exact-nsw-nuw.ll16
-rw-r--r--test/Transforms/InstSimplify/fold-builtin-fma.ll119
-rw-r--r--test/Transforms/InstSimplify/gep.ll80
-rw-r--r--test/Transforms/InstSimplify/rem.ll28
-rw-r--r--test/Transforms/InstSimplify/shr-nop.ll346
-rw-r--r--test/Transforms/InstSimplify/vector_ptr_bitcast.ll35
9 files changed, 954 insertions, 2 deletions
diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll
index c59d6c9..8ed06e8 100644
--- a/test/Transforms/InstSimplify/AndOrXor.ll
+++ b/test/Transforms/InstSimplify/AndOrXor.ll
@@ -20,3 +20,131 @@ define i64 @pow2b(i32 %x) {
ret i64 %e2
; CHECK: ret i64 %e
}
+
+define i32 @sub_neg_nuw(i32 %x, i32 %y) {
+; CHECK-LABEL: @sub_neg_nuw(
+ %neg = sub nuw i32 0, %y
+ %sub = sub i32 %x, %neg
+ ret i32 %sub
+; CHECK: ret i32 %x
+}
+
+define i1 @and_of_icmps0(i32 %b) {
+; CHECK-LABEL: @and_of_icmps0(
+ %1 = add i32 %b, 2
+ %2 = icmp ult i32 %1, 4
+ %cmp3 = icmp sgt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @and_of_icmps1(i32 %b) {
+; CHECK-LABEL: @and_of_icmps1(
+ %1 = add nsw i32 %b, 2
+ %2 = icmp slt i32 %1, 4
+ %cmp3 = icmp sgt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @and_of_icmps2(i32 %b) {
+; CHECK-LABEL: @and_of_icmps2(
+ %1 = add i32 %b, 2
+ %2 = icmp ule i32 %1, 3
+ %cmp3 = icmp sgt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @and_of_icmps3(i32 %b) {
+; CHECK-LABEL: @and_of_icmps3(
+ %1 = add nsw i32 %b, 2
+ %2 = icmp sle i32 %1, 3
+ %cmp3 = icmp sgt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @and_of_icmps4(i32 %b) {
+; CHECK-LABEL: @and_of_icmps4(
+ %1 = add nuw i32 %b, 2
+ %2 = icmp ult i32 %1, 4
+ %cmp3 = icmp ugt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @and_of_icmps5(i32 %b) {
+; CHECK-LABEL: @and_of_icmps5(
+ %1 = add nuw i32 %b, 2
+ %2 = icmp ule i32 %1, 3
+ %cmp3 = icmp ugt i32 %b, 2
+ %cmp = and i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 false
+}
+
+define i1 @or_of_icmps0(i32 %b) {
+; CHECK-LABEL: @or_of_icmps0(
+ %1 = add i32 %b, 2
+ %2 = icmp uge i32 %1, 4
+ %cmp3 = icmp sle i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
+
+define i1 @or_of_icmps1(i32 %b) {
+; CHECK-LABEL: @or_of_icmps1(
+ %1 = add nsw i32 %b, 2
+ %2 = icmp sge i32 %1, 4
+ %cmp3 = icmp sle i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
+
+define i1 @or_of_icmps2(i32 %b) {
+; CHECK-LABEL: @or_of_icmps2(
+ %1 = add i32 %b, 2
+ %2 = icmp ugt i32 %1, 3
+ %cmp3 = icmp sle i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
+
+define i1 @or_of_icmps3(i32 %b) {
+; CHECK-LABEL: @or_of_icmps3(
+ %1 = add nsw i32 %b, 2
+ %2 = icmp sgt i32 %1, 3
+ %cmp3 = icmp sle i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
+
+define i1 @or_of_icmps4(i32 %b) {
+; CHECK-LABEL: @or_of_icmps4(
+ %1 = add nuw i32 %b, 2
+ %2 = icmp uge i32 %1, 4
+ %cmp3 = icmp ule i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
+
+define i1 @or_of_icmps5(i32 %b) {
+; CHECK-LABEL: @or_of_icmps5(
+ %1 = add nuw i32 %b, 2
+ %2 = icmp ugt i32 %1, 3
+ %cmp3 = icmp ule i32 %b, 2
+ %cmp = or i1 %2, %cmp3
+ ret i1 %cmp
+; CHECK: ret i1 true
+}
diff --git a/test/Transforms/InstSimplify/assume.ll b/test/Transforms/InstSimplify/assume.ll
new file mode 100644
index 0000000..4dd0a8f
--- /dev/null
+++ b/test/Transforms/InstSimplify/assume.ll
@@ -0,0 +1,13 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+
+define void @test1() {
+ call void @llvm.assume(i1 1)
+ ret void
+
+; CHECK-LABEL: @test1
+; CHECK-NOT: llvm.assume
+; CHECK: ret void
+}
+
+declare void @llvm.assume(i1) nounwind
+
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index 7d0cd9c..38fd747 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -333,14 +333,46 @@ define i1 @or(i32 %x) {
; CHECK: ret i1 false
}
-define i1 @shl(i32 %x) {
-; CHECK-LABEL: @shl(
+define i1 @shl1(i32 %x) {
+; CHECK-LABEL: @shl1(
%s = shl i32 1, %x
%c = icmp eq i32 %s, 0
ret i1 %c
; CHECK: ret i1 false
}
+define i1 @shl2(i32 %X) {
+; CHECK: @shl2
+ %sub = shl nsw i32 -1, %X
+ %cmp = icmp eq i32 %sub, 31
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @shl3(i32 %X) {
+; CHECK: @shl3
+ %sub = shl nuw i32 4, %X
+ %cmp = icmp eq i32 %sub, 31
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @shl4(i32 %X) {
+; CHECK: @shl4
+ %sub = shl nsw i32 -1, %X
+ %cmp = icmp sle i32 %sub, -1
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @shl5(i32 %X) {
+; CHECK: @shl5
+ %sub = shl nuw i32 4, %X
+ %cmp = icmp ugt i32 %sub, 3
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 true
+}
+
define i1 @lshr1(i32 %x) {
; CHECK-LABEL: @lshr1(
%s = lshr i32 -1, %x
@@ -874,6 +906,21 @@ define i1 @nonnull_arg(i32* nonnull %i) {
; 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()
@@ -883,6 +930,48 @@ define i1 @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
+}
+
+define i1 @nonnull_load(i32** %addr) {
+ %ptr = load i32** %addr, !nonnull !{}
+ %cmp = icmp eq i32* %ptr, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_load
+; CHECK: ret i1 false
+}
+
+define i1 @nonnull_load_as_outer(i32* addrspace(1)* %addr) {
+ %ptr = load i32* addrspace(1)* %addr, !nonnull !{}
+ %cmp = icmp eq i32* %ptr, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_load_as_outer
+; CHECK: ret i1 false
+}
+define i1 @nonnull_load_as_inner(i32 addrspace(1)** %addr) {
+ %ptr = load i32 addrspace(1)** %addr, !nonnull !{}
+ %cmp = icmp eq i32 addrspace(1)* %ptr, null
+ ret i1 %cmp
+; CHECK-LABEL: @nonnull_load_as_inner
+; CHECK: ret i1 false
+}
+
; 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 {
@@ -913,3 +1002,101 @@ define i1 @icmp_sdiv_int_min(i32 %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]]
+}
+
+define i1 @icmp_known_bits(i4 %x, i4 %y) {
+ %and1 = and i4 %y, -7
+ %and2 = and i4 %x, -7
+ %or1 = or i4 %and1, 2
+ %or2 = or i4 %and2, 2
+ %add = add i4 %or1, %or2
+ %cmp = icmp eq i4 %add, 0
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_known_bits
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @icmp_shl_nuw_1(i64 %a) {
+ %shl = shl nuw i64 1, %a
+ %cmp = icmp ne i64 %shl, 0
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_nuw_1
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @icmp_shl_nsw_neg1(i64 %a) {
+ %shl = shl nsw i64 -1, %a
+ %cmp = icmp sge i64 %shl, 3
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_nsw_neg1
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @icmp_shl_nsw_1(i64 %a) {
+ %shl = shl nsw i64 1, %a
+ %cmp = icmp sge i64 %shl, 0
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_nsw_1
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @icmp_shl_1_V_ugt_2147483648(i32 %V) {
+ %shl = shl i32 1, %V
+ %cmp = icmp ugt i32 %shl, 2147483648
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_1_V_ugt_2147483648(
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @icmp_shl_1_V_ule_2147483648(i32 %V) {
+ %shl = shl i32 1, %V
+ %cmp = icmp ule i32 %shl, 2147483648
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_1_V_ule_2147483648(
+; CHECK-NEXT: ret i1 true
+}
+
+define i1 @icmp_shl_1_V_eq_31(i32 %V) {
+ %shl = shl i32 1, %V
+ %cmp = icmp eq i32 %shl, 31
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_1_V_eq_31(
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @icmp_shl_1_V_ne_31(i32 %V) {
+ %shl = shl i32 1, %V
+ %cmp = icmp ne i32 %shl, 31
+ ret i1 %cmp
+
+; CHECK-LABEL: @icmp_shl_1_V_ne_31(
+; CHECK-NEXT: ret i1 true
+}
diff --git a/test/Transforms/InstSimplify/exact-nsw-nuw.ll b/test/Transforms/InstSimplify/exact-nsw-nuw.ll
index a0e326b..5ccc808 100644
--- a/test/Transforms/InstSimplify/exact-nsw-nuw.ll
+++ b/test/Transforms/InstSimplify/exact-nsw-nuw.ll
@@ -42,3 +42,19 @@ define i32 @shift5(i32 %A, i32 %B) {
%D = ashr i32 %C, %B
ret i32 %D
}
+
+; CHECK-LABEL: @div1(
+; CHECK: ret i32 0
+define i32 @div1(i32 %V) {
+ %A = udiv i32 %V, -2147483648
+ %B = udiv i32 %A, -2147483648
+ ret i32 %B
+}
+
+; CHECK-LABEL: @div2(
+; CHECK-NOT: ret i32 0
+define i32 @div2(i32 %V) {
+ %A = sdiv i32 %V, -1
+ %B = sdiv i32 %A, -2147483648
+ ret i32 %B
+}
diff --git a/test/Transforms/InstSimplify/fold-builtin-fma.ll b/test/Transforms/InstSimplify/fold-builtin-fma.ll
new file mode 100644
index 0000000..6331b8c
--- /dev/null
+++ b/test/Transforms/InstSimplify/fold-builtin-fma.ll
@@ -0,0 +1,119 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+
+; Fixes PR20832
+; Make sure that we correctly fold a fused multiply-add where operands
+; are all finite constants and addend is zero.
+
+declare double @llvm.fma.f64(double, double, double)
+
+
+define double @PR20832() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @PR20832(
+; CHECK: ret double 5.600000e+01
+
+; Test builtin fma with all finite non-zero constants.
+define double @test_all_finite() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 5.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_all_finite(
+; CHECK: ret double 6.100000e+01
+
+; Test builtin fma with a +/-NaN addend.
+define double @test_NaN_addend() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0x7FF8000000000000)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_addend(
+; CHECK: ret double 0x7FF8000000000000
+
+define double @test_NaN_addend_2() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0xFFF8000000000000)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_addend_2(
+; CHECK: ret double 0xFFF8000000000000
+
+; Test builtin fma with a +/-Inf addend.
+define double @test_Inf_addend() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0x7FF0000000000000)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_addend(
+; CHECK: ret double 0x7FF0000000000000
+
+define double @test_Inf_addend_2() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 8.0, double 0xFFF0000000000000)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_addend_2(
+; CHECK: ret double 0xFFF0000000000000
+
+; Test builtin fma with one of the operands to the multiply being +/-NaN.
+define double @test_NaN_1() {
+ %1 = call double @llvm.fma.f64(double 0x7FF8000000000000, double 8.0, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_1(
+; CHECK: ret double 0x7FF8000000000000
+
+
+define double @test_NaN_2() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF8000000000000, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_2(
+; CHECK: ret double 0x7FF8000000000000
+
+
+define double @test_NaN_3() {
+ %1 = call double @llvm.fma.f64(double 0xFFF8000000000000, double 8.0, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_3(
+; CHECK: ret double 0x7FF8000000000000
+
+
+define double @test_NaN_4() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF8000000000000, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_NaN_4(
+; CHECK: ret double 0x7FF8000000000000
+
+
+; Test builtin fma with one of the operands to the multiply being +/-Inf.
+define double @test_Inf_1() {
+ %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 8.0, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_1(
+; CHECK: ret double 0x7FF0000000000000
+
+
+define double @test_Inf_2() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF0000000000000, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_2(
+; CHECK: ret double 0x7FF0000000000000
+
+
+define double @test_Inf_3() {
+ %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 8.0, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_3(
+; CHECK: ret double 0xFFF0000000000000
+
+
+define double @test_Inf_4() {
+ %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF0000000000000, double 0.0)
+ ret double %1
+}
+; CHECK-LABEL: @test_Inf_4(
+; CHECK: ret double 0xFFF0000000000000
+
diff --git a/test/Transforms/InstSimplify/gep.ll b/test/Transforms/InstSimplify/gep.ll
new file mode 100644
index 0000000..49a97f1
--- /dev/null
+++ b/test/Transforms/InstSimplify/gep.ll
@@ -0,0 +1,80 @@
+; RUN: opt -S -instsimplify < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+%struct.A = type { [7 x i8] }
+
+define %struct.A* @test1(%struct.A* %b, %struct.A* %e) {
+ %e_ptr = ptrtoint %struct.A* %e to i64
+ %b_ptr = ptrtoint %struct.A* %b to i64
+ %sub = sub i64 %e_ptr, %b_ptr
+ %sdiv = sdiv exact i64 %sub, 7
+ %gep = getelementptr inbounds %struct.A* %b, i64 %sdiv
+ ret %struct.A* %gep
+; CHECK-LABEL: @test1
+; CHECK-NEXT: ret %struct.A* %e
+}
+
+define i8* @test2(i8* %b, i8* %e) {
+ %e_ptr = ptrtoint i8* %e to i64
+ %b_ptr = ptrtoint i8* %b to i64
+ %sub = sub i64 %e_ptr, %b_ptr
+ %gep = getelementptr inbounds i8* %b, i64 %sub
+ ret i8* %gep
+; CHECK-LABEL: @test2
+; CHECK-NEXT: ret i8* %e
+}
+
+define i64* @test3(i64* %b, i64* %e) {
+ %e_ptr = ptrtoint i64* %e to i64
+ %b_ptr = ptrtoint i64* %b to i64
+ %sub = sub i64 %e_ptr, %b_ptr
+ %ashr = ashr exact i64 %sub, 3
+ %gep = getelementptr inbounds i64* %b, i64 %ashr
+ ret i64* %gep
+; CHECK-LABEL: @test3
+; CHECK-NEXT: ret i64* %e
+}
+
+define %struct.A* @test4(%struct.A* %b) {
+ %b_ptr = ptrtoint %struct.A* %b to i64
+ %sub = sub i64 0, %b_ptr
+ %sdiv = sdiv exact i64 %sub, 7
+ %gep = getelementptr inbounds %struct.A* %b, i64 %sdiv
+ ret %struct.A* %gep
+; CHECK-LABEL: @test4
+; CHECK-NEXT: ret %struct.A* null
+}
+
+define i8* @test5(i8* %b) {
+ %b_ptr = ptrtoint i8* %b to i64
+ %sub = sub i64 0, %b_ptr
+ %gep = getelementptr inbounds i8* %b, i64 %sub
+ ret i8* %gep
+; CHECK-LABEL: @test5
+; CHECK-NEXT: ret i8* null
+}
+
+define i64* @test6(i64* %b) {
+ %b_ptr = ptrtoint i64* %b to i64
+ %sub = sub i64 0, %b_ptr
+ %ashr = ashr exact i64 %sub, 3
+ %gep = getelementptr inbounds i64* %b, i64 %ashr
+ ret i64* %gep
+; CHECK-LABEL: @test6
+; CHECK-NEXT: ret i64* null
+}
+
+define i8* @test7(i8* %b, i8** %e) {
+ %e_ptr = ptrtoint i8** %e to i64
+ %b_ptr = ptrtoint i8* %b to i64
+ %sub = sub i64 %e_ptr, %b_ptr
+ %gep = getelementptr inbounds i8* %b, i64 %sub
+ ret i8* %gep
+; CHECK-LABEL: @test7
+; CHECK-NEXT: ptrtoint
+; CHECK-NEXT: ptrtoint
+; CHECK-NEXT: sub
+; CHECK-NEXT: getelementptr
+; CHECK-NEXT: ret
+}
diff --git a/test/Transforms/InstSimplify/rem.ll b/test/Transforms/InstSimplify/rem.ll
index 80fa8e7..f5ea451 100644
--- a/test/Transforms/InstSimplify/rem.ll
+++ b/test/Transforms/InstSimplify/rem.ll
@@ -15,3 +15,31 @@ define i32 @select2(i32 %x, i1 %b) {
ret i32 %rem
; CHECK: ret i32 0
}
+
+define i32 @rem1(i32 %x, i32 %n) {
+; CHECK-LABEL: @rem1(
+; CHECK-NEXT: %mod = srem i32 %x, %n
+; CHECK-NEXT: ret i32 %mod
+ %mod = srem i32 %x, %n
+ %mod1 = srem i32 %mod, %n
+ ret i32 %mod1
+}
+
+define i32 @rem2(i32 %x, i32 %n) {
+; CHECK-LABEL: @rem2(
+; CHECK-NEXT: %mod = urem i32 %x, %n
+; CHECK-NEXT: ret i32 %mod
+ %mod = urem i32 %x, %n
+ %mod1 = urem i32 %mod, %n
+ ret i32 %mod1
+}
+
+define i32 @rem3(i32 %x, i32 %n) {
+; CHECK-LABEL: @rem3(
+; CHECK-NEXT: %[[srem:.*]] = srem i32 %x, %n
+; CHECK-NEXT: %[[urem:.*]] = urem i32 %[[srem]], %n
+; CHECK-NEXT: ret i32 %[[urem]]
+ %mod = srem i32 %x, %n
+ %mod1 = urem i32 %mod, %n
+ ret i32 %mod1
+}
diff --git a/test/Transforms/InstSimplify/shr-nop.ll b/test/Transforms/InstSimplify/shr-nop.ll
new file mode 100644
index 0000000..b0dc873
--- /dev/null
+++ b/test/Transforms/InstSimplify/shr-nop.ll
@@ -0,0 +1,346 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+; CHECK-LABEL: @foo
+; CHECK: %[[and:.*]] = and i32 %x, 1
+; CHECK-NEXT: %[[add:.*]] = add i32 %[[and]], -1
+; CHECK-NEXT: ret i32 %[[add]]
+define i32 @foo(i32 %x) {
+ %o = and i32 %x, 1
+ %n = add i32 %o, -1
+ %t = ashr i32 %n, 17
+ ret i32 %t
+}
+
+; CHECK-LABEL: @exact_lshr_eq_both_zero
+; CHECK-NEXT: ret i1 true
+define i1 @exact_lshr_eq_both_zero(i8 %a) {
+ %shr = lshr exact i8 0, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_both_zero
+; CHECK-NEXT: ret i1 true
+define i1 @exact_ashr_eq_both_zero(i8 %a) {
+ %shr = ashr exact i8 0, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_eq_both_zero
+; CHECK-NEXT: ret i1 true
+define i1 @nonexact_ashr_eq_both_zero(i8 %a) {
+ %shr = ashr i8 0, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_ne_both_zero
+; CHECK-NEXT: ret i1 false
+define i1 @exact_lshr_ne_both_zero(i8 %a) {
+ %shr = lshr exact i8 0, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_both_zero
+; CHECK-NEXT: ret i1 false
+define i1 @exact_ashr_ne_both_zero(i8 %a) {
+ %shr = ashr exact i8 0, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_ne_both_zero
+; CHECK-NEXT: ret i1 false
+define i1 @nonexact_lshr_ne_both_zero(i8 %a) {
+ %shr = lshr i8 0, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_ne_both_zero
+; CHECK-NEXT: ret i1 false
+define i1 @nonexact_ashr_ne_both_zero(i8 %a) {
+ %shr = ashr i8 0, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_eq_last_zero
+; CHECK-NEXT: ret i1 false
+define i1 @exact_lshr_eq_last_zero(i8 %a) {
+ %shr = lshr exact i8 128, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_last_zero
+; CHECK-NEXT: ret i1 false
+define i1 @exact_ashr_eq_last_zero(i8 %a) {
+ %shr = ashr exact i8 -128, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_eq_both_zero
+; CHECK-NEXT: ret i1 true
+define i1 @nonexact_lshr_eq_both_zero(i8 %a) {
+ %shr = lshr i8 0, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_ne_last_zero
+; CHECK-NEXT: ret i1 true
+define i1 @exact_lshr_ne_last_zero(i8 %a) {
+ %shr = lshr exact i8 128, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_last_zero
+; CHECK-NEXT: ret i1 true
+define i1 @exact_ashr_ne_last_zero(i8 %a) {
+ %shr = ashr exact i8 -128, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_eq_last_zero
+; CHECK-NEXT: ret i1 false
+define i1 @nonexact_lshr_eq_last_zero(i8 %a) {
+ %shr = lshr i8 128, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_eq_last_zero
+; CHECK-NEXT: ret i1 false
+define i1 @nonexact_ashr_eq_last_zero(i8 %a) {
+ %shr = ashr i8 -128, %a
+ %cmp = icmp eq i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_ne_last_zero
+; CHECK-NEXT: ret i1 true
+define i1 @nonexact_lshr_ne_last_zero(i8 %a) {
+ %shr = lshr i8 128, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_ne_last_zero
+; CHECK-NEXT: ret i1 true
+define i1 @nonexact_ashr_ne_last_zero(i8 %a) {
+ %shr = ashr i8 -128, %a
+ %cmp = icmp ne i8 %shr, 0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @lshr_eq_first_zero
+; CHECK-NEXT: ret i1 false
+define i1 @lshr_eq_first_zero(i8 %a) {
+ %shr = lshr i8 0, %a
+ %cmp = icmp eq i8 %shr, 2
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_eq_first_zero
+; CHECK-NEXT: ret i1 false
+define i1 @ashr_eq_first_zero(i8 %a) {
+ %shr = ashr i8 0, %a
+ %cmp = icmp eq i8 %shr, 2
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @lshr_ne_first_zero
+; CHECK-NEXT: ret i1 true
+define i1 @lshr_ne_first_zero(i8 %a) {
+ %shr = lshr i8 0, %a
+ %cmp = icmp ne i8 %shr, 2
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_ne_first_zero
+; CHECK-NEXT: ret i1 true
+define i1 @ashr_ne_first_zero(i8 %a) {
+ %shr = ashr i8 0, %a
+ %cmp = icmp ne i8 %shr, 2
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_eq_both_minus1
+; CHECK-NEXT: ret i1 true
+define i1 @ashr_eq_both_minus1(i8 %a) {
+ %shr = ashr i8 -1, %a
+ %cmp = icmp eq i8 %shr, -1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_ne_both_minus1
+; CHECK-NEXT: ret i1 false
+define i1 @ashr_ne_both_minus1(i8 %a) {
+ %shr = ashr i8 -1, %a
+ %cmp = icmp ne i8 %shr, -1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_both_minus1
+; CHECK-NEXT: ret i1 true
+define i1 @exact_ashr_eq_both_minus1(i8 %a) {
+ %shr = ashr exact i8 -1, %a
+ %cmp = icmp eq i8 %shr, -1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_both_minus1
+; CHECK-NEXT: ret i1 false
+define i1 @exact_ashr_ne_both_minus1(i8 %a) {
+ %shr = ashr exact i8 -1, %a
+ %cmp = icmp ne i8 %shr, -1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_opposite_msb
+; CHECK-NEXT: ret i1 false
+define i1 @exact_ashr_eq_opposite_msb(i8 %a) {
+ %shr = ashr exact i8 -128, %a
+ %cmp = icmp eq i8 %shr, 1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_noexactlog
+; CHECK-NEXT: ret i1 false
+define i1 @exact_ashr_eq_noexactlog(i8 %a) {
+ %shr = ashr exact i8 -90, %a
+ %cmp = icmp eq i8 %shr, -30
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_opposite_msb
+; CHECK-NEXT: ret i1 true
+define i1 @exact_ashr_ne_opposite_msb(i8 %a) {
+ %shr = ashr exact i8 -128, %a
+ %cmp = icmp ne i8 %shr, 1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_eq_opposite_msb
+; CHECK-NEXT: ret i1 false
+define i1 @ashr_eq_opposite_msb(i8 %a) {
+ %shr = ashr i8 -128, %a
+ %cmp = icmp eq i8 %shr, 1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @ashr_ne_opposite_msb
+; CHECK-NEXT: ret i1 true
+define i1 @ashr_ne_opposite_msb(i8 %a) {
+ %shr = ashr i8 -128, %a
+ %cmp = icmp ne i8 %shr, 1
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_eq_shift_gt
+; CHECK-NEXT : ret i1 false
+define i1 @exact_ashr_eq_shift_gt(i8 %a) {
+ %shr = ashr exact i8 -2, %a
+ %cmp = icmp eq i8 %shr, -8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_shift_gt
+; CHECK-NEXT : ret i1 true
+define i1 @exact_ashr_ne_shift_gt(i8 %a) {
+ %shr = ashr exact i8 -2, %a
+ %cmp = icmp ne i8 %shr, -8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_eq_shift_gt
+; CHECK-NEXT : ret i1 false
+define i1 @nonexact_ashr_eq_shift_gt(i8 %a) {
+ %shr = ashr i8 -2, %a
+ %cmp = icmp eq i8 %shr, -8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_ashr_ne_shift_gt
+; CHECK-NEXT : ret i1 true
+define i1 @nonexact_ashr_ne_shift_gt(i8 %a) {
+ %shr = ashr i8 -2, %a
+ %cmp = icmp ne i8 %shr, -8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_eq_shift_gt
+; CHECK-NEXT: ret i1 false
+define i1 @exact_lshr_eq_shift_gt(i8 %a) {
+ %shr = lshr exact i8 2, %a
+ %cmp = icmp eq i8 %shr, 8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_ne_shift_gt
+; CHECK-NEXT: ret i1 true
+define i1 @exact_lshr_ne_shift_gt(i8 %a) {
+ %shr = lshr exact i8 2, %a
+ %cmp = icmp ne i8 %shr, 8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_eq_shift_gt
+; CHECK-NEXT : ret i1 false
+define i1 @nonexact_lshr_eq_shift_gt(i8 %a) {
+ %shr = lshr i8 2, %a
+ %cmp = icmp eq i8 %shr, 8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @nonexact_lshr_ne_shift_gt
+; CHECK-NEXT : ret i1 true
+define i1 @nonexact_lshr_ne_shift_gt(i8 %a) {
+ %shr = ashr i8 2, %a
+ %cmp = icmp ne i8 %shr, 8
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_ashr_ne_noexactlog
+; CHECK-NEXT: ret i1 true
+define i1 @exact_ashr_ne_noexactlog(i8 %a) {
+ %shr = ashr exact i8 -90, %a
+ %cmp = icmp ne i8 %shr, -30
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_eq_noexactlog
+; CHECK-NEXT: ret i1 false
+define i1 @exact_lshr_eq_noexactlog(i8 %a) {
+ %shr = lshr exact i8 90, %a
+ %cmp = icmp eq i8 %shr, 30
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_ne_noexactlog
+; CHECK-NEXT: ret i1 true
+define i1 @exact_lshr_ne_noexactlog(i8 %a) {
+ %shr = lshr exact i8 90, %a
+ %cmp = icmp ne i8 %shr, 30
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @exact_lshr_lowbit
+; CHECK-NEXT: ret i32 7
+define i32 @exact_lshr_lowbit(i32 %shiftval) {
+ %shr = lshr exact i32 7, %shiftval
+ ret i32 %shr
+}
+
+; CHECK-LABEL: @exact_ashr_lowbit
+; CHECK-NEXT: ret i32 7
+define i32 @exact_ashr_lowbit(i32 %shiftval) {
+ %shr = ashr exact i32 7, %shiftval
+ ret i32 %shr
+}
diff --git a/test/Transforms/InstSimplify/vector_ptr_bitcast.ll b/test/Transforms/InstSimplify/vector_ptr_bitcast.ll
new file mode 100644
index 0000000..607892a
--- /dev/null
+++ b/test/Transforms/InstSimplify/vector_ptr_bitcast.ll
@@ -0,0 +1,35 @@
+; RUN: opt -S -instsimplify < %s | FileCheck %s
+target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
+
+%mst = type { i8*, i8* }
+%mst2 = type { i32*, i32*, i32*, i32* }
+
+@a = private unnamed_addr constant %mst { i8* inttoptr (i64 -1 to i8*),
+ i8* inttoptr (i64 -1 to i8*)},
+ align 8
+@b = private unnamed_addr constant %mst2 { i32* inttoptr (i64 42 to i32*),
+ i32* inttoptr (i64 67 to i32*),
+ i32* inttoptr (i64 33 to i32*),
+ i32* inttoptr (i64 58 to i32*)},
+ align 8
+
+define i64 @fn() {
+ %x = load <2 x i8*>* bitcast (%mst* @a to <2 x i8*>*), align 8
+ %b = extractelement <2 x i8*> %x, i32 0
+ %c = ptrtoint i8* %b to i64
+ ; CHECK-LABEL: @fn
+ ; CHECK-NEXT: ret i64 -1
+ ret i64 %c
+}
+
+define i64 @fn2() {
+ %x = load <4 x i32*>* bitcast (%mst2* @b to <4 x i32*>*), align 8
+ %b = extractelement <4 x i32*> %x, i32 0
+ %c = extractelement <4 x i32*> %x, i32 3
+ %d = ptrtoint i32* %b to i64
+ %e = ptrtoint i32* %c to i64
+ %r = add i64 %d, %e
+ ; CHECK-LABEL: @fn2
+ ; CHECK-NEXT: ret i64 100
+ ret i64 %r
+}