2016-07-23 04:39:07 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
2002-04-19 01:35:39 +08:00
|
|
|
|
2017-04-05 21:33:10 +08:00
|
|
|
define i32 @select_0_or_1_from_bool(i1 %x) {
|
|
|
|
; CHECK-LABEL: @select_0_or_1_from_bool(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true
|
[InstCombine] add (sext i1 X), 1 --> zext (not X)
http://rise4fun.com/Alive/i8Q
A narrow bitwise logic op is obviously better than math for value tracking,
and zext is better than sext. Typically, the 'not' will be folded into an
icmp predicate.
The IR difference would even survive through codegen for x86, so we would see
worse code:
https://godbolt.org/g/C14HMF
one_or_zero(int, int): # @one_or_zero(int, int)
xorl %eax, %eax
cmpl %esi, %edi
setle %al
retq
one_or_zero_alt(int, int): # @one_or_zero_alt(int, int)
xorl %ecx, %ecx
cmpl %esi, %edi
setg %cl
movl $1, %eax
subl %ecx, %eax
retq
llvm-svn: 306243
2017-06-25 22:15:28 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[TMP1]] to i32
|
2017-04-05 21:33:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[ADD]]
|
|
|
|
;
|
|
|
|
%ext = sext i1 %x to i32
|
|
|
|
%add = add i32 %ext, 1
|
|
|
|
ret i32 %add
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
|
|
|
|
; CHECK-LABEL: @select_0_or_1_from_bool_vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
|
[InstCombine] add (sext i1 X), 1 --> zext (not X)
http://rise4fun.com/Alive/i8Q
A narrow bitwise logic op is obviously better than math for value tracking,
and zext is better than sext. Typically, the 'not' will be folded into an
icmp predicate.
The IR difference would even survive through codegen for x86, so we would see
worse code:
https://godbolt.org/g/C14HMF
one_or_zero(int, int): # @one_or_zero(int, int)
xorl %eax, %eax
cmpl %esi, %edi
setle %al
retq
one_or_zero_alt(int, int): # @one_or_zero_alt(int, int)
xorl %ecx, %ecx
cmpl %esi, %edi
setg %cl
movl $1, %eax
subl %ecx, %eax
retq
llvm-svn: 306243
2017-06-25 22:15:28 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
|
2017-04-05 21:33:10 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[ADD]]
|
|
|
|
;
|
|
|
|
%ext = sext <2 x i1> %x to <2 x i32>
|
|
|
|
%add = add <2 x i32> %ext, <i32 1, i32 1>
|
|
|
|
ret <2 x i32> %add
|
|
|
|
}
|
|
|
|
|
2018-06-26 01:52:10 +08:00
|
|
|
define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
|
|
|
|
; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(
|
|
|
|
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[X:%.*]] to i32
|
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 42
|
|
|
|
; CHECK-NEXT: ret i32 [[ADD]]
|
|
|
|
;
|
|
|
|
%ext = sext i1 %x to i32
|
|
|
|
%add = add i32 %ext, 42
|
|
|
|
ret i32 %add
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {
|
|
|
|
; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(
|
|
|
|
; CHECK-NEXT: [[EXT:%.*]] = sext <2 x i1> [[X:%.*]] to <2 x i32>
|
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i32> [[EXT]], <i32 42, i32 43>
|
|
|
|
; CHECK-NEXT: ret <2 x i32> [[ADD]]
|
|
|
|
;
|
|
|
|
%ext = sext <2 x i1> %x to <2 x i32>
|
|
|
|
%add = add <2 x i32> %ext, <i32 42, i32 43>
|
|
|
|
ret <2 x i32> %add
|
|
|
|
}
|
|
|
|
|
2017-05-10 07:40:13 +08:00
|
|
|
; This is an 'andn' of the low bit.
|
|
|
|
|
|
|
|
define i32 @flip_and_mask(i32 %x) {
|
|
|
|
; CHECK-LABEL: @flip_and_mask(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1
|
2017-05-10 21:56:52 +08:00
|
|
|
; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 1
|
2017-05-10 07:40:13 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[INC]]
|
|
|
|
;
|
|
|
|
%shl = shl i32 %x, 31
|
|
|
|
%shr = ashr i32 %shl, 31
|
|
|
|
%inc = add i32 %shr, 1
|
|
|
|
ret i32 %inc
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
|
|
|
|
; CHECK-LABEL: @flip_and_mask_splat(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 1, i8 1>
|
2017-08-07 07:11:49 +08:00
|
|
|
; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1>
|
2017-05-10 07:40:13 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i8> [[INC]]
|
|
|
|
;
|
|
|
|
%shl = shl <2 x i8> %x, <i8 7, i8 7>
|
|
|
|
%shr = ashr <2 x i8> %shl, <i8 7, i8 7>
|
|
|
|
%inc = add <2 x i8> %shr, <i8 1, i8 1>
|
|
|
|
ret <2 x i8> %inc
|
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test1(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test1(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
|
|
|
%B = add i32 %A, 0
|
|
|
|
ret i32 %B
|
2003-02-19 03:43:53 +08:00
|
|
|
}
|
2002-04-19 01:35:39 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test2(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test2(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
|
|
|
%B = add i32 %A, 5
|
|
|
|
%C = add i32 %B, -5
|
|
|
|
ret i32 %C
|
2003-02-19 03:43:53 +08:00
|
|
|
}
|
2002-04-19 01:35:39 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test3(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test3(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
|
|
|
%B = add i32 %A, 5
|
|
|
|
%C = sub i32 %B, 5
|
|
|
|
ret i32 %C
|
2003-02-19 03:43:53 +08:00
|
|
|
}
|
2002-04-19 01:35:39 +08:00
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; D = B + -A = B - A
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test4(i32 %A, i32 %B) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test4(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
|
|
;
|
|
|
|
%C = sub i32 0, %A
|
|
|
|
%D = add i32 %B, %C
|
|
|
|
ret i32 %D
|
2002-05-07 00:44:53 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; D = -A + B = B - A
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test5(i32 %A, i32 %B) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test5(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
|
|
;
|
|
|
|
%C = sub i32 0, %A
|
|
|
|
%D = add i32 %C, %B
|
|
|
|
ret i32 %D
|
2002-05-07 00:44:53 +08:00
|
|
|
}
|
|
|
|
|
2018-06-30 22:11:46 +08:00
|
|
|
define <2 x i8> @neg_op0_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) {
|
|
|
|
; CHECK-LABEL: @neg_op0_vec_undef_elt(
|
2018-07-01 21:42:57 +08:00
|
|
|
; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]
|
2018-06-30 22:11:46 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i8> [[R]]
|
|
|
|
;
|
|
|
|
%nega = sub <2 x i8> <i8 0, i8 undef>, %a
|
|
|
|
%r = add <2 x i8> %nega, %b
|
|
|
|
ret <2 x i8> %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i8> @neg_neg_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) {
|
|
|
|
; CHECK-LABEL: @neg_neg_vec_undef_elt(
|
2018-07-01 21:42:57 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
|
2018-06-30 22:11:46 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i8> [[R]]
|
|
|
|
;
|
|
|
|
%nega = sub <2 x i8> <i8 undef, i8 0>, %a
|
|
|
|
%negb = sub <2 x i8> <i8 undef, i8 0>, %b
|
|
|
|
%r = add <2 x i8> %nega, %negb
|
|
|
|
ret <2 x i8> %r
|
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; C = 7*A+A == 8*A == A << 3
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test6(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test6(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = mul i32 7, %A
|
|
|
|
%C = add i32 %B, %A
|
|
|
|
ret i32 %C
|
2003-02-19 03:55:31 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; C = A+7*A == 8*A == A << 3
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test7(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test7(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = mul i32 7, %A
|
|
|
|
%C = add i32 %A, %B
|
|
|
|
ret i32 %C
|
2003-02-19 03:55:31 +08:00
|
|
|
}
|
|
|
|
|
2012-09-27 18:14:43 +08:00
|
|
|
; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test8(i32 %A, i32 %B) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test8(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7
|
|
|
|
; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = or i32 [[A1]], [[B1]]
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%A1 = and i32 %A, 7
|
|
|
|
%B1 = and i32 %B, 128
|
|
|
|
%C = add i32 %A1, %B1
|
|
|
|
ret i32 %C
|
2003-03-11 07:52:54 +08:00
|
|
|
}
|
2003-03-11 08:10:59 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test9(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test9(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = shl i32 %A, 4
|
|
|
|
%C = add i32 %B, %B
|
|
|
|
ret i32 %C
|
2003-07-25 03:44:51 +08:00
|
|
|
}
|
2003-08-13 13:27:57 +08:00
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; a != -b
|
|
|
|
define i1 @test10(i8 %a, i8 %b) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test10(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]]
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[ADD]], [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2018-05-01 05:03:36 +08:00
|
|
|
%add = add i8 %a, %b
|
|
|
|
%c = icmp ne i8 %add, 0
|
2016-07-23 04:39:07 +08:00
|
|
|
ret i1 %c
|
2003-08-13 13:27:57 +08:00
|
|
|
}
|
|
|
|
|
2016-07-23 05:02:33 +08:00
|
|
|
define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
|
|
|
|
; CHECK-LABEL: @test10vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]
|
|
|
|
; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[C]], [[A:%.*]]
|
2016-07-23 05:02:33 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[D]]
|
|
|
|
;
|
|
|
|
%c = add <2 x i8> %a, %b
|
|
|
|
%d = icmp ne <2 x i8> %c, zeroinitializer
|
|
|
|
ret <2 x i1> %d
|
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i1 @test11(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test11(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
|
|
|
%B = add i8 %A, -1
|
|
|
|
%c = icmp ne i8 %B, 0
|
|
|
|
ret i1 %c
|
2003-08-13 13:27:57 +08:00
|
|
|
}
|
2003-08-14 03:01:09 +08:00
|
|
|
|
2016-07-23 05:02:33 +08:00
|
|
|
define <2 x i1> @test11vec(<2 x i8> %a) {
|
|
|
|
; CHECK-LABEL: @test11vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 1, i8 1>
|
2016-07-23 05:02:33 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
|
|
;
|
|
|
|
%b = add <2 x i8> %a, <i8 -1, i8 -1>
|
|
|
|
%c = icmp ne <2 x i8> %b, zeroinitializer
|
|
|
|
ret <2 x i1> %c
|
|
|
|
}
|
|
|
|
|
2016-07-23 04:39:07 +08:00
|
|
|
; Should be transformed into shl A, 1?
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test12(i32 %A, i32 %B) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test12(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: br label [[X:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK: X:
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C_OK:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
|
|
|
|
; CHECK-NEXT: [[D:%.*]] = add i32 [[C_OK]], [[A]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
|
|
;
|
|
|
|
%C_OK = add i32 %B, %A
|
|
|
|
br label %X
|
2008-03-09 16:16:40 +08:00
|
|
|
|
|
|
|
X: ; preds = %0
|
2016-07-23 04:39:07 +08:00
|
|
|
%D = add i32 %C_OK, %A
|
|
|
|
ret i32 %D
|
2003-08-14 03:01:09 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
;; TODO: shl A, 1?
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test13(i32 %A, i32 %B, i32 %C) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test13(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
|
|
|
|
; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]
|
|
|
|
; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[F]]
|
|
|
|
;
|
|
|
|
%D_OK = add i32 %A, %B
|
|
|
|
%E_OK = add i32 %D_OK, %C
|
|
|
|
%F = add i32 %E_OK, %A
|
|
|
|
ret i32 %F
|
2003-08-14 03:01:09 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test14(i32 %offset, i32 %difference) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test14(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3
|
|
|
|
; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]
|
|
|
|
; CHECK-NEXT: ret i32 [[TMP_8]]
|
|
|
|
;
|
|
|
|
%tmp.2 = and i32 %difference, 3
|
|
|
|
%tmp.3_OK = add i32 %tmp.2, %offset
|
|
|
|
%tmp.5.mask = and i32 %difference, -4
|
|
|
|
; == add %offset, %difference
|
|
|
|
%tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask
|
|
|
|
ret i32 %tmp.8
|
2003-08-14 03:01:09 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; Only one bit set
|
2008-03-09 16:16:40 +08:00
|
|
|
define i8 @test15(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test15(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%B = add i8 %A, -64
|
|
|
|
%C = and i8 %B, 16
|
|
|
|
ret i8 %C
|
2003-09-19 23:33:46 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; Only one bit set
|
2008-03-09 16:16:40 +08:00
|
|
|
define i8 @test16(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test16(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 16
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = xor i8 [[B]], 16
|
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%B = add i8 %A, 16
|
|
|
|
%C = and i8 %B, 16
|
|
|
|
ret i8 %C
|
2003-09-19 23:33:46 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test17(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test17(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = xor i32 %A, -1
|
|
|
|
%C = add i32 %B, 1
|
|
|
|
ret i32 %C
|
2003-10-02 23:11:09 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i8 @test18(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test18(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%B = xor i8 %A, -1
|
|
|
|
%C = add i8 %B, 17
|
|
|
|
ret i8 %C
|
2003-10-02 23:11:09 +08:00
|
|
|
}
|
2004-04-10 07:47:52 +08:00
|
|
|
|
2017-10-14 04:29:11 +08:00
|
|
|
define <2 x i64> @test18vec(<2 x i64> %A) {
|
|
|
|
; CHECK-LABEL: @test18vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]
|
2017-10-14 04:29:11 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i64> [[ADD]]
|
|
|
|
;
|
|
|
|
%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
|
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test19(i1 %C) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test19(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[V]]
|
|
|
|
;
|
|
|
|
%A = select i1 %C, i32 1000, i32 10
|
|
|
|
%V = add i32 %A, 123
|
|
|
|
ret i32 %V
|
2004-04-10 07:47:52 +08:00
|
|
|
}
|
|
|
|
|
2017-04-04 01:49:15 +08:00
|
|
|
define <2 x i32> @test19vec(i1 %C) {
|
|
|
|
; CHECK-LABEL: @test19vec(
|
2017-04-11 00:40:00 +08:00
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
|
2017-04-04 01:49:15 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[V]]
|
|
|
|
;
|
|
|
|
%A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
|
|
|
|
%V = add <2 x i32> %A, <i32 123, i32 123>
|
|
|
|
ret <2 x i32> %V
|
|
|
|
}
|
|
|
|
|
2017-02-19 05:59:09 +08:00
|
|
|
; This is an InstSimplify fold, but test it here to make sure that
|
|
|
|
; InstCombine does not prevent the fold.
|
|
|
|
; With NSW, add of sign bit -> or of sign bit.
|
2017-02-09 06:14:11 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test20(i32 %x) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test20(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[X:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
2017-02-09 06:14:11 +08:00
|
|
|
%y = xor i32 %x, -2147483648
|
|
|
|
%z = add nsw i32 %y, -2147483648
|
|
|
|
ret i32 %z
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @xor_sign_bit(i32 %x) {
|
|
|
|
; CHECK-LABEL: @xor_sign_bit(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606
|
2017-02-09 06:14:11 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[ADD]]
|
|
|
|
;
|
|
|
|
%xor = xor i32 %x, 2147483648
|
|
|
|
%add = add i32 %xor, 42
|
|
|
|
ret i32 %add
|
|
|
|
}
|
|
|
|
|
2017-02-19 06:20:09 +08:00
|
|
|
; No-wrap info allows converting the add to 'or'.
|
2017-02-09 06:14:11 +08:00
|
|
|
|
|
|
|
define i8 @add_nsw_signbit(i8 %x) {
|
|
|
|
; CHECK-LABEL: @add_nsw_signbit(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
|
2017-02-09 06:14:11 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
|
|
;
|
|
|
|
%y = add nsw i8 %x, -128
|
|
|
|
ret i8 %y
|
|
|
|
}
|
|
|
|
|
2017-02-19 06:20:09 +08:00
|
|
|
; No-wrap info allows converting the add to 'or'.
|
2017-02-09 06:14:11 +08:00
|
|
|
|
|
|
|
define i8 @add_nuw_signbit(i8 %x) {
|
|
|
|
; CHECK-LABEL: @add_nuw_signbit(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
|
2017-02-09 06:14:11 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
|
|
;
|
|
|
|
%y = add nuw i8 %x, 128
|
|
|
|
ret i8 %y
|
2004-04-11 06:01:27 +08:00
|
|
|
}
|
2004-04-10 07:47:52 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i1 @test21(i32 %x) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test21(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[Y]]
|
|
|
|
;
|
|
|
|
%t = add i32 %x, 4
|
|
|
|
%y = icmp eq i32 %t, 123
|
|
|
|
ret i1 %y
|
2004-06-28 06:51:19 +08:00
|
|
|
}
|
2004-07-03 08:25:31 +08:00
|
|
|
|
2016-07-23 05:02:33 +08:00
|
|
|
define <2 x i1> @test21vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test21vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 119, i32 119>
|
2016-07-23 05:02:33 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[Y]]
|
|
|
|
;
|
|
|
|
%t = add <2 x i32> %x, <i32 4, i32 4>
|
|
|
|
%y = icmp eq <2 x i32> %t, <i32 123, i32 123>
|
|
|
|
ret <2 x i1> %y
|
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test22(i32 %V) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test22(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [
|
|
|
|
; CHECK-NEXT: i32 10, label [[LAB1:%.*]]
|
|
|
|
; CHECK-NEXT: i32 20, label [[LAB2:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ]
|
|
|
|
; CHECK: Default:
|
|
|
|
; CHECK-NEXT: ret i32 123
|
|
|
|
; CHECK: Lab1:
|
|
|
|
; CHECK-NEXT: ret i32 12312
|
|
|
|
; CHECK: Lab2:
|
|
|
|
; CHECK-NEXT: ret i32 1231231
|
|
|
|
;
|
|
|
|
%V2 = add i32 %V, 10
|
|
|
|
switch i32 %V2, label %Default [
|
|
|
|
i32 20, label %Lab1
|
|
|
|
i32 30, label %Lab2
|
|
|
|
]
|
2008-03-09 16:16:40 +08:00
|
|
|
|
|
|
|
Default: ; preds = %0
|
2016-07-23 04:39:07 +08:00
|
|
|
ret i32 123
|
2008-03-09 16:16:40 +08:00
|
|
|
|
|
|
|
Lab1: ; preds = %0
|
2016-07-23 04:39:07 +08:00
|
|
|
ret i32 12312
|
2008-03-09 16:16:40 +08:00
|
|
|
|
|
|
|
Lab2: ; preds = %0
|
2016-07-23 04:39:07 +08:00
|
|
|
ret i32 1231231
|
2004-07-03 08:25:31 +08:00
|
|
|
}
|
2004-09-29 13:06:12 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test23(i1 %C, i32 %a) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test23(
|
|
|
|
; CHECK-NEXT: entry:
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK: else:
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: br label [[ENDIF]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK: endif:
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[B_0]]
|
|
|
|
;
|
2004-09-29 13:06:12 +08:00
|
|
|
entry:
|
2016-07-23 04:39:07 +08:00
|
|
|
br i1 %C, label %endif, label %else
|
2004-09-29 13:06:12 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
else: ; preds = %entry
|
2016-07-23 04:39:07 +08:00
|
|
|
br label %endif
|
2004-09-29 13:06:12 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
endif: ; preds = %else, %entry
|
2016-07-23 04:39:07 +08:00
|
|
|
%b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
|
|
|
|
%tmp.4 = add i32 %b.0, 1
|
|
|
|
ret i32 %tmp.4
|
2004-09-29 13:06:12 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test24(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test24(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
|
|
|
%B = add i32 %A, 1
|
|
|
|
%C = shl i32 %B, 1
|
|
|
|
%D = sub i32 %C, 2
|
|
|
|
ret i32 %D
|
2004-10-08 11:41:59 +08:00
|
|
|
}
|
2004-11-14 03:49:39 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i64 @test25(i64 %Y) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test25(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i64 [[TMP_8]]
|
|
|
|
;
|
|
|
|
%tmp.4 = shl i64 %Y, 2
|
|
|
|
%tmp.12 = shl i64 %Y, 2
|
|
|
|
%tmp.8 = add i64 %tmp.4, %tmp.12
|
|
|
|
ret i64 %tmp.8
|
2004-11-14 03:49:39 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test26(i32 %A, i32 %B) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test26(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[A:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
|
|
|
%C = add i32 %A, %B
|
|
|
|
%D = sub i32 %C, %B
|
|
|
|
ret i32 %D
|
2005-01-20 05:48:31 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; Fold add through select.
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test27(i1 %C, i32 %X, i32 %Y) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test27(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]]
|
|
|
|
;
|
|
|
|
%A = add i32 %X, %Y
|
|
|
|
%B = add i32 %Y, 123
|
|
|
|
%C.upgrd.1 = select i1 %C, i32 %A, i32 %B
|
|
|
|
%D = sub i32 %C.upgrd.1, %Y
|
|
|
|
ret i32 %D
|
2005-01-20 05:48:31 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test28(i32 %X) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test28(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
|
|
|
%Y = add i32 %X, 1234
|
|
|
|
%Z = sub i32 42, %Y
|
|
|
|
ret i32 %Z
|
2005-04-08 00:24:59 +08:00
|
|
|
}
|
2005-09-18 12:22:59 +08:00
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
define i32 @test29(i32 %x, i32 %y) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test29(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
|
2018-05-01 05:28:18 +08:00
|
|
|
; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64
|
|
|
|
; CHECK-NEXT: [[TMP_10:%.*]] = or i32 [[TMP_7]], [[TMP_9]]
|
|
|
|
; CHECK-NEXT: ret i32 [[TMP_10]]
|
|
|
|
;
|
2018-05-01 05:03:36 +08:00
|
|
|
%tmp.2 = sub i32 %x, %y
|
2016-07-23 04:39:07 +08:00
|
|
|
%tmp.2.mask = and i32 %tmp.2, 63
|
2018-05-01 05:28:18 +08:00
|
|
|
%tmp.6 = add i32 %tmp.2.mask, %y
|
2016-07-23 04:39:07 +08:00
|
|
|
%tmp.7 = and i32 %tmp.6, 63
|
|
|
|
%tmp.9 = and i32 %tmp.2, -64
|
|
|
|
%tmp.10 = or i32 %tmp.7, %tmp.9
|
|
|
|
ret i32 %tmp.10
|
2005-09-18 12:22:59 +08:00
|
|
|
}
|
2005-11-03 02:34:05 +08:00
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; Add of sign bit -> xor of sign bit.
|
2008-03-09 16:16:40 +08:00
|
|
|
define i64 @test30(i64 %x) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test30(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: ret i64 [[X:%.*]]
|
2016-07-23 04:39:07 +08:00
|
|
|
;
|
|
|
|
%tmp.2 = xor i64 %x, -9223372036854775808
|
|
|
|
%tmp.4 = add i64 %tmp.2, -9223372036854775808
|
|
|
|
ret i64 %tmp.4
|
2005-11-03 02:34:05 +08:00
|
|
|
}
|
2006-03-04 14:02:36 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test31(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test31(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
|
|
;
|
|
|
|
%B = add i32 %A, 4
|
|
|
|
%C = mul i32 %B, 5
|
|
|
|
%D = sub i32 %C, 20
|
|
|
|
ret i32 %D
|
2006-03-04 14:02:36 +08:00
|
|
|
}
|
2006-03-06 07:53:04 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test32(i32 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test32(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
|
|
|
%B = add i32 %A, 4
|
|
|
|
%C = shl i32 %B, 2
|
|
|
|
%D = sub i32 %C, 16
|
|
|
|
ret i32 %D
|
2006-03-06 07:53:04 +08:00
|
|
|
}
|
2006-11-09 13:11:23 +08:00
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i8 @test33(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test33(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%B = and i8 %A, -2
|
|
|
|
%C = add i8 %B, 1
|
|
|
|
ret i8 %C
|
2006-11-09 13:11:23 +08:00
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i8 @test34(i8 %A) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test34(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%B = add i8 %A, 64
|
|
|
|
%C = and i8 %B, 12
|
|
|
|
ret i8 %C
|
2006-11-09 13:11:23 +08:00
|
|
|
}
|
|
|
|
|
2018-05-01 05:03:36 +08:00
|
|
|
; If all bits affected by the add are included
|
|
|
|
; in the mask, do the add before the mask op.
|
|
|
|
|
|
|
|
define i8 @masked_add(i8 %x) {
|
|
|
|
; CHECK-LABEL: @masked_add(
|
|
|
|
; CHECK-NEXT: [[AND1:%.*]] = add i8 [[X:%.*]], 96
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i8 [[AND1]], -16
|
|
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
|
|
;
|
|
|
|
%and = and i8 %x, 240 ; 0xf0
|
|
|
|
%r = add i8 %and, 96 ; 0x60
|
|
|
|
ret i8 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i8> @masked_add_splat(<2 x i8> %x) {
|
|
|
|
; CHECK-LABEL: @masked_add_splat(
|
|
|
|
; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], <i8 64, i8 64>
|
|
|
|
; CHECK-NEXT: ret <2 x i8> [[R]]
|
|
|
|
;
|
|
|
|
%and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
|
|
|
|
%r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40
|
|
|
|
ret <2 x i8> %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i8 @not_masked_add(i8 %x) {
|
|
|
|
; CHECK-LABEL: @not_masked_add(
|
|
|
|
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96
|
|
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
|
|
;
|
|
|
|
%and = and i8 %x, 112 ; 0x70
|
|
|
|
%r = add i8 %and, 96 ; 0x60
|
|
|
|
ret i8 %r
|
|
|
|
}
|
|
|
|
|
2008-03-09 16:16:40 +08:00
|
|
|
define i32 @test35(i32 %a) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test35(
|
|
|
|
; CHECK-NEXT: ret i32 -1
|
|
|
|
;
|
|
|
|
%tmpnot = xor i32 %a, -1
|
|
|
|
%tmp2 = add i32 %tmpnot, %a
|
|
|
|
ret i32 %tmp2
|
2007-01-05 10:16:36 +08:00
|
|
|
}
|
|
|
|
|
2008-03-21 13:19:58 +08:00
|
|
|
define i32 @test36(i32 %a) {
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-LABEL: @test36(
|
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
|
|
|
%x = and i32 %a, -2
|
|
|
|
%y = and i32 %a, -126
|
|
|
|
%z = add i32 %x, %y
|
|
|
|
%q = and i32 %z, 1 ; always zero
|
|
|
|
ret i32 %q
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @test37(i32 %a, i32 %b) {
|
|
|
|
; CHECK-LABEL: @test37(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
2011-02-12 05:46:48 +08:00
|
|
|
%add = add i32 %a, %b
|
2011-01-31 06:01:13 +08:00
|
|
|
%cmp = icmp eq i32 %add, %a
|
2011-02-12 05:46:48 +08:00
|
|
|
ret i1 %cmp
|
2011-01-31 06:01:13 +08:00
|
|
|
}
|
|
|
|
|
2016-07-23 04:39:07 +08:00
|
|
|
define i1 @test38(i32 %a, i32 %b) {
|
|
|
|
; CHECK-LABEL: @test38(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
2011-02-12 05:46:48 +08:00
|
|
|
%add = add i32 %a, %b
|
|
|
|
%cmp = icmp eq i32 %add, %b
|
|
|
|
ret i1 %cmp
|
|
|
|
}
|
|
|
|
|
2016-07-23 04:39:07 +08:00
|
|
|
define i1 @test39(i32 %a, i32 %b) {
|
|
|
|
; CHECK-LABEL: @test39(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
2011-02-12 05:46:48 +08:00
|
|
|
%add = add i32 %b, %a
|
2011-01-31 06:01:13 +08:00
|
|
|
%cmp = icmp eq i32 %add, %a
|
2011-02-12 05:46:48 +08:00
|
|
|
ret i1 %cmp
|
|
|
|
}
|
|
|
|
|
2016-07-23 04:39:07 +08:00
|
|
|
define i1 @test40(i32 %a, i32 %b) {
|
|
|
|
; CHECK-LABEL: @test40(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
|
2016-07-23 04:39:07 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
2011-02-12 05:46:48 +08:00
|
|
|
%add = add i32 %b, %a
|
|
|
|
%cmp = icmp eq i32 %add, %b
|
|
|
|
ret i1 %cmp
|
2011-01-31 06:01:13 +08:00
|
|
|
}
|
2017-01-04 10:21:31 +08:00
|
|
|
|
2017-10-14 01:42:12 +08:00
|
|
|
; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
|
|
|
|
|
2017-01-04 10:21:31 +08:00
|
|
|
define i64 @test41(i32 %a) {
|
|
|
|
; CHECK-LABEL: @test41(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15
|
|
|
|
; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64
|
|
|
|
; CHECK-NEXT: ret i64 [[SUB]]
|
2017-01-04 10:21:31 +08:00
|
|
|
;
|
|
|
|
%add = add nuw i32 %a, 16
|
|
|
|
%zext = zext i32 %add to i64
|
|
|
|
%sub = add i64 %zext, -1
|
|
|
|
ret i64 %sub
|
|
|
|
}
|
2017-04-05 06:22:30 +08:00
|
|
|
|
2017-10-14 01:42:12 +08:00
|
|
|
; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
|
|
|
|
|
|
|
|
define <2 x i64> @test41vec(<2 x i32> %a) {
|
|
|
|
; CHECK-LABEL: @test41vec(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 15, i32 15>
|
2017-10-14 01:42:12 +08:00
|
|
|
; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
|
|
|
|
; CHECK-NEXT: ret <2 x i64> [[SUB]]
|
|
|
|
;
|
|
|
|
%add = add nuw <2 x i32> %a, <i32 16, i32 16>
|
|
|
|
%zext = zext <2 x i32> %add to <2 x i64>
|
|
|
|
%sub = add <2 x i64> %zext, <i64 -1, i64 -1>
|
|
|
|
ret <2 x i64> %sub
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {
|
|
|
|
; CHECK-LABEL: @test41vec_and_multiuse(
|
2018-05-01 05:03:36 +08:00
|
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 16, i32 16>
|
2017-10-14 01:42:12 +08:00
|
|
|
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>
|
2017-10-14 01:47:25 +08:00
|
|
|
; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i64> [[ZEXT]], <i64 -1, i64 -1>
|
|
|
|
; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[SUB]], [[ZEXT]]
|
2017-10-14 01:42:12 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]]
|
|
|
|
;
|
|
|
|
%add = add nuw <2 x i32> %a, <i32 16, i32 16>
|
|
|
|
%zext = zext <2 x i32> %add to <2 x i64>
|
|
|
|
%sub = add <2 x i64> %zext, <i64 -1, i64 -1>
|
|
|
|
%extrause = add <2 x i64> %zext, %sub
|
|
|
|
ret <2 x i64> %extrause
|
|
|
|
}
|
|
|
|
|
2017-04-05 06:22:30 +08:00
|
|
|
define i32 @test42(i1 %C) {
|
|
|
|
; CHECK-LABEL: @test42(
|
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
|
|
|
|
; CHECK-NEXT: ret i32 [[V]]
|
|
|
|
;
|
|
|
|
%A = select i1 %C, i32 1000, i32 10
|
|
|
|
%V = add i32 123, %A
|
|
|
|
ret i32 %V
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @test42vec(i1 %C) {
|
|
|
|
; CHECK-LABEL: @test42vec(
|
2017-04-11 00:40:00 +08:00
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
|
2017-04-05 06:22:30 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[V]]
|
|
|
|
;
|
|
|
|
%A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
|
|
|
|
%V = add <2 x i32> <i32 123, i32 123>, %A
|
|
|
|
ret <2 x i32> %V
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @test42vec2(i1 %C) {
|
|
|
|
; CHECK-LABEL: @test42vec2(
|
2017-04-11 00:40:00 +08:00
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
|
2017-04-05 06:22:30 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[V]]
|
|
|
|
;
|
|
|
|
%A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
|
|
|
|
%V = add <2 x i32> <i32 123, i32 333>, %A
|
|
|
|
ret <2 x i32> %V
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test55(i1 %which) {
|
|
|
|
; CHECK-LABEL: @test55(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
|
|
|
|
; CHECK: delay:
|
|
|
|
; CHECK-NEXT: br label [[FINAL]]
|
|
|
|
; CHECK: final:
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[A]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
br i1 %which, label %final, label %delay
|
|
|
|
|
|
|
|
delay:
|
|
|
|
br label %final
|
|
|
|
|
|
|
|
final:
|
|
|
|
%A = phi i32 [ 1000, %entry ], [ 10, %delay ]
|
|
|
|
%value = add i32 123, %A
|
|
|
|
ret i32 %value
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @test43vec(i1 %which) {
|
|
|
|
; CHECK-LABEL: @test43vec(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
|
|
|
|
; CHECK: delay:
|
|
|
|
; CHECK-NEXT: br label [[FINAL]]
|
|
|
|
; CHECK: final:
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ]
|
|
|
|
; CHECK-NEXT: ret <2 x i32> [[A]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
br i1 %which, label %final, label %delay
|
|
|
|
|
|
|
|
delay:
|
|
|
|
br label %final
|
|
|
|
|
|
|
|
final:
|
|
|
|
%A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
|
|
|
|
%value = add <2 x i32> <i32 123, i32 123>, %A
|
|
|
|
ret <2 x i32> %value
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i32> @test43vec2(i1 %which) {
|
|
|
|
; CHECK-LABEL: @test43vec2(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
|
|
|
|
; CHECK: delay:
|
|
|
|
; CHECK-NEXT: br label [[FINAL]]
|
|
|
|
; CHECK: final:
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
|
|
|
|
; CHECK-NEXT: ret <2 x i32> [[A]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
br i1 %which, label %final, label %delay
|
|
|
|
|
|
|
|
delay:
|
|
|
|
br label %final
|
|
|
|
|
|
|
|
final:
|
|
|
|
%A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
|
|
|
|
%value = add <2 x i32> <i32 123, i32 333>, %A
|
|
|
|
ret <2 x i32> %value
|
|
|
|
}
|
2018-06-26 13:31:18 +08:00
|
|
|
|
|
|
|
; E = (A + 1) + ~B = A - B
|
|
|
|
define i32 @add_not_increment(i32 %A, i32 %B) {
|
|
|
|
; CHECK-LABEL: @add_not_increment(
|
2018-06-30 22:11:46 +08:00
|
|
|
; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
2018-06-26 13:31:18 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[E]]
|
|
|
|
;
|
|
|
|
%C = xor i32 %B, -1
|
|
|
|
%D = add i32 %A, 1
|
|
|
|
%E = add i32 %D, %C
|
|
|
|
ret i32 %E
|
|
|
|
}
|
|
|
|
|
|
|
|
; E = (A + 1) + ~B = A - B
|
|
|
|
define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {
|
|
|
|
; CHECK-LABEL: @add_not_increment_vec(
|
2018-06-30 22:11:46 +08:00
|
|
|
; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]
|
2018-06-26 13:31:18 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[E]]
|
|
|
|
;
|
|
|
|
%C = xor <2 x i32> %B, <i32 -1, i32 -1>
|
|
|
|
%D = add <2 x i32> %A, <i32 1, i32 1>
|
|
|
|
%E = add <2 x i32> %D, %C
|
|
|
|
ret <2 x i32> %E
|
|
|
|
}
|
|
|
|
|
|
|
|
; E = ~B + (1 + A) = A - B
|
|
|
|
define i32 @add_not_increment_commuted(i32 %A, i32 %B) {
|
|
|
|
; CHECK-LABEL: @add_not_increment_commuted(
|
2018-06-30 22:11:46 +08:00
|
|
|
; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
2018-06-26 13:31:18 +08:00
|
|
|
; CHECK-NEXT: ret i32 [[E]]
|
|
|
|
;
|
|
|
|
%C = xor i32 %B, -1
|
|
|
|
%D = add i32 %A, 1
|
|
|
|
%E = add i32 %C, %D
|
|
|
|
ret i32 %E
|
|
|
|
}
|
|
|
|
|