llvm.org GIT mirror llvm / 77438c3
[EarlyCSE] Improve EarlyCSE of some absolute value cases. Change matchSelectPattern to return X and -X for ABS/NABS in a well defined order. Adjust EarlyCSE to account for this. Ensure the SPF result is some kind of min/max and not abs/nabs in one place in InstCombine that made me nervous. Prevously we returned the two operands of the compare part of the abs pattern. The RHS is always going to be a 0i, 1 or -1 constant. This isn't a very meaningful thing to return for any one. There's also some freedom in the abs pattern as to what happens when the value is equal to 0. This freedom led to early cse failing to match when different constants were used in otherwise equivalent operations. By returning the input and its negation in a defined order we can ensure an exact match. This also makes sure both patterns use the exact same subtract instruction for the negation. I believe CSE should evebntually make this happen and properly merge the nsw/nuw flags. But I'm not familiar with CSE and what order it does things in so it seemed like it might be good to really enforce that they were the same. Differential Revision: https://reviews.llvm.org/D47037 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332865 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 1 year, 4 months ago
4 changed file(s) with 53 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
516516 /// Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind
517517 /// and providing the out parameter results if we successfully match.
518518 ///
519 /// For ABS/NABS, LHS will be set to the input to the abs idiom. RHS will be
520 /// the negation instruction from the idiom.
521 ///
519522 /// If CastOp is not nullptr, also match MIN/MAX idioms where the type does
520523 /// not match that of the original select. If this is the case, the cast
521524 /// operation (one of Trunc,SExt,Zext) that must be done to transform the
45734573 if (match(CmpRHS, m_APInt(C1))) {
45744574 if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) ||
45754575 (CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) {
4576 // Set RHS to the negate operand. LHS was assigned to CmpLHS earlier.
4577 RHS = (CmpLHS == TrueVal) ? FalseVal : TrueVal;
45764578
45774579 // ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X
45784580 // NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X
154154 SelectPatternFlavor SPF = matchSelectPattern(Inst, A, B).Flavor;
155155 // TODO: We should also detect FP min/max.
156156 if (SPF == SPF_SMIN || SPF == SPF_SMAX ||
157 SPF == SPF_UMIN || SPF == SPF_UMAX ||
158 SPF == SPF_ABS || SPF == SPF_NABS) {
157 SPF == SPF_UMIN || SPF == SPF_UMAX) {
159158 if (A > B)
160159 std::swap(A, B);
160 return hash_combine(Inst->getOpcode(), SPF, A, B);
161 }
162 if (SPF == SPF_ABS || SPF == SPF_NABS) {
163 // ABS/NABS always puts the input in A and its negation in B.
161164 return hash_combine(Inst->getOpcode(), SPF, A, B);
162165 }
163166
229232 LSPF == SPF_ABS || LSPF == SPF_NABS) {
230233 Value *RHSA, *RHSB;
231234 SelectPatternFlavor RSPF = matchSelectPattern(RHSI, RHSA, RHSB).Flavor;
232 return (LSPF == RSPF && ((LHSA == RHSA && LHSB == RHSB) ||
233 (LHSA == RHSB && LHSB == RHSA)));
235 if (LSPF == RSPF) {
236 // Abs results are placed in a defined order by matchSelectPattern.
237 if (LSPF == SPF_ABS || LSPF == SPF_NABS)
238 return LHSA == RHSA && LHSB == RHSB;
239 return ((LHSA == RHSA && LHSB == RHSB) ||
240 (LHSA == RHSB && LHSB == RHSA));
241 }
234242 }
235243
236244 return false;
251251 ret i8 %r
252252 }
253253
254 ; These two tests make sure we still consider it a match when the RHS of the
255 ; compares are different.
256 define i8 @abs_different_constants(i8 %a) {
257 ; CHECK-LABEL: @abs_different_constants(
258 ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, %a
259 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, -1
260 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %a, 0
261 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 [[NEG]]
262 ; CHECK-NEXT: ret i8 [[M1]]
263 ;
264 %neg = sub i8 0, %a
265 %cmp1 = icmp sgt i8 %a, -1
266 %cmp2 = icmp slt i8 %a, 0
267 %m1 = select i1 %cmp1, i8 %a, i8 %neg
268 %m2 = select i1 %cmp2, i8 %neg, i8 %a
269 %r = or i8 %m2, %m1
270 ret i8 %r
271 }
272
273 define i8 @nabs_different_constants(i8 %a) {
274 ; CHECK-LABEL: @nabs_different_constants(
275 ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, %a
276 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, 0
277 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %a, -1
278 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 [[NEG]]
279 ; CHECK-NEXT: ret i8 0
280 ;
281 %neg = sub i8 0, %a
282 %cmp1 = icmp slt i8 %a, 0
283 %cmp2 = icmp sgt i8 %a, -1
284 %m1 = select i1 %cmp1, i8 %a, i8 %neg
285 %m2 = select i1 %cmp2, i8 %neg, i8 %a
286 %r = xor i8 %m2, %m1
287 ret i8 %r
288 }
289