llvm.org GIT mirror llvm / 11c1e43
[InstCombine] add tests for checking power-of-2; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363938 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 26 days ago
1 changed file(s) with 138 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
2
3 define i1 @is_pow2or0_negate_op(i32 %x) {
4 ; CHECK-LABEL: @is_pow2or0_negate_op(
5 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
6 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]]
7 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]]
8 ; CHECK-NEXT: ret i1 [[CMP]]
9 ;
10 %neg = sub i32 0, %x
11 %and = and i32 %neg, %x
12 %cmp = icmp eq i32 %and, %x
13 ret i1 %cmp
14 }
15
16 define <2 x i1> @is_pow2or0_negate_op_vec(<2 x i32> %x) {
17 ; CHECK-LABEL: @is_pow2or0_negate_op_vec(
18 ; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
19 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[NEG]], [[X]]
20 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[X]]
21 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
22 ;
23 %neg = sub <2 x i32> zeroinitializer, %x
24 %and = and <2 x i32> %neg, %x
25 %cmp = icmp eq <2 x i32> %and, %x
26 ret <2 x i1> %cmp
27 }
28
29 define i1 @is_pow2or0_decrement_op(i8 %x) {
30 ; CHECK-LABEL: @is_pow2or0_decrement_op(
31 ; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1
32 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[X]]
33 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
34 ; CHECK-NEXT: ret i1 [[CMP]]
35 ;
36 %dec = add i8 %x, -1
37 %and = and i8 %dec, %x
38 %cmp = icmp eq i8 %and, 0
39 ret i1 %cmp
40 }
41
42 define <2 x i1> @is_pow2or0_decrement_op_vec(<2 x i8> %x) {
43 ; CHECK-LABEL: @is_pow2or0_decrement_op_vec(
44 ; CHECK-NEXT: [[DEC:%.*]] = add <2 x i8> [[X:%.*]],
45 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[DEC]], [[X]]
46 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
47 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
48 ;
49 %dec = add <2 x i8> %x,
50 %and = and <2 x i8> %dec, %x
51 %cmp = icmp eq <2 x i8> %and, zeroinitializer
52 ret <2 x i1> %cmp
53 }
54
55 define i1 @isnot_pow2or0_negate_op(i32 %x) {
56 ; CHECK-LABEL: @isnot_pow2or0_negate_op(
57 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
58 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]]
59 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], [[X]]
60 ; CHECK-NEXT: ret i1 [[CMP]]
61 ;
62 %neg = sub i32 0, %x
63 %and = and i32 %neg, %x
64 %cmp = icmp ne i32 %and, %x
65 ret i1 %cmp
66 }
67
68 define <2 x i1> @isnot_pow2or0_negate_op_vec(<2 x i32> %x) {
69 ; CHECK-LABEL: @isnot_pow2or0_negate_op_vec(
70 ; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
71 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[NEG]], [[X]]
72 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], [[X]]
73 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
74 ;
75 %neg = sub <2 x i32> zeroinitializer, %x
76 %and = and <2 x i32> %neg, %x
77 %cmp = icmp ne <2 x i32> %and, %x
78 ret <2 x i1> %cmp
79 }
80
81 define i1 @isnot_pow2or0_decrement_op(i8 %x) {
82 ; CHECK-LABEL: @isnot_pow2or0_decrement_op(
83 ; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1
84 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[X]]
85 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
86 ; CHECK-NEXT: ret i1 [[CMP]]
87 ;
88 %dec = add i8 %x, -1
89 %and = and i8 %dec, %x
90 %cmp = icmp ne i8 %and, 0
91 ret i1 %cmp
92 }
93
94 define <2 x i1> @isnot_pow2or0_decrement_op_vec(<2 x i8> %x) {
95 ; CHECK-LABEL: @isnot_pow2or0_decrement_op_vec(
96 ; CHECK-NEXT: [[DEC:%.*]] = add <2 x i8> [[X:%.*]],
97 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[DEC]], [[X]]
98 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[AND]], zeroinitializer
99 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
100 ;
101 %dec = add <2 x i8> %x,
102 %and = and <2 x i8> %dec, %x
103 %cmp = icmp ne <2 x i8> %and, zeroinitializer
104 ret <2 x i1> %cmp
105 }
106
107 declare void @use(i32)
108
109 define i1 @is_pow2or0_negate_op_extra_use1(i32 %x) {
110 ; CHECK-LABEL: @is_pow2or0_negate_op_extra_use1(
111 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
112 ; CHECK-NEXT: call void @use(i32 [[NEG]])
113 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]]
114 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]]
115 ; CHECK-NEXT: ret i1 [[CMP]]
116 ;
117 %neg = sub i32 0, %x
118 call void @use(i32 %neg)
119 %and = and i32 %neg, %x
120 %cmp = icmp eq i32 %and, %x
121 ret i1 %cmp
122 }
123
124 define i1 @is_pow2or0_negate_op_extra_use2(i32 %x) {
125 ; CHECK-LABEL: @is_pow2or0_negate_op_extra_use2(
126 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
127 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]]
128 ; CHECK-NEXT: call void @use(i32 [[AND]])
129 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]]
130 ; CHECK-NEXT: ret i1 [[CMP]]
131 ;
132 %neg = sub i32 0, %x
133 %and = and i32 %neg, %x
134 call void @use(i32 %and)
135 %cmp = icmp eq i32 %and, %x
136 ret i1 %cmp
137 }