llvm.org GIT mirror llvm / 47c99e0
[InstCombine] foldICmpWithLowBitMaskedVal(): handle uncanonical ((1 << y)+(-1)) mask Summary: Same as to D52146. `((1 << y)+(-1))` is simply non-canoniacal version of `~(-1 << y)`: https://rise4fun.com/Alive/0vl We can not canonicalize it due to the extra uses. But we can handle it here. Reviewers: spatel, craig.topper, RKSimon Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D52147 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342547 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Lebedev 1 year, 9 months ago
3 changed file(s) with 65 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
28862886 /// Where Mask is some pattern that produces all-ones in low bits:
28872887 /// (-1 >> y)
28882888 /// ~(-1 << y)
2889 /// ((1 << y) + (-1)) <- non-canonical, has extra uses
28892890 /// The Mask can be a constant, too.
28902891 /// For some predicates, the operands are commutative.
28912892 /// For others, x can only be on a specific side.
28932894 InstCombiner::BuilderTy &Builder) {
28942895 ICmpInst::Predicate SrcPred;
28952896 Value *X, *M;
2896 auto m_VariableMask = m_CombineOr(m_Not(m_Shl(m_AllOnes(), m_Value())),
2897 m_LShr(m_AllOnes(), m_Value()));
2897 auto m_VariableMask =
2898 m_CombineOr(m_CombineOr(m_Not(m_Shl(m_AllOnes(), m_Value())),
2899 m_Add(m_Shl(m_One(), m_Value()), m_AllOnes())),
2900 m_LShr(m_AllOnes(), m_Value()));
28982901 auto m_Mask = m_CombineOr(m_VariableMask, m_LowBitMask());
28992902 if (!match(&I, m_c_ICmp(SrcPred,
29002903 m_c_And(m_CombineAnd(m_Mask, m_Value(M)), m_Value(X)),
2323 ; CHECK-LABEL: @p0(
2424 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
2525 ; CHECK-NEXT: call void @use8(i8 [[T0]])
26 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
27 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
28 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
29 ; CHECK-NEXT: ret i1 [[RET]]
26 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
27 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
28 ; CHECK-NEXT: ret i1 [[TMP1]]
3029 ;
3130 %t0 = shl i8 1, %y
3231 call void @use8(i8 %t0)
4443 ; CHECK-LABEL: @p1_vec(
4544 ; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> , [[Y:%.*]]
4645 ; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
47 ; CHECK-NEXT: [[T1:%.*]] = add <2 x i8> [[T0]],
48 ; CHECK-NEXT: [[T2:%.*]] = and <2 x i8> [[T1]], [[X:%.*]]
49 ; CHECK-NEXT: [[RET:%.*]] = icmp eq <2 x i8> [[T2]], [[X]]
50 ; CHECK-NEXT: ret <2 x i1> [[RET]]
46 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <2 x i8> [[X:%.*]], [[Y]]
47 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X_HIGHBITS]], zeroinitializer
48 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
5149 ;
5250 %t0 = shl <2 x i8> , %y
5351 call void @use2i8(<2 x i8> %t0)
6159 ; CHECK-LABEL: @p2_vec_undef0(
6260 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
6361 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
64 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
65 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
66 ; CHECK-NEXT: [[RET:%.*]] = icmp eq <3 x i8> [[T2]], [[X]]
67 ; CHECK-NEXT: ret <3 x i1> [[RET]]
62 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
63 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
64 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
6865 ;
6966 %t0 = shl <3 x i8> , %y
7067 call void @use3i8(<3 x i8> %t0)
7875 ; CHECK-LABEL: @p3_vec_undef0(
7976 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
8077 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
81 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
82 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
83 ; CHECK-NEXT: [[RET:%.*]] = icmp eq <3 x i8> [[T2]], [[X]]
84 ; CHECK-NEXT: ret <3 x i1> [[RET]]
78 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
79 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
80 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
8581 ;
8682 %t0 = shl <3 x i8> , %y
8783 call void @use3i8(<3 x i8> %t0)
9591 ; CHECK-LABEL: @p4_vec_undef2(
9692 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
9793 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
98 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
99 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
100 ; CHECK-NEXT: [[RET:%.*]] = icmp eq <3 x i8> [[T2]], [[X]]
101 ; CHECK-NEXT: ret <3 x i1> [[RET]]
94 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
95 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
96 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
10297 ;
10398 %t0 = shl <3 x i8> , %y
10499 call void @use3i8(<3 x i8> %t0)
118113 ; CHECK-LABEL: @c0(
119114 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
120115 ; CHECK-NEXT: call void @use8(i8 [[T0]])
121 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
122116 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
123 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X]], [[T1]]
124 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
125 ; CHECK-NEXT: ret i1 [[RET]]
117 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
118 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
119 ; CHECK-NEXT: ret i1 [[TMP1]]
126120 ;
127121 %t0 = shl i8 1, %y
128122 call void @use8(i8 %t0)
137131 ; CHECK-LABEL: @c1(
138132 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
139133 ; CHECK-NEXT: call void @use8(i8 [[T0]])
140 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
141134 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
142 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X]]
143 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[X]], [[T2]]
144 ; CHECK-NEXT: ret i1 [[RET]]
135 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
136 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
137 ; CHECK-NEXT: ret i1 [[TMP1]]
145138 ;
146139 %t0 = shl i8 1, %y
147140 call void @use8(i8 %t0)
156149 ; CHECK-LABEL: @c2(
157150 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
158151 ; CHECK-NEXT: call void @use8(i8 [[T0]])
159 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
160152 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
161 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X]], [[T1]]
162 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[X]], [[T2]]
163 ; CHECK-NEXT: ret i1 [[RET]]
153 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
154 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
155 ; CHECK-NEXT: ret i1 [[TMP1]]
164156 ;
165157 %t0 = shl i8 1, %y
166158 call void @use8(i8 %t0)
181173 ; CHECK-NEXT: call void @use8(i8 [[T0]])
182174 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
183175 ; CHECK-NEXT: call void @use8(i8 [[T1]])
184 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
185 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
186 ; CHECK-NEXT: ret i1 [[RET]]
176 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i8 [[T1]], [[X:%.*]]
177 ; CHECK-NEXT: ret i1 [[TMP1]]
187178 ;
188179 %t0 = shl i8 1, %y
189180 call void @use8(i8 %t0) ; needed anyway
201192 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
202193 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
203194 ; CHECK-NEXT: call void @use8(i8 [[T2]])
204 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
205 ; CHECK-NEXT: ret i1 [[RET]]
195 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i8 [[T1]], [[X]]
196 ; CHECK-NEXT: ret i1 [[TMP1]]
206197 ;
207198 %t0 = shl i8 1, %y
208199 call void @use8(i8 %t0) ; needed anyway
221212 ; CHECK-NEXT: call void @use8(i8 [[T1]])
222213 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
223214 ; CHECK-NEXT: call void @use8(i8 [[T2]])
224 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
225 ; CHECK-NEXT: ret i1 [[RET]]
215 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i8 [[T1]], [[X]]
216 ; CHECK-NEXT: ret i1 [[TMP1]]
226217 ;
227218 %t0 = shl i8 1, %y
228219 call void @use8(i8 %t0)
2323 ; CHECK-LABEL: @p0(
2424 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
2525 ; CHECK-NEXT: call void @use8(i8 [[T0]])
26 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
27 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
28 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
29 ; CHECK-NEXT: ret i1 [[RET]]
26 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
27 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
28 ; CHECK-NEXT: ret i1 [[TMP1]]
3029 ;
3130 %t0 = shl i8 1, %y
3231 call void @use8(i8 %t0)
4443 ; CHECK-LABEL: @p1_vec(
4544 ; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> , [[Y:%.*]]
4645 ; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
47 ; CHECK-NEXT: [[T1:%.*]] = add <2 x i8> [[T0]],
48 ; CHECK-NEXT: [[T2:%.*]] = and <2 x i8> [[T1]], [[X:%.*]]
49 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i8> [[T2]], [[X]]
50 ; CHECK-NEXT: ret <2 x i1> [[RET]]
46 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <2 x i8> [[X:%.*]], [[Y]]
47 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X_HIGHBITS]], zeroinitializer
48 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
5149 ;
5250 %t0 = shl <2 x i8> , %y
5351 call void @use2i8(<2 x i8> %t0)
6159 ; CHECK-LABEL: @p2_vec_undef0(
6260 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
6361 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
64 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
65 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
66 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[T2]], [[X]]
67 ; CHECK-NEXT: ret <3 x i1> [[RET]]
62 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
63 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
64 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
6865 ;
6966 %t0 = shl <3 x i8> , %y
7067 call void @use3i8(<3 x i8> %t0)
7875 ; CHECK-LABEL: @p3_vec_undef0(
7976 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
8077 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
81 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
82 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
83 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[T2]], [[X]]
84 ; CHECK-NEXT: ret <3 x i1> [[RET]]
78 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
79 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
80 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
8581 ;
8682 %t0 = shl <3 x i8> , %y
8783 call void @use3i8(<3 x i8> %t0)
9591 ; CHECK-LABEL: @p4_vec_undef2(
9692 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> , [[Y:%.*]]
9793 ; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
98 ; CHECK-NEXT: [[T1:%.*]] = add <3 x i8> [[T0]],
99 ; CHECK-NEXT: [[T2:%.*]] = and <3 x i8> [[T1]], [[X:%.*]]
100 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[T2]], [[X]]
101 ; CHECK-NEXT: ret <3 x i1> [[RET]]
94 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
95 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
96 ; CHECK-NEXT: ret <3 x i1> [[TMP1]]
10297 ;
10398 %t0 = shl <3 x i8> , %y
10499 call void @use3i8(<3 x i8> %t0)
118113 ; CHECK-LABEL: @c0(
119114 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
120115 ; CHECK-NEXT: call void @use8(i8 [[T0]])
121 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
122116 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
123 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X]], [[T1]]
124 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
125 ; CHECK-NEXT: ret i1 [[RET]]
117 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
118 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
119 ; CHECK-NEXT: ret i1 [[TMP1]]
126120 ;
127121 %t0 = shl i8 1, %y
128122 call void @use8(i8 %t0)
137131 ; CHECK-LABEL: @c1(
138132 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
139133 ; CHECK-NEXT: call void @use8(i8 [[T0]])
140 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
141134 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
142 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X]]
143 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[X]], [[T2]]
144 ; CHECK-NEXT: ret i1 [[RET]]
135 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
136 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
137 ; CHECK-NEXT: ret i1 [[TMP1]]
145138 ;
146139 %t0 = shl i8 1, %y
147140 call void @use8(i8 %t0)
156149 ; CHECK-LABEL: @c2(
157150 ; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
158151 ; CHECK-NEXT: call void @use8(i8 [[T0]])
159 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
160152 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
161 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X]], [[T1]]
162 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[X]], [[T2]]
163 ; CHECK-NEXT: ret i1 [[RET]]
153 ; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
154 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
155 ; CHECK-NEXT: ret i1 [[TMP1]]
164156 ;
165157 %t0 = shl i8 1, %y
166158 call void @use8(i8 %t0)
181173 ; CHECK-NEXT: call void @use8(i8 [[T0]])
182174 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
183175 ; CHECK-NEXT: call void @use8(i8 [[T1]])
184 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
185 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
186 ; CHECK-NEXT: ret i1 [[RET]]
176 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[T1]], [[X:%.*]]
177 ; CHECK-NEXT: ret i1 [[TMP1]]
187178 ;
188179 %t0 = shl i8 1, %y
189180 call void @use8(i8 %t0) ; needed anyway
201192 ; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
202193 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
203194 ; CHECK-NEXT: call void @use8(i8 [[T2]])
204 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
205 ; CHECK-NEXT: ret i1 [[RET]]
195 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[T1]], [[X]]
196 ; CHECK-NEXT: ret i1 [[TMP1]]
206197 ;
207198 %t0 = shl i8 1, %y
208199 call void @use8(i8 %t0) ; needed anyway
221212 ; CHECK-NEXT: call void @use8(i8 [[T1]])
222213 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
223214 ; CHECK-NEXT: call void @use8(i8 [[T2]])
224 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
225 ; CHECK-NEXT: ret i1 [[RET]]
215 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[T1]], [[X]]
216 ; CHECK-NEXT: ret i1 [[TMP1]]
226217 ;
227218 %t0 = shl i8 1, %y
228219 call void @use8(i8 %t0)