aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine')
-rw-r--r--test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll4
-rw-r--r--test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll4
-rw-r--r--test/Transforms/InstCombine/2010-03-03-ExtElim.ll4
-rw-r--r--test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll69
-rw-r--r--test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll2
-rw-r--r--test/Transforms/InstCombine/AddOverFlow.ll118
-rw-r--r--test/Transforms/InstCombine/OverlappingInsertvalues.ll36
-rw-r--r--test/Transforms/InstCombine/abs_abs.ll961
-rw-r--r--test/Transforms/InstCombine/add-shrink.ll10
-rw-r--r--test/Transforms/InstCombine/add-sitofp.ll2
-rw-r--r--test/Transforms/InstCombine/add2.ll272
-rw-r--r--test/Transforms/InstCombine/add4.ll23
-rw-r--r--test/Transforms/InstCombine/addrspacecast.ll80
-rw-r--r--test/Transforms/InstCombine/align-2d-gep.ll2
-rw-r--r--test/Transforms/InstCombine/alloca.ll21
-rw-r--r--test/Transforms/InstCombine/ashr-nop.ll8
-rw-r--r--test/Transforms/InstCombine/bitcast-store.ll18
-rw-r--r--test/Transforms/InstCombine/blend_x86.ll55
-rw-r--r--test/Transforms/InstCombine/call-cast-target-inalloca.ll22
-rw-r--r--test/Transforms/InstCombine/call-cast-target.ll12
-rw-r--r--test/Transforms/InstCombine/cast-call-combine.ll23
-rw-r--r--test/Transforms/InstCombine/cast-set.ll7
-rw-r--r--test/Transforms/InstCombine/cast.ll59
-rw-r--r--test/Transforms/InstCombine/ceil.ll56
-rw-r--r--test/Transforms/InstCombine/constant-fold-address-space-pointer.ll10
-rw-r--r--test/Transforms/InstCombine/constant-fold-math.ll47
-rw-r--r--test/Transforms/InstCombine/copysign.ll49
-rw-r--r--test/Transforms/InstCombine/descale-zero.ll21
-rw-r--r--test/Transforms/InstCombine/distribute.ll68
-rw-r--r--test/Transforms/InstCombine/div.ll43
-rw-r--r--test/Transforms/InstCombine/double-float-shrink-1.ll5
-rw-r--r--test/Transforms/InstCombine/exp2-1.ll24
-rw-r--r--test/Transforms/InstCombine/fast-math.ll53
-rw-r--r--test/Transforms/InstCombine/fdiv.ll26
-rw-r--r--test/Transforms/InstCombine/ffs-1.ll6
-rw-r--r--test/Transforms/InstCombine/float-shrink-compare.ll54
-rw-r--r--test/Transforms/InstCombine/fmul.ll34
-rw-r--r--test/Transforms/InstCombine/fpcast.ll9
-rw-r--r--test/Transforms/InstCombine/fpextend.ll14
-rw-r--r--test/Transforms/InstCombine/fpextend_x86.ll57
-rw-r--r--test/Transforms/InstCombine/fprintf-1.ll8
-rw-r--r--test/Transforms/InstCombine/gep-addrspace.ll17
-rw-r--r--test/Transforms/InstCombine/gepphigep.ll56
-rw-r--r--test/Transforms/InstCombine/getelementptr.ll37
-rw-r--r--test/Transforms/InstCombine/icmp.ll72
-rw-r--r--test/Transforms/InstCombine/insert-extract-shuffle.ll37
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll13
-rw-r--r--test/Transforms/InstCombine/load-addrspace-cast.ll12
-rw-r--r--test/Transforms/InstCombine/load.ll48
-rw-r--r--test/Transforms/InstCombine/loadstore-alignment.ll114
-rw-r--r--test/Transforms/InstCombine/memcpy-from-global.ll68
-rw-r--r--test/Transforms/InstCombine/mul.ll16
-rw-r--r--test/Transforms/InstCombine/onehot_merge.ll4
-rw-r--r--test/Transforms/InstCombine/overflow-mul.ll175
-rw-r--r--test/Transforms/InstCombine/pow-1.ll29
-rw-r--r--test/Transforms/InstCombine/pr19420.ll67
-rw-r--r--test/Transforms/InstCombine/pr20059.ll16
-rw-r--r--test/Transforms/InstCombine/pr20079.ll9
-rw-r--r--test/Transforms/InstCombine/printf-1.ll8
-rw-r--r--test/Transforms/InstCombine/r600-intrinsics.ll47
-rw-r--r--test/Transforms/InstCombine/rem.ll11
-rw-r--r--test/Transforms/InstCombine/round.ll90
-rw-r--r--test/Transforms/InstCombine/select-2.ll10
-rw-r--r--test/Transforms/InstCombine/select-select.ll24
-rw-r--r--test/Transforms/InstCombine/select.ll213
-rw-r--r--test/Transforms/InstCombine/sext.ll4
-rw-r--r--test/Transforms/InstCombine/shift.ll94
-rw-r--r--test/Transforms/InstCombine/sign-test-and-or.ll38
-rw-r--r--test/Transforms/InstCombine/sincospi.ll9
-rw-r--r--test/Transforms/InstCombine/sprintf-1.ll8
-rw-r--r--test/Transforms/InstCombine/strchr-1.ll13
-rw-r--r--test/Transforms/InstCombine/strlen-1.ll12
-rw-r--r--test/Transforms/InstCombine/sub.ll72
-rw-r--r--test/Transforms/InstCombine/vec_demanded_elts.ll366
-rw-r--r--test/Transforms/InstCombine/vec_phi_extract.ll4
-rw-r--r--test/Transforms/InstCombine/vec_sext.ll23
-rw-r--r--test/Transforms/InstCombine/vec_shuffle.ll186
-rw-r--r--test/Transforms/InstCombine/zext-bool-add-sub.ll2
-rw-r--r--test/Transforms/InstCombine/zext.ll34
79 files changed, 4329 insertions, 125 deletions
diff --git a/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll b/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll
index c27fe0ab6a6d..7f9bd9e40dcb 100644
--- a/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll
+++ b/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll
@@ -3,7 +3,9 @@
@__gthrw_pthread_cancel = alias weak i32 (i32)* @pthread_cancel ; <i32 (i32)*> [#uses=1]
@__gthread_active_ptr.5335 = internal constant i8* bitcast (i32 (i32)* @__gthrw_pthread_cancel to i8*) ; <i8**> [#uses=1]
-declare extern_weak i32 @pthread_cancel(i32)
+define weak i32 @pthread_cancel(i32) {
+ ret i32 0
+}
define i1 @__gthread_active_p() {
entry:
diff --git a/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll b/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll
index 23ee12ba754f..c7cef752dcc9 100644
--- a/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll
+++ b/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll
@@ -3,7 +3,9 @@
@A = alias weak void ()* @B ; <void ()*> [#uses=1]
-declare extern_weak void @B()
+define weak void @B() {
+ ret void
+}
define i32 @active() {
entry:
diff --git a/test/Transforms/InstCombine/2010-03-03-ExtElim.ll b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll
index b1384ec00209..e0def997d974 100644
--- a/test/Transforms/InstCombine/2010-03-03-ExtElim.ll
+++ b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll
@@ -22,11 +22,11 @@ define i1 @PR6486() nounwind {
define i1 @PR16462_1() nounwind {
; CHECK-LABEL: @PR16462_1(
ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 65535)
-; CHECK: ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 65535)
+; CHECK: ret i1 false
}
define i1 @PR16462_2() nounwind {
; CHECK-LABEL: @PR16462_2(
ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 42)
-; CHECK: ret i1 icmp sgt (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16), i16 42)
+; CHECK: ret i1 false
}
diff --git a/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll b/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll
index 2dedd44e2be1..39408a2d394c 100644
--- a/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll
+++ b/test/Transforms/InstCombine/2012-04-23-Neon-Intrinsics.ll
@@ -1,6 +1,3 @@
-target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
-target triple = "thumbv7-apple-ios0"
-
; RUN: opt -S -instcombine < %s | FileCheck %s
define <4 x i32> @mulByZero(<4 x i16> %x) nounwind readnone ssp {
@@ -67,6 +64,72 @@ entry:
declare <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16>, <4 x i16>) nounwind readnone
declare <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16>, <4 x i16>) nounwind readnone
+; ARM64 variants - <rdar://problem/12349617>
+
+define <4 x i32> @mulByZeroARM64(<4 x i16> %x) nounwind readnone ssp {
+entry:
+ %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %x, <4 x i16> zeroinitializer) nounwind
+ ret <4 x i32> %a
+; CHECK: entry:
+; CHECK-NEXT: ret <4 x i32> zeroinitializer
+}
+
+define <4 x i32> @mulByOneARM64(<4 x i16> %x) nounwind readnone ssp {
+entry:
+ %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> %x, <4 x i16> <i16 1, i16 1, i16 1, i16 1>) nounwind
+ ret <4 x i32> %a
+; CHECK: entry:
+; CHECK-NEXT: %a = sext <4 x i16> %x to <4 x i32>
+; CHECK-NEXT: ret <4 x i32> %a
+}
+
+define <4 x i32> @constantMulARM64() nounwind readnone ssp {
+entry:
+ %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> <i16 3, i16 3, i16 3, i16 3>, <4 x i16> <i16 2, i16 2, i16 2, i16 2>) nounwind
+ ret <4 x i32> %a
+; CHECK: entry:
+; CHECK-NEXT: ret <4 x i32> <i32 6, i32 6, i32 6, i32 6>
+}
+
+define <4 x i32> @constantMulSARM64() nounwind readnone ssp {
+entry:
+ %b = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>, <4 x i16> <i16 1, i16 1, i16 1, i16 1>) nounwind
+ ret <4 x i32> %b
+; CHECK: entry:
+; CHECK-NEXT: ret <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+}
+
+define <4 x i32> @constantMulUARM64() nounwind readnone ssp {
+entry:
+ %b = tail call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>, <4 x i16> <i16 1, i16 1, i16 1, i16 1>) nounwind
+ ret <4 x i32> %b
+; CHECK: entry:
+; CHECK-NEXT: ret <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
+}
+
+define <4 x i32> @complex1ARM64(<4 x i16> %x) nounwind readnone ssp {
+entry:
+ %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> <i16 2, i16 2, i16 2, i16 2>, <4 x i16> %x) nounwind
+ %b = add <4 x i32> zeroinitializer, %a
+ ret <4 x i32> %b
+; CHECK: entry:
+; CHECK-NEXT: %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> <i16 2, i16 2, i16 2, i16 2>, <4 x i16> %x) [[NUW:#[0-9]+]]
+; CHECK-NEXT: ret <4 x i32> %a
+}
+
+define <4 x i32> @complex2ARM64(<4 x i32> %x) nounwind readnone ssp {
+entry:
+ %a = tail call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> <i16 3, i16 3, i16 3, i16 3>, <4 x i16> <i16 2, i16 2, i16 2, i16 2>) nounwind
+ %b = add <4 x i32> %x, %a
+ ret <4 x i32> %b
+; CHECK: entry:
+; CHECK-NEXT: %b = add <4 x i32> %x, <i32 6, i32 6, i32 6, i32 6>
+; CHECK-NEXT: ret <4 x i32> %b
+}
+
+declare <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone
+declare <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone
+
; CHECK: attributes #0 = { nounwind readnone ssp }
; CHECK: attributes #1 = { nounwind readnone }
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll b/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll
index 4d185bf7e06e..ac9c555020d0 100644
--- a/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll
+++ b/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll
@@ -1,7 +1,7 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
; CHECK: addrspacecast
-@base = internal addrspace(3) unnamed_addr global [16 x i32] zeroinitializer, align 16
+@base = internal unnamed_addr addrspace(3) global [16 x i32] zeroinitializer, align 16
declare void @foo(i32*)
define void @test() nounwind {
diff --git a/test/Transforms/InstCombine/AddOverFlow.ll b/test/Transforms/InstCombine/AddOverFlow.ll
new file mode 100644
index 000000000000..8f3d429c8d60
--- /dev/null
+++ b/test/Transforms/InstCombine/AddOverFlow.ll
@@ -0,0 +1,118 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; CHECK-LABEL: @oppositesign
+; CHECK: add nsw i16 %a, %b
+define i16 @oppositesign(i16 %x, i16 %y) {
+; %a is negative, %b is positive
+ %a = or i16 %x, 32768
+ %b = and i16 %y, 32767
+ %c = add i16 %a, %b
+ ret i16 %c
+}
+
+define i16 @zero_sign_bit(i16 %a) {
+; CHECK-LABEL: @zero_sign_bit(
+; CHECK-NEXT: and
+; CHECK-NEXT: add nuw
+; CHECK-NEXT: ret
+ %1 = and i16 %a, 32767
+ %2 = add i16 %1, 512
+ ret i16 %2
+}
+
+define i16 @zero_sign_bit2(i16 %a, i16 %b) {
+; CHECK-LABEL: @zero_sign_bit2(
+; CHECK-NEXT: and
+; CHECK-NEXT: and
+; CHECK-NEXT: add nuw
+; CHECK-NEXT: ret
+ %1 = and i16 %a, 32767
+ %2 = and i16 %b, 32767
+ %3 = add i16 %1, %2
+ ret i16 %3
+}
+
+declare i16 @bounded(i16 %input);
+declare i32 @__gxx_personality_v0(...);
+!0 = metadata !{i16 0, i16 32768} ; [0, 32767]
+!1 = metadata !{i16 0, i16 32769} ; [0, 32768]
+
+define i16 @add_bounded_values(i16 %a, i16 %b) {
+; CHECK-LABEL: @add_bounded_values(
+entry:
+ %c = call i16 @bounded(i16 %a), !range !0
+ %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0
+cont:
+; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow.
+ %e = add i16 %c, %d
+; CHECK: add nuw i16 %c, %d
+ ret i16 %e
+lpad:
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ filter [0 x i8*] zeroinitializer
+ ret i16 42
+}
+
+define i16 @add_bounded_values_2(i16 %a, i16 %b) {
+; CHECK-LABEL: @add_bounded_values_2(
+entry:
+ %c = call i16 @bounded(i16 %a), !range !1
+ %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1
+cont:
+; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore,
+; %c + %d may unsigned overflow and we cannot add NUW.
+ %e = add i16 %c, %d
+; CHECK: add i16 %c, %d
+ ret i16 %e
+lpad:
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ filter [0 x i8*] zeroinitializer
+ ret i16 42
+}
+
+; CHECK-LABEL: @ripple_nsw1
+; CHECK: add nsw i16 %a, %b
+define i16 @ripple_nsw1(i16 %x, i16 %y) {
+; %a has at most one bit set
+ %a = and i16 %y, 1
+
+; %b has a 0 bit other than the sign bit
+ %b = and i16 %x, 49151
+
+ %c = add i16 %a, %b
+ ret i16 %c
+}
+
+; Like the previous test, but flip %a and %b
+; CHECK-LABEL: @ripple_nsw2
+; CHECK: add nsw i16 %b, %a
+define i16 @ripple_nsw2(i16 %x, i16 %y) {
+ %a = and i16 %y, 1
+ %b = and i16 %x, 49151
+ %c = add i16 %b, %a
+ ret i16 %c
+}
+
+; CHECK-LABEL: @ripple_no_nsw1
+; CHECK: add i32 %a, %x
+define i32 @ripple_no_nsw1(i32 %x, i32 %y) {
+; We know nothing about %x
+ %a = and i32 %y, 1
+ %b = add i32 %a, %x
+ ret i32 %b
+}
+
+; CHECK-LABEL: @ripple_no_nsw2
+; CHECK: add nuw i16 %a, %b
+define i16 @ripple_no_nsw2(i16 %x, i16 %y) {
+; %a has at most one bit set
+ %a = and i16 %y, 1
+
+; %b has a 0 bit, but it is the sign bit
+ %b = and i16 %x, 32767
+
+ %c = add i16 %a, %b
+ ret i16 %c
+}
diff --git a/test/Transforms/InstCombine/OverlappingInsertvalues.ll b/test/Transforms/InstCombine/OverlappingInsertvalues.ll
new file mode 100644
index 000000000000..9248aecdf575
--- /dev/null
+++ b/test/Transforms/InstCombine/OverlappingInsertvalues.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; Check that we can find and remove redundant insertvalues
+; CHECK-LABEL: foo_simple
+; CHECK-NOT: i8* %x, 0
+define { i8*, i64, i32 } @foo_simple(i8* %x, i8* %y) nounwind {
+entry:
+ %0 = insertvalue { i8*, i64, i32 } undef, i8* %x, 0
+ %1 = insertvalue { i8*, i64, i32 } %0, i8* %y, 0
+ ret { i8*, i64, i32 } %1
+}
+; Check that we can find and remove redundant nodes in insertvalues chain
+; CHECK-LABEL: foo_ovwrt_chain
+; CHECK-NOT: i64 %y, 1
+; CHECK-NOT: i32 555, 2
+define { i8*, i64, i32 } @foo_ovwrt_chain(i8* %x, i64 %y, i64 %z) nounwind {
+entry:
+ %0 = insertvalue { i8*, i64, i32 } undef, i8* %x, 0
+ %1 = insertvalue { i8*, i64, i32 } %0, i64 %y, 1
+ %2 = insertvalue { i8*, i64, i32 } %1, i32 555, 2
+ %3 = insertvalue { i8*, i64, i32 } %2, i64 %z, 1
+ %4 = insertvalue { i8*, i64, i32 } %3, i32 777, 2
+ ret { i8*, i64, i32 } %4
+}
+; Check that we propagate insertvalues only if they are use as the first
+; operand (as initial value of aggregate)
+; CHECK-LABEL: foo_use_as_second_operand
+; CHECK: i16 %x, 0
+; CHECK: %0, 1
+define { i8, {i16, i32} } @foo_use_as_second_operand(i16 %x) nounwind {
+entry:
+ %0 = insertvalue { i16, i32 } undef, i16 %x, 0
+ %1 = insertvalue { i8, {i16, i32} } undef, { i16, i32 } %0, 1
+ ret { i8, {i16, i32} } %1
+}
diff --git a/test/Transforms/InstCombine/abs_abs.ll b/test/Transforms/InstCombine/abs_abs.ll
new file mode 100644
index 000000000000..de10fd180a79
--- /dev/null
+++ b/test/Transforms/InstCombine/abs_abs.ll
@@ -0,0 +1,961 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define i32 @abs_abs_x01(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x01(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x02(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x02(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x03(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x03(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x04(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x04(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x05(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x05(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x06(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x06(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x07(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x07(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x08(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x08(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x09(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x09(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x10(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x10(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x11(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x11(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x12(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x12(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x13(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x13(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x14(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x14(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x15(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x15(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_abs_x16(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_abs_x16(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x01(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x01(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x02(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x02(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x03(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x03(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x04(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x04(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x05(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x05(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x06(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x06(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x07(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x07(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x08(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x08(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x09(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x09(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x10(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x10(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x11(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x11(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x12(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x12(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x13(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x13(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x14(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x14(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x15(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x15(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_nabs_x16(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_nabs_x16(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x01(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x01(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x02(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x02(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x03(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x03(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x04(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x04(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x05(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x05(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x06(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x06(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x07(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x07(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x08(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x08(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x09(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x09(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x10(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x10(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x11(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x11(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x12(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x12(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x13(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x13(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x14(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x14(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x15(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x15(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @abs_nabs_x16(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @abs_nabs_x16(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x01(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x01(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x02(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x02(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x03(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x03(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x04(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, -1
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x04(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x05(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x05(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x06(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x06(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x07(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x07(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x08(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp sgt i32 %cond, 0
+ %sub9 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x08(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x09(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x09(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x10(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x10(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x11(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x11(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x12(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 0
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x12(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x13(i32 %x) {
+ %cmp = icmp sgt i32 %x, -1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x13(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x14(i32 %x) {
+ %cmp = icmp sgt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %x, i32 %sub
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x14(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x15(i32 %x) {
+ %cmp = icmp slt i32 %x, 0
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x15(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+define i32 @nabs_abs_x16(i32 %x) {
+ %cmp = icmp slt i32 %x, 1
+ %sub = sub nsw i32 0, %x
+ %cond = select i1 %cmp, i32 %sub, i32 %x
+ %cmp1 = icmp slt i32 %cond, 1
+ %sub16 = sub nsw i32 0, %cond
+ %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16
+ ret i32 %cond18
+; CHECK-LABEL: @nabs_abs_x16(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1
+; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]]
+; CHECK-NEXT: ret i32 [[SEL]]
+} \ No newline at end of file
diff --git a/test/Transforms/InstCombine/add-shrink.ll b/test/Transforms/InstCombine/add-shrink.ll
index 3edb392ed184..67a990fcb105 100644
--- a/test/Transforms/InstCombine/add-shrink.ll
+++ b/test/Transforms/InstCombine/add-shrink.ll
@@ -1,9 +1,11 @@
-; RUN: opt < %s -instcombine -S | grep "add nsw i32"
-; RUN: opt < %s -instcombine -S | grep sext | count 1
-
-; Should only have one sext and the add should be i32 instead of i64.
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; CHECK-LABEL: define i64 @test
define i64 @test1(i32 %A) {
+; CHECK: %[[ADD:.*]] = add nsw i32 %B, %C
+; CHECK: %F = sext i32 %[[ADD]] to i64
+; CHECK: ret i64 %F
+
%B = ashr i32 %A, 7 ; <i32> [#uses=1]
%C = ashr i32 %A, 9 ; <i32> [#uses=1]
%D = sext i32 %B to i64 ; <i64> [#uses=1]
diff --git a/test/Transforms/InstCombine/add-sitofp.ll b/test/Transforms/InstCombine/add-sitofp.ll
index 40edf7114a06..3b5485e00528 100644
--- a/test/Transforms/InstCombine/add-sitofp.ll
+++ b/test/Transforms/InstCombine/add-sitofp.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep "add nsw i32"
+; RUN: opt < %s -instcombine -S | grep "add nuw nsw i32"
define double @x(i32 %a, i32 %b) nounwind {
%m = lshr i32 %a, 24
diff --git a/test/Transforms/InstCombine/add2.ll b/test/Transforms/InstCombine/add2.ll
index 0964bc00d1cb..d7eac4b0fd21 100644
--- a/test/Transforms/InstCombine/add2.ll
+++ b/test/Transforms/InstCombine/add2.ll
@@ -41,3 +41,275 @@ define i32 @test4(i32 %A) {
; CHECK-NEXT: ret i32 %B
}
+define <2 x i1> @test5(<2 x i1> %A, <2 x i1> %B) {
+ %add = add <2 x i1> %A, %B
+ ret <2 x i1> %add
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: %add = xor <2 x i1> %A, %B
+; CHECK-NEXT: ret <2 x i1> %add
+}
+
+define <2 x i64> @test6(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 2, i64 3>
+ %add = add <2 x i64> %shl, %A
+ ret <2 x i64> %add
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 5, i64 9>
+; CHECK-NEXT: ret <2 x i64> %add
+}
+
+define <2 x i64> @test7(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 2, i64 3>
+ %mul = mul <2 x i64> %A, <i64 3, i64 4>
+ %add = add <2 x i64> %shl, %mul
+ ret <2 x i64> %add
+; CHECK-LABEL: @test7(
+; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 7, i64 12>
+; CHECK-NEXT: ret <2 x i64> %add
+}
+
+define <2 x i64> @test8(<2 x i64> %A) {
+ %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
+ %add = add <2 x i64> %xor, <i64 2, i64 3>
+ ret <2 x i64> %add
+; CHECK-LABEL: @test8(
+; CHECK-NEXT: %add = sub <2 x i64> <i64 1, i64 2>, %A
+; CHECK-NEXT: ret <2 x i64> %add
+}
+
+define i16 @test9(i16 %a) {
+ %b = mul i16 %a, 2
+ %c = mul i16 %a, 32767
+ %d = add i16 %b, %c
+ ret i16 %d
+; CHECK-LABEL: @test9(
+; CHECK-NEXT: %d = mul i16 %a, -32767
+; CHECK-NEXT: ret i16 %d
+}
+
+; y + (~((x >> 3) & 0x55555555) + 1) -> y - ((x >> 3) & 0x55555555)
+define i32 @test10(i32 %x, i32 %y) {
+ %shr = ashr i32 %x, 3
+ %shr.not = or i32 %shr, -1431655766
+ %neg = xor i32 %shr.not, 1431655765
+ %add = add i32 %y, 1
+ %add1 = add i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x & 0x55555555) + 1) -> y - (x & 0x55555555)
+define i32 @test11(i32 %x, i32 %y) {
+ %x.not = or i32 %x, -1431655766
+ %neg = xor i32 %x.not, 1431655765
+ %add = add i32 %y, 1
+ %add1 = add i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test11(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x & 0x55555555) -> y - (x & 0x55555555)
+define i32 @test12(i32 %x, i32 %y) {
+ %add = add nsw i32 %y, 1
+ %x.not = or i32 %x, -1431655766
+ %neg = xor i32 %x.not, 1431655765
+ %add1 = add nsw i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test12(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x & 0x55555556) + 1) -> y - (x & 0x55555556)
+define i32 @test13(i32 %x, i32 %y) {
+ %x.not = or i32 %x, -1431655767
+ %neg = xor i32 %x.not, 1431655766
+ %add = add i32 %y, 1
+ %add1 = add i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test13(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x & 0x55555556) -> y - (x & 0x55555556)
+define i32 @test14(i32 %x, i32 %y) {
+ %add = add nsw i32 %y, 1
+ %x.not = or i32 %x, -1431655767
+ %neg = xor i32 %x.not, 1431655766
+ %add1 = add nsw i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test14(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x | 0x55555556) + 1) -> y - (x | 0x55555556)
+define i32 @test15(i32 %x, i32 %y) {
+ %x.not = and i32 %x, -1431655767
+ %neg = xor i32 %x.not, -1431655767
+ %add = add i32 %y, 1
+ %add1 = add i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test15(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x | 0x55555556) -> y - (x | 0x555555556)
+define i32 @test16(i32 %x, i32 %y) {
+ %add = add nsw i32 %y, 1
+ %x.not = and i32 %x, -1431655767
+ %neg = xor i32 %x.not, -1431655767
+ %add1 = add nsw i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x | 0x55555555) + 1) -> y - (x | 0x55555555)
+define i32 @test17(i32 %x, i32 %y) {
+ %x.not = and i32 %x, -1431655766
+ %add2 = xor i32 %x.not, -1431655765
+ %add1 = add nsw i32 %add2, %y
+ ret i32 %add1
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x | 0x55555555) -> y - (x | 0x55555555)
+define i32 @test18(i32 %x, i32 %y) {
+ %add = add nsw i32 %y, 1
+ %x.not = and i32 %x, -1431655766
+ %neg = xor i32 %x.not, -1431655766
+ %add1 = add nsw i32 %add, %neg
+ ret i32 %add1
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+define i16 @add_nsw_mul_nsw(i16 %x) {
+ %add1 = add nsw i16 %x, %x
+ %add2 = add nsw i16 %add1, %x
+ ret i16 %add2
+; CHECK-LABEL: @add_nsw_mul_nsw(
+; CHECK-NEXT: %add2 = mul nsw i16 %x, 3
+; CHECK-NEXT: ret i16 %add2
+}
+
+define i16 @mul_add_to_mul_1(i16 %x) {
+ %mul1 = mul nsw i16 %x, 8
+ %add2 = add nsw i16 %x, %mul1
+ ret i16 %add2
+; CHECK-LABEL: @mul_add_to_mul_1(
+; CHECK-NEXT: %add2 = mul nsw i16 %x, 9
+; CHECK-NEXT: ret i16 %add2
+}
+
+define i16 @mul_add_to_mul_2(i16 %x) {
+ %mul1 = mul nsw i16 %x, 8
+ %add2 = add nsw i16 %mul1, %x
+ ret i16 %add2
+; CHECK-LABEL: @mul_add_to_mul_2(
+; CHECK-NEXT: %add2 = mul nsw i16 %x, 9
+; CHECK-NEXT: ret i16 %add2
+}
+
+define i16 @mul_add_to_mul_3(i16 %a) {
+ %mul1 = mul i16 %a, 2
+ %mul2 = mul i16 %a, 3
+ %add = add nsw i16 %mul1, %mul2
+ ret i16 %add
+; CHECK-LABEL: @mul_add_to_mul_3(
+; CHECK-NEXT: %add = mul i16 %a, 5
+; CHECK-NEXT: ret i16 %add
+}
+
+define i16 @mul_add_to_mul_4(i16 %a) {
+ %mul1 = mul nsw i16 %a, 2
+ %mul2 = mul nsw i16 %a, 7
+ %add = add nsw i16 %mul1, %mul2
+ ret i16 %add
+; CHECK-LABEL: @mul_add_to_mul_4(
+; CHECK-NEXT: %add = mul nsw i16 %a, 9
+; CHECK-NEXT: ret i16 %add
+}
+
+define i16 @mul_add_to_mul_5(i16 %a) {
+ %mul1 = mul nsw i16 %a, 3
+ %mul2 = mul nsw i16 %a, 7
+ %add = add nsw i16 %mul1, %mul2
+ ret i16 %add
+; CHECK-LABEL: @mul_add_to_mul_5(
+; CHECK-NEXT: %add = mul nsw i16 %a, 10
+; CHECK-NEXT: ret i16 %add
+}
+
+define i32 @mul_add_to_mul_6(i32 %x, i32 %y) {
+ %mul1 = mul nsw i32 %x, %y
+ %mul2 = mul nsw i32 %mul1, 5
+ %add = add nsw i32 %mul1, %mul2
+ ret i32 %add
+; CHECK-LABEL: @mul_add_to_mul_6(
+; CHECK-NEXT: %mul1 = mul nsw i32 %x, %y
+; CHECK-NEXT: %add = mul nsw i32 %mul1, 6
+; CHECK-NEXT: ret i32 %add
+}
+
+; This test and the next test verify that when a range metadata is attached to
+; llvm.cttz, ValueTracking correctly intersects the range specified by the
+; metadata and the range implied by the intrinsic.
+;
+; In this test, the range specified by the metadata is more strict. Therefore,
+; ValueTracking uses that range.
+define i16 @add_cttz(i16 %a) {
+; CHECK-LABEL: @add_cttz(
+ ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned
+ ; is in [0, 16). The range metadata indicates the value returned is in [0, 8).
+ ; Intersecting these ranges, we know the value returned is in [0, 8).
+ ; Therefore, InstCombine will transform
+ ; add %cttz, 1111 1111 1111 1000 ; decimal -8
+ ; to
+ ; or %cttz, 1111 1111 1111 1000
+ %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !0
+ %b = add i16 %cttz, -8
+; CHECK: or i16 %cttz, -8
+ ret i16 %b
+}
+declare i16 @llvm.cttz.i16(i16, i1)
+!0 = metadata !{i16 0, i16 8}
+
+; Similar to @add_cttz, but in this test, the range implied by the
+; intrinsic is more strict. Therefore, ValueTracking uses that range.
+define i16 @add_cttz_2(i16 %a) {
+; CHECK-LABEL: @add_cttz_2(
+ ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned
+ ; is in [0, 16). The range metadata indicates the value returned is in
+ ; [0, 32). Intersecting these ranges, we know the value returned is in
+ ; [0, 16). Therefore, InstCombine will transform
+ ; add %cttz, 1111 1111 1111 0000 ; decimal -16
+ ; to
+ ; or %cttz, 1111 1111 1111 0000
+ %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !1
+ %b = add i16 %cttz, -16
+; CHECK: or i16 %cttz, -16
+ ret i16 %b
+}
+!1 = metadata !{i16 0, i16 32}
diff --git a/test/Transforms/InstCombine/add4.ll b/test/Transforms/InstCombine/add4.ll
index 208c7f03200e..f9b7e3b5a079 100644
--- a/test/Transforms/InstCombine/add4.ll
+++ b/test/Transforms/InstCombine/add4.ll
@@ -77,3 +77,26 @@ define float @test7(float %A, float %B, i32 %C) {
; CHECK: uitofp
}
+define <4 x float> @test8(<4 x float> %A, <4 x float> %B, <4 x i1> %C) {
+ ;; B*(uitofp i1 C) + A*(1 - uitofp i1 C) -> select C, A, B
+ %cf = uitofp <4 x i1> %C to <4 x float>
+ %mc = fsub fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %cf
+ %p1 = fmul fast <4 x float> %A, %mc
+ %p2 = fmul fast <4 x float> %B, %cf
+ %s1 = fadd fast <4 x float> %p2, %p1
+ ret <4 x float> %s1
+; CHECK-LABEL: @test8(
+; CHECK: select <4 x i1> %C, <4 x float> %B, <4 x float> %A
+}
+
+define <4 x float> @test9(<4 x float> %A, <4 x float> %B, <4 x i1> %C) {
+ ;; A*(1 - uitofp i1 C) + B*(uitofp i1 C) -> select C, A, B
+ %cf = uitofp <4 x i1> %C to <4 x float>
+ %mc = fsub fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %cf
+ %p1 = fmul fast <4 x float> %A, %mc
+ %p2 = fmul fast <4 x float> %B, %cf
+ %s1 = fadd fast <4 x float> %p1, %p2
+ ret <4 x float> %s1
+; CHECK-LABEL: @test9
+; CHECK: select <4 x i1> %C, <4 x float> %B, <4 x float> %A
+}
diff --git a/test/Transforms/InstCombine/addrspacecast.ll b/test/Transforms/InstCombine/addrspacecast.ll
index d908b556e195..c1684361f99f 100644
--- a/test/Transforms/InstCombine/addrspacecast.ll
+++ b/test/Transforms/InstCombine/addrspacecast.ll
@@ -28,13 +28,91 @@ define <4 x i32*> @combine_redundant_addrspacecast_vector(<4 x i32 addrspace(1)*
define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
; CHECK-LABEL: @combine_redundant_addrspacecast_types(
-; CHECK: addrspacecast i32 addrspace(1)* %x to float*
+; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
+; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float*
; CHECK-NEXT: ret
%y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
%z = addrspacecast i32 addrspace(3)* %y to float*
ret float* %z
}
+define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
+; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
+; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
+; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float*>
+; CHECK-NEXT: ret
+ %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
+ %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*>
+ ret <4 x float*> %z
+}
+
+define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
+; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
+; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+ %z = bitcast i32 addrspace(2)* %y to float addrspace(2)*
+ ret float addrspace(2)* %z
+}
+
+define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
+; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
+ %z = bitcast float addrspace(2)* %y to i32 addrspace(2)*
+ ret i32 addrspace(2)* %z
+}
+
+define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
+; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: ret
+ %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
+ %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)*
+ ret i32 addrspace(2)* %z
+}
+
+define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
+; CHECK: bitcast i32 addrspace(1)* %x to float addrspace(1)*
+; CHECK: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
+ %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)*
+ ret float addrspace(2)* %z
+}
+
+define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_types(
+; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
+; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
+ ret float addrspace(2)* %y
+}
+
+define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_types_vector(
+; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
+; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float addrspace(2)*>
+; CHECK-NEXT: ret
+ %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
+ ret <4 x float addrspace(2)*> %y
+}
+
+define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) {
+; CHECK-LABEL: @canonicalize_addrspacecast(
+; CHECK-NEXT: getelementptr inbounds [16 x i32] addrspace(1)* %arr, i32 0, i32 0
+; CHECK-NEXT: addrspacecast i32 addrspace(1)* %{{[a-zA-Z0-9]+}} to i32*
+; CHECK-NEXT: load i32*
+; CHECK-NEXT: ret i32
+ %p = addrspacecast [16 x i32] addrspace(1)* %arr to i32*
+ %v = load i32* %p
+ ret i32 %v
+}
+
@const_array = addrspace(2) constant [60 x i8] [i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
diff --git a/test/Transforms/InstCombine/align-2d-gep.ll b/test/Transforms/InstCombine/align-2d-gep.ll
index 5bca46d5a21d..f6a877684ce4 100644
--- a/test/Transforms/InstCombine/align-2d-gep.ll
+++ b/test/Transforms/InstCombine/align-2d-gep.ll
@@ -31,7 +31,7 @@ bb1:
store <2 x double><double 0.0, double 0.0>, <2 x double>* %r, align 8
%indvar.next = add i64 %j, 2
- %exitcond = icmp eq i64 %indvar.next, 557
+ %exitcond = icmp eq i64 %indvar.next, 556
br i1 %exitcond, label %bb11, label %bb1
bb11:
diff --git a/test/Transforms/InstCombine/alloca.ll b/test/Transforms/InstCombine/alloca.ll
index ae1cfa1ed2fc..6d0c131c51ed 100644
--- a/test/Transforms/InstCombine/alloca.ll
+++ b/test/Transforms/InstCombine/alloca.ll
@@ -129,3 +129,24 @@ define void @test8() {
call void (...)* @use(i32* %x)
ret void
}
+
+; PR19569
+%struct_type = type { i32, i32 }
+declare void @test9_aux(<{ %struct_type }>* inalloca)
+declare i8* @llvm.stacksave()
+declare void @llvm.stackrestore(i8*)
+
+define void @test9(%struct_type* %a) {
+; CHECK-LABEL: @test9(
+entry:
+ %inalloca.save = call i8* @llvm.stacksave()
+ %argmem = alloca inalloca <{ %struct_type }>
+; CHECK: alloca inalloca i64, align 8
+ %0 = getelementptr inbounds <{ %struct_type }>* %argmem, i32 0, i32 0
+ %1 = bitcast %struct_type* %0 to i8*
+ %2 = bitcast %struct_type* %a to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %2, i32 8, i32 4, i1 false)
+ call void @test9_aux(<{ %struct_type }>* inalloca %argmem)
+ call void @llvm.stackrestore(i8* %inalloca.save)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/ashr-nop.ll b/test/Transforms/InstCombine/ashr-nop.ll
deleted file mode 100644
index 870ede38cd88..000000000000
--- a/test/Transforms/InstCombine/ashr-nop.ll
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: opt < %s -instcombine -S | not grep 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/InstCombine/bitcast-store.ll b/test/Transforms/InstCombine/bitcast-store.ll
index e4a61e98e4f5..e46b5c82d9ff 100644
--- a/test/Transforms/InstCombine/bitcast-store.ll
+++ b/test/Transforms/InstCombine/bitcast-store.ll
@@ -3,14 +3,14 @@
; Instcombine should preserve metadata and alignment while
; folding a bitcast into a store.
-; CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 16, !tag !0
-
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
%struct.A = type { i32 (...)** }
@G = external constant [5 x i8*]
+; CHECK-LABEL: @foo
+; CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 16, !tag !0
define void @foo(%struct.A* %a) nounwind {
entry:
%0 = bitcast %struct.A* %a to i8***
@@ -18,4 +18,18 @@ entry:
ret void
}
+; Check instcombine doesn't try and fold the following bitcast into the store.
+; This transformation would not be safe since we would need to use addrspacecast
+; and addrspacecast is not guaranteed to be a no-op cast.
+
+; CHECK-LABEL: @bar
+; CHECK: %cast = bitcast i8** %b to i8 addrspace(1)**
+; CHECK: store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
+define void @bar(i8 addrspace(1)* %a, i8** %b) nounwind {
+entry:
+ %cast = bitcast i8** %b to i8 addrspace(1)**
+ store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
+ ret void
+}
+
!0 = metadata !{metadata !"hello"}
diff --git a/test/Transforms/InstCombine/blend_x86.ll b/test/Transforms/InstCombine/blend_x86.ll
new file mode 100644
index 000000000000..778d44ba342c
--- /dev/null
+++ b/test/Transforms/InstCombine/blend_x86.ll
@@ -0,0 +1,55 @@
+; RUN: opt < %s -instcombine -mtriple=x86_64-apple-macosx -mcpu=core-avx2 -S | FileCheck %s
+
+define <2 x double> @constant_blendvpd(<2 x double> %xy, <2 x double> %ab) {
+; CHECK-LABEL: @constant_blendvpd
+; CHECK: select <2 x i1> <i1 true, i1 false>, <2 x double> %ab, <2 x double> %xy
+ %1 = tail call <2 x double> @llvm.x86.sse41.blendvpd(<2 x double> %xy, <2 x double> %ab, <2 x double> <double 0xFFFFFFFFE0000000, double 0.000000e+00>)
+ ret <2 x double> %1
+}
+
+define <4 x float> @constant_blendvps(<4 x float> %xyzw, <4 x float> %abcd) {
+; CHECK-LABEL: @constant_blendvps
+; CHECK: select <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x float> %abcd, <4 x float> %xyzw
+ %1 = tail call <4 x float> @llvm.x86.sse41.blendvps(<4 x float> %xyzw, <4 x float> %abcd, <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0xFFFFFFFFE0000000>)
+ ret <4 x float> %1
+}
+
+define <16 x i8> @constant_pblendvb(<16 x i8> %xyzw, <16 x i8> %abcd) {
+; CHECK-LABEL: @constant_pblendvb
+; CHECK: select <16 x i1> <i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false>, <16 x i8> %abcd, <16 x i8> %xyzw
+ %1 = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> %xyzw, <16 x i8> %abcd, <16 x i8> <i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0, i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0>)
+ ret <16 x i8> %1
+}
+
+define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) {
+; CHECK-LABEL: @constant_blendvpd_avx
+; CHECK: select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %ab, <4 x double> %xy
+ %1 = tail call <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double> %xy, <4 x double> %ab, <4 x double> <double 0xFFFFFFFFE0000000, double 0.000000e+00, double 0xFFFFFFFFE0000000, double 0.000000e+00>)
+ ret <4 x double> %1
+}
+
+define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) {
+; CHECK-LABEL: @constant_blendvps_avx
+; CHECK: select <8 x i1> <i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true>, <8 x float> %abcd, <8 x float> %xyzw
+ %1 = tail call <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float> %xyzw, <8 x float> %abcd, <8 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0xFFFFFFFFE0000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0xFFFFFFFFE0000000>)
+ ret <8 x float> %1
+}
+
+define <32 x i8> @constant_pblendvb_avx2(<32 x i8> %xyzw, <32 x i8> %abcd) {
+; CHECK-LABEL: @constant_pblendvb_avx2
+; CHECK: select <32 x i1> <i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false>, <32 x i8> %abcd, <32 x i8> %xyzw
+ %1 = tail call <32 x i8> @llvm.x86.avx2.pblendvb(<32 x i8> %xyzw, <32 x i8> %abcd,
+ <32 x i8> <i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0,
+ i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0,
+ i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0,
+ i8 0, i8 0, i8 255, i8 0, i8 255, i8 255, i8 255, i8 0>)
+ ret <32 x i8> %1
+}
+
+declare <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8>, <16 x i8>, <16 x i8>)
+declare <4 x float> @llvm.x86.sse41.blendvps(<4 x float>, <4 x float>, <4 x float>)
+declare <2 x double> @llvm.x86.sse41.blendvpd(<2 x double>, <2 x double>, <2 x double>)
+
+declare <32 x i8> @llvm.x86.avx2.pblendvb(<32 x i8>, <32 x i8>, <32 x i8>)
+declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
+declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
diff --git a/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/test/Transforms/InstCombine/call-cast-target-inalloca.ll
new file mode 100644
index 000000000000..90289e2468f8
--- /dev/null
+++ b/test/Transforms/InstCombine/call-cast-target-inalloca.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:32:32"
+target triple = "i686-pc-linux-gnu"
+
+declare void @takes_i32(i32)
+declare void @takes_i32_inalloca(i32* inalloca)
+
+define void @f() {
+; CHECK-LABEL: define void @f()
+ %args = alloca inalloca i32
+ call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca %args)
+; CHECK: call void bitcast
+ ret void
+}
+
+define void @g() {
+; CHECK-LABEL: define void @g()
+ call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0)
+; CHECK: call void bitcast
+ ret void
+}
diff --git a/test/Transforms/InstCombine/call-cast-target.ll b/test/Transforms/InstCombine/call-cast-target.ll
index 315c51683fd2..1af3317a398b 100644
--- a/test/Transforms/InstCombine/call-cast-target.ll
+++ b/test/Transforms/InstCombine/call-cast-target.ll
@@ -13,3 +13,15 @@ entry:
declare i8* @ctime(i32*)
+define internal { i8 } @foo(i32*) {
+entry:
+ ret { i8 } { i8 0 }
+}
+
+define void @test_struct_ret() {
+; CHECK-LABEL: @test_struct_ret
+; CHECK-NOT: bitcast
+entry:
+ %0 = call { i8 } bitcast ({ i8 } (i32*)* @foo to { i8 } (i16*)*)(i16* null)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/cast-call-combine.ll b/test/Transforms/InstCombine/cast-call-combine.ll
new file mode 100644
index 000000000000..be70a8763ea8
--- /dev/null
+++ b/test/Transforms/InstCombine/cast-call-combine.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -always-inline -instcombine -S | FileCheck %s
+
+define internal void @foo(i16*) alwaysinline {
+ ret void
+}
+
+define void @bar() noinline noreturn {
+ unreachable
+}
+
+define void @test() {
+ br i1 false, label %then, label %else
+
+then:
+ call void @bar()
+ unreachable
+
+else:
+ ; CHECK-NOT: call
+ call void bitcast (void (i16*)* @foo to void (i8*)*) (i8* null)
+ ret void
+}
+
diff --git a/test/Transforms/InstCombine/cast-set.ll b/test/Transforms/InstCombine/cast-set.ll
index 893440424c4c..47ba920d9286 100644
--- a/test/Transforms/InstCombine/cast-set.ll
+++ b/test/Transforms/InstCombine/cast-set.ll
@@ -10,6 +10,7 @@ define i1 @test1(i32 %X) {
; Convert to setne int %X, 12
%c = icmp ne i32 %A, 12 ; <i1> [#uses=1]
ret i1 %c
+; CHECK-LABEL @test1(
; CHECK: %c = icmp ne i32 %X, 12
; CHECK: ret i1 %c
}
@@ -20,6 +21,7 @@ define i1 @test2(i32 %X, i32 %Y) {
; Convert to setne int %X, %Y
%c = icmp ne i32 %A, %B ; <i1> [#uses=1]
ret i1 %c
+; CHECK-LABEL @test2(
; CHECK: %c = icmp ne i32 %X, %Y
; CHECK: ret i1 %c
}
@@ -29,6 +31,7 @@ define i32 @test4(i32 %A) {
%C = shl i32 %B, 2 ; <i32> [#uses=1]
%D = bitcast i32 %C to i32 ; <i32> [#uses=1]
ret i32 %D
+; CHECK-LABEL: @test4(
; CHECK: %C = shl i32 %A, 2
; CHECK: ret i32 %C
}
@@ -38,6 +41,7 @@ define i16 @test5(i16 %A) {
%C = and i32 %B, 15 ; <i32> [#uses=1]
%D = trunc i32 %C to i16 ; <i16> [#uses=1]
ret i16 %D
+; CHECK-LABEL: @test5(
; CHECK: %C = and i16 %A, 15
; CHECK: ret i16 %C
}
@@ -46,6 +50,7 @@ define i1 @test6(i1 %A) {
%B = zext i1 %A to i32 ; <i32> [#uses=1]
%C = icmp ne i32 %B, 0 ; <i1> [#uses=1]
ret i1 %C
+; CHECK-LABEL: @test6(
; CHECK: ret i1 %A
}
@@ -53,6 +58,7 @@ define i1 @test6a(i1 %A) {
%B = zext i1 %A to i32 ; <i32> [#uses=1]
%C = icmp ne i32 %B, -1 ; <i1> [#uses=1]
ret i1 %C
+; CHECK-LABEL: @test6a(
; CHECK: ret i1 true
}
@@ -60,6 +66,7 @@ define i1 @test7(i8* %A) {
%B = bitcast i8* %A to i32* ; <i32*> [#uses=1]
%C = icmp eq i32* %B, null ; <i1> [#uses=1]
ret i1 %C
+; CHECK-LABEL: @test7(
; CHECK: %C = icmp eq i8* %A, null
; CHECK: ret i1 %C
}
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index cac0ec109163..0cbfbb071bb7 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -1,6 +1,6 @@
; Tests to make sure elimination of casts is working correctly
; RUN: opt < %s -instcombine -S | FileCheck %s
-target datalayout = "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
+target datalayout = "E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
@inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1]
@@ -370,7 +370,7 @@ define zeroext i64 @test43(i8 zeroext %on_off) nounwind readonly {
ret i64 %C ;; Should be (add (zext i8 -> i64), -1)
; CHECK-LABEL: @test43(
; CHECK-NEXT: %A = zext i8 %on_off to i64
-; CHECK-NEXT: %B = add i64 %A, -1
+; CHECK-NEXT: %B = add nsw i64 %A, -1
; CHECK-NEXT: ret i64 %B
}
@@ -708,6 +708,34 @@ define %s @test68(%s *%p, i64 %i) {
; CHECK-NEXT: ret %s
}
+; addrspacecasts should be eliminated.
+define %s @test68_addrspacecast(%s* %p, i64 %i) {
+; CHECK-LABEL: @test68_addrspacecast(
+; CHECK-NEXT: getelementptr %s*
+; CHECK-NEXT: load %s*
+; CHECK-NEXT: ret %s
+ %o = mul i64 %i, 12
+ %q = addrspacecast %s* %p to i8 addrspace(2)*
+ %pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
+ %r = addrspacecast i8 addrspace(2)* %pp to %s*
+ %l = load %s* %r
+ ret %s %l
+}
+
+define %s @test68_addrspacecast_2(%s* %p, i64 %i) {
+; CHECK-LABEL: @test68_addrspacecast_2(
+; CHECK-NEXT: getelementptr %s* %p
+; CHECK-NEXT: addrspacecast
+; CHECK-NEXT: load %s addrspace(1)*
+; CHECK-NEXT: ret %s
+ %o = mul i64 %i, 12
+ %q = addrspacecast %s* %p to i8 addrspace(2)*
+ %pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
+ %r = addrspacecast i8 addrspace(2)* %pp to %s addrspace(1)*
+ %l = load %s addrspace(1)* %r
+ ret %s %l
+}
+
define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
; CHECK-LABEL: @test68_as1(
%o = mul i32 %i, 12
@@ -903,6 +931,33 @@ define double @test80([100 x double]* %p, i32 %i) {
; CHECK-NEXT: ret double
}
+define double @test80_addrspacecast([100 x double] addrspace(1)* %p, i32 %i) {
+; CHECK-LABEL: @test80_addrspacecast(
+; CHECK-NEXT: getelementptr [100 x double] addrspace(1)* %p
+; CHECK-NEXT: load double addrspace(1)*
+; CHECK-NEXT: ret double
+ %tmp = mul nsw i32 %i, 8
+ %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
+ %pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
+ %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(1)*
+ %l = load double addrspace(1)* %r
+ ret double %l
+}
+
+define double @test80_addrspacecast_2([100 x double] addrspace(1)* %p, i32 %i) {
+; CHECK-LABEL: @test80_addrspacecast_2(
+; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
+; CHECK-NEXT: addrspacecast double addrspace(1)*
+; CHECK-NEXT: load double addrspace(3)*
+; CHECK-NEXT: ret double
+ %tmp = mul nsw i32 %i, 8
+ %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
+ %pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
+ %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(3)*
+ %l = load double addrspace(3)* %r
+ ret double %l
+}
+
define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
; CHECK-LABEL: @test80_as1(
%tmp = mul nsw i16 %i, 8
diff --git a/test/Transforms/InstCombine/ceil.ll b/test/Transforms/InstCombine/ceil.ll
new file mode 100644
index 000000000000..9f965a3c34b4
--- /dev/null
+++ b/test/Transforms/InstCombine/ceil.ll
@@ -0,0 +1,56 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+declare float @llvm.ceil.f32(float) #0
+declare double @llvm.ceil.f64(double) #0
+declare <4 x float> @llvm.ceil.v4f32(<4 x float>) #0
+
+; CHECK-LABEL: @constant_fold_ceil_f32_01
+; CHECK-NEXT: ret float 1.000000e+00
+define float @constant_fold_ceil_f32_01() #0 {
+ %x = call float @llvm.ceil.f32(float 1.00) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_f32_02
+; CHECK-NEXT: ret float 2.000000e+00
+define float @constant_fold_ceil_f32_02() #0 {
+ %x = call float @llvm.ceil.f32(float 1.25) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_f32_03
+; CHECK-NEXT: ret float -1.000000e+00
+define float @constant_fold_ceil_f32_03() #0 {
+ %x = call float @llvm.ceil.f32(float -1.25) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_v4f32_01
+; CHECK-NEXT: ret <4 x float> <float 1.000000e+00, float 2.000000e+00, float -1.000000e+00, float -1.000000e+00>
+define <4 x float> @constant_fold_ceil_v4f32_01() #0 {
+ %x = call <4 x float> @llvm.ceil.v4f32(<4 x float> <float 1.00, float 1.25, float -1.25, float -1.00>)
+ ret <4 x float> %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_f64_01
+; CHECK-NEXT: ret double 1.000000e+00
+define double @constant_fold_ceil_f64_01() #0 {
+ %x = call double @llvm.ceil.f64(double 1.0) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_f64_02
+; CHECK-NEXT: ret double 2.000000e+00
+define double @constant_fold_ceil_f64_02() #0 {
+ %x = call double @llvm.ceil.f64(double 1.3) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_ceil_f64_03
+; CHECK-NEXT: ret double -1.000000e+00
+define double @constant_fold_ceil_f64_03() #0 {
+ %x = call double @llvm.ceil.f64(double -1.75) #0
+ ret double %x
+}
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll b/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll
index 9f21d5419b72..7fac78a40f56 100644
--- a/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll
+++ b/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll
@@ -230,3 +230,13 @@ define i32 @constant_through_array_as_ptrs() {
%b = load i32 addrspace(1)* %a, align 4
ret i32 %b
}
+
+@shared_mem = external addrspace(3) global [0 x i8]
+
+define float @canonicalize_addrspacecast(i32 %i) {
+; CHECK-LABEL: @canonicalize_addrspacecast
+; CHECK-NEXT: getelementptr inbounds float* addrspacecast (float addrspace(3)* bitcast ([0 x i8] addrspace(3)* @shared_mem to float addrspace(3)*) to float*), i32 %i
+ %p = getelementptr inbounds float* addrspacecast ([0 x i8] addrspace(3)* @shared_mem to float*), i32 %i
+ %v = load float* %p
+ ret float %v
+}
diff --git a/test/Transforms/InstCombine/constant-fold-math.ll b/test/Transforms/InstCombine/constant-fold-math.ll
new file mode 100644
index 000000000000..14377df37299
--- /dev/null
+++ b/test/Transforms/InstCombine/constant-fold-math.ll
@@ -0,0 +1,47 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+declare float @llvm.fma.f32(float, float, float) #0
+declare float @llvm.fmuladd.f32(float, float, float) #0
+declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) #0
+
+declare double @llvm.fma.f64(double, double, double) #0
+declare double @llvm.fmuladd.f64(double, double, double) #0
+
+
+
+; CHECK-LABEL: @constant_fold_fma_f32
+; CHECK-NEXT: ret float 6.000000e+00
+define float @constant_fold_fma_f32() #0 {
+ %x = call float @llvm.fma.f32(float 1.0, float 2.0, float 4.0) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_fma_v4f32
+; CHECK-NEXT: ret <4 x float> <float 1.200000e+01, float 1.400000e+01, float 1.600000e+01, float 1.800000e+01>
+define <4 x float> @constant_fold_fma_v4f32() #0 {
+ %x = call <4 x float> @llvm.fma.v4f32(<4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, <4 x float> <float 2.0, float 2.0, float 2.0, float 2.0>, <4 x float> <float 10.0, float 10.0, float 10.0, float 10.0>)
+ ret <4 x float> %x
+}
+
+; CHECK-LABEL: @constant_fold_fmuladd_f32
+; CHECK-NEXT: ret float 6.000000e+00
+define float @constant_fold_fmuladd_f32() #0 {
+ %x = call float @llvm.fmuladd.f32(float 1.0, float 2.0, float 4.0) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_fma_f64
+; CHECK-NEXT: ret double 6.000000e+00
+define double @constant_fold_fma_f64() #0 {
+ %x = call double @llvm.fma.f64(double 1.0, double 2.0, double 4.0) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_fmuladd_f64
+; CHECK-NEXT: ret double 6.000000e+00
+define double @constant_fold_fmuladd_f64() #0 {
+ %x = call double @llvm.fmuladd.f64(double 1.0, double 2.0, double 4.0) #0
+ ret double %x
+}
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Transforms/InstCombine/copysign.ll b/test/Transforms/InstCombine/copysign.ll
new file mode 100644
index 000000000000..556b79999b02
--- /dev/null
+++ b/test/Transforms/InstCombine/copysign.ll
@@ -0,0 +1,49 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+declare float @llvm.copysign.f32(float, float) #0
+declare double @llvm.copysign.f64(double, double) #0
+
+; CHECK-LABEL: @constant_fold_copysign_f32_01
+; CHECK-NEXT: ret float -1.000000e+00
+define float @constant_fold_copysign_f32_01() #0 {
+ %x = call float @llvm.copysign.f32(float 1.0, float -2.0) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_copysign_f32_02
+; CHECK-NEXT: ret float 2.000000e+00
+define float @constant_fold_copysign_f32_02() #0 {
+ %x = call float @llvm.copysign.f32(float -2.0, float 1.0) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_copysign_f32_03
+; CHECK-NEXT: ret float -2.000000e+00
+define float @constant_fold_copysign_f32_03() #0 {
+ %x = call float @llvm.copysign.f32(float -2.0, float -1.0) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_copysign_f64_01
+; CHECK-NEXT: ret double -1.000000e+00
+define double @constant_fold_copysign_f64_01() #0 {
+ %x = call double @llvm.copysign.f64(double 1.0, double -2.0) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_copysign_f64_02
+; CHECK-NEXT: ret double 1.000000e+00
+define double @constant_fold_copysign_f64_02() #0 {
+ %x = call double @llvm.copysign.f64(double -1.0, double 2.0) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_copysign_f64_03
+; CHECK-NEXT: ret double -1.000000e+00
+define double @constant_fold_copysign_f64_03() #0 {
+ %x = call double @llvm.copysign.f64(double -1.0, double -2.0) #0
+ ret double %x
+}
+
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Transforms/InstCombine/descale-zero.ll b/test/Transforms/InstCombine/descale-zero.ll
new file mode 100644
index 000000000000..7990fdb3eca3
--- /dev/null
+++ b/test/Transforms/InstCombine/descale-zero.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+define internal i8* @descale_zero() {
+entry:
+; CHECK: load i16** inttoptr (i64 48 to i16**), align 16
+; CHECK-NEXT: bitcast i16*
+; CHECK-NEXT: ret i8*
+ %i16_ptr = load i16** inttoptr (i64 48 to i16**), align 16
+ %num = load i64* inttoptr (i64 64 to i64*), align 64
+ %num_times_2 = shl i64 %num, 1
+ %num_times_2_plus_4 = add i64 %num_times_2, 4
+ %i8_ptr = bitcast i16* %i16_ptr to i8*
+ %i8_ptr_num_times_2_plus_4 = getelementptr i8* %i8_ptr, i64 %num_times_2_plus_4
+ %num_times_neg2 = mul i64 %num, -2
+ %num_times_neg2_minus_4 = add i64 %num_times_neg2, -4
+ %addr = getelementptr i8* %i8_ptr_num_times_2_plus_4, i64 %num_times_neg2_minus_4
+ ret i8* %addr
+}
diff --git a/test/Transforms/InstCombine/distribute.ll b/test/Transforms/InstCombine/distribute.ll
new file mode 100644
index 000000000000..e6360f8ba64e
--- /dev/null
+++ b/test/Transforms/InstCombine/distribute.ll
@@ -0,0 +1,68 @@
+; RUN: opt < %s -instcombine -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: %z = or i32 %b, %x
+; CHECK: ret i32 %z
+}
+
+define i32 @factorize4(i32 %x, i32 %y) {
+; CHECK-LABEL: @factorize4(
+; ((Y << 1) * X) - (X * Y) -> (X * (Y * 2 - Y)) -> (X * Y)
+ %sh = shl i32 %y, 1
+ %ml = mul i32 %sh, %x
+ %mr = mul i32 %x, %y
+ %s = sub i32 %ml, %mr
+ ret i32 %s
+; CHECK: %s = mul i32 %y, %x
+; CHECK: ret i32 %s
+}
+
+define i32 @factorize5(i32 %x, i32 %y) {
+; CHECK-LABEL: @factorize5(
+; ((Y * 2) * X) - (X * Y) -> (X * Y)
+ %sh = mul i32 %y, 2
+ %ml = mul i32 %sh, %x
+ %mr = mul i32 %x, %y
+ %s = sub i32 %ml, %mr
+ ret i32 %s
+; CHECK: %s = mul i32 %y, %x
+; CHECK: ret i32 %s
+}
+
+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: %a = and i32 %x, 1
+; CHECK: ret i32 %a
+}
diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll
index f67fd1c51be3..9c7ba9b03059 100644
--- a/test/Transforms/InstCombine/div.ll
+++ b/test/Transforms/InstCombine/div.ll
@@ -131,4 +131,47 @@ define i32 @test15(i32 %a, i32 %b) nounwind {
; CHECK-NEXT: ret i32
}
+define <2 x i64> @test16(<2 x i64> %x) nounwind {
+ %shr = lshr <2 x i64> %x, <i64 3, i64 5>
+ %div = udiv <2 x i64> %shr, <i64 4, i64 6>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: udiv <2 x i64> %x, <i64 32, i64 192>
+; CHECK-NEXT: ret <2 x i64>
+}
+
+define <2 x i64> @test17(<2 x i64> %x) nounwind {
+ %neg = sub nsw <2 x i64> zeroinitializer, %x
+ %div = sdiv <2 x i64> %neg, <i64 3, i64 4>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: sdiv <2 x i64> %x, <i64 -3, i64 -4>
+; CHECK-NEXT: ret <2 x i64>
+}
+
+define <2 x i64> @test18(<2 x i64> %x) nounwind {
+ %div = sdiv <2 x i64> %x, <i64 -1, i64 -1>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: sub <2 x i64> zeroinitializer, %x
+; CHECK-NEXT: ret <2 x i64>
+}
+define i32 @test19(i32 %x) {
+ %A = udiv i32 1, %x
+ ret i32 %A
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: icmp eq i32 %x, 1
+; CHECK-NEXT: zext i1 %{{.*}} to i32
+; CHECK-NEXT ret i32
+}
+
+define i32 @test20(i32 %x) {
+ %A = sdiv i32 1, %x
+ ret i32 %A
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: add i32 %x, 1
+; CHECK-NEXT: icmp ult i32 %{{.*}}, 3
+; CHECK-NEXT: select i1 %{{.*}}, i32 %x, i32 {{.*}}
+; CHECK-NEXT: ret i32
+}
diff --git a/test/Transforms/InstCombine/double-float-shrink-1.ll b/test/Transforms/InstCombine/double-float-shrink-1.ll
index 5cacb591e006..d958470f1baa 100644
--- a/test/Transforms/InstCombine/double-float-shrink-1.ll
+++ b/test/Transforms/InstCombine/double-float-shrink-1.ll
@@ -157,7 +157,10 @@ define float @exp10_test(float %f) nounwind readnone {
%call = call double @exp10(double %conv)
%conv1 = fptrunc double %call to float
ret float %conv1
-; CHECK: call float @exp10f(float %f)
+; FIXME: Re-enable this when Linux allows transforming this again, or when we
+; can use builtin attributes to test the transform regardless of OS.
+; DISABLED-CHECK: call float @exp10f(float %f)
+; CHECK: call double @exp10(double %conv)
}
define double @exp10_test2(float %f) nounwind readnone {
diff --git a/test/Transforms/InstCombine/exp2-1.ll b/test/Transforms/InstCombine/exp2-1.ll
index 99fb9ecfd2b2..8e6a0e0d93f6 100644
--- a/test/Transforms/InstCombine/exp2-1.ll
+++ b/test/Transforms/InstCombine/exp2-1.ll
@@ -1,6 +1,7 @@
; Test that the exp2 library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
+; RUN: opt < %s -instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefix=CHECK-WIN
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
@@ -74,3 +75,26 @@ define float @test_simplify8(i8 zeroext %x) {
; CHECK: call float @ldexpf
ret float %ret
}
+
+declare double @llvm.exp2.f64(double)
+declare float @llvm.exp2.f32(float)
+
+define double @test_simplify9(i8 zeroext %x) {
+; CHECK-LABEL: @test_simplify9(
+; CHECK-WIN-LABEL: @test_simplify9(
+ %conv = uitofp i8 %x to double
+ %ret = call double @llvm.exp2.f64(double %conv)
+; CHECK: call double @ldexp
+; CHECK-WIN: call double @ldexp
+ ret double %ret
+}
+
+define float @test_simplify10(i8 zeroext %x) {
+; CHECK-LABEL: @test_simplify10(
+; CHECK-WIN-LABEL: @test_simplify10(
+ %conv = uitofp i8 %x to float
+ %ret = call float @llvm.exp2.f32(float %conv)
+; CHECK: call float @ldexpf
+; CHECK-WIN-NOT: call float @ldexpf
+ ret float %ret
+}
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index d8ba2a59ff5e..2ee4b0f2c381 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -140,6 +140,42 @@ define float @fold13(float %x) {
; CHECK: ret
}
+; -x + y => y - x
+define float @fold14(float %x, float %y) {
+ %neg = fsub fast float -0.0, %x
+ %add = fadd fast float %neg, %y
+ ret float %add
+; CHECK: fold14
+; CHECK: fsub fast float %y, %x
+; CHECK: ret
+}
+
+; x + -y => x - y
+define float @fold15(float %x, float %y) {
+ %neg = fsub fast float -0.0, %y
+ %add = fadd fast float %x, %neg
+ ret float %add
+; CHECK: fold15
+; CHECK: fsub fast float %x, %y
+; CHECK: ret
+}
+
+; (select X+Y, X-Y) => X + (select Y, -Y)
+define float @fold16(float %x, float %y) {
+ %cmp = fcmp ogt float %x, %y
+ %plus = fadd fast float %x, %y
+ %minus = fsub fast float %x, %y
+ %r = select i1 %cmp, float %plus, float %minus
+ ret float %r
+; CHECK: fold16
+; CHECK: fsub fast float
+; CHECK: select
+; CHECK: fadd fast float
+; CHECK: ret
+}
+
+
+
; =========================================================================
;
; Testing-cases about fmul begin
@@ -223,6 +259,14 @@ define float @fmul3(float %f1, float %f2) {
; CHECK: fmul fast float %f1, 3.000000e+00
}
+define <4 x float> @fmul3_vec(<4 x float> %f1, <4 x float> %f2) {
+ %t1 = fdiv <4 x float> %f1, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3>
+ %t3 = fmul fast <4 x float> %t1, <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3>
+ ret <4 x float> %t3
+; CHECK-LABEL: @fmul3_vec(
+; CHECK: fmul fast <4 x float> %f1, <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00>
+}
+
; Rule "X/C1 * C2 => X * (C2/C1) is not applicable if C2/C1 is either a special
; value of a denormal. The 0x3810000000000000 here take value FLT_MIN
;
@@ -309,6 +353,15 @@ define float @fdiv2(float %x) {
; CHECK: fmul fast float %x, 0x3FE0B21660000000
}
+define <2 x float> @fdiv2_vec(<2 x float> %x) {
+ %mul = fmul <2 x float> %x, <float 6.0, float 9.0>
+ %div1 = fdiv fast <2 x float> %mul, <float 2.0, float 3.0>
+ ret <2 x float> %div1
+
+; CHECK-LABEL: @fdiv2_vec(
+; CHECK: fmul fast <2 x float> %x, <float 3.000000e+00, float 3.000000e+00>
+}
+
; "X/C1 / C2 => X * (1/(C2*C1))" is disabled (for now) is C2/C1 is a denormal
;
define float @fdiv3(float %x) {
diff --git a/test/Transforms/InstCombine/fdiv.ll b/test/Transforms/InstCombine/fdiv.ll
index 1edbc5ecd60b..af6a2401a8fc 100644
--- a/test/Transforms/InstCombine/fdiv.ll
+++ b/test/Transforms/InstCombine/fdiv.ll
@@ -23,3 +23,29 @@ define float @test3(float %x) nounwind readnone ssp {
; CHECK-LABEL: @test3(
; CHECK-NEXT: fdiv float %x, 0x36A0000000000000
}
+
+define float @test4(float %x) nounwind readnone ssp {
+ %div = fdiv fast float %x, 8.0
+ ret float %div
+
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: fmul fast float %x, 1.250000e-01
+}
+
+define float @test5(float %x, float %y, float %z) nounwind readnone ssp {
+ %div1 = fdiv fast float %x, %y
+ %div2 = fdiv fast float %div1, %z
+ ret float %div2
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: fmul fast
+; CHECK-NEXT: fdiv fast
+}
+
+define float @test6(float %x, float %y, float %z) nounwind readnone ssp {
+ %div1 = fdiv fast float %x, %y
+ %div2 = fdiv fast float %z, %div1
+ ret float %div2
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: fmul fast
+; CHECK-NEXT: fdiv fast
+}
diff --git a/test/Transforms/InstCombine/ffs-1.ll b/test/Transforms/InstCombine/ffs-1.ll
index 1dec11da0eb0..c8763dc199a9 100644
--- a/test/Transforms/InstCombine/ffs-1.ll
+++ b/test/Transforms/InstCombine/ffs-1.ll
@@ -103,7 +103,7 @@ define i32 @test_simplify13(i32 %x) {
; CHECK-LABEL: @test_simplify13(
%ret = call i32 @ffs(i32 %x)
; CHECK-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false)
-; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1
+; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
; CHECK-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
ret i32 %ret
@@ -114,7 +114,7 @@ define i32 @test_simplify14(i32 %x) {
; CHECK-LINUX-LABEL: @test_simplify14(
%ret = call i32 @ffsl(i32 %x)
; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false)
-; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1
+; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1
; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
ret i32 %ret
@@ -125,7 +125,7 @@ define i32 @test_simplify15(i64 %x) {
; CHECK-LINUX-LABEL: @test_simplify15(
%ret = call i32 @ffsll(i64 %x)
; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %x, i1 false)
-; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i64 [[CTTZ]], 1
+; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i64 [[CTTZ]], 1
; CHECK-LINUX-NEXT: [[TRUNC:%[a-z0-9]+]] = trunc i64 [[INC]] to i32
; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i64 %x, 0
; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[TRUNC]], i32 0
diff --git a/test/Transforms/InstCombine/float-shrink-compare.ll b/test/Transforms/InstCombine/float-shrink-compare.ll
index 26f77a7f702b..e50046790da8 100644
--- a/test/Transforms/InstCombine/float-shrink-compare.ll
+++ b/test/Transforms/InstCombine/float-shrink-compare.ll
@@ -170,6 +170,58 @@ define i32 @test14(float %x, float %y) nounwind uwtable {
; CHECK-NEXT: fcmp oeq float %truncf, %y
}
+define i32 @test15(float %x, float %y, float %z) nounwind uwtable {
+ %1 = fpext float %x to double
+ %2 = fpext float %y to double
+ %3 = call double @fmin(double %1, double %2) nounwind
+ %4 = fpext float %z to double
+ %5 = fcmp oeq double %3, %4
+ %6 = zext i1 %5 to i32
+ ret i32 %6
+; CHECK-LABEL: @test15(
+; CHECK-NEXT: %fminf = call float @fminf(float %x, float %y)
+; CHECK-NEXT: fcmp oeq float %fminf, %z
+}
+
+define i32 @test16(float %x, float %y, float %z) nounwind uwtable {
+ %1 = fpext float %z to double
+ %2 = fpext float %x to double
+ %3 = fpext float %y to double
+ %4 = call double @fmin(double %2, double %3) nounwind
+ %5 = fcmp oeq double %1, %4
+ %6 = zext i1 %5 to i32
+ ret i32 %6
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: %fminf = call float @fminf(float %x, float %y)
+; CHECK-NEXT: fcmp oeq float %fminf, %z
+}
+
+define i32 @test17(float %x, float %y, float %z) nounwind uwtable {
+ %1 = fpext float %x to double
+ %2 = fpext float %y to double
+ %3 = call double @fmax(double %1, double %2) nounwind
+ %4 = fpext float %z to double
+ %5 = fcmp oeq double %3, %4
+ %6 = zext i1 %5 to i32
+ ret i32 %6
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: %fmaxf = call float @fmaxf(float %x, float %y)
+; CHECK-NEXT: fcmp oeq float %fmaxf, %z
+}
+
+define i32 @test18(float %x, float %y, float %z) nounwind uwtable {
+ %1 = fpext float %z to double
+ %2 = fpext float %x to double
+ %3 = fpext float %y to double
+ %4 = call double @fmax(double %2, double %3) nounwind
+ %5 = fcmp oeq double %1, %4
+ %6 = zext i1 %5 to i32
+ ret i32 %6
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: %fmaxf = call float @fmaxf(float %x, float %y)
+; CHECK-NEXT: fcmp oeq float %fmaxf, %z
+}
+
declare double @fabs(double) nounwind readnone
declare double @ceil(double) nounwind readnone
declare double @floor(double) nounwind readnone
@@ -177,3 +229,5 @@ declare double @nearbyint(double) nounwind readnone
declare double @rint(double) nounwind readnone
declare double @round(double) nounwind readnone
declare double @trunc(double) nounwind readnone
+declare double @fmin(double, double) nounwind readnone
+declare double @fmax(double, double) nounwind readnone
diff --git a/test/Transforms/InstCombine/fmul.ll b/test/Transforms/InstCombine/fmul.ll
index 402ee52e624a..18cbf9da5361 100644
--- a/test/Transforms/InstCombine/fmul.ll
+++ b/test/Transforms/InstCombine/fmul.ll
@@ -24,10 +24,10 @@ define float @test2(float %x) {
define float @test3(float %x, float %y) {
%sub1 = fsub float -0.000000e+00, %x
%sub2 = fsub float -0.000000e+00, %y
- %mul = fmul float %sub1, %sub2
+ %mul = fmul fast float %sub1, %sub2
ret float %mul
; CHECK-LABEL: @test3(
-; CHECK: fmul float %x, %y
+; CHECK: fmul fast float %x, %y
}
; (0.0 - X) * (0.0 - Y) => X * Y
@@ -93,3 +93,33 @@ for.body: ; preds = %for.cond
for.end: ; preds = %for.cond
ret void
}
+
+; X * -1.0 => -0.0 - X
+define float @test9(float %x) {
+ %mul = fmul float %x, -1.0
+ ret float %mul
+
+; CHECK-LABEL: @test9(
+; CHECK-NOT: fmul
+; CHECK: fsub
+}
+
+; PR18532
+define <4 x float> @test10(<4 x float> %x) {
+ %mul = fmul <4 x float> %x, <float -1.0, float -1.0, float -1.0, float -1.0>
+ ret <4 x float> %mul
+
+; CHECK-LABEL: @test10(
+; CHECK-NOT: fmul
+; CHECK: fsub
+}
+
+define float @test11(float %x, float %y) {
+ %a = fadd fast float %x, 1.0
+ %b = fadd fast float %y, 2.0
+ %c = fadd fast float %a, %b
+ ret float %c
+; CHECK-LABEL: @test11(
+; CHECK-NOT: fadd float
+; CHECK: fadd fast float
+}
diff --git a/test/Transforms/InstCombine/fpcast.ll b/test/Transforms/InstCombine/fpcast.ll
index 05d1b48d5996..9be66fd42c68 100644
--- a/test/Transforms/InstCombine/fpcast.ll
+++ b/test/Transforms/InstCombine/fpcast.ll
@@ -31,6 +31,15 @@ define half @test4(float %a) {
ret half %c
}
+; CHECK: test4-fast
+define half @test4-fast(float %a) {
+; CHECK: fptrunc
+; CHECK: fsub fast
+ %b = fsub fast float -0.0, %a
+ %c = fptrunc float %b to half
+ ret half %c
+}
+
; CHECK: test5
define half @test5(float %a, float %b, float %c) {
; CHECK: fcmp ogt
diff --git a/test/Transforms/InstCombine/fpextend.ll b/test/Transforms/InstCombine/fpextend.ll
index 70e0c62dd70e..8640cd2b6f5c 100644
--- a/test/Transforms/InstCombine/fpextend.ll
+++ b/test/Transforms/InstCombine/fpextend.ll
@@ -1,3 +1,4 @@
+
; RUN: opt < %s -instcombine -S | not grep fpext
@X = external global float
@Y = external global float
@@ -12,6 +13,18 @@ entry:
ret void
}
+define void @test2() nounwind {
+entry:
+ %tmp = load float* @X, align 4 ; <float> [#uses=1]
+ %tmp1 = fpext float %tmp to double ; <double> [#uses=1]
+ %tmp2 = load float* @Y, align 4 ; <float> [#uses=1]
+ %tmp23 = fpext float %tmp2 to double ; <double> [#uses=1]
+ %tmp5 = fmul double %tmp1, %tmp23 ; <double> [#uses=1]
+ %tmp56 = fptrunc double %tmp5 to float ; <float> [#uses=1]
+ store float %tmp56, float* @X, align 4
+ ret void
+}
+
define void @test3() nounwind {
entry:
%tmp = load float* @X, align 4 ; <float> [#uses=1]
@@ -33,4 +46,3 @@ entry:
store float %tmp34, float* @X, align 4
ret void
}
-
diff --git a/test/Transforms/InstCombine/fpextend_x86.ll b/test/Transforms/InstCombine/fpextend_x86.ll
new file mode 100644
index 000000000000..e012551ebdf4
--- /dev/null
+++ b/test/Transforms/InstCombine/fpextend_x86.ll
@@ -0,0 +1,57 @@
+; RUN: opt < %s -instcombine -mtriple=x86_64-apple-macosx -S | FileCheck %s
+target triple = "x86_64-apple-macosx"
+
+define double @test1(double %a, double %b) nounwind {
+ %wa = fpext double %a to x86_fp80
+ %wb = fpext double %b to x86_fp80
+ %wr = fadd x86_fp80 %wa, %wb
+ %r = fptrunc x86_fp80 %wr to double
+ ret double %r
+; CHECK: test1
+; CHECK: fadd x86_fp80
+; CHECK: ret
+}
+
+define double @test2(double %a, double %b) nounwind {
+ %wa = fpext double %a to x86_fp80
+ %wb = fpext double %b to x86_fp80
+ %wr = fsub x86_fp80 %wa, %wb
+ %r = fptrunc x86_fp80 %wr to double
+ ret double %r
+; CHECK: test2
+; CHECK: fsub x86_fp80
+; CHECK: ret
+}
+
+define double @test3(double %a, double %b) nounwind {
+ %wa = fpext double %a to x86_fp80
+ %wb = fpext double %b to x86_fp80
+ %wr = fmul x86_fp80 %wa, %wb
+ %r = fptrunc x86_fp80 %wr to double
+ ret double %r
+; CHECK: test3
+; CHECK: fmul x86_fp80
+; CHECK: ret
+}
+
+define double @test4(double %a, half %b) nounwind {
+ %wa = fpext double %a to x86_fp80
+ %wb = fpext half %b to x86_fp80
+ %wr = fmul x86_fp80 %wa, %wb
+ %r = fptrunc x86_fp80 %wr to double
+ ret double %r
+; CHECK: test4
+; CHECK: fmul double
+; CHECK: ret
+}
+
+define double @test5(double %a, double %b) nounwind {
+ %wa = fpext double %a to x86_fp80
+ %wb = fpext double %b to x86_fp80
+ %wr = fdiv x86_fp80 %wa, %wb
+ %r = fptrunc x86_fp80 %wr to double
+ ret double %r
+; CHECK: test5
+; CHECK: fdiv x86_fp80
+; CHECK: ret
+}
diff --git a/test/Transforms/InstCombine/fprintf-1.ll b/test/Transforms/InstCombine/fprintf-1.ll
index 3f6a314e3472..6741345839a0 100644
--- a/test/Transforms/InstCombine/fprintf-1.ll
+++ b/test/Transforms/InstCombine/fprintf-1.ll
@@ -56,18 +56,18 @@ define void @test_simplify4(%FILE* %fp) {
; CHECK-IPRINTF-LABEL: @test_simplify4(
%fmt = getelementptr [3 x i8]* @percent_d, i32 0, i32 0
call i32 (%FILE*, i8*, ...)* @fprintf(%FILE* %fp, i8* %fmt, i32 187)
-; CHECK-NEXT-IPRINTF: call i32 (%FILE*, i8*, ...)* @fiprintf(%FILE* %fp, i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-IPRINTF-NEXT: call i32 (%FILE*, i8*, ...)* @fiprintf(%FILE* %fp, i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify1(%FILE* %fp) {
; CHECK-IPRINTF-LABEL: @test_no_simplify1(
%fmt = getelementptr [3 x i8]* @percent_f, i32 0, i32 0
call i32 (%FILE*, i8*, ...)* @fprintf(%FILE* %fp, i8* %fmt, double 1.87)
-; CHECK-NEXT-IPRINTF: call i32 (%FILE*, i8*, ...)* @fprintf(%FILE* %fp, i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-IPRINTF-NEXT: call i32 (%FILE*, i8*, ...)* @fprintf(%FILE* %fp, i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify2(%FILE* %fp, double %d) {
diff --git a/test/Transforms/InstCombine/gep-addrspace.ll b/test/Transforms/InstCombine/gep-addrspace.ll
index 24c355d817e5..29511a3c6677 100644
--- a/test/Transforms/InstCombine/gep-addrspace.ll
+++ b/test/Transforms/InstCombine/gep-addrspace.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S
+; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-win32"
@@ -17,3 +17,18 @@ ST:
ret void
}
+@array = internal addrspace(3) global [256 x float] zeroinitializer, align 4
+@scalar = internal addrspace(3) global float 0.000000e+00, align 4
+
+define void @keep_necessary_addrspacecast(i64 %i, float** %out0, float** %out1) {
+entry:
+; CHECK-LABEL: @keep_necessary_addrspacecast
+ %0 = getelementptr [256 x float]* addrspacecast ([256 x float] addrspace(3)* @array to [256 x float]*), i64 0, i64 %i
+; CHECK: addrspacecast float addrspace(3)* %{{[0-9]+}} to float*
+ %1 = getelementptr [0 x float]* addrspacecast (float addrspace(3)* @scalar to [0 x float]*), i64 0, i64 %i
+; CHECK: addrspacecast float addrspace(3)* %{{[0-9]+}} to float*
+ store float* %0, float** %out0, align 4
+ store float* %1, float** %out1, align 4
+ ret void
+}
+
diff --git a/test/Transforms/InstCombine/gepphigep.ll b/test/Transforms/InstCombine/gepphigep.ll
new file mode 100644
index 000000000000..9aab609901e2
--- /dev/null
+++ b/test/Transforms/InstCombine/gepphigep.ll
@@ -0,0 +1,56 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+%struct1 = type { %struct2*, i32, i32, i32 }
+%struct2 = type { i32, i32 }
+
+define i32 @test1(%struct1* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {
+bb:
+ %tmp = getelementptr inbounds %struct1* %dm, i64 0, i32 0
+ %tmp1 = load %struct2** %tmp, align 8
+ br i1 %tmp4, label %bb1, label %bb2
+
+bb1:
+ %tmp10 = getelementptr inbounds %struct2* %tmp1, i64 %tmp9
+ %tmp11 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 0
+ store i32 0, i32* %tmp11, align 4
+ br label %bb3
+
+bb2:
+ %tmp20 = getelementptr inbounds %struct2* %tmp1, i64 %tmp19
+ %tmp21 = getelementptr inbounds %struct2* %tmp20, i64 0, i32 0
+ store i32 0, i32* %tmp21, align 4
+ br label %bb3
+
+bb3:
+ %phi = phi %struct2* [ %tmp10, %bb1 ], [ %tmp20, %bb2 ]
+ %tmp24 = getelementptr inbounds %struct2* %phi, i64 0, i32 1
+ %tmp25 = load i32* %tmp24, align 4
+ ret i32 %tmp25
+
+; CHECK-LABEL: @test1(
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 0
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp19, i32 0
+; CHECK: %[[PHI:[0-9A-Za-z]+]] = phi i64 [ %tmp9, %bb1 ], [ %tmp19, %bb2 ]
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %[[PHI]], i32 1
+
+}
+
+define i32 @test2(%struct1* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {
+bb:
+ %tmp = getelementptr inbounds %struct1* %dm, i64 0, i32 0
+ %tmp1 = load %struct2** %tmp, align 8
+ %tmp10 = getelementptr inbounds %struct2* %tmp1, i64 %tmp9
+ %tmp11 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 0
+ store i32 0, i32* %tmp11, align 4
+ %tmp20 = getelementptr inbounds %struct2* %tmp1, i64 %tmp19
+ %tmp21 = getelementptr inbounds %struct2* %tmp20, i64 0, i32 0
+ store i32 0, i32* %tmp21, align 4
+ %tmp24 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 1
+ %tmp25 = load i32* %tmp24, align 4
+ ret i32 %tmp25
+
+; CHECK-LABEL: @test2(
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 0
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp19, i32 0
+; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 1
+}
diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll
index c29a7dccb8ee..3240c6d2a4d0 100644
--- a/test/Transforms/InstCombine/getelementptr.ll
+++ b/test/Transforms/InstCombine/getelementptr.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32"
+target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
%intstruct = type { i32 }
%pair = type { i32, i32 }
@@ -728,6 +728,20 @@ define i64 @test_gep_bitcast_array_same_size_element([100 x double]* %arr, i64 %
ret i64 %x
}
+; gep should be done in the original address space.
+define i64 @test_gep_bitcast_array_same_size_element_addrspacecast([100 x double]* %arr, i64 %N) {
+; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast(
+; CHECK: getelementptr [100 x double]* %arr, i64 0, i64 %V
+; CHECK-NEXT: bitcast double*
+; CHECK-NEXT: %t = addrspacecast i64*
+; CHECK: load i64 addrspace(3)* %t
+ %cast = addrspacecast [100 x double]* %arr to i64 addrspace(3)*
+ %V = mul i64 %N, 8
+ %t = getelementptr i64 addrspace(3)* %cast, i64 %V
+ %x = load i64 addrspace(3)* %t
+ ret i64 %x
+}
+
; The element size of the array is different the element size of the pointer
define i8 @test_gep_bitcast_array_different_size_element([100 x double]* %arr, i64 %N) {
; CHECK-LABEL: @test_gep_bitcast_array_different_size_element(
@@ -789,4 +803,25 @@ define i16 @test41([3 x i32] addrspace(1)* %array) {
; CHECK-NEXT: ret i16 8
}
+define i32 addrspace(1)* @ascast_0_gep(i32* %p) nounwind {
+; CHECK-LABEL: @ascast_0_gep(
+; CHECK-NOT: getelementptr
+; CHECK: ret
+ %gep = getelementptr i32* %p, i32 0
+ %x = addrspacecast i32* %gep to i32 addrspace(1)*
+ ret i32 addrspace(1)* %x
+}
+
+; Do not merge the GEP and the addrspacecast, because it would undo the
+; addrspacecast canonicalization.
+define i32 addrspace(1)* @ascast_0_0_gep([128 x i32]* %p) nounwind {
+; CHECK-LABEL: @ascast_0_0_gep(
+; CHECK-NEXT: getelementptr [128 x i32]
+; CHECK-NEXT: addrspacecast i32*
+; CHECK-NEXT: ret i32 addrspace(1)*
+ %gep = getelementptr [128 x i32]* %p, i32 0, i32 0
+ %x = addrspacecast i32* %gep to i32 addrspace(1)*
+ ret i32 addrspace(1)* %x
+}
+
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 12a4744cc0fe..26e144f93a57 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -1,7 +1,6 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-target datalayout =
-"e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
define i32 @test1(i32 %X) {
entry:
@@ -166,6 +165,14 @@ define i1 @test17(i32 %x) nounwind {
; CHECK-NEXT: %cmp = icmp ne i32 %x, 3
}
+define i1 @test17a(i32 %x) nounwind {
+ %shl = shl i32 1, %x
+ %and = and i32 %shl, 7
+ %cmp = icmp eq i32 %and, 0
+ ret i1 %cmp
+; CHECK-LABEL: @test17a(
+; CHECK-NEXT: %cmp = icmp ugt i32 %x, 2
+}
define i1 @test18(i32 %x) nounwind {
%sh = lshr i32 8, %x
@@ -194,6 +201,15 @@ define i1 @test20(i32 %x) nounwind {
; CHECK-NEXT: %cmp = icmp eq i32 %x, 3
}
+define i1 @test20a(i32 %x) nounwind {
+ %shl = shl i32 1, %x
+ %and = and i32 %shl, 7
+ %cmp = icmp ne i32 %and, 0
+ ret i1 %cmp
+; CHECK-LABEL: @test20a(
+; CHECK-NEXT: %cmp = icmp ult i32 %x, 3
+}
+
define i1 @test21(i8 %x, i8 %y) {
; CHECK-LABEL: @test21(
; CHECK-NOT: or i8
@@ -657,6 +673,49 @@ define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
; CHECK-NEXT: ret i1
}
+; Same as test60, but look through an addrspacecast instead of a
+; bitcast. This uses the same sized addrspace.
+define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
+ %bit = addrspacecast i8* %foo to i32 addrspace(3)*
+ %gep1 = getelementptr inbounds i32 addrspace(3)* %bit, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; CHECK-LABEL: @test60_addrspacecast(
+; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
+; CHECK-NEXT: icmp slt i64 %gep1.idx, %j
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
+ %bit = addrspacecast i8* %foo to i32 addrspace(1)*
+ %gep1 = getelementptr inbounds i32 addrspace(1)* %bit, i16 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; CHECK-LABEL: @test60_addrspacecast_smaller(
+; CHECK-NEXT: %gep1.idx = shl nuw i16 %i, 2
+; CHECK-NEXT: trunc i64 %j to i16
+; CHECK-NEXT: icmp sgt i16 %1, %gep1.idx
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
+ %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
+ %gep1 = getelementptr inbounds i32 addrspace(2)* %bit, i32 %i
+ %gep2 = getelementptr inbounds i8 addrspace(1)* %foo, i16 %j
+ %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
+ %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
+ ret i1 %cmp
+; CHECK-LABEL: @test60_addrspacecast_larger(
+; CHECK-NEXT: %gep1.idx = shl nuw i32 %i, 2
+; CHECK-NEXT: trunc i32 %gep1.idx to i16
+; CHECK-NEXT: icmp slt i16 %1, %j
+; CHECK-NEXT: ret i1
+}
+
define i1 @test61(i8* %foo, i64 %i, i64 %j) {
%bit = bitcast i8* %foo to i32*
%gep1 = getelementptr i32* %bit, i64 %i
@@ -1356,3 +1415,12 @@ define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) nounwind {
%z = icmp ne i32 %x, %y
ret i1 %z
}
+
+; CHECK-LABEL: @icmp_neg_cst_slt
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %a, 10
+; CHECK-NEXT: ret i1 [[CMP]]
+define i1 @icmp_neg_cst_slt(i32 %a) {
+ %1 = sub nsw i32 0, %a
+ %2 = icmp slt i32 %1, -10
+ ret i1 %2
+}
diff --git a/test/Transforms/InstCombine/insert-extract-shuffle.ll b/test/Transforms/InstCombine/insert-extract-shuffle.ll
new file mode 100644
index 000000000000..8929c82def7b
--- /dev/null
+++ b/test/Transforms/InstCombine/insert-extract-shuffle.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S -instcombine %s | FileCheck %s
+
+define <1 x i8> @test1(<8 x i8> %in) {
+; CHECK-LABEL: @test1
+; CHECK: shufflevector <8 x i8> %in, <8 x i8> undef, <1 x i32> <i32 5>
+ %val = extractelement <8 x i8> %in, i32 5
+ %vec = insertelement <1 x i8> undef, i8 %val, i32 0
+ ret <1 x i8> %vec
+}
+
+define <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {
+; CHECK-LABEL: @test2
+; CHECK: shufflevector <8 x i16> %in2, <8 x i16> %in, <4 x i32> <i32 11, i32 9, i32 0, i32 10>
+ %elt0 = extractelement <8 x i16> %in, i32 3
+ %elt1 = extractelement <8 x i16> %in, i32 1
+ %elt2 = extractelement <8 x i16> %in2, i32 0
+ %elt3 = extractelement <8 x i16> %in, i32 2
+
+ %vec.0 = insertelement <4 x i16> undef, i16 %elt0, i32 0
+ %vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 1
+ %vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 2
+ %vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 3
+
+ ret <4 x i16> %vec.3
+}
+
+define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) #0 {
+; CHECK-LABEL: @test_vcopyq_lane_p64
+; CHECK: extractelement
+; CHECK: insertelement
+; CHECK-NOT: shufflevector
+entry:
+ %elt = extractelement <1 x i64> %b, i32 0
+ %res = insertelement <2 x i64> %a, i64 %elt, i32 1
+ ret <2 x i64> %res
+}
+
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index 91c44704ce78..9b58d9386f58 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -3,6 +3,7 @@
%overflow.result = type {i8, i1}
declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
+declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
declare double @llvm.powi.f64(double, i32) nounwind readonly
declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
@@ -89,6 +90,18 @@ define i8 @uaddtest7(i8 %A, i8 %B) {
; CHECK-NEXT: ret i8 %z
}
+; PR20194
+define { i32, i1 } @saddtest1(i8 %a, i8 %b) {
+ %A = sext i8 %a to i32
+ %B = sext i8 %b to i32
+ %x = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %A, i32 %B)
+ ret { i32, i1 } %x
+; CHECK-LABEL: @saddtest1
+; CHECK: %x = add nsw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret { i32, i1 } %1
+}
+
define i8 @umultest1(i8 %A, i1* %overflowPtr) {
%x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
diff --git a/test/Transforms/InstCombine/load-addrspace-cast.ll b/test/Transforms/InstCombine/load-addrspace-cast.ll
new file mode 100644
index 000000000000..fd6339cc9262
--- /dev/null
+++ b/test/Transforms/InstCombine/load-addrspace-cast.ll
@@ -0,0 +1,12 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-n8:16:32:64"
+
+define i32* @pointer_to_addrspace_pointer(i32 addrspace(1)** %x) nounwind {
+; CHECK-LABEL: @pointer_to_addrspace_pointer(
+; CHECK: load
+; CHECK: addrspacecast
+ %y = bitcast i32 addrspace(1)** %x to i32**
+ %z = load i32** %y
+ ret i32* %z
+}
+
diff --git a/test/Transforms/InstCombine/load.ll b/test/Transforms/InstCombine/load.ll
index d11e08e10de9..c8ce70a5c03a 100644
--- a/test/Transforms/InstCombine/load.ll
+++ b/test/Transforms/InstCombine/load.ll
@@ -1,6 +1,7 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
; This test makes sure that these instructions are properly eliminated.
-;
-; RUN: opt < %s -instcombine -S | not grep load
+
@X = constant i32 42 ; <i32*> [#uses=2]
@X2 = constant i32 47 ; <i32*> [#uses=1]
@@ -10,47 +11,63 @@
@GLOBAL = internal constant [4 x i32] zeroinitializer
+; CHECK-LABEL: @test1(
+; CHECK-NOT: load
define i32 @test1() {
%B = load i32* @X ; <i32> [#uses=1]
ret i32 %B
}
+; CHECK-LABEL: @test2(
+; CHECK-NOT: load
define float @test2() {
%A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 1, i32 1 ; <float*> [#uses=1]
%B = load float* %A ; <float> [#uses=1]
ret float %B
}
+; CHECK-LABEL: @test3(
+; CHECK-NOT: load
define i32 @test3() {
%A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; <i32*> [#uses=1]
%B = load i32* %A ; <i32> [#uses=1]
ret i32 %B
}
+; CHECK-LABEL: @test4(
+; CHECK-NOT: load
define i32 @test4() {
%A = getelementptr [2 x { i32, float }]* @Z, i64 0, i64 1, i32 0 ; <i32*> [#uses=1]
%B = load i32* %A ; <i32> [#uses=1]
ret i32 %B
}
+; CHECK-LABEL: @test5(
+; CHECK-NOT: load
define i32 @test5(i1 %C) {
%Y = select i1 %C, i32* @X, i32* @X2 ; <i32*> [#uses=1]
%Z = load i32* %Y ; <i32> [#uses=1]
ret i32 %Z
}
+; CHECK-LABEL: @test7(
+; CHECK-NOT: load
define i32 @test7(i32 %X) {
%V = getelementptr i32* null, i32 %X ; <i32*> [#uses=1]
%R = load i32* %V ; <i32> [#uses=1]
ret i32 %R
}
+; CHECK-LABEL: @test8(
+; CHECK-NOT: load
define i32 @test8(i32* %P) {
store i32 1, i32* %P
%X = load i32* %P ; <i32> [#uses=1]
ret i32 %X
}
+; CHECK-LABEL: @test9(
+; CHECK-NOT: load
define i32 @test9(i32* %P) {
%X = load i32* %P ; <i32> [#uses=1]
%Y = load i32* %P ; <i32> [#uses=1]
@@ -58,6 +75,8 @@ define i32 @test9(i32* %P) {
ret i32 %Z
}
+; CHECK-LABEL: @test10(
+; CHECK-NOT: load
define i32 @test10(i1 %C.upgrd.1, i32* %P, i32* %Q) {
br i1 %C.upgrd.1, label %T, label %F
T: ; preds = %0
@@ -72,6 +91,8 @@ C: ; preds = %F, %T
ret i32 %V
}
+; CHECK-LABEL: @test11(
+; CHECK-NOT: load
define double @test11(double* %p) {
%t0 = getelementptr double* %p, i32 1
store double 2.0, double* %t0
@@ -80,19 +101,20 @@ define double @test11(double* %p) {
ret double %x
}
+; CHECK-LABEL: @test12(
+; CHECK-NOT: load
define i32 @test12(i32* %P) {
- %A = alloca i32
- store i32 123, i32* %A
- ; Cast the result of the load not the source
- %Q = bitcast i32* %A to i32*
- %V = load i32* %Q
- ret i32 %V
+ %A = alloca i32
+ store i32 123, i32* %A
+ ; Cast the result of the load not the source
+ %Q = bitcast i32* %A to i32*
+ %V = load i32* %Q
+ ret i32 %V
}
+; CHECK-LABEL: @test13(
+; CHECK-NOT: load
define <16 x i8> @test13(<2 x i64> %x) {
-entry:
- %tmp = load <16 x i8> * bitcast ([4 x i32]* @GLOBAL to <16 x i8>*)
- ret <16 x i8> %tmp
+ %tmp = load <16 x i8>* bitcast ([4 x i32]* @GLOBAL to <16 x i8>*)
+ ret <16 x i8> %tmp
}
-
-
diff --git a/test/Transforms/InstCombine/loadstore-alignment.ll b/test/Transforms/InstCombine/loadstore-alignment.ll
index 2263cb20ec5e..e90bdb7cdd99 100644
--- a/test/Transforms/InstCombine/loadstore-alignment.ll
+++ b/test/Transforms/InstCombine/loadstore-alignment.ll
@@ -1,67 +1,117 @@
-; RUN: opt < %s -instcombine -S | grep ", align 16" | count 14
-target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+; RUN: opt -instcombine -S < %s | FileCheck %s
+target datalayout = "E-p:64:64:64-p1:64:64:64-p2:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
@x = external global <2 x i64>, align 16
@xx = external global [13 x <2 x i64>], align 16
+@x.as2 = external addrspace(2) global <2 x i64>, align 16
+
+; CHECK-LABEL: @static_hem(
+; CHECK: , align 16
define <2 x i64> @static_hem() {
- %t = getelementptr <2 x i64>* @x, i32 7
- %tmp1 = load <2 x i64>* %t, align 1
- ret <2 x i64> %tmp1
+ %t = getelementptr <2 x i64>* @x, i32 7
+ %tmp1 = load <2 x i64>* %t, align 1
+ ret <2 x i64> %tmp1
+}
+
+; CHECK-LABEL: @static_hem_addrspacecast(
+; CHECK: , align 16
+define <2 x i64> @static_hem_addrspacecast() {
+ %t = getelementptr <2 x i64>* @x, i32 7
+ %t.asc = addrspacecast <2 x i64>* %t to <2 x i64> addrspace(1)*
+ %tmp1 = load <2 x i64> addrspace(1)* %t.asc, align 1
+ ret <2 x i64> %tmp1
+}
+
+; CHECK-LABEL: @static_hem_addrspacecast_smaller_ptr(
+; CHECK: , align 16
+define <2 x i64> @static_hem_addrspacecast_smaller_ptr() {
+ %t = getelementptr <2 x i64>* @x, i32 7
+ %t.asc = addrspacecast <2 x i64>* %t to <2 x i64> addrspace(2)*
+ %tmp1 = load <2 x i64> addrspace(2)* %t.asc, align 1
+ ret <2 x i64> %tmp1
+}
+
+; CHECK-LABEL: @static_hem_addrspacecast_larger_ptr(
+; CHECK: , align 16
+define <2 x i64> @static_hem_addrspacecast_larger_ptr() {
+ %t = getelementptr <2 x i64> addrspace(2)* @x.as2, i32 7
+ %t.asc = addrspacecast <2 x i64> addrspace(2)* %t to <2 x i64> addrspace(1)*
+ %tmp1 = load <2 x i64> addrspace(1)* %t.asc, align 1
+ ret <2 x i64> %tmp1
}
+; CHECK-LABEL: @hem(
+; CHECK: , align 16
define <2 x i64> @hem(i32 %i) {
- %t = getelementptr <2 x i64>* @x, i32 %i
- %tmp1 = load <2 x i64>* %t, align 1
- ret <2 x i64> %tmp1
+ %t = getelementptr <2 x i64>* @x, i32 %i
+ %tmp1 = load <2 x i64>* %t, align 1
+ ret <2 x i64> %tmp1
}
+; CHECK-LABEL: @hem_2d(
+; CHECK: , align 16
define <2 x i64> @hem_2d(i32 %i, i32 %j) {
- %t = getelementptr [13 x <2 x i64>]* @xx, i32 %i, i32 %j
- %tmp1 = load <2 x i64>* %t, align 1
- ret <2 x i64> %tmp1
+ %t = getelementptr [13 x <2 x i64>]* @xx, i32 %i, i32 %j
+ %tmp1 = load <2 x i64>* %t, align 1
+ ret <2 x i64> %tmp1
}
+; CHECK-LABEL: @foo(
+; CHECK: , align 16
define <2 x i64> @foo() {
- %tmp1 = load <2 x i64>* @x, align 1
- ret <2 x i64> %tmp1
+ %tmp1 = load <2 x i64>* @x, align 1
+ ret <2 x i64> %tmp1
}
+; CHECK-LABEL: @bar(
+; CHECK: , align 16
+; CHECK: , align 16
define <2 x i64> @bar() {
- %t = alloca <2 x i64>
- call void @kip(<2 x i64>* %t)
- %tmp1 = load <2 x i64>* %t, align 1
- ret <2 x i64> %tmp1
+ %t = alloca <2 x i64>
+ call void @kip(<2 x i64>* %t)
+ %tmp1 = load <2 x i64>* %t, align 1
+ ret <2 x i64> %tmp1
}
+; CHECK-LABEL: @static_hem_store(
+; CHECK: , align 16
define void @static_hem_store(<2 x i64> %y) {
- %t = getelementptr <2 x i64>* @x, i32 7
- store <2 x i64> %y, <2 x i64>* %t, align 1
- ret void
+ %t = getelementptr <2 x i64>* @x, i32 7
+ store <2 x i64> %y, <2 x i64>* %t, align 1
+ ret void
}
+; CHECK-LABEL: @hem_store(
+; CHECK: , align 16
define void @hem_store(i32 %i, <2 x i64> %y) {
- %t = getelementptr <2 x i64>* @x, i32 %i
- store <2 x i64> %y, <2 x i64>* %t, align 1
- ret void
+ %t = getelementptr <2 x i64>* @x, i32 %i
+ store <2 x i64> %y, <2 x i64>* %t, align 1
+ ret void
}
+; CHECK-LABEL: @hem_2d_store(
+; CHECK: , align 16
define void @hem_2d_store(i32 %i, i32 %j, <2 x i64> %y) {
- %t = getelementptr [13 x <2 x i64>]* @xx, i32 %i, i32 %j
- store <2 x i64> %y, <2 x i64>* %t, align 1
- ret void
+ %t = getelementptr [13 x <2 x i64>]* @xx, i32 %i, i32 %j
+ store <2 x i64> %y, <2 x i64>* %t, align 1
+ ret void
}
+; CHECK-LABEL: @foo_store(
+; CHECK: , align 16
define void @foo_store(<2 x i64> %y) {
- store <2 x i64> %y, <2 x i64>* @x, align 1
- ret void
+ store <2 x i64> %y, <2 x i64>* @x, align 1
+ ret void
}
+; CHECK-LABEL: @bar_store(
+; CHECK: , align 16
define void @bar_store(<2 x i64> %y) {
- %t = alloca <2 x i64>
- call void @kip(<2 x i64>* %t)
- store <2 x i64> %y, <2 x i64>* %t, align 1
- ret void
+ %t = alloca <2 x i64>
+ call void @kip(<2 x i64>* %t)
+ store <2 x i64> %y, <2 x i64>* %t, align 1
+ ret void
}
declare void @kip(<2 x i64>* %t)
diff --git a/test/Transforms/InstCombine/memcpy-from-global.ll b/test/Transforms/InstCombine/memcpy-from-global.ll
index 58793ab431d1..3bc1d36f486d 100644
--- a/test/Transforms/InstCombine/memcpy-from-global.ll
+++ b/test/Transforms/InstCombine/memcpy-from-global.ll
@@ -7,11 +7,11 @@ entry:
%lookupTable = alloca [128 x float], align 16 ; <[128 x float]*> [#uses=5]
%lookupTable1 = bitcast [128 x float]* %lookupTable to i8* ; <i8*> [#uses=1]
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %lookupTable1, i8* bitcast ([128 x float]* @C.0.1248 to i8*), i64 512, i32 16, i1 false)
-
+
; CHECK-LABEL: @test1(
; CHECK-NOT: alloca
; CHECK-NOT: call{{.*}}@llvm.memcpy
-
+
%tmp3 = shl i32 %hash, 2 ; <i32> [#uses=1]
%tmp5 = and i32 %tmp3, 124 ; <i32> [#uses=4]
%tmp753 = getelementptr [128 x float]* %lookupTable, i32 0, i32 %tmp5 ; <float*> [#uses=1]
@@ -37,6 +37,9 @@ entry:
}
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
+declare void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* nocapture, i8* nocapture, i64, i32, i1) nounwind
+declare void @llvm.memcpy.p0i8.p1i8.i64(i8* nocapture, i8 addrspace(1)* nocapture, i64, i32, i1) nounwind
+declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture, i64, i32, i1) nounwind
%T = type { i8, [123 x i8] }
%U = type { i32, i32, i32, i32, i32 }
@@ -64,7 +67,31 @@ define void @test2() {
ret void
}
+define void @test2_addrspacecast() {
+ %A = alloca %T
+ %B = alloca %T
+ %a = addrspacecast %T* %A to i8 addrspace(1)*
+ %b = addrspacecast %T* %B to i8 addrspace(1)*
+
+; CHECK-LABEL: @test2_addrspacecast(
+
+; %A alloca is deleted
+; This doesn't exactly match what test2 does, because folding the type
+; cast into the alloca doesn't work for the addrspacecast yet.
+; CHECK-NEXT: alloca [124 x i8]
+; CHECK-NEXT: getelementptr
+; CHECK-NEXT: addrspacecast
+
+; use @G instead of %A
+; CHECK-NEXT: call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %{{.*}},
+ call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %a, i8* bitcast (%T* @G to i8*), i64 124, i32 4, i1 false)
+ call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %b, i8 addrspace(1)* %a, i64 124, i32 4, i1 false)
+ call void @bar_as1(i8 addrspace(1)* %b)
+ ret void
+}
+
declare void @bar(i8*)
+declare void @bar_as1(i8 addrspace(1)*)
;; Should be able to eliminate the alloca.
@@ -78,11 +105,22 @@ define void @test3() {
ret void
}
+define void @test3_addrspacecast() {
+ %A = alloca %T
+ %a = bitcast %T* %A to i8*
+ call void @llvm.memcpy.p0i8.p1i8.i64(i8* %a, i8 addrspace(1)* addrspacecast (%T* @G to i8 addrspace(1)*), i64 124, i32 4, i1 false)
+ call void @bar(i8* %a) readonly
+; CHECK-LABEL: @test3_addrspacecast(
+; CHECK-NEXT: call void @bar(i8* getelementptr inbounds (%T* @G, i64 0, i32 0))
+ ret void
+}
+
+
define void @test4() {
%A = alloca %T
%a = bitcast %T* %A to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* bitcast (%T* @G to i8*), i64 124, i32 4, i1 false)
- call void @baz(i8* byval %a)
+ call void @baz(i8* byval %a)
; CHECK-LABEL: @test4(
; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds (%T* @G, i64 0, i32 0))
ret void
@@ -94,7 +132,7 @@ define void @test5() {
%a = bitcast %T* %A to i8*
call void @llvm.lifetime.start(i64 -1, i8* %a)
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* bitcast (%T* @G to i8*), i64 124, i32 4, i1 false)
- call void @baz(i8* byval %a)
+ call void @baz(i8* byval %a)
; CHECK-LABEL: @test5(
; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds (%T* @G, i64 0, i32 0))
ret void
@@ -135,6 +173,18 @@ define void @test8() {
ret void
}
+
+define void @test8_addrspacecast() {
+ %A = alloca %U, align 16
+ %a = bitcast %U* %A to i8*
+ call void @llvm.memcpy.p0i8.p1i8.i64(i8* %a, i8 addrspace(1)* addrspacecast (%U* getelementptr ([2 x %U]* @H, i64 0, i32 1) to i8 addrspace(1)*), i64 20, i32 4, i1 false)
+ call void @bar(i8* %a) readonly
+; CHECK-LABEL: @test8_addrspacecast(
+; CHECK: llvm.memcpy
+; CHECK: bar
+ ret void
+}
+
define void @test9() {
%A = alloca %U, align 4
%a = bitcast %U* %A to i8*
@@ -144,3 +194,13 @@ define void @test9() {
; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr inbounds ([2 x %U]* @H, i64 0, i64 1) to i8*))
ret void
}
+
+define void @test9_addrspacecast() {
+ %A = alloca %U, align 4
+ %a = bitcast %U* %A to i8*
+ call void @llvm.memcpy.p0i8.p1i8.i64(i8* %a, i8 addrspace(1)* addrspacecast (%U* getelementptr ([2 x %U]* @H, i64 0, i32 1) to i8 addrspace(1)*), i64 20, i32 4, i1 false)
+ call void @bar(i8* %a) readonly
+; CHECK-LABEL: @test9_addrspacecast(
+; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr inbounds ([2 x %U]* @H, i64 0, i64 1) to i8*))
+ ret void
+}
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index 94fc1183c55a..d19bedc7a10c 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -181,3 +181,19 @@ define i32 @test19(i32 %A, i32 %B) {
ret i32 %H
; CHECK: ret i32 0
}
+
+define <2 x i64> @test20(<2 x i64> %A) {
+; CHECK-LABEL: @test20(
+ %B = add <2 x i64> %A, <i64 12, i64 14>
+ %C = mul <2 x i64> %B, <i64 3, i64 2>
+ ret <2 x i64> %C
+; CHECK: mul <2 x i64> %A, <i64 3, i64 2>
+; CHECK: add <2 x i64> %{{.}}, <i64 36, i64 28>
+}
+
+define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {
+; CHECK-LABEL: @test21(
+ %C = mul <2 x i1> %A, %B
+ ret <2 x i1> %C
+; CHECK: %C = and <2 x i1> %A, %B
+}
diff --git a/test/Transforms/InstCombine/onehot_merge.ll b/test/Transforms/InstCombine/onehot_merge.ll
index 51f955c2c248..496d847b5321 100644
--- a/test/Transforms/InstCombine/onehot_merge.ll
+++ b/test/Transforms/InstCombine/onehot_merge.ll
@@ -16,7 +16,7 @@ bb:
;CHECK: @foo1_and
;CHECK: shl i32 1, %c1
-;CHECK-NEXT: shl i32 1, %c2
+;CHECK-NEXT: lshr i32 -2147483648, %c2
;CHECK-NEXT: or i32
;CHECK-NEXT: and i32
;CHECK-NEXT: icmp ne i32 %1, %0
@@ -24,7 +24,7 @@ bb:
define i1 @foo1_and(i32 %k, i32 %c1, i32 %c2) {
bb:
%tmp = shl i32 1, %c1
- %tmp4 = shl i32 1, %c2
+ %tmp4 = lshr i32 -2147483648, %c2
%tmp1 = and i32 %tmp, %k
%tmp2 = icmp eq i32 %tmp1, 0
%tmp5 = and i32 %tmp4, %k
diff --git a/test/Transforms/InstCombine/overflow-mul.ll b/test/Transforms/InstCombine/overflow-mul.ll
new file mode 100644
index 000000000000..cbb2f5f95003
--- /dev/null
+++ b/test/Transforms/InstCombine/overflow-mul.ll
@@ -0,0 +1,175 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; return mul(zext x, zext y) > MAX
+define i32 @pr4917_1(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_1(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+; CHECK-NOT: zext i32
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %overflow = icmp ugt i64 %mul64, 4294967295
+; CHECK: extractvalue { i32, i1 } [[MUL]], 1
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+; return mul(zext x, zext y) >= MAX+1
+define i32 @pr4917_1a(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_1a(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+; CHECK-NOT: zext i32
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %overflow = icmp uge i64 %mul64, 4294967296
+; CHECK: extractvalue { i32, i1 } [[MUL]], 1
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+; mul(zext x, zext y) > MAX
+; mul(x, y) is used
+define i32 @pr4917_2(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_2(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+; CHECK-NOT: zext i32
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %overflow = icmp ugt i64 %mul64, 4294967295
+; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0
+ %mul32 = trunc i64 %mul64 to i32
+; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1
+ %retval = select i1 %overflow, i32 %mul32, i32 111
+; CHECK: select i1 [[OVFL]], i32 [[VAL]]
+ ret i32 %retval
+}
+
+; return mul(zext x, zext y) > MAX
+; mul is used in non-truncate
+define i64 @pr4917_3(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_3(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+ %mul64 = mul i64 %l, %r
+; CHECK-NOT: umul.with.overflow.i32
+ %overflow = icmp ugt i64 %mul64, 4294967295
+ %retval = select i1 %overflow, i64 %mul64, i64 111
+ ret i64 %retval
+}
+
+; return mul(zext x, zext y) <= MAX
+define i32 @pr4917_4(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_4(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+; CHECK-NOT: zext i32
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %overflow = icmp ule i64 %mul64, 4294967295
+; CHECK: extractvalue { i32, i1 } [[MUL]], 1
+; CHECK: xor
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+; return mul(zext x, zext y) < MAX+1
+define i32 @pr4917_4a(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4917_4a(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+; CHECK-NOT: zext i32
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %overflow = icmp ult i64 %mul64, 4294967296
+; CHECK: extractvalue { i32, i1 } [[MUL]], 1
+; CHECK: xor
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+; operands of mul are of different size
+define i32 @pr4917_5(i32 %x, i8 %y) nounwind {
+; CHECK-LABEL: @pr4917_5(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i8 %y to i64
+; CHECK: [[Y:%.*]] = zext i8 %y to i32
+ %mul64 = mul i64 %l, %r
+ %overflow = icmp ugt i64 %mul64, 4294967295
+ %mul32 = trunc i64 %mul64 to i32
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 [[Y]])
+; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0
+; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1
+ %retval = select i1 %overflow, i32 %mul32, i32 111
+; CHECK: select i1 [[OVFL]], i32 [[VAL]]
+ ret i32 %retval
+}
+
+; mul(zext x, zext y) != zext trunc mul
+define i32 @pr4918_1(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4918_1(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %part32 = trunc i64 %mul64 to i32
+ %part64 = zext i32 %part32 to i64
+ %overflow = icmp ne i64 %mul64, %part64
+; CHECK: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL:%.*]], 1
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+; mul(zext x, zext y) == zext trunc mul
+define i32 @pr4918_2(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4918_2(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %part32 = trunc i64 %mul64 to i32
+ %part64 = zext i32 %part32 to i64
+ %overflow = icmp eq i64 %mul64, %part64
+; CHECK: extractvalue { i32, i1 } [[MUL]]
+ %retval = zext i1 %overflow to i32
+; CHECK: xor
+ ret i32 %retval
+}
+
+; zext trunc mul != mul(zext x, zext y)
+define i32 @pr4918_3(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: @pr4918_3(
+entry:
+ %l = zext i32 %x to i64
+ %r = zext i32 %y to i64
+ %mul64 = mul i64 %l, %r
+; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
+ %part32 = trunc i64 %mul64 to i32
+ %part64 = zext i32 %part32 to i64
+ %overflow = icmp ne i64 %part64, %mul64
+; CHECK: extractvalue { i32, i1 } [[MUL]], 1
+ %retval = zext i1 %overflow to i32
+ ret i32 %retval
+}
+
+define <4 x i32> @pr20113(<4 x i16> %a, <4 x i16> %b) {
+; CHECK-LABEL: @pr20113
+; CHECK-NOT: mul.with.overflow
+; CHECK: ret
+ %vmovl.i.i726 = zext <4 x i16> %a to <4 x i32>
+ %vmovl.i.i712 = zext <4 x i16> %b to <4 x i32>
+ %mul.i703 = mul <4 x i32> %vmovl.i.i712, %vmovl.i.i726
+ %tmp = icmp sge <4 x i32> %mul.i703, zeroinitializer
+ %vcgez.i = sext <4 x i1> %tmp to <4 x i32>
+ ret <4 x i32> %vcgez.i
+}
diff --git a/test/Transforms/InstCombine/pow-1.ll b/test/Transforms/InstCombine/pow-1.ll
index 9f1d073fe760..fb3b7d796160 100644
--- a/test/Transforms/InstCombine/pow-1.ll
+++ b/test/Transforms/InstCombine/pow-1.ll
@@ -1,6 +1,11 @@
; Test that the pow library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefix=CHECK-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefix=CHECK-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefix=CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefix=CHECK-NO-EXP10
+; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefix=CHECK-NO-EXP10
; rdar://7251832
; NOTE: The readonly attribute on the pow call should be preserved
@@ -155,13 +160,33 @@ declare double @llvm.pow.f64(double %Val, double %Power)
define double @test_simplify17(double %x) {
; CHECK-LABEL: @test_simplify17(
%retval = call double @llvm.pow.f64(double %x, double 0.5)
-; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) [[NUW_RO]]
-; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) [[NUW_RO]]
+; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x)
+; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]])
; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq double %x, 0xFFF0000000000000
; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], double 0x7FF0000000000000, double [[FABS]]
ret double %retval
; CHECK-NEXT: ret double [[SELECT]]
}
+; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
+
+define float @test_simplify18(float %x) {
+; CHECK-LABEL: @test_simplify18(
+ %retval = call float @powf(float 10.0, float %x)
+; CHECK-EXP10: [[EXP10F:%[_a-z0-9]+]] = call float @__exp10f(float %x) [[NUW_RO:#[0-9]+]]
+ ret float %retval
+; CHECK-EXP10: ret float [[EXP10F]]
+; CHECK-NO-EXP10: call float @powf
+}
+
+define double @test_simplify19(double %x) {
+; CHECK-LABEL: @test_simplify19(
+ %retval = call double @pow(double 10.0, double %x)
+; CHECK-EXP10: [[EXP10:%[_a-z0-9]+]] = call double @__exp10(double %x) [[NUW_RO]]
+ ret double %retval
+; CHECK-EXP10: ret double [[EXP10]]
+; CHECK-NO-EXP10: call double @pow
+}
+
; CHECK: attributes [[NUW_RO]] = { nounwind readonly }
diff --git a/test/Transforms/InstCombine/pr19420.ll b/test/Transforms/InstCombine/pr19420.ll
new file mode 100644
index 000000000000..23fa0a409745
--- /dev/null
+++ b/test/Transforms/InstCombine/pr19420.ll
@@ -0,0 +1,67 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL
+; CHECK: mul <4 x i32> %in, <i32 0, i32 -32, i32 0, i32 -32>
+; CHECK-NEXT: ret
+define <4 x i32> @test_FoldShiftByConstant_CreateSHL(<4 x i32> %in) {
+ %mul.i = mul <4 x i32> %in, <i32 0, i32 -1, i32 0, i32 -1>
+ %vshl_n = shl <4 x i32> %mul.i, <i32 5, i32 5, i32 5, i32 5>
+ ret <4 x i32> %vshl_n
+}
+
+; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL2
+; CHECK: mul <8 x i16> %in, <i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32>
+; CHECK-NEXT: ret
+define <8 x i16> @test_FoldShiftByConstant_CreateSHL2(<8 x i16> %in) {
+ %mul.i = mul <8 x i16> %in, <i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1>
+ %vshl_n = shl <8 x i16> %mul.i, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+ ret <8 x i16> %vshl_n
+}
+
+; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd
+; CHECK: mul <16 x i8> %in0, <i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33>
+; CHECK-NEXT: and <16 x i8> %vsra_n2, <i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32>
+; CHECK-NEXT: ret
+define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
+ %vsra_n = ashr <16 x i8> %in0, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+ %tmp = add <16 x i8> %in0, %vsra_n
+ %vshl_n = shl <16 x i8> %tmp, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+ ret <16 x i8> %vshl_n
+}
+
+
+define i32 @bar(i32 %x, i32 %y) {
+ %a = lshr i32 %x, 4
+ %b = add i32 %a, %y
+ %c = shl i32 %b, 4
+ ret i32 %c
+}
+
+define <2 x i32> @bar_v2i32(<2 x i32> %x, <2 x i32> %y) {
+ %a = lshr <2 x i32> %x, <i32 5, i32 5>
+ %b = add <2 x i32> %a, %y
+ %c = shl <2 x i32> %b, <i32 5, i32 5>
+ ret <2 x i32> %c
+}
+
+
+
+
+define i32 @foo(i32 %x, i32 %y) {
+ %a = lshr i32 %x, 4
+ %b = and i32 %a, 8
+ %c = add i32 %b, %y
+ %d = shl i32 %c, 4
+ ret i32 %d
+}
+
+define <2 x i32> @foo_v2i32(<2 x i32> %x, <2 x i32> %y) {
+ %a = lshr <2 x i32> %x, <i32 4, i32 4>
+ %b = and <2 x i32> %a, <i32 8, i32 8>
+ %c = add <2 x i32> %b, %y
+ %d = shl <2 x i32> %c, <i32 4, i32 4>
+ ret <2 x i32> %d
+}
+
+
+
diff --git a/test/Transforms/InstCombine/pr20059.ll b/test/Transforms/InstCombine/pr20059.ll
new file mode 100644
index 000000000000..0ef315936ff2
--- /dev/null
+++ b/test/Transforms/InstCombine/pr20059.ll
@@ -0,0 +1,16 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed
+; for an srem operation. This is not a valid optimization because it may cause a trap
+; on div-by-zero.
+
+; CHECK-LABEL: @do_not_reorder
+; CHECK: %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer
+; CHECK-NEXT: %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer
+; CHECK-NEXT: %retval = srem <4 x i32> %splat1, %splat2
+define <4 x i32> @do_not_reorder(<4 x i32> %p1, <4 x i32> %p2) {
+ %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer
+ %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer
+ %retval = srem <4 x i32> %splat1, %splat2
+ ret <4 x i32> %retval
+}
diff --git a/test/Transforms/InstCombine/pr20079.ll b/test/Transforms/InstCombine/pr20079.ll
new file mode 100644
index 000000000000..ce9c4deb06a0
--- /dev/null
+++ b/test/Transforms/InstCombine/pr20079.ll
@@ -0,0 +1,9 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+@b = internal global [1 x i32] zeroinitializer, align 4
+@c = internal global i32 0, align 4
+
+; CHECK-LABEL: @fn1
+; CHECK-NEXT: ret i32 0
+define i32 @fn1(i32 %a) {
+ ret i32 0
+}
diff --git a/test/Transforms/InstCombine/printf-1.ll b/test/Transforms/InstCombine/printf-1.ll
index c98ddd55df10..483bc7a6b079 100644
--- a/test/Transforms/InstCombine/printf-1.ll
+++ b/test/Transforms/InstCombine/printf-1.ll
@@ -87,18 +87,18 @@ define void @test_simplify7() {
; CHECK-IPRINTF-LABEL: @test_simplify7(
%fmt = getelementptr [3 x i8]* @percent_d, i32 0, i32 0
call i32 (i8*, ...)* @printf(i8* %fmt, i32 187)
-; CHECK-NEXT-IPRINTF: call i32 (i8*, ...)* @iprintf(i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-IPRINTF-NEXT: call i32 (i8*, ...)* @iprintf(i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify1() {
; CHECK-IPRINTF-LABEL: @test_no_simplify1(
%fmt = getelementptr [3 x i8]* @percent_f, i32 0, i32 0
call i32 (i8*, ...)* @printf(i8* %fmt, double 1.87)
-; CHECK-NEXT-IPRINTF: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-IPRINTF-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify2(i8* %fmt, double %d) {
diff --git a/test/Transforms/InstCombine/r600-intrinsics.ll b/test/Transforms/InstCombine/r600-intrinsics.ll
new file mode 100644
index 000000000000..1db6b0d28bf5
--- /dev/null
+++ b/test/Transforms/InstCombine/r600-intrinsics.ll
@@ -0,0 +1,47 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+declare float @llvm.AMDGPU.rcp.f32(float) nounwind readnone
+declare double @llvm.AMDGPU.rcp.f64(double) nounwind readnone
+
+; CHECK-LABEL: @test_constant_fold_rcp_f32_1
+; CHECK-NEXT: ret float 1.000000e+00
+define float @test_constant_fold_rcp_f32_1() nounwind {
+ %val = call float @llvm.AMDGPU.rcp.f32(float 1.0) nounwind readnone
+ ret float %val
+}
+
+; CHECK-LABEL: @test_constant_fold_rcp_f64_1
+; CHECK-NEXT: ret double 1.000000e+00
+define double @test_constant_fold_rcp_f64_1() nounwind {
+ %val = call double @llvm.AMDGPU.rcp.f64(double 1.0) nounwind readnone
+ ret double %val
+}
+
+; CHECK-LABEL: @test_constant_fold_rcp_f32_half
+; CHECK-NEXT: ret float 2.000000e+00
+define float @test_constant_fold_rcp_f32_half() nounwind {
+ %val = call float @llvm.AMDGPU.rcp.f32(float 0.5) nounwind readnone
+ ret float %val
+}
+
+; CHECK-LABEL: @test_constant_fold_rcp_f64_half
+; CHECK-NEXT: ret double 2.000000e+00
+define double @test_constant_fold_rcp_f64_half() nounwind {
+ %val = call double @llvm.AMDGPU.rcp.f64(double 0.5) nounwind readnone
+ ret double %val
+}
+
+; CHECK-LABEL: @test_constant_fold_rcp_f32_43
+; CHECK-NEXT: call float @llvm.AMDGPU.rcp.f32(float 4.300000e+01)
+define float @test_constant_fold_rcp_f32_43() nounwind {
+ %val = call float @llvm.AMDGPU.rcp.f32(float 4.300000e+01) nounwind readnone
+ ret float %val
+}
+
+; CHECK-LABEL: @test_constant_fold_rcp_f64_43
+; CHECK-NEXT: call double @llvm.AMDGPU.rcp.f64(double 4.300000e+01)
+define double @test_constant_fold_rcp_f64_43() nounwind {
+ %val = call double @llvm.AMDGPU.rcp.f64(double 4.300000e+01) nounwind readnone
+ ret double %val
+}
+
diff --git a/test/Transforms/InstCombine/rem.ll b/test/Transforms/InstCombine/rem.ll
index 22fd90bf7a75..0595a67393a6 100644
--- a/test/Transforms/InstCombine/rem.ll
+++ b/test/Transforms/InstCombine/rem.ll
@@ -127,7 +127,7 @@ define i64 @test14(i64 %x, i32 %y) {
; CHECK-LABEL: @test14(
; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, %y
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64
-; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ZEXT]], -1
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[ZEXT]], -1
; CHECK-NEXT: [[AND:%.*]] = and i64 [[ADD]], %x
; CHECK-NEXT: ret i64 [[AND]]
%shl = shl i32 1, %y
@@ -204,3 +204,12 @@ define i32 @test19(i32 %x, i32 %y) {
%E = urem i32 %y, %D
ret i32 %E
}
+
+define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) {
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer
+; CHECK-NEXT: ret <2 x i64>
+ %V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9>
+ %R = urem <2 x i64> %V, <i64 2, i64 3>
+ ret <2 x i64> %R
+}
diff --git a/test/Transforms/InstCombine/round.ll b/test/Transforms/InstCombine/round.ll
new file mode 100644
index 000000000000..ecc62dda36ba
--- /dev/null
+++ b/test/Transforms/InstCombine/round.ll
@@ -0,0 +1,90 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+declare float @llvm.round.f32(float) #0
+declare double @llvm.round.f64(double) #0
+
+; CHECK-LABEL: @constant_fold_round_f32_01
+; CHECK-NEXT: ret float 1.000000e+00
+define float @constant_fold_round_f32_01() #0 {
+ %x = call float @llvm.round.f32(float 1.25) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f32_02
+; CHECK-NEXT: ret float -1.000000e+00
+define float @constant_fold_round_f32_02() #0 {
+ %x = call float @llvm.round.f32(float -1.25) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f32_03
+; CHECK-NEXT: ret float 2.000000e+00
+define float @constant_fold_round_f32_03() #0 {
+ %x = call float @llvm.round.f32(float 1.5) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f32_04
+; CHECK-NEXT: ret float -2.000000e+00
+define float @constant_fold_round_f32_04() #0 {
+ %x = call float @llvm.round.f32(float -1.5) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f32_05
+; CHECK-NEXT: ret float 3.000000e+00
+define float @constant_fold_round_f32_05() #0 {
+ %x = call float @llvm.round.f32(float 2.75) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f32_06
+; CHECK-NEXT: ret float -3.000000e+00
+define float @constant_fold_round_f32_06() #0 {
+ %x = call float @llvm.round.f32(float -2.75) #0
+ ret float %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_01
+; CHECK-NEXT: ret double 1.000000e+00
+define double @constant_fold_round_f64_01() #0 {
+ %x = call double @llvm.round.f64(double 1.3) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_02
+; CHECK-NEXT: ret double -1.000000e+00
+define double @constant_fold_round_f64_02() #0 {
+ %x = call double @llvm.round.f64(double -1.3) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_03
+; CHECK-NEXT: ret double 2.000000e+00
+define double @constant_fold_round_f64_03() #0 {
+ %x = call double @llvm.round.f64(double 1.5) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_04
+; CHECK-NEXT: ret double -2.000000e+00
+define double @constant_fold_round_f64_04() #0 {
+ %x = call double @llvm.round.f64(double -1.5) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_05
+; CHECK-NEXT: ret double 3.000000e+00
+define double @constant_fold_round_f64_05() #0 {
+ %x = call double @llvm.round.f64(double 2.7) #0
+ ret double %x
+}
+
+; CHECK-LABEL: @constant_fold_round_f64_06
+; CHECK-NEXT: ret double -3.000000e+00
+define double @constant_fold_round_f64_06() #0 {
+ %x = call double @llvm.round.f64(double -2.7) #0
+ ret double %x
+}
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Transforms/InstCombine/select-2.ll b/test/Transforms/InstCombine/select-2.ll
index 5b9deb4515a8..832d958c5f34 100644
--- a/test/Transforms/InstCombine/select-2.ll
+++ b/test/Transforms/InstCombine/select-2.ll
@@ -19,3 +19,13 @@ define i32 @t2(i32 %c, i32 %x) nounwind {
%t3 = select i1 %t1, i32 %t2, i32 %x
ret i32 %t3
}
+
+define float @t3(float %x, float %y) nounwind {
+ %t1 = fcmp ogt float %x, %y
+ %t2 = select i1 %t1, float %x, float 1.0
+ %t3 = fadd fast float %t2, 1.0
+ ret float %t3
+; CHECK-LABEL: @t3(
+; CHECK: fadd fast
+; CHECK: select
+}
diff --git a/test/Transforms/InstCombine/select-select.ll b/test/Transforms/InstCombine/select-select.ll
new file mode 100644
index 000000000000..65820acf07b8
--- /dev/null
+++ b/test/Transforms/InstCombine/select-select.ll
@@ -0,0 +1,24 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+; CHECK: @foo1
+define float @foo1(float %a) #0 {
+; CHECK-NOT: xor
+ %b = fcmp ogt float %a, 0.000000e+00
+ %c = select i1 %b, float %a, float 0.000000e+00
+ %d = fcmp olt float %c, 1.000000e+00
+ %f = select i1 %d, float %c, float 1.000000e+00
+ ret float %f
+}
+
+; CHECK: @foo2
+define float @foo2(float %a) #0 {
+; CHECK-NOT: xor
+ %b = fcmp ogt float %a, 0.000000e+00
+ %c = select i1 %b, float %a, float 0.000000e+00
+ %d = fcmp olt float %c, 1.000000e+00
+ %e = select i1 %b, float %a, float 0.000000e+00
+ %f = select i1 %d, float %e, float 1.000000e+00
+ ret float %f
+}
+
+attributes #0 = { nounwind readnone ssp uwtable }
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 1458bde82124..d625f3b1b33d 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -281,7 +281,7 @@ define i32 @test15i(i32 %X) {
; CHECK-NEXT: %t1 = shl i32 %X, 8
; CHECK-NEXT: %1 = and i32 %t1, 512
; CHECK-NEXT: %2 = xor i32 %1, 512
-; CHECK-NEXT: %3 = add i32 %2, 577
+; CHECK-NEXT: %3 = add nuw nsw i32 %2, 577
; CHECK-NEXT: ret i32 %3
}
@@ -294,7 +294,7 @@ define i32 @test15j(i32 %X) {
; CHECK-LABEL: @test15j(
; CHECK-NEXT: %t1 = shl i32 %X, 8
; CHECK-NEXT: %1 = and i32 %t1, 512
-; CHECK-NEXT: %2 = add i32 %1, 577
+; CHECK-NEXT: %2 = add nuw nsw i32 %1, 577
; CHECK-NEXT: ret i32 %2
}
@@ -521,7 +521,7 @@ define i32 @test35(i32 %x) {
; CHECK-LABEL: @test35(
; CHECK: ashr i32 %x, 31
; CHECK: and i32 {{.*}}, 40
-; CHECK: add i32 {{.*}}, 60
+; CHECK: add nuw nsw i32 {{.*}}, 60
; CHECK: ret
}
@@ -532,7 +532,7 @@ define i32 @test36(i32 %x) {
; CHECK-LABEL: @test36(
; CHECK: ashr i32 %x, 31
; CHECK: and i32 {{.*}}, -40
-; CHECK: add i32 {{.*}}, 100
+; CHECK: add nsw i32 {{.*}}, 100
; CHECK: ret
}
@@ -996,6 +996,111 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_vector_of_2s(i32 %x, <2 x i32> %y) {
ret <2 x i32> %select
}
+; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %or = or i32 %x, 8
+ %or.x = select i1 %cmp, i32 %or, i32 %x
+ ret i32 %or.x
+}
+
+; CHECK-LABEL: @select_icmp_and_8_ne_0_xor_8(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
+; CHECK-NEXT: ret i32 [[AND]]
+define i32 @select_icmp_and_8_ne_0_xor_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 8
+ %x.xor = select i1 %cmp, i32 %x, i32 %xor
+ ret i32 %x.xor
+}
+
+; CHECK-LABEL: @select_icmp_and_8_eq_0_xor_8(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_and_8_eq_0_xor_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 8
+ %xor.x = select i1 %cmp, i32 %xor, i32 %x
+ ret i32 %xor.x
+}
+
+; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
+; CHECK-NEXT: ret i32 [[AND]]
+define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i32 %x, -9
+ %x.and1 = select i1 %cmp, i32 %x, i32 %and1
+ ret i32 %x.and1
+}
+
+; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
+; CHECK-NEXT: ret i32 %x
+define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i32 %x, -9
+ %and1.x = select i1 %cmp, i32 %and1, i32 %x
+ ret i32 %and1.x
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_xor_8(
+; CHECK: select i1 %cmp, i64 %y, i64 %xor
+define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i64 %y, 8
+ %y.xor = select i1 %cmp, i64 %y, i64 %xor
+ ret i64 %y.xor
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
+; CHECK: select i1 %cmp, i64 %y, i64 %and1
+define i64 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i64 %y, -9
+ %y.and1 = select i1 %cmp, i64 %y, i64 %and1
+ ret i64 %y.and1
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_xor_8(
+; CHECK: select i1 %cmp, i64 %xor, i64 %y
+define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i64 %y, 8
+ %xor.y = select i1 %cmp, i64 %xor, i64 %y
+ ret i64 %xor.y
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_and_not_8(
+; CHECK: select i1 %cmp, i64 %and1, i64 %y
+define i64 @select_icmp_x_and_8_ne_0_y_and_not_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i64 %y, -9
+ %and1.y = select i1 %cmp, i64 %and1, i64 %y
+ ret i64 %and1.y
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_or_8(
+; CHECK: xor i64 %1, 8
+; CHECK: or i64 %2, %y
+define i64 @select_icmp_x_and_8_ne_0_y_or_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %or = or i64 %y, 8
+ %or.y = select i1 %cmp, i64 %or, i64 %y
+ ret i64 %or.y
+}
+
define i32 @test65(i64 %x) {
%1 = and i64 %x, 16
%2 = icmp ne i64 %1, 0
@@ -1031,3 +1136,103 @@ define i32 @test67(i16 %x) {
; CHECK: lshr exact i32 %2, 1
; CHECK: xor i32 %3, 42
}
+
+; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11)
+define i32 @test68(i32 %x) {
+entry:
+ %cmp = icmp slt i32 11, %x
+ %cond = select i1 %cmp, i32 11, i32 %x
+ %cmp3 = icmp slt i32 92, %cond
+ %retval = select i1 %cmp3, i32 92, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test68(
+; CHECK: ret i32 %cond
+}
+
+; MIN(MIN(X, 24), 83) -> MIN(X, 24)
+define i32 @test69(i32 %x) {
+entry:
+ %cmp = icmp ult i32 24, %x
+ %cond = select i1 %cmp, i32 24, i32 %x
+ %cmp3 = icmp ult i32 83, %cond
+ %retval = select i1 %cmp3, i32 83, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test69(
+; CHECK: ret i32 %cond
+}
+
+; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
+define i32 @test70(i32 %x) {
+entry:
+ %cmp = icmp slt i32 %x, 75
+ %cond = select i1 %cmp, i32 75, i32 %x
+ %cmp3 = icmp slt i32 %cond, 36
+ %retval = select i1 %cmp3, i32 36, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test70(
+; CHECK: ret i32 %cond
+}
+
+; MAX(MAX(X, 68), 47) -> MAX(X, 68)
+define i32 @test71(i32 %x) {
+entry:
+ %cmp = icmp ult i32 %x, 68
+ %cond = select i1 %cmp, i32 68, i32 %x
+ %cmp3 = icmp ult i32 %cond, 47
+ %retval = select i1 %cmp3, i32 47, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test71(
+; CHECK: ret i32 %cond
+}
+
+; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
+define i32 @test72(i32 %x) {
+ %cmp = icmp sgt i32 %x, 92
+ %cond = select i1 %cmp, i32 92, i32 %x
+ %cmp3 = icmp sgt i32 %cond, 11
+ %retval = select i1 %cmp3, i32 11, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test72(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 11
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 11, i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+; MIN(MIN(X, 83), 24) -> MIN(X, 24)
+define i32 @test73(i32 %x) {
+ %cmp = icmp ugt i32 %x, 83
+ %cond = select i1 %cmp, i32 83, i32 %x
+ %cmp3 = icmp ugt i32 %cond, 24
+ %retval = select i1 %cmp3, i32 24, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test73(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %x, 24
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 24, i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
+define i32 @test74(i32 %x) {
+ %cmp = icmp slt i32 %x, 36
+ %cond = select i1 %cmp, i32 36, i32 %x
+ %cmp3 = icmp slt i32 %cond, 75
+ %retval = select i1 %cmp3, i32 75, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test74(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 75
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 75, i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
+
+; MAX(MAX(X, 47), 68) -> MAX(X, 68)
+define i32 @test75(i32 %x) {
+ %cmp = icmp ult i32 %x, 47
+ %cond = select i1 %cmp, i32 47, i32 %x
+ %cmp3 = icmp ult i32 %cond, 68
+ %retval = select i1 %cmp3, i32 68, i32 %cond
+ ret i32 %retval
+; CHECK-LABEL: @test75(
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %x, 68
+; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 68, i32 %x
+; CHECK-NEXT: ret i32 [[SEL]]
+}
diff --git a/test/Transforms/InstCombine/sext.ll b/test/Transforms/InstCombine/sext.ll
index b8dfe2257b18..f04afcc747b8 100644
--- a/test/Transforms/InstCombine/sext.ll
+++ b/test/Transforms/InstCombine/sext.ll
@@ -145,7 +145,7 @@ define i32 @test13(i32 %x) nounwind {
; CHECK-LABEL: @test13(
; CHECK-NEXT: %and = lshr i32 %x, 3
; CHECK-NEXT: %1 = and i32 %and, 1
-; CHECK-NEXT: %sext = add i32 %1, -1
+; CHECK-NEXT: %sext = add nsw i32 %1, -1
; CHECK-NEXT: ret i32 %sext
}
@@ -157,7 +157,7 @@ define i32 @test14(i16 %x) nounwind {
; CHECK-LABEL: @test14(
; CHECK-NEXT: %and = lshr i16 %x, 4
; CHECK-NEXT: %1 = and i16 %and, 1
-; CHECK-NEXT: %sext = add i16 %1, -1
+; CHECK-NEXT: %sext = add nsw i16 %1, -1
; CHECK-NEXT: %ext = sext i16 %sext to i32
; CHECK-NEXT: ret i32 %ext
}
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index b1082f06ef74..5586bb652783 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -36,17 +36,52 @@ define i32 @test4(i8 %A) {
define i32 @test5(i32 %A) {
; CHECK-LABEL: @test5(
; CHECK: ret i32 undef
- %B = lshr i32 %A, 32 ;; shift all bits out
+ %B = lshr i32 %A, 32 ;; shift all bits out
ret i32 %B
}
+define <4 x i32> @test5_splat_vector(<4 x i32> %A) {
+; CHECK-LABEL: @test5_splat_vector(
+; CHECK: ret <4 x i32> undef
+ %B = lshr <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32> ;; shift all bits out
+ ret <4 x i32> %B
+}
+
+define <4 x i32> @test5_zero_vector(<4 x i32> %A) {
+; CHECK-LABEL: @test5_zero_vector(
+; CHECK-NEXT: ret <4 x i32> %A
+ %B = lshr <4 x i32> %A, zeroinitializer
+ ret <4 x i32> %B
+}
+
+define <4 x i32> @test5_non_splat_vector(<4 x i32> %A) {
+; CHECK-LABEL: @test5_non_splat_vector(
+; CHECK-NOT: ret <4 x i32> undef
+ %B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
+ ret <4 x i32> %B
+}
+
define i32 @test5a(i32 %A) {
; CHECK-LABEL: @test5a(
; CHECK: ret i32 undef
- %B = shl i32 %A, 32 ;; shift all bits out
+ %B = shl i32 %A, 32 ;; shift all bits out
ret i32 %B
}
+define <4 x i32> @test5a_splat_vector(<4 x i32> %A) {
+; CHECK-LABEL: @test5a_splat_vector(
+; CHECK: ret <4 x i32> undef
+ %B = shl <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32> ;; shift all bits out
+ ret <4 x i32> %B
+}
+
+define <4 x i32> @test5a_non_splat_vector(<4 x i32> %A) {
+; CHECK-LABEL: @test5a_non_splat_vector(
+; CHECK-NOT: ret <4 x i32> undef
+ %B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
+ ret <4 x i32> %B
+}
+
define i32 @test5b() {
; CHECK-LABEL: @test5b(
; CHECK: ret i32 -1
@@ -82,7 +117,7 @@ define i32 @test6a(i32 %A) {
define i32 @test7(i8 %A) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: ret i32 -1
- %shift.upgrd.3 = zext i8 %A to i32
+ %shift.upgrd.3 = zext i8 %A to i32
%B = ashr i32 -1, %shift.upgrd.3 ;; Always equal to -1
ret i32 %B
}
@@ -232,7 +267,7 @@ define i1 @test16(i32 %X) {
; CHECK-NEXT: and i32 %X, 16
; CHECK-NEXT: icmp ne i32
; CHECK-NEXT: ret i1
- %tmp.3 = ashr i32 %X, 4
+ %tmp.3 = ashr i32 %X, 4
%tmp.6 = and i32 %tmp.3, 1
%tmp.7 = icmp ne i32 %tmp.6, 0
ret i1 %tmp.7
@@ -344,6 +379,20 @@ define i32 @test25(i32 %tmp.2, i32 %AA) {
ret i32 %tmp.6
}
+define <2 x i32> @test25_vector(<2 x i32> %tmp.2, <2 x i32> %AA) {
+; CHECK-LABEL: @test25_vector(
+; CHECK: %tmp.3 = lshr <2 x i32> %tmp.2, <i32 17, i32 17>
+; CHECK-NEXT: shl <2 x i32> %tmp.3, <i32 17, i32 17>
+; CHECK-NEXT: add <2 x i32> %tmp.51, %AA
+; CHECK-NEXT: and <2 x i32> %x2, <i32 -131072, i32 -131072>
+; CHECK-NEXT: ret <2 x i32>
+ %x = lshr <2 x i32> %AA, <i32 17, i32 17>
+ %tmp.3 = lshr <2 x i32> %tmp.2, <i32 17, i32 17>
+ %tmp.5 = add <2 x i32> %tmp.3, %x
+ %tmp.6 = shl <2 x i32> %tmp.5, <i32 17, i32 17>
+ ret <2 x i32> %tmp.6
+}
+
;; handle casts between shifts.
define i32 @test26(i32 %A) {
; CHECK-LABEL: @test26(
@@ -365,12 +414,12 @@ define i1 @test27(i32 %x) nounwind {
%z = trunc i32 %y to i1
ret i1 %z
}
-
+
define i8 @test28(i8 %x) {
entry:
; CHECK-LABEL: @test28(
; CHECK: icmp slt i8 %x, 0
-; CHECK-NEXT: br i1
+; CHECK-NEXT: br i1
%tmp1 = lshr i8 %x, 7
%cond1 = icmp ne i8 %tmp1, 0
br i1 %cond1, label %bb1, label %bb2
@@ -476,7 +525,7 @@ entry:
%ins = or i128 %tmp23, %tmp27
%tmp45 = lshr i128 %ins, 64
ret i128 %tmp45
-
+
; CHECK-LABEL: @test36(
; CHECK: %tmp231 = or i128 %B, %A
; CHECK: %ins = and i128 %tmp231, 18446744073709551615
@@ -492,7 +541,7 @@ entry:
%tmp45 = lshr i128 %ins, 64
%tmp46 = trunc i128 %tmp45 to i64
ret i64 %tmp46
-
+
; CHECK-LABEL: @test37(
; CHECK: %tmp23 = shl nuw nsw i128 %tmp22, 32
; CHECK: %ins = or i128 %tmp23, %A
@@ -780,3 +829,32 @@ bb11: ; preds = %bb8
bb12: ; preds = %bb11, %bb8, %bb
ret void
}
+
+define i32 @test64(i32 %a) {
+; CHECK-LABEL: @test64(
+; CHECK-NEXT: ret i32 undef
+ %b = ashr i32 %a, 32 ; shift all bits out
+ ret i32 %b
+}
+
+define <4 x i32> @test64_splat_vector(<4 x i32> %a) {
+; CHECK-LABEL: @test64_splat_vector
+; CHECK-NEXT: ret <4 x i32> undef
+ %b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32> ; shift all bits out
+ ret <4 x i32> %b
+}
+
+define <4 x i32> @test64_non_splat_vector(<4 x i32> %a) {
+; CHECK-LABEL: @test64_non_splat_vector
+; CHECK-NOT: ret <4 x i32> undef
+ %b = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2> ; shift all bits out
+ ret <4 x i32> %b
+}
+
+define <2 x i65> @test_65(<2 x i64> %t) {
+; CHECK-LABEL: @test_65
+ %a = zext <2 x i64> %t to <2 x i65>
+ %sext = shl <2 x i65> %a, <i65 33, i65 33>
+ %b = ashr <2 x i65> %sext, <i65 33, i65 33>
+ ret <2 x i65> %b
+}
diff --git a/test/Transforms/InstCombine/sign-test-and-or.ll b/test/Transforms/InstCombine/sign-test-and-or.ll
index 95ed9b976ba3..aa23d933b09e 100644
--- a/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -177,3 +177,41 @@ if.then:
if.end:
ret void
}
+
+define void @test10(i32 %a) nounwind {
+ %1 = and i32 %a, 2
+ %2 = icmp eq i32 %1, 0
+ %3 = icmp ult i32 %a, 4
+ %or.cond = and i1 %2, %3
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: %1 = icmp ult i32 %a, 2
+; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test11(i32 %a) nounwind {
+ %1 = and i32 %a, 2
+ %2 = icmp ne i32 %1, 0
+ %3 = icmp ugt i32 %a, 3
+ %or.cond = or i1 %2, %3
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK-LABEL: @test11(
+; CHECK-NEXT: %1 = icmp ugt i32 %a, 1
+; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
diff --git a/test/Transforms/InstCombine/sincospi.ll b/test/Transforms/InstCombine/sincospi.ll
index 0d1a6027a00a..739827f1962a 100644
--- a/test/Transforms/InstCombine/sincospi.ll
+++ b/test/Transforms/InstCombine/sincospi.ll
@@ -1,5 +1,6 @@
; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefix=CHECK-FLOAT-IN-VEC
; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s
+; RUN: opt -instcombine -S < %s -mtriple=arm64-apple-ios7.0 | FileCheck %s
; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefix=CHECK-NO-SINCOS
; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefix=CHECK-NO-SINCOS
; RUN: opt -instcombine -S < %s -mtriple=x86_64-none-linux-gnu | FileCheck %s --check-prefix=CHECK-NO-SINCOS
@@ -23,12 +24,12 @@ define float @test_instbased_f32() {
%res = fadd float %sin, %cos
ret float %res
; CHECK-FLOAT-IN-VEC: [[VAL:%[a-z0-9]+]] = load float* @var32
-; CHECK-FLOAT-IN-VEC: [[SINCOS:%[a-z0-9]+]] = call <2 x float> @__sincospi_stretf(float [[VAL]])
+; CHECK-FLOAT-IN-VEC: [[SINCOS:%[a-z0-9]+]] = call <2 x float> @__sincospif_stret(float [[VAL]])
; CHECK-FLOAT-IN-VEC: extractelement <2 x float> [[SINCOS]], i32 0
; CHECK-FLOAT-IN-VEC: extractelement <2 x float> [[SINCOS]], i32 1
; CHECK: [[VAL:%[a-z0-9]+]] = load float* @var32
-; CHECK: [[SINCOS:%[a-z0-9]+]] = call { float, float } @__sincospi_stretf(float [[VAL]])
+; CHECK: [[SINCOS:%[a-z0-9]+]] = call { float, float } @__sincospif_stret(float [[VAL]])
; CHECK: extractvalue { float, float } [[SINCOS]], 0
; CHECK: extractvalue { float, float } [[SINCOS]], 1
@@ -41,11 +42,11 @@ define float @test_constant_f32() {
%cos = call float @__cospif(float 1.0) #0
%res = fadd float %sin, %cos
ret float %res
-; CHECK-FLOAT-IN-VEC: [[SINCOS:%[a-z0-9]+]] = call <2 x float> @__sincospi_stretf(float 1.000000e+00)
+; CHECK-FLOAT-IN-VEC: [[SINCOS:%[a-z0-9]+]] = call <2 x float> @__sincospif_stret(float 1.000000e+00)
; CHECK-FLOAT-IN-VEC: extractelement <2 x float> [[SINCOS]], i32 0
; CHECK-FLOAT-IN-VEC: extractelement <2 x float> [[SINCOS]], i32 1
-; CHECK: [[SINCOS:%[a-z0-9]+]] = call { float, float } @__sincospi_stretf(float 1.000000e+00)
+; CHECK: [[SINCOS:%[a-z0-9]+]] = call { float, float } @__sincospif_stret(float 1.000000e+00)
; CHECK: extractvalue { float, float } [[SINCOS]], 0
; CHECK: extractvalue { float, float } [[SINCOS]], 1
diff --git a/test/Transforms/InstCombine/sprintf-1.ll b/test/Transforms/InstCombine/sprintf-1.ll
index 78dd7aa7df47..afa38f35ae83 100644
--- a/test/Transforms/InstCombine/sprintf-1.ll
+++ b/test/Transforms/InstCombine/sprintf-1.ll
@@ -77,18 +77,18 @@ define void @test_simplify6(i8* %dst) {
; CHECK-IPRINTF-LABEL: @test_simplify6(
%fmt = getelementptr [3 x i8]* @percent_d, i32 0, i32 0
call i32 (i8*, i8*, ...)* @sprintf(i8* %dst, i8* %fmt, i32 187)
-; CHECK-NEXT-IPRINTF: call i32 (i8*, i8*, ...)* @siprintf(i8* %dst, i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-IPRINTF-NEXT: call i32 (i8*, i8*, ...)* @siprintf(i8* %dst, i8* getelementptr inbounds ([3 x i8]* @percent_d, i32 0, i32 0), i32 187)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify1(i8* %dst) {
; CHECK-IPRINTF-LABEL: @test_no_simplify1(
%fmt = getelementptr [3 x i8]* @percent_f, i32 0, i32 0
call i32 (i8*, i8*, ...)* @sprintf(i8* %dst, i8* %fmt, double 1.87)
-; CHECK-NEXT-IPRINTF: call i32 (i8*, i8*, ...)* @sprintf(i8* %dst, i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-IPRINTF-NEXT: call i32 (i8*, i8*, ...)* @sprintf(i8* %dst, i8* getelementptr inbounds ([3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
ret void
-; CHECK-NEXT-IPRINTF: ret void
+; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify2(i8* %dst, i8* %fmt, double %d) {
diff --git a/test/Transforms/InstCombine/strchr-1.ll b/test/Transforms/InstCombine/strchr-1.ll
index d2c989462156..66b3e2e51c7a 100644
--- a/test/Transforms/InstCombine/strchr-1.ll
+++ b/test/Transforms/InstCombine/strchr-1.ll
@@ -63,3 +63,16 @@ define void @test_simplify5() {
store i8* %dst, i8** @chp
ret void
}
+
+; Check transformation strchr(p, 0) -> p + strlen(p)
+define void @test_simplify6(i8* %str) {
+; CHECK: %strlen = call i32 @strlen(i8* %str)
+; CHECK-NOT: call i8* @strchr
+; CHECK: %strchr = getelementptr i8* %str, i32 %strlen
+; CHECK: store i8* %strchr, i8** @chp, align 4
+; CHECK: ret void
+
+ %dst = call i8* @strchr(i8* %str, i32 0)
+ store i8* %dst, i8** @chp
+ ret void
+}
diff --git a/test/Transforms/InstCombine/strlen-1.ll b/test/Transforms/InstCombine/strlen-1.ll
index 4fa5b4fdb62f..4a3caf28a0fe 100644
--- a/test/Transforms/InstCombine/strlen-1.ll
+++ b/test/Transforms/InstCombine/strlen-1.ll
@@ -5,6 +5,7 @@
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
@hello = constant [6 x i8] c"hello\00"
+@longer = constant [7 x i8] c"longer\00"
@null = constant [1 x i8] zeroinitializer
@null_hello = constant [7 x i8] c"\00hello\00"
@nullstring = constant i8 0
@@ -85,6 +86,17 @@ define i1 @test_simplify8() {
; CHECK-NEXT: ret i1 false
}
+define i32 @test_simplify9(i1 %x) {
+; CHECK-LABEL: @test_simplify9
+ %hello = getelementptr [6 x i8]* @hello, i32 0, i32 0
+ %longer = getelementptr [7 x i8]* @longer, i32 0, i32 0
+ %s = select i1 %x, i8* %hello, i8* %longer
+ %l = call i32 @strlen(i8* %s)
+; CHECK-NEXT: select i1 %x, i32 5, i32 6
+ ret i32 %l
+; CHECK-NEXT: ret
+}
+
; Check cases that shouldn't be simplified.
define i32 @test_no_simplify1() {
diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll
index 36c523bd7b75..67b7c4996b07 100644
--- a/test/Transforms/InstCombine/sub.ll
+++ b/test/Transforms/InstCombine/sub.ll
@@ -391,4 +391,76 @@ define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
ret i16 %sub
}
+define <2 x i64> @test31(<2 x i64> %A) {
+ %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
+ %sub = sub <2 x i64> <i64 2, i64 3>, %xor
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test31(
+; CHECK-NEXT: %sub = add <2 x i64> %A, <i64 3, i64 4>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test32(<2 x i64> %A) {
+ %add = add <2 x i64> %A, <i64 -1, i64 -1>
+ %sub = sub <2 x i64> <i64 2, i64 3>, %add
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test32(
+; CHECK-NEXT: %sub = sub <2 x i64> <i64 3, i64 4>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test33(<2 x i1> %A) {
+ %ext = zext <2 x i1> %A to <2 x i64>
+ %sub = sub <2 x i64> zeroinitializer, %ext
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test33(
+; CHECK-NEXT: %sub = sext <2 x i1> %A to <2 x i64>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test34(<2 x i1> %A) {
+ %ext = sext <2 x i1> %A to <2 x i64>
+ %sub = sub <2 x i64> zeroinitializer, %ext
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test34(
+; CHECK-NEXT: %sub = zext <2 x i1> %A to <2 x i64>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+define <2 x i64> @test35(<2 x i64> %A) {
+ %mul = mul <2 x i64> %A, <i64 3, i64 4>
+ %sub = sub <2 x i64> %A, %mul
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test35(
+; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 -2, i64 -3>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test36(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 3, i64 4>
+ %sub = sub <2 x i64> %shl, %A
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test36(
+; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 7, i64 15>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i32> @test37(<2 x i32> %A) {
+ %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
+ %sub = sub nsw <2 x i32> zeroinitializer, %div
+ ret <2 x i32> %sub
+; CHECK-LABEL: @test37(
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[ICMP]] to <2 x i32>
+; CHECK-NEXT: ret <2 x i32> [[SEXT]]
+}
+
+define i32 @test38(i32 %A) {
+ %div = sdiv i32 %A, -2147483648
+ %sub = sub nsw i32 0, %div
+ ret i32 %sub
+; CHECK-LABEL: @test38(
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 %A, -2147483648
+; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
+; CHECK-NEXT: ret i32 [[SEXT]]
+}
diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll
index d12412a92977..41d2b292eeff 100644
--- a/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define i16 @test1(float %f) {
entry:
@@ -209,4 +210,369 @@ define <4 x float> @test_select(float %f, float %g) {
ret <4 x float> %ret
}
+; We should optimize these two redundant insertqi into one
+; CHECK: define <2 x i64> @testInsertTwice(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertTwice(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 32)
+; CHECK-NOT: insertqi
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 32)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 32)
+ ret <2 x i64> %2
+}
+
+; The result of this insert is the second arg, since the top 64 bits of
+; the result are undefined, and we copy the bottom 64 bits from the
+; second arg
+; CHECK: define <2 x i64> @testInsert64Bits(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsert64Bits(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: ret <2 x i64> %i
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 64, i8 0)
+ ret <2 x i64> %1
+}
+
+; Test the several types of ranges and ordering that exist for two insertqi
+; CHECK: define <2 x i64> @testInsertContainedRange(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertContainedRange(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 16)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertContainedRange_2(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertContainedRange_2(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 16)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertOverlappingRange(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertOverlappingRange(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 16)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertOverlappingRange_2(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertOverlappingRange_2(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 16)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertAdjacentRange(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertAdjacentRange(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertAdjacentRange_2(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertAdjacentRange_2(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)
+; CHECK: ret <2 x i64> %[[RES]]
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 32)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertDisjointRange(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertDisjointRange(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)
+; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)
+ ret <2 x i64> %2
+}
+
+; CHECK: define <2 x i64> @testInsertDisjointRange_2(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testInsertDisjointRange_2(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)
+; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)
+ %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)
+ ret <2 x i64> %2
+}
+
+
+; CHECK: declare <2 x i64> @llvm.x86.sse4a.insertqi
+declare <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64>, <2 x i64>, i8, i8) nounwind
+
+declare <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float>, <4 x i32>)
+define <4 x float> @test_vpermilvar_ps(<4 x float> %v) {
+; CHECK-LABEL: @test_vpermilvar_ps(
+; CHECK: shufflevector <4 x float> %v, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+ %a = tail call <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float> %v, <4 x i32> <i32 3, i32 2, i32 1, i32 0>)
+ ret <4 x float> %a
+}
+
+declare <8 x float> @llvm.x86.avx.vpermilvar.ps.256(<8 x float>, <8 x i32>)
+define <8 x float> @test_vpermilvar_ps_256(<8 x float> %v) {
+; CHECK-LABEL: @test_vpermilvar_ps_256(
+; CHECK: shufflevector <8 x float> %v, <8 x float> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
+ %a = tail call <8 x float> @llvm.x86.avx.vpermilvar.ps.256(<8 x float> %v, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>)
+ ret <8 x float> %a
+}
+
+declare <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double>, <2 x i32>)
+define <2 x double> @test_vpermilvar_pd(<2 x double> %v) {
+; CHECK-LABEL: @test_vpermilvar_pd(
+; CHECK: shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+ %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i32> <i32 2, i32 0>)
+ ret <2 x double> %a
+}
+
+declare <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double>, <4 x i32>)
+define <4 x double> @test_vpermilvar_pd_256(<4 x double> %v) {
+; CHECK-LABEL: @test_vpermilvar_pd_256(
+; CHECK: shufflevector <4 x double> %v, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+ %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i32> <i32 3, i32 1, i32 2, i32 0>)
+ ret <4 x double> %a
+}
+
+define <4 x float> @test_vpermilvar_ps_zero(<4 x float> %v) {
+; CHECK-LABEL: @test_vpermilvar_ps_zero(
+; CHECK: shufflevector <4 x float> %v, <4 x float> undef, <4 x i32> zeroinitializer
+ %a = tail call <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float> %v, <4 x i32> zeroinitializer)
+ ret <4 x float> %a
+}
+
+define <8 x float> @test_vpermilvar_ps_256_zero(<8 x float> %v) {
+; CHECK-LABEL: @test_vpermilvar_ps_256_zero(
+; CHECK: shufflevector <8 x float> %v, <8 x float> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+ %a = tail call <8 x float> @llvm.x86.avx.vpermilvar.ps.256(<8 x float> %v, <8 x i32> zeroinitializer)
+ ret <8 x float> %a
+}
+
+define <2 x double> @test_vpermilvar_pd_zero(<2 x double> %v) {
+; CHECK-LABEL: @test_vpermilvar_pd_zero(
+; CHECK: shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> zeroinitializer
+ %a = tail call <2 x double> @llvm.x86.avx.vpermilvar.pd(<2 x double> %v, <2 x i32> zeroinitializer)
+ ret <2 x double> %a
+}
+
+define <4 x double> @test_vpermilvar_pd_256_zero(<4 x double> %v) {
+; CHECK-LABEL: @test_vpermilvar_pd_256_zero(
+; CHECK: shufflevector <4 x double> %v, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
+ %a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i32> zeroinitializer)
+ ret <4 x double> %a
+}
+
+define <2 x i64> @test_sse2_1() nounwind readnone uwtable {
+ %S = bitcast i32 1 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, <8 x i16> %4)
+ %6 = bitcast <8 x i16> %5 to <4 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <4 x i32> %8 to <2 x i64>
+ %10 = tail call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <2 x i64> %10 to <8 x i16>
+ %12 = tail call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %11, i32 %S)
+ %13 = bitcast <8 x i16> %12 to <4 x i32>
+ %14 = tail call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %13, i32 %S)
+ %15 = bitcast <4 x i32> %14 to <2 x i64>
+ %16 = tail call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %15, i32 %S)
+ ret <2 x i64> %16
+; CHECK: test_sse2_1
+; CHECK: ret <2 x i64> <i64 72058418680037440, i64 144117112246370624>
+}
+
+define <4 x i64> @test_avx2_1() nounwind readnone uwtable {
+ %S = bitcast i32 1 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <16 x i16> @llvm.x86.avx2.psll.w(<16 x i16> <i16 1, i16 0, i16 0, i16 0, i16 2, i16 0, i16 0, i16 0, i16 3, i16 0, i16 0, i16 0, i16 4, i16 0, i16 0, i16 0>, <8 x i16> %4)
+ %6 = bitcast <16 x i16> %5 to <8 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <8 x i32> @llvm.x86.avx2.psll.d(<8 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <8 x i32> %8 to <4 x i64>
+ %10 = tail call <4 x i64> @llvm.x86.avx2.psll.q(<4 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <4 x i64> %10 to <16 x i16>
+ %12 = tail call <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16> %11, i32 %S)
+ %13 = bitcast <16 x i16> %12 to <8 x i32>
+ %14 = tail call <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32> %13, i32 %S)
+ %15 = bitcast <8 x i32> %14 to <4 x i64>
+ %16 = tail call <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64> %15, i32 %S)
+ ret <4 x i64> %16
+; CHECK: test_avx2_1
+; CHECK: ret <4 x i64> <i64 64, i64 128, i64 192, i64 256>
+}
+
+define <2 x i64> @test_sse2_0() nounwind readnone uwtable {
+ %S = bitcast i32 128 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, <8 x i16> %4)
+ %6 = bitcast <8 x i16> %5 to <4 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <4 x i32> %8 to <2 x i64>
+ %10 = tail call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <2 x i64> %10 to <8 x i16>
+ %12 = tail call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %11, i32 %S)
+ %13 = bitcast <8 x i16> %12 to <4 x i32>
+ %14 = tail call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %13, i32 %S)
+ %15 = bitcast <4 x i32> %14 to <2 x i64>
+ %16 = tail call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %15, i32 %S)
+ ret <2 x i64> %16
+; CHECK: test_sse2_0
+; CHECK: ret <2 x i64> zeroinitializer
+}
+
+define <4 x i64> @test_avx2_0() nounwind readnone uwtable {
+ %S = bitcast i32 128 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <16 x i16> @llvm.x86.avx2.psll.w(<16 x i16> <i16 1, i16 0, i16 0, i16 0, i16 2, i16 0, i16 0, i16 0, i16 3, i16 0, i16 0, i16 0, i16 4, i16 0, i16 0, i16 0>, <8 x i16> %4)
+ %6 = bitcast <16 x i16> %5 to <8 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <8 x i32> @llvm.x86.avx2.psll.d(<8 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <8 x i32> %8 to <4 x i64>
+ %10 = tail call <4 x i64> @llvm.x86.avx2.psll.q(<4 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <4 x i64> %10 to <16 x i16>
+ %12 = tail call <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16> %11, i32 %S)
+ %13 = bitcast <16 x i16> %12 to <8 x i32>
+ %14 = tail call <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32> %13, i32 %S)
+ %15 = bitcast <8 x i32> %14 to <4 x i64>
+ %16 = tail call <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64> %15, i32 %S)
+ ret <4 x i64> %16
+; CHECK: test_avx2_0
+; CHECK: ret <4 x i64> zeroinitializer
+}
+define <2 x i64> @test_sse2_psrl_1() nounwind readnone uwtable {
+ %S = bitcast i32 1 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> <i16 16, i16 32, i16 64, i16 128, i16 256, i16 512, i16 1024, i16 2048>, <8 x i16> %4)
+ %6 = bitcast <8 x i16> %5 to <4 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <4 x i32> %8 to <2 x i64>
+ %10 = tail call <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <2 x i64> %10 to <8 x i16>
+ %12 = tail call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %11, i32 %S)
+ %13 = bitcast <8 x i16> %12 to <4 x i32>
+ %14 = tail call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %13, i32 %S)
+ %15 = bitcast <4 x i32> %14 to <2 x i64>
+ %16 = tail call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %15, i32 %S)
+ ret <2 x i64> %16
+; CHECK: test_sse2_psrl_1
+; CHECK: ret <2 x i64> <i64 562954248421376, i64 9007267974742020>
+}
+
+define <4 x i64> @test_avx2_psrl_1() nounwind readnone uwtable {
+ %S = bitcast i32 1 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <16 x i16> @llvm.x86.avx2.psrl.w(<16 x i16> <i16 1024, i16 0, i16 0, i16 0, i16 2048, i16 0, i16 0, i16 0, i16 4096, i16 0, i16 0, i16 0, i16 8192, i16 0, i16 0, i16 0>, <8 x i16> %4)
+ %6 = bitcast <16 x i16> %5 to <8 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <8 x i32> @llvm.x86.avx2.psrl.d(<8 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <8 x i32> %8 to <4 x i64>
+ %10 = tail call <4 x i64> @llvm.x86.avx2.psrl.q(<4 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <4 x i64> %10 to <16 x i16>
+ %12 = tail call <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16> %11, i32 %S)
+ %13 = bitcast <16 x i16> %12 to <8 x i32>
+ %14 = tail call <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32> %13, i32 %S)
+ %15 = bitcast <8 x i32> %14 to <4 x i64>
+ %16 = tail call <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64> %15, i32 %S)
+ ret <4 x i64> %16
+; CHECK: test_avx2_psrl_1
+; CHECK: ret <4 x i64> <i64 16, i64 32, i64 64, i64 128>
+}
+
+define <2 x i64> @test_sse2_psrl_0() nounwind readnone uwtable {
+ %S = bitcast i32 128 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> <i16 32, i16 64, i16 128, i16 256, i16 512, i16 1024, i16 2048, i16 4096>, <8 x i16> %4)
+ %6 = bitcast <8 x i16> %5 to <4 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <4 x i32> %8 to <2 x i64>
+ %10 = tail call <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <2 x i64> %10 to <8 x i16>
+ %12 = tail call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %11, i32 %S)
+ %13 = bitcast <8 x i16> %12 to <4 x i32>
+ %14 = tail call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %13, i32 %S)
+ %15 = bitcast <4 x i32> %14 to <2 x i64>
+ %16 = tail call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %15, i32 %S)
+ ret <2 x i64> %16
+; CHECK: test_sse2_psrl_0
+; CHECK: ret <2 x i64> zeroinitializer
+}
+
+define <4 x i64> @test_avx2_psrl_0() nounwind readnone uwtable {
+ %S = bitcast i32 128 to i32
+ %1 = zext i32 %S to i64
+ %2 = insertelement <2 x i64> undef, i64 %1, i32 0
+ %3 = insertelement <2 x i64> %2, i64 0, i32 1
+ %4 = bitcast <2 x i64> %3 to <8 x i16>
+ %5 = tail call <16 x i16> @llvm.x86.avx2.psrl.w(<16 x i16> <i16 1024, i16 0, i16 0, i16 0, i16 2048, i16 0, i16 0, i16 0, i16 4096, i16 0, i16 0, i16 0, i16 8192, i16 0, i16 0, i16 0>, <8 x i16> %4)
+ %6 = bitcast <16 x i16> %5 to <8 x i32>
+ %7 = bitcast <2 x i64> %3 to <4 x i32>
+ %8 = tail call <8 x i32> @llvm.x86.avx2.psrl.d(<8 x i32> %6, <4 x i32> %7)
+ %9 = bitcast <8 x i32> %8 to <4 x i64>
+ %10 = tail call <4 x i64> @llvm.x86.avx2.psrl.q(<4 x i64> %9, <2 x i64> %3)
+ %11 = bitcast <4 x i64> %10 to <16 x i16>
+ %12 = tail call <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16> %11, i32 %S)
+ %13 = bitcast <16 x i16> %12 to <8 x i32>
+ %14 = tail call <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32> %13, i32 %S)
+ %15 = bitcast <8 x i32> %14 to <4 x i64>
+ %16 = tail call <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64> %15, i32 %S)
+ ret <4 x i64> %16
+; CHECK: test_avx2_psrl_0
+; CHECK: ret <4 x i64> zeroinitializer
+}
+
+declare <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64>, i32) #1
+declare <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32>, i32) #1
+declare <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16>, i32) #1
+declare <4 x i64> @llvm.x86.avx2.psll.q(<4 x i64>, <2 x i64>) #1
+declare <8 x i32> @llvm.x86.avx2.psll.d(<8 x i32>, <4 x i32>) #1
+declare <16 x i16> @llvm.x86.avx2.psll.w(<16 x i16>, <8 x i16>) #1
+declare <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64>, i32) #1
+declare <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32>, i32) #1
+declare <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16>, i32) #1
+declare <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64>, <2 x i64>) #1
+declare <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32>, <4 x i32>) #1
+declare <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16>, <8 x i16>) #1
+declare <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64>, i32) #1
+declare <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32>, i32) #1
+declare <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16>, i32) #1
+declare <4 x i64> @llvm.x86.avx2.psrl.q(<4 x i64>, <2 x i64>) #1
+declare <8 x i32> @llvm.x86.avx2.psrl.d(<8 x i32>, <4 x i32>) #1
+declare <16 x i16> @llvm.x86.avx2.psrl.w(<16 x i16>, <8 x i16>) #1
+declare <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64>, i32) #1
+declare <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32>, i32) #1
+declare <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16>, i32) #1
+declare <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64>, <2 x i64>) #1
+declare <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32>, <4 x i32>) #1
+declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <8 x i16>) #1
+attributes #1 = { nounwind readnone }
diff --git a/test/Transforms/InstCombine/vec_phi_extract.ll b/test/Transforms/InstCombine/vec_phi_extract.ll
index 73ec1f1bb04f..1d778a000fb7 100644
--- a/test/Transforms/InstCombine/vec_phi_extract.ll
+++ b/test/Transforms/InstCombine/vec_phi_extract.ll
@@ -36,10 +36,10 @@ for.cond:
%input_1.addr.1 = phi <3 x i32> [ undef, %entry ], [ %dec43, %for.body ]
br i1 undef, label %for.end, label %for.body
-; CHECK extractelement
+; CHECK: extractelement
for.body:
%dec43 = add <3 x i32> %input_1.addr.1, <i32 -1, i32 -1, i32 -1>
- %sub44 = sub <3 x i32> zeroinitializer, %dec43
+ %sub44 = sub <3 x i32> <i32 -1, i32 -1, i32 -1>, %dec43
%div45 = sdiv <3 x i32> %input_2.addr.0, %sub44
br label %for.cond
diff --git a/test/Transforms/InstCombine/vec_sext.ll b/test/Transforms/InstCombine/vec_sext.ll
index d7ab96b9cfd8..6f0d21476e3e 100644
--- a/test/Transforms/InstCombine/vec_sext.ll
+++ b/test/Transforms/InstCombine/vec_sext.ll
@@ -13,6 +13,7 @@ entry:
%cond = or <4 x i32> %2, %3
ret <4 x i32> %cond
+; CHECK-LABEL: @psignd_3
; CHECK: ashr <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31>
; CHECK: sub nsw <4 x i32> zeroinitializer, %a
; CHECK: xor <4 x i32> %b.lobit, <i32 -1, i32 -1, i32 -1, i32 -1>
@@ -20,3 +21,25 @@ entry:
; CHECK: and <4 x i32> %b.lobit, %sub
; CHECK: or <4 x i32> %1, %2
}
+
+define <4 x i32> @test1(<4 x i32> %a, <4 x i32> %b) nounwind ssp {
+entry:
+ %cmp = icmp sgt <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
+ %sext = sext <4 x i1> %cmp to <4 x i32>
+ %sub = sub nsw <4 x i32> zeroinitializer, %a
+ %0 = icmp slt <4 x i32> %sext, zeroinitializer
+ %sext3 = sext <4 x i1> %0 to <4 x i32>
+ %1 = xor <4 x i32> %sext3, <i32 -1, i32 -1, i32 -1, i32 -1>
+ %2 = and <4 x i32> %a, %1
+ %3 = and <4 x i32> %sext3, %sub
+ %cond = or <4 x i32> %2, %3
+ ret <4 x i32> %cond
+
+; CHECK-LABEL: @test1
+; CHECK: ashr <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31>
+; CHECK: xor <4 x i32> %b.lobit, <i32 -1, i32 -1, i32 -1, i32 -1>
+; CHECK: sub nsw <4 x i32> zeroinitializer, %a
+; CHECK: and <4 x i32> %b.lobit, %a
+; CHECK: and <4 x i32> %b.lobit.not, %sub
+; CHECK: or <4 x i32> %0, %1
+}
diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll
index 3ee43dc63a6f..eb4e9d6f8c30 100644
--- a/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/test/Transforms/InstCombine/vec_shuffle.ll
@@ -228,3 +228,189 @@ define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {
ret <4 x float> %tmp5
}
+define <1 x i32> @test16a(i32 %ele) {
+; CHECK-LABEL: @test16a(
+; CHECK-NEXT: ret <1 x i32> <i32 2>
+ %tmp0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1
+ %tmp1 = shl <2 x i32> %tmp0, <i32 1, i32 1>
+ %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <1 x i32> <i32 0>
+ ret <1 x i32> %tmp2
+}
+
+define <4 x i8> @test16b(i8 %ele) {
+; CHECK-LABEL: @test16b(
+; CHECK-NEXT: ret <4 x i8> <i8 2, i8 2, i8 2, i8 2>
+ %tmp0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6
+ %tmp1 = shl <8 x i8> %tmp0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+ %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
+ ret <4 x i8> %tmp2
+}
+
+; If composition of two shuffles is identity, shuffles can be removed.
+define <4 x i32> @shuffle_17ident(<4 x i32> %v) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17ident(
+; CHECK-NOT: shufflevector
+ %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 3, i32 0, i32 1, i32 2>
+ ret <4 x i32> %shuffle2
+}
+
+; swizzle can be put after operation
+define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17and(
+; CHECK-NOT: shufflevector
+; CHECK: and <4 x i32> %v1, %v2
+; CHECK: shufflevector
+ %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = and <4 x i32> %t1, %t2
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17add(
+; CHECK-NOT: shufflevector
+; CHECK: add <4 x i32> %v1, %v2
+; CHECK: shufflevector
+ %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = add <4 x i32> %t1, %t2
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17addnsw(
+; CHECK-NOT: shufflevector
+; CHECK: add nsw <4 x i32> %v1, %v2
+; CHECK: shufflevector
+ %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = add nsw <4 x i32> %t1, %t2
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17addnuw(
+; CHECK-NOT: shufflevector
+; CHECK: add nuw <4 x i32> %v1, %v2
+; CHECK: shufflevector
+ %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = add nuw <4 x i32> %t1, %t2
+ ret <4 x i32> %r
+}
+
+define <4 x float> @shuffle_17fsub(<4 x float> %v1, <4 x float> %v2) nounwind uwtable {
+; CHECK-LABEL: @shuffle_17fsub(
+; CHECK-NOT: shufflevector
+; CHECK: fsub <4 x float> %v1, %v2
+; CHECK: shufflevector
+ %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = fsub <4 x float> %t1, %t2
+ ret <4 x float> %r
+}
+
+define <4 x i32> @shuffle_17addconst(<4 x i32> %v1, <4 x i32> %v2) {
+; CHECK-LABEL: @shuffle_17addconst(
+; CHECK-NOT: shufflevector
+; CHECK: [[VAR1:%[a-zA-Z0-9.]+]] = add <4 x i32> %v1, <i32 4, i32 1, i32 2, i32 3>
+; CHECK: [[VAR2:%[a-zA-Z0-9.]+]] = shufflevector <4 x i32> [[VAR1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+; CHECK: ret <4 x i32> [[VAR2]]
+ %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 2, i32 3, i32 0>
+ %r = add <4 x i32> %t1, <i32 1, i32 2, i32 3, i32 4>
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @shuffle_17add2(<4 x i32> %v) {
+; CHECK-LABEL: @shuffle_17add2(
+; CHECK-NOT: shufflevector
+; CHECK: [[VAR:%[a-zA-Z0-9.]+]] = shl <4 x i32> %v, <i32 1, i32 1, i32 1, i32 1>
+; CHECK: ret <4 x i32> [[VAR]]
+ %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+ %t2 = add <4 x i32> %t1, %t1
+ %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer,
+ <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {
+; CHECK-LABEL: @shuffle_17mulsplat(
+; CHECK-NOT: shufflevector
+; CHECK: [[VAR1:%[a-zA-Z0-9.]+]] = mul <4 x i32> %v, %v
+; CHECK: [[VAR2:%[a-zA-Z0-9.]+]] = shufflevector <4 x i32> [[VAR1]], <4 x i32> undef, <4 x i32> zeroinitializer
+; CHECK: ret <4 x i32> [[VAR2]]
+ %s1 = shufflevector <4 x i32> %v,
+ <4 x i32> zeroinitializer,
+ <4 x i32> zeroinitializer
+ %m1 = mul <4 x i32> %s1, %s1
+ %s2 = shufflevector <4 x i32> %m1,
+ <4 x i32> zeroinitializer,
+ <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ ret <4 x i32> %s2
+}
+
+; Do not reorder shuffle and binop if LHS of shuffles are of different size
+define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {
+; CHECK-LABEL: @pr19717(
+; CHECK: shufflevector
+; CHECK: shufflevector
+; CHECK: mul
+ %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer
+ %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer
+ %mul = mul <2 x i32> %shuffle, %shuffle4
+ ret <2 x i32> %mul
+}
+
+define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {
+; CHECK-LABEL: @pr19717a(
+; CHECK: [[VAR1:%[a-zA-Z0-9.]+]] = mul <8 x i16> %in0, %in1
+; CHECK: [[VAR2:%[a-zA-Z0-9.]+]] = shufflevector <8 x i16> [[VAR1]], <8 x i16> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
+; CHECK: ret <4 x i16> [[VAR2]]
+ %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
+ %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
+ %mul = mul <4 x i16> %shuffle, %shuffle1
+ ret <4 x i16> %mul
+}
+
+define <8 x i8> @pr19730(<16 x i8> %in0) {
+; CHECK-LABEL: @pr19730(
+; CHECK: shufflevector
+ %shuffle = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
+ %shuffle1 = shufflevector <8 x i8> %shuffle, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
+ ret <8 x i8> %shuffle1
+}
+
+define i32 @pr19737(<4 x i32> %in0) {
+; CHECK-LABEL: @pr19737(
+; CHECK: [[VAR:%[a-zA-Z0-9.]+]] = extractelement <4 x i32> %in0, i32 0
+; CHECK: ret i32 [[VAR]]
+ %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
+ %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>
+ %and.i = and <4 x i32> %in0, %neg.i
+ %rv = extractelement <4 x i32> %and.i, i32 0
+ ret i32 %rv
+}
+
+define <4 x i32> @pr20114(<4 x i32> %__mask) {
+; CHECK-LABEL: @pr20114
+; CHECK: shufflevector
+; CHECK: and
+ %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ %masked_new.i.i.i = and <4 x i32> bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>), %mask01.i
+ ret <4 x i32> %masked_new.i.i.i
+}
diff --git a/test/Transforms/InstCombine/zext-bool-add-sub.ll b/test/Transforms/InstCombine/zext-bool-add-sub.ll
index d7f338b659b4..6fa4d70d6360 100644
--- a/test/Transforms/InstCombine/zext-bool-add-sub.ll
+++ b/test/Transforms/InstCombine/zext-bool-add-sub.ll
@@ -6,7 +6,7 @@ entry:
; CHECK-LABEL: @a(
; CHECK: [[TMP1:%.*]] = sext i1 %y to i32
; CHECK: [[TMP2:%.*]] = select i1 %x, i32 2, i32 1
-; CHECK-NEXT: add i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT: add nsw i32 [[TMP2]], [[TMP1]]
%conv = zext i1 %x to i32
%conv3 = zext i1 %y to i32
%conv3.neg = sub i32 0, %conv3
diff --git a/test/Transforms/InstCombine/zext.ll b/test/Transforms/InstCombine/zext.ll
index 10eabf7aed46..b62c626c95c0 100644
--- a/test/Transforms/InstCombine/zext.ll
+++ b/test/Transforms/InstCombine/zext.ll
@@ -5,7 +5,41 @@ define i64 @test_sext_zext(i16 %A) {
%c1 = zext i16 %A to i32 ; <i32> [#uses=1]
%c2 = sext i32 %c1 to i64 ; <i64> [#uses=1]
ret i64 %c2
+
+; CHECK-LABEL: @test_sext_zext
; CHECK-NOT: %c1
; CHECK: %c2 = zext i16 %A to i64
; CHECK: ret i64 %c2
}
+
+define <2 x i64> @test2(<2 x i1> %A) {
+ %xor = xor <2 x i1> %A, <i1 true, i1 true>
+ %zext = zext <2 x i1> %xor to <2 x i64>
+ ret <2 x i64> %zext
+
+; CHECK-LABEL: @test2
+; CHECK-NEXT: zext <2 x i1> %A to <2 x i64>
+; CHECK-NEXT: xor <2 x i64> %1, <i64 1, i64 1>
+}
+
+define <2 x i64> @test3(<2 x i64> %A) {
+ %trunc = trunc <2 x i64> %A to <2 x i32>
+ %and = and <2 x i32> %trunc, <i32 23, i32 42>
+ %zext = zext <2 x i32> %and to <2 x i64>
+ ret <2 x i64> %zext
+
+; CHECK-LABEL: @test3
+; CHECK-NEXT: and <2 x i64> %A, <i64 23, i64 42>
+}
+
+define <2 x i64> @test4(<2 x i64> %A) {
+ %trunc = trunc <2 x i64> %A to <2 x i32>
+ %and = and <2 x i32> %trunc, <i32 23, i32 42>
+ %xor = xor <2 x i32> %and, <i32 23, i32 42>
+ %zext = zext <2 x i32> %xor to <2 x i64>
+ ret <2 x i64> %zext
+
+; CHECK-LABEL: @test4
+; CHECK-NEXT: xor <2 x i64> %A, <i64 4294967295, i64 4294967295>
+; CHECK-NEXT: and <2 x i64> %1, <i64 23, i64 42>
+}