1//===- InstCombineAndOrXor.cpp --------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the visitAnd, visitOr, and visitXor functions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "InstCombineInternal.h"
14#include "llvm/ADT/SmallBitVector.h"
15#include "llvm/Analysis/CmpInstAnalysis.h"
16#include "llvm/Analysis/FloatingPointPredicateUtils.h"
17#include "llvm/Analysis/InstructionSimplify.h"
18#include "llvm/IR/ConstantRange.h"
19#include "llvm/IR/DerivedTypes.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/Intrinsics.h"
22#include "llvm/IR/PatternMatch.h"
23#include "llvm/IR/ProfDataUtils.h"
24#include "llvm/Transforms/InstCombine/InstCombiner.h"
25#include "llvm/Transforms/Utils/Local.h"
26
27using namespace llvm;
28using namespace PatternMatch;
29
30#define DEBUG_TYPE "instcombine"
31
32namespace llvm {
33extern cl::opt<bool> ProfcheckDisableMetadataFixes;
34}
35
36/// This is the complement of getICmpCode, which turns an opcode and two
37/// operands into either a constant true or false, or a brand new ICmp
38/// instruction. The sign is passed in to determine which kind of predicate to
39/// use in the new icmp instruction.
40static Value *getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS,
41 InstCombiner::BuilderTy &Builder) {
42 ICmpInst::Predicate NewPred;
43 if (Constant *TorF = getPredForICmpCode(Code, Sign, OpTy: LHS->getType(), Pred&: NewPred))
44 return TorF;
45 return Builder.CreateICmp(P: NewPred, LHS, RHS);
46}
47
48/// This is the complement of getFCmpCode, which turns an opcode and two
49/// operands into either a FCmp instruction, or a true/false constant.
50static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS,
51 InstCombiner::BuilderTy &Builder, FMFSource FMF) {
52 FCmpInst::Predicate NewPred;
53 if (Constant *TorF = getPredForFCmpCode(Code, OpTy: LHS->getType(), Pred&: NewPred))
54 return TorF;
55 return Builder.CreateFCmpFMF(P: NewPred, LHS, RHS, FMFSource: FMF);
56}
57
58/// Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise
59/// (V < Lo || V >= Hi). This method expects that Lo < Hi. IsSigned indicates
60/// whether to treat V, Lo, and Hi as signed or not.
61Value *InstCombinerImpl::insertRangeTest(Value *V, const APInt &Lo,
62 const APInt &Hi, bool isSigned,
63 bool Inside) {
64 assert((isSigned ? Lo.slt(Hi) : Lo.ult(Hi)) &&
65 "Lo is not < Hi in range emission code!");
66
67 Type *Ty = V->getType();
68
69 // V >= Min && V < Hi --> V < Hi
70 // V < Min || V >= Hi --> V >= Hi
71 ICmpInst::Predicate Pred = Inside ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_UGE;
72 if (isSigned ? Lo.isMinSignedValue() : Lo.isMinValue()) {
73 Pred = isSigned ? ICmpInst::getSignedPredicate(Pred) : Pred;
74 return Builder.CreateICmp(P: Pred, LHS: V, RHS: ConstantInt::get(Ty, V: Hi));
75 }
76
77 // V >= Lo && V < Hi --> V - Lo u< Hi - Lo
78 // V < Lo || V >= Hi --> V - Lo u>= Hi - Lo
79 Value *VMinusLo =
80 Builder.CreateSub(LHS: V, RHS: ConstantInt::get(Ty, V: Lo), Name: V->getName() + ".off");
81 Constant *HiMinusLo = ConstantInt::get(Ty, V: Hi - Lo);
82 return Builder.CreateICmp(P: Pred, LHS: VMinusLo, RHS: HiMinusLo);
83}
84
85/// Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns
86/// that can be simplified.
87/// One of A and B is considered the mask. The other is the value. This is
88/// described as the "AMask" or "BMask" part of the enum. If the enum contains
89/// only "Mask", then both A and B can be considered masks. If A is the mask,
90/// then it was proven that (A & C) == C. This is trivial if C == A or C == 0.
91/// If both A and C are constants, this proof is also easy.
92/// For the following explanations, we assume that A is the mask.
93///
94/// "AllOnes" declares that the comparison is true only if (A & B) == A or all
95/// bits of A are set in B.
96/// Example: (icmp eq (A & 3), 3) -> AMask_AllOnes
97///
98/// "AllZeros" declares that the comparison is true only if (A & B) == 0 or all
99/// bits of A are cleared in B.
100/// Example: (icmp eq (A & 3), 0) -> Mask_AllZeroes
101///
102/// "Mixed" declares that (A & B) == C and C might or might not contain any
103/// number of one bits and zero bits.
104/// Example: (icmp eq (A & 3), 1) -> AMask_Mixed
105///
106/// "Not" means that in above descriptions "==" should be replaced by "!=".
107/// Example: (icmp ne (A & 3), 3) -> AMask_NotAllOnes
108///
109/// If the mask A contains a single bit, then the following is equivalent:
110/// (icmp eq (A & B), A) equals (icmp ne (A & B), 0)
111/// (icmp ne (A & B), A) equals (icmp eq (A & B), 0)
112enum MaskedICmpType {
113 AMask_AllOnes = 1,
114 AMask_NotAllOnes = 2,
115 BMask_AllOnes = 4,
116 BMask_NotAllOnes = 8,
117 Mask_AllZeros = 16,
118 Mask_NotAllZeros = 32,
119 AMask_Mixed = 64,
120 AMask_NotMixed = 128,
121 BMask_Mixed = 256,
122 BMask_NotMixed = 512
123};
124
125/// Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C)
126/// satisfies.
127static unsigned getMaskedICmpType(Value *A, Value *B, Value *C,
128 ICmpInst::Predicate Pred) {
129 const APInt *ConstA = nullptr, *ConstB = nullptr, *ConstC = nullptr;
130 match(V: A, P: m_APInt(Res&: ConstA));
131 match(V: B, P: m_APInt(Res&: ConstB));
132 match(V: C, P: m_APInt(Res&: ConstC));
133 bool IsEq = (Pred == ICmpInst::ICMP_EQ);
134 bool IsAPow2 = ConstA && ConstA->isPowerOf2();
135 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
136 unsigned MaskVal = 0;
137 if (ConstC && ConstC->isZero()) {
138 // if C is zero, then both A and B qualify as mask
139 MaskVal |= (IsEq ? (Mask_AllZeros | AMask_Mixed | BMask_Mixed)
140 : (Mask_NotAllZeros | AMask_NotMixed | BMask_NotMixed));
141 if (IsAPow2)
142 MaskVal |= (IsEq ? (AMask_NotAllOnes | AMask_NotMixed)
143 : (AMask_AllOnes | AMask_Mixed));
144 if (IsBPow2)
145 MaskVal |= (IsEq ? (BMask_NotAllOnes | BMask_NotMixed)
146 : (BMask_AllOnes | BMask_Mixed));
147 return MaskVal;
148 }
149
150 if (A == C) {
151 MaskVal |= (IsEq ? (AMask_AllOnes | AMask_Mixed)
152 : (AMask_NotAllOnes | AMask_NotMixed));
153 if (IsAPow2)
154 MaskVal |= (IsEq ? (Mask_NotAllZeros | AMask_NotMixed)
155 : (Mask_AllZeros | AMask_Mixed));
156 } else if (ConstA && ConstC && ConstC->isSubsetOf(RHS: *ConstA)) {
157 MaskVal |= (IsEq ? AMask_Mixed : AMask_NotMixed);
158 }
159
160 if (B == C) {
161 MaskVal |= (IsEq ? (BMask_AllOnes | BMask_Mixed)
162 : (BMask_NotAllOnes | BMask_NotMixed));
163 if (IsBPow2)
164 MaskVal |= (IsEq ? (Mask_NotAllZeros | BMask_NotMixed)
165 : (Mask_AllZeros | BMask_Mixed));
166 } else if (ConstB && ConstC && ConstC->isSubsetOf(RHS: *ConstB)) {
167 MaskVal |= (IsEq ? BMask_Mixed : BMask_NotMixed);
168 }
169
170 return MaskVal;
171}
172
173/// Convert an analysis of a masked ICmp into its equivalent if all boolean
174/// operations had the opposite sense. Since each "NotXXX" flag (recording !=)
175/// is adjacent to the corresponding normal flag (recording ==), this just
176/// involves swapping those bits over.
177static unsigned conjugateICmpMask(unsigned Mask) {
178 unsigned NewMask;
179 NewMask = (Mask & (AMask_AllOnes | BMask_AllOnes | Mask_AllZeros |
180 AMask_Mixed | BMask_Mixed))
181 << 1;
182
183 NewMask |= (Mask & (AMask_NotAllOnes | BMask_NotAllOnes | Mask_NotAllZeros |
184 AMask_NotMixed | BMask_NotMixed))
185 >> 1;
186
187 return NewMask;
188}
189
190// Adapts the external decomposeBitTest for local use.
191static bool decomposeBitTest(Value *Cond, CmpInst::Predicate &Pred, Value *&X,
192 Value *&Y, Value *&Z) {
193 auto Res =
194 llvm::decomposeBitTest(Cond, /*LookThroughTrunc=*/true,
195 /*AllowNonZeroC=*/true, /*DecomposeAnd=*/true);
196 if (!Res)
197 return false;
198
199 Pred = Res->Pred;
200 X = Res->X;
201 Y = ConstantInt::get(Ty: X->getType(), V: Res->Mask);
202 Z = ConstantInt::get(Ty: X->getType(), V: Res->C);
203 return true;
204}
205
206/// Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
207/// Return the pattern classes (from MaskedICmpType) for the left hand side and
208/// the right hand side as a pair.
209/// LHS and RHS are the left hand side and the right hand side ICmps and PredL
210/// and PredR are their predicates, respectively.
211static std::optional<std::pair<unsigned, unsigned>>
212getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E,
213 Value *LHS, Value *RHS, ICmpInst::Predicate &PredL,
214 ICmpInst::Predicate &PredR) {
215
216 // Here comes the tricky part:
217 // LHS might be of the form L11 & L12 == X, X == L21 & L22,
218 // and L11 & L12 == L21 & L22. The same goes for RHS.
219 // Now we must find those components L** and R**, that are equal, so
220 // that we can extract the parameters A, B, C, D, and E for the canonical
221 // above.
222
223 // Check whether the icmp can be decomposed into a bit test.
224 Value *L1, *L11, *L12, *L2, *L21, *L22;
225 if (decomposeBitTest(Cond: LHS, Pred&: PredL, X&: L11, Y&: L12, Z&: L2)) {
226 L21 = L22 = L1 = nullptr;
227 } else {
228 auto *LHSCMP = dyn_cast<ICmpInst>(Val: LHS);
229 if (!LHSCMP)
230 return std::nullopt;
231
232 // Don't allow pointers. Splat vectors are fine.
233 if (!LHSCMP->getOperand(i_nocapture: 0)->getType()->isIntOrIntVectorTy())
234 return std::nullopt;
235
236 PredL = LHSCMP->getPredicate();
237 L1 = LHSCMP->getOperand(i_nocapture: 0);
238 L2 = LHSCMP->getOperand(i_nocapture: 1);
239 // Look for ANDs in the LHS icmp.
240 if (!match(V: L1, P: m_And(L: m_Value(V&: L11), R: m_Value(V&: L12)))) {
241 // Any icmp can be viewed as being trivially masked; if it allows us to
242 // remove one, it's worth it.
243 L11 = L1;
244 L12 = Constant::getAllOnesValue(Ty: L1->getType());
245 }
246
247 if (!match(V: L2, P: m_And(L: m_Value(V&: L21), R: m_Value(V&: L22)))) {
248 L21 = L2;
249 L22 = Constant::getAllOnesValue(Ty: L2->getType());
250 }
251 }
252
253 // Bail if LHS was a icmp that can't be decomposed into an equality.
254 if (!ICmpInst::isEquality(P: PredL))
255 return std::nullopt;
256
257 Value *R11, *R12, *R2;
258 if (decomposeBitTest(Cond: RHS, Pred&: PredR, X&: R11, Y&: R12, Z&: R2)) {
259 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
260 A = R11;
261 D = R12;
262 } else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
263 A = R12;
264 D = R11;
265 } else {
266 return std::nullopt;
267 }
268 E = R2;
269 } else {
270 auto *RHSCMP = dyn_cast<ICmpInst>(Val: RHS);
271 if (!RHSCMP)
272 return std::nullopt;
273 // Don't allow pointers. Splat vectors are fine.
274 if (!RHSCMP->getOperand(i_nocapture: 0)->getType()->isIntOrIntVectorTy())
275 return std::nullopt;
276
277 PredR = RHSCMP->getPredicate();
278
279 Value *R1 = RHSCMP->getOperand(i_nocapture: 0);
280 R2 = RHSCMP->getOperand(i_nocapture: 1);
281 bool Ok = false;
282 if (!match(V: R1, P: m_And(L: m_Value(V&: R11), R: m_Value(V&: R12)))) {
283 // As before, model no mask as a trivial mask if it'll let us do an
284 // optimization.
285 R11 = R1;
286 R12 = Constant::getAllOnesValue(Ty: R1->getType());
287 }
288
289 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
290 A = R11;
291 D = R12;
292 E = R2;
293 Ok = true;
294 } else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
295 A = R12;
296 D = R11;
297 E = R2;
298 Ok = true;
299 }
300
301 // Avoid matching against the -1 value we created for unmasked operand.
302 if (Ok && match(V: A, P: m_AllOnes()))
303 Ok = false;
304
305 // Look for ANDs on the right side of the RHS icmp.
306 if (!Ok) {
307 if (!match(V: R2, P: m_And(L: m_Value(V&: R11), R: m_Value(V&: R12)))) {
308 R11 = R2;
309 R12 = Constant::getAllOnesValue(Ty: R2->getType());
310 }
311
312 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
313 A = R11;
314 D = R12;
315 E = R1;
316 } else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
317 A = R12;
318 D = R11;
319 E = R1;
320 } else {
321 return std::nullopt;
322 }
323 }
324 }
325
326 // Bail if RHS was a icmp that can't be decomposed into an equality.
327 if (!ICmpInst::isEquality(P: PredR))
328 return std::nullopt;
329
330 if (L11 == A) {
331 B = L12;
332 C = L2;
333 } else if (L12 == A) {
334 B = L11;
335 C = L2;
336 } else if (L21 == A) {
337 B = L22;
338 C = L1;
339 } else if (L22 == A) {
340 B = L21;
341 C = L1;
342 }
343
344 unsigned LeftType = getMaskedICmpType(A, B, C, Pred: PredL);
345 unsigned RightType = getMaskedICmpType(A, B: D, C: E, Pred: PredR);
346 return std::optional<std::pair<unsigned, unsigned>>(
347 std::make_pair(x&: LeftType, y&: RightType));
348}
349
350/// Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single
351/// (icmp(A & X) ==/!= Y), where the left-hand side is of type Mask_NotAllZeros
352/// and the right hand side is of type BMask_Mixed. For example,
353/// (icmp (A & 12) != 0) & (icmp (A & 15) == 8) -> (icmp (A & 15) == 8).
354/// Also used for logical and/or, must be poison safe.
355static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
356 Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *D, Value *E,
357 ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
358 InstCombiner::BuilderTy &Builder) {
359 // We are given the canonical form:
360 // (icmp ne (A & B), 0) & (icmp eq (A & D), E).
361 // where D & E == E.
362 //
363 // If IsAnd is false, we get it in negated form:
364 // (icmp eq (A & B), 0) | (icmp ne (A & D), E) ->
365 // !((icmp ne (A & B), 0) & (icmp eq (A & D), E)).
366 //
367 // We currently handle the case of B, C, D, E are constant.
368 //
369 const APInt *BCst, *DCst, *OrigECst;
370 if (!match(V: B, P: m_APInt(Res&: BCst)) || !match(V: D, P: m_APInt(Res&: DCst)) ||
371 !match(V: E, P: m_APInt(Res&: OrigECst)))
372 return nullptr;
373
374 ICmpInst::Predicate NewCC = IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
375
376 // Update E to the canonical form when D is a power of two and RHS is
377 // canonicalized as,
378 // (icmp ne (A & D), 0) -> (icmp eq (A & D), D) or
379 // (icmp ne (A & D), D) -> (icmp eq (A & D), 0).
380 APInt ECst = *OrigECst;
381 if (PredR != NewCC)
382 ECst ^= *DCst;
383
384 // If B or D is zero, skip because if LHS or RHS can be trivially folded by
385 // other folding rules and this pattern won't apply any more.
386 if (*BCst == 0 || *DCst == 0)
387 return nullptr;
388
389 // If B and D don't intersect, ie. (B & D) == 0, try to fold isNaN idiom:
390 // (icmp ne (A & FractionBits), 0) & (icmp eq (A & ExpBits), ExpBits)
391 // -> isNaN(A)
392 // Otherwise, we cannot deduce anything from it.
393 if (!BCst->intersects(RHS: *DCst)) {
394 Value *Src;
395 if (*DCst == ECst && match(V: A, P: m_ElementWiseBitCast(Op: m_Value(V&: Src))) &&
396 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
397 Kind: Attribute::StrictFP)) {
398 Type *Ty = Src->getType()->getScalarType();
399 if (!Ty->isIEEELikeFPTy())
400 return nullptr;
401
402 APInt ExpBits = APFloat::getInf(Sem: Ty->getFltSemantics()).bitcastToAPInt();
403 if (ECst != ExpBits)
404 return nullptr;
405 APInt FractionBits = ~ExpBits;
406 FractionBits.clearSignBit();
407 if (*BCst != FractionBits)
408 return nullptr;
409
410 return Builder.CreateFCmp(P: IsAnd ? FCmpInst::FCMP_UNO : FCmpInst::FCMP_ORD,
411 LHS: Src, RHS: ConstantFP::getZero(Ty: Src->getType()));
412 }
413 return nullptr;
414 }
415
416 // If the following two conditions are met:
417 //
418 // 1. mask B covers only a single bit that's not covered by mask D, that is,
419 // (B & (B ^ D)) is a power of 2 (in other words, B minus the intersection of
420 // B and D has only one bit set) and,
421 //
422 // 2. RHS (and E) indicates that the rest of B's bits are zero (in other
423 // words, the intersection of B and D is zero), that is, ((B & D) & E) == 0
424 //
425 // then that single bit in B must be one and thus the whole expression can be
426 // folded to
427 // (A & (B | D)) == (B & (B ^ D)) | E.
428 //
429 // For example,
430 // (icmp ne (A & 12), 0) & (icmp eq (A & 7), 1) -> (icmp eq (A & 15), 9)
431 // (icmp ne (A & 15), 0) & (icmp eq (A & 7), 0) -> (icmp eq (A & 15), 8)
432 if ((((*BCst & *DCst) & ECst) == 0) &&
433 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
434 APInt BorD = *BCst | *DCst;
435 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
436 Value *NewMask = ConstantInt::get(Ty: A->getType(), V: BorD);
437 Value *NewMaskedValue = ConstantInt::get(Ty: A->getType(), V: BandBxorDorE);
438 Value *NewAnd = Builder.CreateAnd(LHS: A, RHS: NewMask);
439 return Builder.CreateICmp(P: NewCC, LHS: NewAnd, RHS: NewMaskedValue);
440 }
441
442 auto IsSubSetOrEqual = [](const APInt *C1, const APInt *C2) {
443 return (*C1 & *C2) == *C1;
444 };
445 auto IsSuperSetOrEqual = [](const APInt *C1, const APInt *C2) {
446 return (*C1 & *C2) == *C2;
447 };
448
449 // In the following, we consider only the cases where B is a superset of D, B
450 // is a subset of D, or B == D because otherwise there's at least one bit
451 // covered by B but not D, in which case we can't deduce much from it, so
452 // no folding (aside from the single must-be-one bit case right above.)
453 // For example,
454 // (icmp ne (A & 14), 0) & (icmp eq (A & 3), 1) -> no folding.
455 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
456 return nullptr;
457
458 // At this point, either B is a superset of D, B is a subset of D or B == D.
459
460 // If E is zero, if B is a subset of (or equal to) D, LHS and RHS contradict
461 // and the whole expression becomes false (or true if negated), otherwise, no
462 // folding.
463 // For example,
464 // (icmp ne (A & 3), 0) & (icmp eq (A & 7), 0) -> false.
465 // (icmp ne (A & 15), 0) & (icmp eq (A & 3), 0) -> no folding.
466 if (ECst.isZero()) {
467 if (IsSubSetOrEqual(BCst, DCst))
468 return ConstantInt::get(Ty: LHS->getType(), V: !IsAnd);
469 return nullptr;
470 }
471
472 // At this point, B, D, E aren't zero and (B & D) == B, (B & D) == D or B ==
473 // D. If B is a superset of (or equal to) D, since E is not zero, LHS is
474 // subsumed by RHS (RHS implies LHS.) So the whole expression becomes
475 // RHS. For example,
476 // (icmp ne (A & 255), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8).
477 // (icmp ne (A & 15), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8).
478 if (IsSuperSetOrEqual(BCst, DCst)) {
479 // We can't guarantee that samesign hold after this fold.
480 if (auto *ICmp = dyn_cast<ICmpInst>(Val: RHS))
481 ICmp->setSameSign(false);
482 return RHS;
483 }
484 // Otherwise, B is a subset of D. If B and E have a common bit set,
485 // ie. (B & E) != 0, then LHS is subsumed by RHS. For example.
486 // (icmp ne (A & 12), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8).
487 assert(IsSubSetOrEqual(BCst, DCst) && "Precondition due to above code");
488 if ((*BCst & ECst) != 0) {
489 // We can't guarantee that samesign hold after this fold.
490 if (auto *ICmp = dyn_cast<ICmpInst>(Val: RHS))
491 ICmp->setSameSign(false);
492 return RHS;
493 }
494 // Otherwise, LHS and RHS contradict and the whole expression becomes false
495 // (or true if negated.) For example,
496 // (icmp ne (A & 7), 0) & (icmp eq (A & 15), 8) -> false.
497 // (icmp ne (A & 6), 0) & (icmp eq (A & 15), 8) -> false.
498 return ConstantInt::get(Ty: LHS->getType(), V: !IsAnd);
499}
500
501/// Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single
502/// (icmp(A & X) ==/!= Y), where the left-hand side and the right hand side
503/// aren't of the common mask pattern type.
504/// Also used for logical and/or, must be poison safe.
505static Value *foldLogOpOfMaskedICmpsAsymmetric(
506 Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D,
507 Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
508 unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder) {
509 assert(ICmpInst::isEquality(PredL) && ICmpInst::isEquality(PredR) &&
510 "Expected equality predicates for masked type of icmps.");
511 // Handle Mask_NotAllZeros-BMask_Mixed cases.
512 // (icmp ne/eq (A & B), C) &/| (icmp eq/ne (A & D), E), or
513 // (icmp eq/ne (A & B), C) &/| (icmp ne/eq (A & D), E)
514 // which gets swapped to
515 // (icmp ne/eq (A & D), E) &/| (icmp eq/ne (A & B), C).
516 if (!IsAnd) {
517 LHSMask = conjugateICmpMask(Mask: LHSMask);
518 RHSMask = conjugateICmpMask(Mask: RHSMask);
519 }
520 if ((LHSMask & Mask_NotAllZeros) && (RHSMask & BMask_Mixed)) {
521 if (Value *V = foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
522 LHS, RHS, IsAnd, A, B, D, E, PredL, PredR, Builder)) {
523 return V;
524 }
525 } else if ((LHSMask & BMask_Mixed) && (RHSMask & Mask_NotAllZeros)) {
526 if (Value *V = foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
527 LHS: RHS, RHS: LHS, IsAnd, A, B: D, D: B, E: C, PredL: PredR, PredR: PredL, Builder)) {
528 return V;
529 }
530 }
531 return nullptr;
532}
533
534/// Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E)
535/// into a single (icmp(A & X) ==/!= Y).
536static Value *foldLogOpOfMaskedICmps(Value *LHS, Value *RHS, bool IsAnd,
537 bool IsLogical,
538 InstCombiner::BuilderTy &Builder,
539 const SimplifyQuery &Q) {
540 Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr, *E = nullptr;
541 ICmpInst::Predicate PredL, PredR;
542 std::optional<std::pair<unsigned, unsigned>> MaskPair =
543 getMaskedTypeForICmpPair(A, B, C, D, E, LHS, RHS, PredL, PredR);
544 if (!MaskPair)
545 return nullptr;
546 assert(ICmpInst::isEquality(PredL) && ICmpInst::isEquality(PredR) &&
547 "Expected equality predicates for masked type of icmps.");
548 unsigned LHSMask = MaskPair->first;
549 unsigned RHSMask = MaskPair->second;
550 unsigned Mask = LHSMask & RHSMask;
551 if (Mask == 0) {
552 // Even if the two sides don't share a common pattern, check if folding can
553 // still happen.
554 if (Value *V = foldLogOpOfMaskedICmpsAsymmetric(
555 LHS, RHS, IsAnd, A, B, C, D, E, PredL, PredR, LHSMask, RHSMask,
556 Builder))
557 return V;
558 return nullptr;
559 }
560
561 // In full generality:
562 // (icmp (A & B) Op C) | (icmp (A & D) Op E)
563 // == ![ (icmp (A & B) !Op C) & (icmp (A & D) !Op E) ]
564 //
565 // If the latter can be converted into (icmp (A & X) Op Y) then the former is
566 // equivalent to (icmp (A & X) !Op Y).
567 //
568 // Therefore, we can pretend for the rest of this function that we're dealing
569 // with the conjunction, provided we flip the sense of any comparisons (both
570 // input and output).
571
572 // In most cases we're going to produce an EQ for the "&&" case.
573 ICmpInst::Predicate NewCC = IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
574 if (!IsAnd) {
575 // Convert the masking analysis into its equivalent with negated
576 // comparisons.
577 Mask = conjugateICmpMask(Mask);
578 }
579
580 if (Mask & Mask_AllZeros) {
581 // (icmp eq (A & B), 0) & (icmp eq (A & D), 0)
582 // -> (icmp eq (A & (B|D)), 0)
583 if (IsLogical && !isGuaranteedNotToBeUndefOrPoison(V: D))
584 return nullptr; // TODO: Use freeze?
585 Value *NewOr = Builder.CreateOr(LHS: B, RHS: D);
586 Value *NewAnd = Builder.CreateAnd(LHS: A, RHS: NewOr);
587 // We can't use C as zero because we might actually handle
588 // (icmp ne (A & B), B) & (icmp ne (A & D), D)
589 // with B and D, having a single bit set.
590 Value *Zero = Constant::getNullValue(Ty: A->getType());
591 return Builder.CreateICmp(P: NewCC, LHS: NewAnd, RHS: Zero);
592 }
593 if (Mask & BMask_AllOnes) {
594 // (icmp eq (A & B), B) & (icmp eq (A & D), D)
595 // -> (icmp eq (A & (B|D)), (B|D))
596 if (IsLogical && !isGuaranteedNotToBeUndefOrPoison(V: D))
597 return nullptr; // TODO: Use freeze?
598 Value *NewOr = Builder.CreateOr(LHS: B, RHS: D);
599 Value *NewAnd = Builder.CreateAnd(LHS: A, RHS: NewOr);
600 return Builder.CreateICmp(P: NewCC, LHS: NewAnd, RHS: NewOr);
601 }
602 if (Mask & AMask_AllOnes) {
603 // (icmp eq (A & B), A) & (icmp eq (A & D), A)
604 // -> (icmp eq (A & (B&D)), A)
605 if (IsLogical && !isGuaranteedNotToBeUndefOrPoison(V: D))
606 return nullptr; // TODO: Use freeze?
607 Value *NewAnd1 = Builder.CreateAnd(LHS: B, RHS: D);
608 Value *NewAnd2 = Builder.CreateAnd(LHS: A, RHS: NewAnd1);
609 return Builder.CreateICmp(P: NewCC, LHS: NewAnd2, RHS: A);
610 }
611
612 const APInt *ConstB, *ConstD;
613 if (match(V: B, P: m_APInt(Res&: ConstB)) && match(V: D, P: m_APInt(Res&: ConstD))) {
614 if (Mask & (Mask_NotAllZeros | BMask_NotAllOnes)) {
615 // (icmp ne (A & B), 0) & (icmp ne (A & D), 0) and
616 // (icmp ne (A & B), B) & (icmp ne (A & D), D)
617 // -> (icmp ne (A & B), 0) or (icmp ne (A & D), 0)
618 // Only valid if one of the masks is a superset of the other (check "B&D"
619 // is the same as either B or D).
620 APInt NewMask = *ConstB & *ConstD;
621 if (NewMask == *ConstB)
622 return LHS;
623 if (NewMask == *ConstD) {
624 if (IsLogical) {
625 if (auto *RHSI = dyn_cast<Instruction>(Val: RHS))
626 RHSI->dropPoisonGeneratingFlags();
627 }
628 return RHS;
629 }
630 }
631
632 if (Mask & AMask_NotAllOnes) {
633 // (icmp ne (A & B), B) & (icmp ne (A & D), D)
634 // -> (icmp ne (A & B), A) or (icmp ne (A & D), A)
635 // Only valid if one of the masks is a superset of the other (check "B|D"
636 // is the same as either B or D).
637 APInt NewMask = *ConstB | *ConstD;
638 if (NewMask == *ConstB)
639 return LHS;
640 if (NewMask == *ConstD)
641 return RHS;
642 }
643
644 if (Mask & (BMask_Mixed | BMask_NotMixed)) {
645 // Mixed:
646 // (icmp eq (A & B), C) & (icmp eq (A & D), E)
647 // We already know that B & C == C && D & E == E.
648 // If we can prove that (B & D) & (C ^ E) == 0, that is, the bits of
649 // C and E, which are shared by both the mask B and the mask D, don't
650 // contradict, then we can transform to
651 // -> (icmp eq (A & (B|D)), (C|E))
652 // Currently, we only handle the case of B, C, D, and E being constant.
653 // We can't simply use C and E because we might actually handle
654 // (icmp ne (A & B), B) & (icmp eq (A & D), D)
655 // with B and D, having a single bit set.
656
657 // NotMixed:
658 // (icmp ne (A & B), C) & (icmp ne (A & D), E)
659 // -> (icmp ne (A & (B & D)), (C & E))
660 // Check the intersection (B & D) for inequality.
661 // Assume that (B & D) == B || (B & D) == D, i.e B/D is a subset of D/B
662 // and (B & D) & (C ^ E) == 0, bits of C and E, which are shared by both
663 // the B and the D, don't contradict. Note that we can assume (~B & C) ==
664 // 0 && (~D & E) == 0, previous operation should delete these icmps if it
665 // hadn't been met.
666
667 const APInt *OldConstC, *OldConstE;
668 if (!match(V: C, P: m_APInt(Res&: OldConstC)) || !match(V: E, P: m_APInt(Res&: OldConstE)))
669 return nullptr;
670
671 auto FoldBMixed = [&](ICmpInst::Predicate CC, bool IsNot) -> Value * {
672 CC = IsNot ? CmpInst::getInversePredicate(pred: CC) : CC;
673 const APInt ConstC = PredL != CC ? *ConstB ^ *OldConstC : *OldConstC;
674 const APInt ConstE = PredR != CC ? *ConstD ^ *OldConstE : *OldConstE;
675
676 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
677 return IsNot ? nullptr : ConstantInt::get(Ty: LHS->getType(), V: !IsAnd);
678
679 if (IsNot && !ConstB->isSubsetOf(RHS: *ConstD) &&
680 !ConstD->isSubsetOf(RHS: *ConstB))
681 return nullptr;
682
683 APInt BD, CE;
684 if (IsNot) {
685 BD = *ConstB & *ConstD;
686 CE = ConstC & ConstE;
687 } else {
688 BD = *ConstB | *ConstD;
689 CE = ConstC | ConstE;
690 }
691 Value *NewAnd = Builder.CreateAnd(LHS: A, RHS: BD);
692 Value *CEVal = ConstantInt::get(Ty: A->getType(), V: CE);
693 return Builder.CreateICmp(P: CC, LHS: NewAnd, RHS: CEVal);
694 };
695
696 if (Mask & BMask_Mixed)
697 return FoldBMixed(NewCC, false);
698 if (Mask & BMask_NotMixed) // can be else also
699 return FoldBMixed(NewCC, true);
700 }
701 }
702
703 // (icmp eq (A & B), 0) | (icmp eq (A & D), 0)
704 // -> (icmp ne (A & (B|D)), (B|D))
705 // (icmp ne (A & B), 0) & (icmp ne (A & D), 0)
706 // -> (icmp eq (A & (B|D)), (B|D))
707 // iff B and D is known to be a power of two
708 if (Mask & Mask_NotAllZeros &&
709 isKnownToBeAPowerOfTwo(V: B, /*OrZero=*/false, Q) &&
710 isKnownToBeAPowerOfTwo(V: D, /*OrZero=*/false, Q)) {
711 // If this is a logical and/or, then we must prevent propagation of a
712 // poison value from the RHS by inserting freeze.
713 if (IsLogical)
714 D = Builder.CreateFreeze(V: D);
715 Value *Mask = Builder.CreateOr(LHS: B, RHS: D);
716 Value *Masked = Builder.CreateAnd(LHS: A, RHS: Mask);
717 return Builder.CreateICmp(P: NewCC, LHS: Masked, RHS: Mask);
718 }
719 return nullptr;
720}
721
722/// Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
723/// Example: (icmp sge x, 0) & (icmp slt x, n) --> icmp ult x, n
724/// If \p Inverted is true then the check is for the inverted range, e.g.
725/// (icmp slt x, 0) | (icmp sgt x, n) --> icmp ugt x, n
726Value *InstCombinerImpl::simplifyRangeCheck(CmpPredicate PredL, Value *LHS0,
727 Value *LHS1, CmpPredicate PredR,
728 Value *RHS0, Value *RHS1,
729 Instruction *CxtI, bool Inverted) {
730 // Check the lower range comparison, e.g. x >= 0
731 // InstCombine already ensured that if there is a constant it's on the RHS.
732 ConstantInt *RangeStart = dyn_cast<ConstantInt>(Val: LHS1);
733 if (!RangeStart)
734 return nullptr;
735
736 if (Inverted) {
737 PredL = CmpPredicate::getInverse(P: PredL);
738 PredR = CmpPredicate::getInverse(P: PredR);
739 }
740
741 // Accept x > -1 or x >= 0 (after potentially inverting the predicate).
742 if (!((PredL == ICmpInst::ICMP_SGT && RangeStart->isMinusOne()) ||
743 (PredL == ICmpInst::ICMP_SGE && RangeStart->isZero())))
744 return nullptr;
745
746 Value *Input = LHS0;
747 Value *RangeEnd;
748 if (match(V: RHS0, P: m_SExtOrSelf(Op: m_Specific(V: Input)))) {
749 // For the upper range compare we have: icmp x, n
750 Input = RHS0;
751 RangeEnd = RHS1;
752 } else if (match(V: RHS1, P: m_SExtOrSelf(Op: m_Specific(V: Input)))) {
753 // For the upper range compare we have: icmp n, x
754 Input = RHS1;
755 RangeEnd = RHS0;
756 PredR = CmpPredicate::getSwapped(P: PredR);
757 } else {
758 return nullptr;
759 }
760
761 // Check the upper range comparison, e.g. x < n
762 ICmpInst::Predicate NewPred;
763 switch (PredR) {
764 case ICmpInst::ICMP_SLT:
765 NewPred = ICmpInst::ICMP_ULT;
766 break;
767 case ICmpInst::ICMP_SLE:
768 NewPred = ICmpInst::ICMP_ULE;
769 break;
770 default:
771 return nullptr;
772 }
773
774 // This simplification is only valid if the upper range is not negative.
775 KnownBits Known = computeKnownBits(V: RangeEnd, CxtI);
776 if (!Known.isNonNegative())
777 return nullptr;
778
779 if (Inverted)
780 NewPred = ICmpInst::getInversePredicate(pred: NewPred);
781
782 return Builder.CreateICmp(P: NewPred, LHS: Input, RHS: RangeEnd);
783}
784
785// (or (icmp eq X, 0), (icmp eq X, Pow2OrZero))
786// -> (icmp eq (and X, Pow2OrZero), X)
787// (and (icmp ne X, 0), (icmp ne X, Pow2OrZero))
788// -> (icmp ne (and X, Pow2OrZero), X)
789static Value *foldAndOrOfICmpsWithPow2AndWithZero(
790 InstCombiner::BuilderTy &Builder, CmpPredicate PredL, Value *LHS0,
791 Value *LHS1, bool LHSOneUse, CmpPredicate PredR, Value *RHS0, Value *RHS1,
792 bool RHSOneUse, bool IsAnd, const SimplifyQuery &Q) {
793 CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
794 // Make sure we have right compares for our op.
795 if (PredL != Pred || PredR != Pred)
796 return nullptr;
797
798 // Make it so we can match LHS against the (icmp eq/ne X, 0) just for
799 // simplicity.
800 if (match(V: RHS1, P: m_Zero())) {
801 std::swap(a&: PredL, b&: PredR);
802 std::swap(a&: LHS0, b&: RHS0);
803 std::swap(a&: LHS1, b&: RHS1);
804 }
805
806 if (RHS1 == LHS0)
807 std::swap(a&: RHS0, b&: RHS1);
808
809 // Match the desired pattern:
810 // LHS: (icmp eq/ne X, 0)
811 // RHS: (icmp eq/ne X, Pow2OrZero)
812 // Skip if Pow2OrZero is 1. Either way it gets folded to (icmp ugt X, 1) but
813 // this form ends up slightly less canonical.
814 // We could potentially be more sophisticated than requiring LHS/RHS
815 // be one-use. We don't create additional instructions if only one
816 // of them is one-use. So cases where one is one-use and the other
817 // is two-use might be profitable.
818 if (!LHSOneUse || !RHSOneUse || !match(V: LHS1, P: m_Zero()) || RHS0 != LHS0 ||
819 match(V: RHS1, P: m_One()) || !isKnownToBeAPowerOfTwo(V: RHS1, /*OrZero=*/true, Q))
820 return nullptr;
821
822 Value *And = Builder.CreateAnd(LHS: LHS0, RHS: RHS1);
823 return Builder.CreateICmp(P: Pred, LHS: And, RHS: LHS0);
824}
825
826/// General pattern:
827/// X & Y
828///
829/// Where Y is checking that all the high bits (covered by a mask 4294967168)
830/// are uniform, i.e. %arg & 4294967168 can be either 4294967168 or 0
831/// Pattern can be one of:
832/// %t = add i32 %arg, 128
833/// %r = icmp ult i32 %t, 256
834/// Or
835/// %t0 = shl i32 %arg, 24
836/// %t1 = ashr i32 %t0, 24
837/// %r = icmp eq i32 %t1, %arg
838/// Or
839/// %t0 = trunc i32 %arg to i8
840/// %t1 = sext i8 %t0 to i32
841/// %r = icmp eq i32 %t1, %arg
842/// This pattern is a signed truncation check.
843///
844/// And X is checking that some bit in that same mask is zero.
845/// I.e. can be one of:
846/// %r = icmp sgt i32 %arg, -1
847/// Or
848/// %t = and i32 %arg, 2147483648
849/// %r = icmp eq i32 %t, 0
850///
851/// Since we are checking that all the bits in that mask are the same,
852/// and a particular bit is zero, what we are really checking is that all the
853/// masked bits are zero.
854/// So this should be transformed to:
855/// %r = icmp ult i32 %arg, 128
856static Value *foldSignedTruncationCheck(CmpPredicate PredL, Value *LHS0,
857 Value *LHS1, CmpPredicate PredR,
858 Value *RHS0, Value *RHS1,
859 Instruction &CxtI,
860 InstCombiner::BuilderTy &Builder) {
861 assert(CxtI.getOpcode() == Instruction::And);
862
863 // Match icmp ult (add %arg, C01), C1 (C1 == C01 << 1; powers of two)
864 auto tryToMatchSignedTruncationCheck = [](CmpPredicate Pred, Value *LHS,
865 Value *RHS, Value *&X,
866 APInt &SignBitMask) -> bool {
867 const APInt *I01, *I1; // powers of two; I1 == I01 << 1
868 if (Pred != ICmpInst::ICMP_ULT ||
869 !match(V: LHS, P: m_Add(L: m_Value(V&: X), R: m_Power2(V&: I01))) ||
870 !match(V: RHS, P: m_Power2(V&: I1)) || I1->ule(RHS: *I01) || I01->shl(shiftAmt: 1) != *I1)
871 return false;
872 // Which bit is the new sign bit as per the 'signed truncation' pattern?
873 SignBitMask = *I01;
874 return true;
875 };
876
877 // One icmp needs to be 'signed truncation check'.
878 // We need to match this first, else we will mismatch commutative cases.
879 Value *X1;
880 APInt HighestBit;
881 if (tryToMatchSignedTruncationCheck(PredR, RHS0, RHS1, X1, HighestBit)) {
882 std::swap(a&: PredL, b&: PredR);
883 std::swap(a&: LHS0, b&: RHS0);
884 std::swap(a&: LHS1, b&: RHS1);
885 } else if (!tryToMatchSignedTruncationCheck(PredL, LHS0, LHS1, X1,
886 HighestBit))
887 return nullptr;
888
889 assert(HighestBit.isPowerOf2() && "expected to be power of two (non-zero)");
890
891 // Try to match/decompose into: icmp eq (X & Mask), 0
892 auto tryToDecompose = [](CmpPredicate Pred, Value *LHS, Value *RHS, Value *&X,
893 APInt &UnsetBitsMask) -> bool {
894 // Can it be decomposed into icmp eq (X & Mask), 0 ?
895 auto Res = llvm::decomposeBitTestICmp(LHS, RHS, Pred,
896 /*LookThroughTrunc=*/false,
897 /*AllowNonZeroC=*/false,
898 /*DecomposeAnd=*/true);
899 if (Res && Res->Pred == ICmpInst::ICMP_EQ) {
900 X = Res->X;
901 UnsetBitsMask = Res->Mask;
902 return true;
903 }
904
905 return false;
906 };
907
908 // And the other icmp needs to be decomposable into a bit test.
909 Value *X0;
910 APInt UnsetBitsMask;
911 if (!tryToDecompose(PredR, RHS0, RHS1, X0, UnsetBitsMask))
912 return nullptr;
913
914 assert(!UnsetBitsMask.isZero() && "empty mask makes no sense.");
915
916 // Are they working on the same value?
917 Value *X;
918 if (X1 == X0) {
919 // Ok as is.
920 X = X1;
921 } else if (match(V: X0, P: m_Trunc(Op: m_Specific(V: X1)))) {
922 UnsetBitsMask = UnsetBitsMask.zext(width: X1->getType()->getScalarSizeInBits());
923 X = X1;
924 } else
925 return nullptr;
926
927 // So which bits should be uniform as per the 'signed truncation check'?
928 // (all the bits starting with (i.e. including) HighestBit)
929 APInt SignBitsMask = ~(HighestBit - 1U);
930
931 // UnsetBitsMask must have some common bits with SignBitsMask,
932 if (!UnsetBitsMask.intersects(RHS: SignBitsMask))
933 return nullptr;
934
935 // Does UnsetBitsMask contain any bits outside of SignBitsMask?
936 if (!UnsetBitsMask.isSubsetOf(RHS: SignBitsMask)) {
937 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
938 if (!OtherHighestBit.isPowerOf2())
939 return nullptr;
940 HighestBit = APIntOps::umin(A: HighestBit, B: OtherHighestBit);
941 }
942 // Else, if it does not, then all is ok as-is.
943
944 // %r = icmp ult %X, SignBit
945 return Builder.CreateICmpULT(LHS: X, RHS: ConstantInt::get(Ty: X->getType(), V: HighestBit),
946 Name: CxtI.getName() + ".simplified");
947}
948
949/// Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and
950/// fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1).
951/// Also used for logical and/or, must be poison safe if range attributes are
952/// dropped.
953static Value *foldIsPowerOf2OrZero(CmpPredicate PredL, Value *LHS0, Value *LHS1,
954 CmpPredicate PredR, Value *RHS0, Value *RHS1,
955 bool IsAnd, InstCombiner::BuilderTy &Builder,
956 InstCombinerImpl &IC) {
957
958 Value *X;
959 if (!match(V: LHS0, P: m_Ctpop(Op0: m_Value(V&: X))) || !match(V: LHS1, P: m_SpecificInt(V: 1)) ||
960 RHS0 != X || !match(V: RHS1, P: m_ZeroInt()))
961 return nullptr;
962
963 auto *CtPop = cast<Instruction>(Val: LHS0);
964 if (IsAnd && PredL == ICmpInst::ICMP_NE && PredR == ICmpInst::ICMP_NE) {
965 // Drop range attributes and re-infer them in the next iteration.
966 CtPop->dropPoisonGeneratingAnnotations();
967 IC.addToWorklist(I: CtPop);
968 return Builder.CreateICmpUGT(LHS: CtPop, RHS: ConstantInt::get(Ty: CtPop->getType(), V: 1));
969 }
970 if (!IsAnd && PredL == ICmpInst::ICMP_EQ && PredR == ICmpInst::ICMP_EQ) {
971 // Drop range attributes and re-infer them in the next iteration.
972 CtPop->dropPoisonGeneratingAnnotations();
973 IC.addToWorklist(I: CtPop);
974 return Builder.CreateICmpULT(LHS: CtPop, RHS: ConstantInt::get(Ty: CtPop->getType(), V: 2));
975 }
976
977 return nullptr;
978}
979
980/// Reduce a pair of compares that check if a value has exactly 1 bit set.
981/// Also used for logical and/or, must be poison safe if range attributes are
982/// dropped.
983static Value *foldIsPowerOf2(CmpPredicate PredL, Value *LHS0, Value *LHS1,
984 CmpPredicate PredR, Value *RHS0, Value *RHS1,
985 bool JoinedByAnd, InstCombiner::BuilderTy &Builder,
986 InstCombinerImpl &IC) {
987 // Handle 'and' / 'or' commutation: make the equality check the first operand.
988 if (PredR == (JoinedByAnd ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ)) {
989 std::swap(a&: PredL, b&: PredR);
990 std::swap(a&: LHS0, b&: RHS0);
991 std::swap(a&: LHS1, b&: RHS1);
992 }
993
994 // (X != 0) && (ctpop(X) u< 2) --> ctpop(X) == 1
995 if (JoinedByAnd && PredL == ICmpInst::ICMP_NE && match(V: LHS1, P: m_ZeroInt()) &&
996 PredR == ICmpInst::ICMP_ULT && match(V: RHS0, P: m_Ctpop(Op0: m_Specific(V: LHS0))) &&
997 match(V: RHS1, P: m_SpecificInt(V: 2))) {
998 auto *CtPop = cast<Instruction>(Val: RHS0);
999 // Drop range attributes and re-infer them in the next iteration.
1000 CtPop->dropPoisonGeneratingAnnotations();
1001 IC.addToWorklist(I: CtPop);
1002 return Builder.CreateICmpEQ(LHS: CtPop, RHS: ConstantInt::get(Ty: CtPop->getType(), V: 1));
1003 }
1004 // (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1
1005 if (!JoinedByAnd && PredL == ICmpInst::ICMP_EQ && match(V: LHS1, P: m_ZeroInt()) &&
1006 PredR == ICmpInst::ICMP_UGT && match(V: RHS0, P: m_Ctpop(Op0: m_Specific(V: LHS0))) &&
1007 match(V: RHS1, P: m_SpecificInt(V: 1))) {
1008 auto *CtPop = cast<Instruction>(Val: RHS0);
1009 // Drop range attributes and re-infer them in the next iteration.
1010 CtPop->dropPoisonGeneratingAnnotations();
1011 IC.addToWorklist(I: CtPop);
1012 return Builder.CreateICmpNE(LHS: CtPop, RHS: ConstantInt::get(Ty: CtPop->getType(), V: 1));
1013 }
1014 return nullptr;
1015}
1016
1017/// Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff
1018/// B is a contiguous set of ones starting from the most significant bit
1019/// (negative power of 2), D and E are equal, and D is a contiguous set of ones
1020/// starting at the most significant zero bit in B. Parameter B supports masking
1021/// using undef/poison in either scalar or vector values.
1022static Value *foldNegativePower2AndShiftedMask(
1023 Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL,
1024 ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder) {
1025 assert(ICmpInst::isEquality(PredL) && ICmpInst::isEquality(PredR) &&
1026 "Expected equality predicates for masked type of icmps.");
1027 if (PredL != ICmpInst::ICMP_EQ || PredR != ICmpInst::ICMP_NE)
1028 return nullptr;
1029
1030 if (!match(V: B, P: m_NegatedPower2()) || !match(V: D, P: m_ShiftedMask()) ||
1031 !match(V: E, P: m_ShiftedMask()))
1032 return nullptr;
1033
1034 // Test scalar arguments for conversion. B has been validated earlier to be a
1035 // negative power of two and thus is guaranteed to have one or more contiguous
1036 // ones starting from the MSB followed by zero or more contiguous zeros. D has
1037 // been validated earlier to be a shifted set of one or more contiguous ones.
1038 // In order to match, B leading ones and D leading zeros should be equal. The
1039 // predicate that B be a negative power of 2 prevents the condition of there
1040 // ever being zero leading ones. Thus 0 == 0 cannot occur. The predicate that
1041 // D always be a shifted mask prevents the condition of D equaling 0. This
1042 // prevents matching the condition where B contains the maximum number of
1043 // leading one bits (-1) and D contains the maximum number of leading zero
1044 // bits (0).
1045 auto isReducible = [](const Value *B, const Value *D, const Value *E) {
1046 const APInt *BCst, *DCst, *ECst;
1047 return match(V: B, P: m_APIntAllowPoison(Res&: BCst)) && match(V: D, P: m_APInt(Res&: DCst)) &&
1048 match(V: E, P: m_APInt(Res&: ECst)) && *DCst == *ECst &&
1049 (isa<PoisonValue>(Val: B) ||
1050 (BCst->countLeadingOnes() == DCst->countLeadingZeros()));
1051 };
1052
1053 // Test vector type arguments for conversion.
1054 if (const auto *BVTy = dyn_cast<VectorType>(Val: B->getType())) {
1055 const auto *BFVTy = dyn_cast<FixedVectorType>(Val: BVTy);
1056 const auto *BConst = dyn_cast<Constant>(Val: B);
1057 const auto *DConst = dyn_cast<Constant>(Val: D);
1058 const auto *EConst = dyn_cast<Constant>(Val: E);
1059
1060 if (!BFVTy || !BConst || !DConst || !EConst)
1061 return nullptr;
1062
1063 for (unsigned I = 0; I != BFVTy->getNumElements(); ++I) {
1064 const auto *BElt = BConst->getAggregateElement(Elt: I);
1065 const auto *DElt = DConst->getAggregateElement(Elt: I);
1066 const auto *EElt = EConst->getAggregateElement(Elt: I);
1067
1068 if (!BElt || !DElt || !EElt)
1069 return nullptr;
1070 if (!isReducible(BElt, DElt, EElt))
1071 return nullptr;
1072 }
1073 } else {
1074 // Test scalar type arguments for conversion.
1075 if (!isReducible(B, D, E))
1076 return nullptr;
1077 }
1078 return Builder.CreateICmp(P: ICmpInst::ICMP_ULT, LHS: A, RHS: D);
1079}
1080
1081/// Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) &
1082/// (icmp(X & M) != M)) into (icmp X u< M). Where P is a power of 2, M < P, and
1083/// M is a contiguous shifted mask starting at the right most significant zero
1084/// bit in P. SGT is supported as when P is the largest representable power of
1085/// 2, an earlier optimization converts the expression into (icmp X s> -1).
1086/// Parameter P supports masking using undef/poison in either scalar or vector
1087/// values.
1088static Value *foldPowerOf2AndShiftedMask(Value *Cmp0, Value *Cmp1,
1089 bool JoinedByAnd,
1090 InstCombiner::BuilderTy &Builder) {
1091 if (!JoinedByAnd)
1092 return nullptr;
1093 Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr, *E = nullptr;
1094 ICmpInst::Predicate CmpPred0, CmpPred1;
1095 // Assuming P is a 2^n, getMaskedTypeForICmpPair will normalize (icmp X u<
1096 // 2^n) into (icmp (X & ~(2^n-1)) == 0) and (icmp X s> -1) into (icmp (X &
1097 // SignMask) == 0).
1098 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1099 getMaskedTypeForICmpPair(A, B, C, D, E, LHS: Cmp0, RHS: Cmp1, PredL&: CmpPred0, PredR&: CmpPred1);
1100 if (!MaskPair)
1101 return nullptr;
1102
1103 const auto compareBMask = BMask_NotMixed | BMask_NotAllOnes;
1104 unsigned CmpMask0 = MaskPair->first;
1105 unsigned CmpMask1 = MaskPair->second;
1106 if ((CmpMask0 & Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1107 if (Value *V = foldNegativePower2AndShiftedMask(A, B, D, E, PredL: CmpPred0,
1108 PredR: CmpPred1, Builder))
1109 return V;
1110 } else if ((CmpMask0 == compareBMask) && (CmpMask1 & Mask_AllZeros)) {
1111 if (Value *V = foldNegativePower2AndShiftedMask(A, B: D, D: B, E: C, PredL: CmpPred1,
1112 PredR: CmpPred0, Builder))
1113 return V;
1114 }
1115 return nullptr;
1116}
1117
1118/// Commuted variants are assumed to be handled by calling this function again
1119/// with the parameters swapped.
1120static Value *foldUnsignedUnderflowCheck(CmpPredicate PredL, Value *LHS0,
1121 Value *LHS1, bool LHSOneUse,
1122 CmpPredicate PredR, Value *RHS0,
1123 Value *RHS1, bool RHSOneUse,
1124 bool IsAnd, const SimplifyQuery &Q,
1125 InstCombiner::BuilderTy &Builder) {
1126 if (!match(V: LHS1, P: m_Zero()) || !ICmpInst::isEquality(P: PredL))
1127 return nullptr;
1128
1129 Value *A, *B;
1130 if (RHS0 == LHS0)
1131 A = RHS1;
1132 else if (RHS1 == LHS0) {
1133 A = RHS0;
1134 PredR = CmpPredicate::getSwapped(P: PredR);
1135 } else
1136 return nullptr;
1137
1138 if (!match(V: LHS0, P: m_c_Add(L: m_Specific(V: A), R: m_Value(V&: B))) ||
1139 !(LHSOneUse || RHSOneUse))
1140 return nullptr;
1141
1142 auto GetKnownNonZeroAndOther = [&](Value *&NonZero, Value *&Other) {
1143 if (!isKnownNonZero(V: NonZero, Q))
1144 std::swap(a&: NonZero, b&: Other);
1145 return isKnownNonZero(V: NonZero, Q);
1146 };
1147
1148 // Given ZeroCmpOp = (A + B)
1149 // ZeroCmpOp < A && ZeroCmpOp != 0 --> (0-X) < Y iff
1150 // ZeroCmpOp >= A || ZeroCmpOp == 0 --> (0-X) >= Y iff
1151 // with X being the value (A/B) that is known to be non-zero,
1152 // and Y being remaining value.
1153 if (PredR == ICmpInst::ICMP_ULT && PredL == ICmpInst::ICMP_NE && IsAnd &&
1154 GetKnownNonZeroAndOther(B, A))
1155 return Builder.CreateICmpULT(LHS: Builder.CreateNeg(V: B), RHS: A);
1156 if (PredR == ICmpInst::ICMP_UGE && PredL == ICmpInst::ICMP_EQ && !IsAnd &&
1157 GetKnownNonZeroAndOther(B, A))
1158 return Builder.CreateICmpUGE(LHS: Builder.CreateNeg(V: B), RHS: A);
1159
1160 return nullptr;
1161}
1162
1163struct IntPart {
1164 Value *From;
1165 unsigned StartBit;
1166 unsigned NumBits;
1167};
1168
1169/// Match an extraction of bits from an integer.
1170static std::optional<IntPart> matchIntPart(Value *V) {
1171 Value *X;
1172 if (!match(V, P: m_OneUse(SubPattern: m_Trunc(Op: m_Value(V&: X)))))
1173 return std::nullopt;
1174
1175 unsigned NumOriginalBits = X->getType()->getScalarSizeInBits();
1176 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1177 Value *Y;
1178 const APInt *Shift;
1179 // For a trunc(lshr Y, Shift) pattern, make sure we're only extracting bits
1180 // from Y, not any shifted-in zeroes.
1181 if (match(V: X, P: m_OneUse(SubPattern: m_LShr(L: m_Value(V&: Y), R: m_APInt(Res&: Shift)))) &&
1182 Shift->ule(RHS: NumOriginalBits - NumExtractedBits))
1183 return {{.From: Y, .StartBit: (unsigned)Shift->getZExtValue(), .NumBits: NumExtractedBits}};
1184 return {{.From: X, .StartBit: 0, .NumBits: NumExtractedBits}};
1185}
1186
1187/// Materialize an extraction of bits from an integer in IR.
1188static Value *extractIntPart(const IntPart &P, IRBuilderBase &Builder) {
1189 Value *V = P.From;
1190 if (P.StartBit)
1191 V = Builder.CreateLShr(LHS: V, RHS: P.StartBit);
1192 Type *TruncTy = V->getType()->getWithNewBitWidth(NewBitWidth: P.NumBits);
1193 if (TruncTy != V->getType())
1194 V = Builder.CreateTrunc(V, DestTy: TruncTy);
1195 return V;
1196}
1197
1198/// (icmp eq X0, Y0) & (icmp eq X1, Y1) -> icmp eq X01, Y01
1199/// (icmp ne X0, Y0) | (icmp ne X1, Y1) -> icmp ne X01, Y01
1200/// where X0, X1 and Y0, Y1 are adjacent parts extracted from an integer.
1201Value *InstCombinerImpl::foldEqOfParts(Value *Cmp0, Value *Cmp1, bool IsAnd) {
1202 if (!Cmp0->hasOneUse() || !Cmp1->hasOneUse())
1203 return nullptr;
1204
1205 CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE;
1206 auto GetMatchPart = [&](Value *CmpV,
1207 unsigned OpNo) -> std::optional<IntPart> {
1208 assert(CmpV->getType()->isIntOrIntVectorTy(1) && "Must be bool");
1209
1210 Value *X, *Y;
1211 // icmp ne (and x, 1), (and y, 1) <=> trunc (xor x, y) to i1
1212 // icmp eq (and x, 1), (and y, 1) <=> not (trunc (xor x, y) to i1)
1213 if (Pred == CmpInst::ICMP_NE
1214 ? match(V: CmpV, P: m_Trunc(Op: m_Xor(L: m_Value(V&: X), R: m_Value(V&: Y))))
1215 : match(V: CmpV, P: m_Not(V: m_Trunc(Op: m_Xor(L: m_Value(V&: X), R: m_Value(V&: Y))))))
1216 return {{.From: OpNo == 0 ? X : Y, .StartBit: 0, .NumBits: 1}};
1217
1218 auto *Cmp = dyn_cast<ICmpInst>(Val: CmpV);
1219 if (!Cmp)
1220 return std::nullopt;
1221
1222 if (Pred == Cmp->getPredicate())
1223 return matchIntPart(V: Cmp->getOperand(i_nocapture: OpNo));
1224
1225 const APInt *C;
1226 // (icmp eq (lshr x, C), (lshr y, C)) gets optimized to:
1227 // (icmp ult (xor x, y), 1 << C) so also look for that.
1228 if (Pred == CmpInst::ICMP_EQ && Cmp->getPredicate() == CmpInst::ICMP_ULT) {
1229 if (!match(V: Cmp->getOperand(i_nocapture: 1), P: m_Power2(V&: C)) ||
1230 !match(V: Cmp->getOperand(i_nocapture: 0), P: m_Xor(L: m_Value(), R: m_Value())))
1231 return std::nullopt;
1232 }
1233
1234 // (icmp ne (lshr x, C), (lshr y, C)) gets optimized to:
1235 // (icmp ugt (xor x, y), (1 << C) - 1) so also look for that.
1236 else if (Pred == CmpInst::ICMP_NE &&
1237 Cmp->getPredicate() == CmpInst::ICMP_UGT) {
1238 if (!match(V: Cmp->getOperand(i_nocapture: 1), P: m_LowBitMask(V&: C)) ||
1239 !match(V: Cmp->getOperand(i_nocapture: 0), P: m_Xor(L: m_Value(), R: m_Value())))
1240 return std::nullopt;
1241 } else {
1242 return std::nullopt;
1243 }
1244
1245 unsigned From = Pred == CmpInst::ICMP_NE ? C->popcount() : C->countr_zero();
1246 Instruction *I = cast<Instruction>(Val: Cmp->getOperand(i_nocapture: 0));
1247 return {{.From: I->getOperand(i: OpNo), .StartBit: From, .NumBits: C->getBitWidth() - From}};
1248 };
1249
1250 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1251 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1252 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1253 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1254 if (!L0 || !R0 || !L1 || !R1)
1255 return nullptr;
1256
1257 // Make sure the LHS/RHS compare a part of the same value, possibly after
1258 // an operand swap.
1259 if (L0->From != L1->From || R0->From != R1->From) {
1260 if (L0->From != R1->From || R0->From != L1->From)
1261 return nullptr;
1262 std::swap(lhs&: L1, rhs&: R1);
1263 }
1264
1265 // Make sure the extracted parts are adjacent, canonicalizing to L0/R0 being
1266 // the low part and L1/R1 being the high part.
1267 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1268 R0->StartBit + R0->NumBits != R1->StartBit) {
1269 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1270 R1->StartBit + R1->NumBits != R0->StartBit)
1271 return nullptr;
1272 std::swap(lhs&: L0, rhs&: L1);
1273 std::swap(lhs&: R0, rhs&: R1);
1274 }
1275
1276 // We can simplify to a comparison of these larger parts of the integers.
1277 IntPart L = {.From: L0->From, .StartBit: L0->StartBit, .NumBits: L0->NumBits + L1->NumBits};
1278 IntPart R = {.From: R0->From, .StartBit: R0->StartBit, .NumBits: R0->NumBits + R1->NumBits};
1279 Value *LValue = extractIntPart(P: L, Builder);
1280 Value *RValue = extractIntPart(P: R, Builder);
1281 return Builder.CreateICmp(P: Pred, LHS: LValue, RHS: RValue);
1282}
1283
1284/// Reduce logic-of-compares with equality to a constant by substituting a
1285/// common operand with the constant. Callers are expected to call this with
1286/// Cmp0/Cmp1 switched to handle logic op commutativity.
1287static Value *
1288foldAndOrOfICmpsWithConstEq(CmpPredicate PredL, Value *LHS0, Value *LHS1,
1289 Value *LHS, CmpPredicate PredR, Value *RHS0,
1290 Value *RHS1, bool RHSOneUse, bool IsAnd,
1291 bool IsLogical, InstCombiner::BuilderTy &Builder,
1292 const SimplifyQuery &Q, Instruction &I) {
1293 // Match an equality compare with a non-poison constant as Cmp0.
1294 // Also, give up if the compare can be constant-folded to avoid looping.
1295 if (!isa<Constant>(Val: LHS1) || !isGuaranteedNotToBeUndefOrPoison(V: LHS1) ||
1296 isa<Constant>(Val: LHS0))
1297 return nullptr;
1298 if ((IsAnd && PredL != ICmpInst::ICMP_EQ) ||
1299 (!IsAnd && PredL != ICmpInst::ICMP_NE))
1300 return nullptr;
1301
1302 // The other compare must include a common operand (X). Canonicalize the
1303 // common operand as operand 1 (Pred1 is swapped if the common operand was
1304 // operand 0).
1305 Value *Y;
1306
1307 if (LHS0 == RHS0) {
1308 Y = RHS1;
1309 PredR = CmpPredicate::getSwapped(P: PredR);
1310 } else if (LHS0 == RHS1)
1311 Y = RHS0;
1312 else
1313 return nullptr;
1314
1315 // Replace variable with constant value equivalence to remove a variable use:
1316 // (X == C) && (Y Pred1 X) --> (X == C) && (Y Pred1 C)
1317 // (X != C) || (Y Pred1 X) --> (X != C) || (Y Pred1 C)
1318 // Can think of the 'or' substitution with the 'and' bool equivalent:
1319 // A || B --> A || (!A && B)
1320 Value *SubstituteCmp = simplifyICmpInst(Pred: PredR, LHS: Y, RHS: LHS1, Q);
1321 if (!SubstituteCmp) {
1322 // If we need to create a new instruction, require that the old compare can
1323 // be removed.
1324 if (!RHSOneUse)
1325 return nullptr;
1326 SubstituteCmp = Builder.CreateICmp(P: PredR, LHS: Y, RHS: LHS1);
1327 }
1328 if (IsLogical) {
1329 Instruction *MDFrom = isa<SelectInst>(Val: I) ? &I : nullptr;
1330 return IsAnd ? Builder.CreateLogicalAnd(Cond1: LHS, Cond2: SubstituteCmp, Name: "", MDFrom)
1331 : Builder.CreateLogicalOr(Cond1: LHS, Cond2: SubstituteCmp, Name: "", MDFrom);
1332 }
1333 return Builder.CreateBinOp(Opc: IsAnd ? Instruction::And : Instruction::Or, LHS,
1334 RHS: SubstituteCmp);
1335}
1336
1337/// Fold (icmp Pred1 V1, C1) & (icmp Pred2 V2, C2)
1338/// or (icmp Pred1 V1, C1) | (icmp Pred2 V2, C2)
1339/// into a single comparison using range-based reasoning.
1340/// NOTE: This is also used for logical and/or, must be poison-safe!
1341Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
1342 CmpPredicate PredL, Value *LHS0, Value *LHS1, bool LHSOneUse,
1343 CmpPredicate PredR, Value *RHS0, Value *RHS1, bool RHSOneUse, bool IsAnd) {
1344 // Return (V, CR) for a range check idiom V in CR.
1345 auto MatchExactRangeCheck =
1346 [](CmpPredicate Pred, Value *LHS,
1347 Value *RHS) -> std::optional<std::pair<Value *, ConstantRange>> {
1348 const APInt *C;
1349 if (!match(V: RHS, P: m_APInt(Res&: C)))
1350 return std::nullopt;
1351
1352 Value *X;
1353 // Match (x & NegPow2) ==/!= C
1354 const APInt *Mask;
1355 if (ICmpInst::isEquality(P: Pred) &&
1356 match(V: LHS, P: m_OneUse(SubPattern: m_And(L: m_Value(V&: X), R: m_NegatedPower2(V&: Mask)))) &&
1357 C->countr_zero() >= Mask->countr_zero()) {
1358 ConstantRange CR(*C, *C - *Mask);
1359 if (Pred == ICmpInst::ICMP_NE)
1360 CR = CR.inverse();
1361 return std::make_pair(x&: X, y&: CR);
1362 }
1363 ConstantRange CR = ConstantRange::makeExactICmpRegion(Pred, Other: *C);
1364 // Match (add X, C1) pred C
1365 // TODO: investigate whether we should apply the one-use check on m_AddLike.
1366 const APInt *C1;
1367 if (match(V: LHS, P: m_AddLike(L: m_Value(V&: X), R: m_APInt(Res&: C1))))
1368 return std::make_pair(x&: X, y: CR.subtract(CI: *C1));
1369 return std::make_pair(x&: LHS, y&: CR);
1370 };
1371
1372 auto RC1 = MatchExactRangeCheck(PredL, LHS0, LHS1);
1373 if (!RC1)
1374 return nullptr;
1375
1376 auto RC2 = MatchExactRangeCheck(PredR, RHS0, RHS1);
1377 if (!RC2)
1378 return nullptr;
1379
1380 auto &[V1, CR1] = *RC1;
1381 auto &[V2, CR2] = *RC2;
1382 if (V1 != V2)
1383 return nullptr;
1384
1385 // For 'and', we use the De Morgan's Laws to simplify the implementation.
1386 if (IsAnd) {
1387 CR1 = CR1.inverse();
1388 CR2 = CR2.inverse();
1389 }
1390
1391 Type *Ty = V1->getType();
1392 Value *NewV = V1;
1393 std::optional<ConstantRange> CR = CR1.exactUnionWith(CR: CR2);
1394 if (!CR) {
1395 if (!LHSOneUse || !RHSOneUse || CR1.isWrappedSet() || CR2.isWrappedSet())
1396 return nullptr;
1397
1398 // Check whether we have equal-size ranges that only differ by one bit.
1399 // In that case we can apply a mask to map one range onto the other.
1400 APInt LowerDiff = CR1.getLower() ^ CR2.getLower();
1401 APInt UpperDiff = (CR1.getUpper() - 1) ^ (CR2.getUpper() - 1);
1402 APInt CR1Size = CR1.getUpper() - CR1.getLower();
1403 if (!LowerDiff.isPowerOf2() || LowerDiff != UpperDiff ||
1404 CR1Size != CR2.getUpper() - CR2.getLower())
1405 return nullptr;
1406
1407 CR = CR1.getLower().ult(RHS: CR2.getLower()) ? CR1 : CR2;
1408 NewV = Builder.CreateAnd(LHS: NewV, RHS: ConstantInt::get(Ty, V: ~LowerDiff));
1409 }
1410
1411 if (IsAnd)
1412 CR = CR->inverse();
1413
1414 CmpInst::Predicate NewPred;
1415 APInt NewC, Offset;
1416 CR->getEquivalentICmp(Pred&: NewPred, RHS&: NewC, Offset);
1417
1418 if (Offset != 0)
1419 NewV = Builder.CreateAdd(LHS: NewV, RHS: ConstantInt::get(Ty, V: Offset));
1420 return Builder.CreateICmp(P: NewPred, LHS: NewV, RHS: ConstantInt::get(Ty, V: NewC));
1421}
1422
1423/// Matches canonical form of isnan, fcmp ord x, 0
1424static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS) {
1425 return P == FCmpInst::FCMP_ORD && match(V: RHS, P: m_AnyZeroFP());
1426}
1427
1428/// Matches fcmp u__ x, +/-inf
1429static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS,
1430 Value *RHS) {
1431 return FCmpInst::isUnordered(predicate: P) && match(V: RHS, P: m_Inf());
1432}
1433
1434/// and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
1435///
1436/// Clang emits this pattern for doing an isfinite check in __builtin_isnormal.
1437static Value *matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS,
1438 FCmpInst *RHS) {
1439 Value *LHS0 = LHS->getOperand(i_nocapture: 0), *LHS1 = LHS->getOperand(i_nocapture: 1);
1440 Value *RHS0 = RHS->getOperand(i_nocapture: 0), *RHS1 = RHS->getOperand(i_nocapture: 1);
1441 FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
1442
1443 if (!matchIsNotNaN(P: PredL, LHS: LHS0, RHS: LHS1) ||
1444 !matchUnorderedInfCompare(P: PredR, LHS: RHS0, RHS: RHS1))
1445 return nullptr;
1446
1447 return Builder.CreateFCmpFMF(P: FCmpInst::getOrderedPredicate(Pred: PredR), LHS: RHS0, RHS: RHS1,
1448 FMFSource: FMFSource::intersect(A: LHS, B: RHS));
1449}
1450
1451Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
1452 bool IsAnd, bool IsLogicalSelect) {
1453 Value *LHS0 = LHS->getOperand(i_nocapture: 0), *LHS1 = LHS->getOperand(i_nocapture: 1);
1454 Value *RHS0 = RHS->getOperand(i_nocapture: 0), *RHS1 = RHS->getOperand(i_nocapture: 1);
1455 FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
1456
1457 if (LHS0 == RHS1 && RHS0 == LHS1) {
1458 // Swap RHS operands to match LHS.
1459 PredR = FCmpInst::getSwappedPredicate(pred: PredR);
1460 std::swap(a&: RHS0, b&: RHS1);
1461 }
1462
1463 // Simplify (fcmp cc0 x, y) & (fcmp cc1 x, y).
1464 // Suppose the relation between x and y is R, where R is one of
1465 // U(1000), L(0100), G(0010) or E(0001), and CC0 and CC1 are the bitmasks for
1466 // testing the desired relations.
1467 //
1468 // Since (R & CC0) and (R & CC1) are either R or 0, we actually have this:
1469 // bool(R & CC0) && bool(R & CC1)
1470 // = bool((R & CC0) & (R & CC1))
1471 // = bool(R & (CC0 & CC1)) <= by re-association, commutation, and idempotency
1472 //
1473 // Since (R & CC0) and (R & CC1) are either R or 0, we actually have this:
1474 // bool(R & CC0) || bool(R & CC1)
1475 // = bool((R & CC0) | (R & CC1))
1476 // = bool(R & (CC0 | CC1)) <= by reversed distribution (contribution? ;)
1477 if (LHS0 == RHS0 && LHS1 == RHS1) {
1478 unsigned FCmpCodeL = getFCmpCode(CC: PredL);
1479 unsigned FCmpCodeR = getFCmpCode(CC: PredR);
1480 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1481
1482 // Intersect the fast math flags.
1483 // TODO: We can union the fast math flags unless this is a logical select.
1484 return getFCmpValue(Code: NewPred, LHS: LHS0, RHS: LHS1, Builder,
1485 FMF: FMFSource::intersect(A: LHS, B: RHS));
1486 }
1487
1488 if ((PredL == FCmpInst::FCMP_ORD && PredR == FCmpInst::FCMP_ORD && IsAnd) ||
1489 (PredL == FCmpInst::FCMP_UNO && PredR == FCmpInst::FCMP_UNO && !IsAnd)) {
1490 if (LHS0->getType() != RHS0->getType())
1491 return nullptr;
1492
1493 // FCmp canonicalization ensures that (fcmp ord/uno X, X) and
1494 // (fcmp ord/uno X, C) will be transformed to (fcmp X, +0.0).
1495 if (match(V: LHS1, P: m_PosZeroFP()) && match(V: RHS1, P: m_PosZeroFP())) {
1496 // Ignore the constants because they are obviously not NANs:
1497 // (fcmp ord x, 0.0) & (fcmp ord y, 0.0) -> (fcmp ord x, y)
1498 // (fcmp uno x, 0.0) | (fcmp uno y, 0.0) -> (fcmp uno x, y)
1499 Value *Y = RHS0;
1500 FastMathFlags FMF = LHS->getFastMathFlags() & RHS->getFastMathFlags();
1501 if (IsLogicalSelect) {
1502 Y = Builder.CreateFreeze(V: Y, Name: Y->getName() + ".fr");
1503 FMF.setNoNaNs(false);
1504 FMF.setNoInfs(false);
1505 }
1506 return Builder.CreateFCmpFMF(P: PredL, LHS: LHS0, RHS: Y, FMFSource: FMF);
1507 }
1508 }
1509
1510 // This transform is not valid for a logical select.
1511 if (!IsLogicalSelect && IsAnd &&
1512 stripSignOnlyFPOps(Val: LHS0) == stripSignOnlyFPOps(Val: RHS0)) {
1513 // and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
1514 // and (fcmp ord x, 0), (fcmp u* fabs(x), inf) -> fcmp o* x, inf
1515 if (Value *Left = matchIsFiniteTest(Builder, LHS, RHS))
1516 return Left;
1517 if (Value *Right = matchIsFiniteTest(Builder, LHS: RHS, RHS: LHS))
1518 return Right;
1519 }
1520
1521 // Turn at least two fcmps with constants into llvm.is.fpclass.
1522 //
1523 // If we can represent a combined value test with one class call, we can
1524 // potentially eliminate 4-6 instructions. If we can represent a test with a
1525 // single fcmp with fneg and fabs, that's likely a better canonical form.
1526 if (LHS->hasOneUse() && RHS->hasOneUse()) {
1527 auto [ClassValRHS, ClassMaskRHS] =
1528 fcmpToClassTest(Pred: PredR, F: *RHS->getFunction(), LHS: RHS0, RHS: RHS1);
1529 if (ClassValRHS) {
1530 auto [ClassValLHS, ClassMaskLHS] =
1531 fcmpToClassTest(Pred: PredL, F: *LHS->getFunction(), LHS: LHS0, RHS: LHS1);
1532 if (ClassValLHS == ClassValRHS) {
1533 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1534 : (ClassMaskLHS | ClassMaskRHS);
1535 return Builder.CreateIntrinsic(
1536 ID: Intrinsic::is_fpclass, OverloadTypes: {ClassValLHS->getType()},
1537 Args: {ClassValLHS, Builder.getInt32(C: CombinedMask)});
1538 }
1539 }
1540 }
1541
1542 // Canonicalize the range check idiom:
1543 // and (fcmp olt/ole/ult/ule x, C), (fcmp ogt/oge/ugt/uge x, -C)
1544 // --> fabs(x) olt/ole/ult/ule C
1545 // or (fcmp ogt/oge/ugt/uge x, C), (fcmp olt/ole/ult/ule x, -C)
1546 // --> fabs(x) ogt/oge/ugt/uge C
1547 // TODO: Generalize to handle a negated variable operand?
1548 const APFloat *LHSC, *RHSC;
1549 if (LHS0 == RHS0 && LHS->hasOneUse() && RHS->hasOneUse() &&
1550 FCmpInst::getSwappedPredicate(pred: PredL) == PredR &&
1551 match(V: LHS1, P: m_APFloatAllowPoison(Res&: LHSC)) &&
1552 match(V: RHS1, P: m_APFloatAllowPoison(Res&: RHSC)) &&
1553 LHSC->bitwiseIsEqual(RHS: neg(X: *RHSC))) {
1554 auto IsLessThanOrLessEqual = [](FCmpInst::Predicate Pred) {
1555 switch (Pred) {
1556 case FCmpInst::FCMP_OLT:
1557 case FCmpInst::FCMP_OLE:
1558 case FCmpInst::FCMP_ULT:
1559 case FCmpInst::FCMP_ULE:
1560 return true;
1561 default:
1562 return false;
1563 }
1564 };
1565 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1566 std::swap(a&: LHSC, b&: RHSC);
1567 std::swap(a&: PredL, b&: PredR);
1568 }
1569 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1570 FastMathFlags NewFlag = LHS->getFastMathFlags();
1571 if (!IsLogicalSelect)
1572 NewFlag |= RHS->getFastMathFlags();
1573
1574 Value *FAbs = Builder.CreateFAbs(V: LHS0, FMFSource: NewFlag);
1575 return Builder.CreateFCmpFMF(
1576 P: PredL, LHS: FAbs, RHS: ConstantFP::get(Ty: LHS0->getType(), V: *LHSC), FMFSource: NewFlag);
1577 }
1578 }
1579
1580 return nullptr;
1581}
1582
1583/// Match an fcmp against a special value that performs a test possible by
1584/// llvm.is.fpclass.
1585static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal,
1586 uint64_t &ClassMask) {
1587 auto *FCmp = dyn_cast<FCmpInst>(Val: Op);
1588 if (!FCmp || !FCmp->hasOneUse())
1589 return false;
1590
1591 std::tie(args&: ClassVal, args&: ClassMask) =
1592 fcmpToClassTest(Pred: FCmp->getPredicate(), F: *FCmp->getParent()->getParent(),
1593 LHS: FCmp->getOperand(i_nocapture: 0), RHS: FCmp->getOperand(i_nocapture: 1));
1594 return ClassVal != nullptr;
1595}
1596
1597/// or (is_fpclass x, mask0), (is_fpclass x, mask1)
1598/// -> is_fpclass x, (mask0 | mask1)
1599/// and (is_fpclass x, mask0), (is_fpclass x, mask1)
1600/// -> is_fpclass x, (mask0 & mask1)
1601/// xor (is_fpclass x, mask0), (is_fpclass x, mask1)
1602/// -> is_fpclass x, (mask0 ^ mask1)
1603Instruction *InstCombinerImpl::foldLogicOfIsFPClass(BinaryOperator &BO,
1604 Value *Op0, Value *Op1) {
1605 Value *ClassVal0 = nullptr;
1606 Value *ClassVal1 = nullptr;
1607 uint64_t ClassMask0, ClassMask1;
1608
1609 // Restrict to folding one fcmp into one is.fpclass for now, don't introduce a
1610 // new class.
1611 //
1612 // TODO: Support forming is.fpclass out of 2 separate fcmps when codegen is
1613 // better.
1614
1615 bool IsLHSClass =
1616 match(V: Op0, P: m_OneUse(SubPattern: m_Intrinsic<Intrinsic::is_fpclass>(
1617 Ops: m_Value(V&: ClassVal0), Ops: m_ConstantInt(V&: ClassMask0))));
1618 bool IsRHSClass =
1619 match(V: Op1, P: m_OneUse(SubPattern: m_Intrinsic<Intrinsic::is_fpclass>(
1620 Ops: m_Value(V&: ClassVal1), Ops: m_ConstantInt(V&: ClassMask1))));
1621 if ((((IsLHSClass || matchIsFPClassLikeFCmp(Op: Op0, ClassVal&: ClassVal0, ClassMask&: ClassMask0)) &&
1622 (IsRHSClass || matchIsFPClassLikeFCmp(Op: Op1, ClassVal&: ClassVal1, ClassMask&: ClassMask1)))) &&
1623 ClassVal0 == ClassVal1) {
1624 unsigned NewClassMask;
1625 switch (BO.getOpcode()) {
1626 case Instruction::And:
1627 NewClassMask = ClassMask0 & ClassMask1;
1628 break;
1629 case Instruction::Or:
1630 NewClassMask = ClassMask0 | ClassMask1;
1631 break;
1632 case Instruction::Xor:
1633 NewClassMask = ClassMask0 ^ ClassMask1;
1634 break;
1635 default:
1636 llvm_unreachable("not a binary logic operator");
1637 }
1638
1639 if (IsLHSClass) {
1640 auto *II = cast<IntrinsicInst>(Val: Op0);
1641 II->setArgOperand(
1642 i: 1, v: ConstantInt::get(Ty: II->getArgOperand(i: 1)->getType(), V: NewClassMask));
1643 return replaceInstUsesWith(I&: BO, V: II);
1644 }
1645
1646 if (IsRHSClass) {
1647 auto *II = cast<IntrinsicInst>(Val: Op1);
1648 II->setArgOperand(
1649 i: 1, v: ConstantInt::get(Ty: II->getArgOperand(i: 1)->getType(), V: NewClassMask));
1650 return replaceInstUsesWith(I&: BO, V: II);
1651 }
1652
1653 Value *NewClass =
1654 Builder.CreateIntrinsic(ID: Intrinsic::is_fpclass, OverloadTypes: {ClassVal0->getType()},
1655 Args: {ClassVal0, Builder.getInt32(C: NewClassMask)});
1656 return replaceInstUsesWith(I&: BO, V: NewClass);
1657 }
1658
1659 return nullptr;
1660}
1661
1662/// Look for the pattern that conditionally negates a value via math operations:
1663/// cond.splat = sext i1 cond
1664/// sub = add cond.splat, x
1665/// xor = xor sub, cond.splat
1666/// and rewrite it to do the same, but via logical operations:
1667/// value.neg = sub 0, value
1668/// cond = select i1 neg, value.neg, value
1669Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1670 BinaryOperator &I) {
1671 assert(I.getOpcode() == BinaryOperator::Xor && "Only for xor!");
1672 Value *Cond, *X;
1673 // As per complexity ordering, `xor` is not commutative here.
1674 if (!match(V: &I, P: m_c_BinOp(L: m_OneUse(SubPattern: m_Value()), R: m_Value())) ||
1675 !match(V: I.getOperand(i_nocapture: 1), P: m_SExt(Op: m_Value(V&: Cond))) ||
1676 !Cond->getType()->isIntOrIntVectorTy(BitWidth: 1) ||
1677 !match(V: I.getOperand(i_nocapture: 0), P: m_c_Add(L: m_SExt(Op: m_Specific(V: Cond)), R: m_Value(V&: X))))
1678 return nullptr;
1679 return createSelectInstWithUnknownProfile(
1680 C: Cond, S1: Builder.CreateNeg(V: X, Name: X->getName() + ".neg"), S2: X);
1681}
1682
1683/// This a limited reassociation for a special case (see above) where we are
1684/// checking if two values are either both NAN (unordered) or not-NAN (ordered).
1685/// This could be handled more generally in '-reassociation', but it seems like
1686/// an unlikely pattern for a large number of logic ops and fcmps.
1687static Instruction *reassociateFCmps(BinaryOperator &BO,
1688 InstCombiner::BuilderTy &Builder) {
1689 Instruction::BinaryOps Opcode = BO.getOpcode();
1690 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1691 "Expecting and/or op for fcmp transform");
1692
1693 // There are 4 commuted variants of the pattern. Canonicalize operands of this
1694 // logic op so an fcmp is operand 0 and a matching logic op is operand 1.
1695 Value *Op0 = BO.getOperand(i_nocapture: 0), *Op1 = BO.getOperand(i_nocapture: 1), *X;
1696 if (match(V: Op1, P: m_FCmp(L: m_Value(), R: m_AnyZeroFP())))
1697 std::swap(a&: Op0, b&: Op1);
1698
1699 // Match inner binop and the predicate for combining 2 NAN checks into 1.
1700 Value *BO10, *BO11;
1701 FCmpInst::Predicate NanPred = Opcode == Instruction::And ? FCmpInst::FCMP_ORD
1702 : FCmpInst::FCMP_UNO;
1703 if (!match(V: Op0, P: m_SpecificFCmp(MatchPred: NanPred, L: m_Value(V&: X), R: m_AnyZeroFP())) ||
1704 !match(V: Op1, P: m_BinOp(Opcode, L: m_Value(V&: BO10), R: m_Value(V&: BO11))))
1705 return nullptr;
1706
1707 // The inner logic op must have a matching fcmp operand.
1708 Value *Y;
1709 if (!match(V: BO10, P: m_SpecificFCmp(MatchPred: NanPred, L: m_Value(V&: Y), R: m_AnyZeroFP())) ||
1710 X->getType() != Y->getType())
1711 std::swap(a&: BO10, b&: BO11);
1712
1713 if (!match(V: BO10, P: m_SpecificFCmp(MatchPred: NanPred, L: m_Value(V&: Y), R: m_AnyZeroFP())) ||
1714 X->getType() != Y->getType())
1715 return nullptr;
1716
1717 // and (fcmp ord X, 0), (and (fcmp ord Y, 0), Z) --> and (fcmp ord X, Y), Z
1718 // or (fcmp uno X, 0), (or (fcmp uno Y, 0), Z) --> or (fcmp uno X, Y), Z
1719 // Intersect FMF from the 2 source fcmps.
1720 Value *NewFCmp =
1721 Builder.CreateFCmpFMF(P: NanPred, LHS: X, RHS: Y, FMFSource: FMFSource::intersect(A: Op0, B: BO10));
1722 return BinaryOperator::Create(Op: Opcode, S1: NewFCmp, S2: BO11);
1723}
1724
1725/// Match variations of De Morgan's Laws:
1726/// (~A & ~B) == (~(A | B))
1727/// (~A | ~B) == (~(A & B))
1728static Instruction *matchDeMorgansLaws(BinaryOperator &I,
1729 InstCombiner &IC) {
1730 const Instruction::BinaryOps Opcode = I.getOpcode();
1731 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1732 "Trying to match De Morgan's Laws with something other than and/or");
1733
1734 // Flip the logic operation.
1735 const Instruction::BinaryOps FlippedOpcode =
1736 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1737
1738 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
1739 Value *A, *B;
1740 if (match(V: Op0, P: m_OneUse(SubPattern: m_Not(V: m_Value(V&: A)))) &&
1741 match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_Value(V&: B)))) &&
1742 !IC.isFreeToInvert(V: A, WillInvertAllUses: A->hasOneUse()) &&
1743 !IC.isFreeToInvert(V: B, WillInvertAllUses: B->hasOneUse())) {
1744 Value *AndOr =
1745 IC.Builder.CreateBinOp(Opc: FlippedOpcode, LHS: A, RHS: B, Name: I.getName() + ".demorgan");
1746 return BinaryOperator::CreateNot(Op: AndOr);
1747 }
1748
1749 // The 'not' ops may require reassociation.
1750 // (A & ~B) & ~C --> A & ~(B | C)
1751 // (~B & A) & ~C --> A & ~(B | C)
1752 // (A | ~B) | ~C --> A | ~(B & C)
1753 // (~B | A) | ~C --> A | ~(B & C)
1754 Value *C;
1755 if (match(V: Op0, P: m_OneUse(SubPattern: m_c_BinOp(Opcode, L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B))))) &&
1756 match(V: Op1, P: m_Not(V: m_Value(V&: C)))) {
1757 Value *FlippedBO = IC.Builder.CreateBinOp(Opc: FlippedOpcode, LHS: B, RHS: C);
1758 return BinaryOperator::Create(Op: Opcode, S1: A, S2: IC.Builder.CreateNot(V: FlippedBO));
1759 }
1760
1761 return nullptr;
1762}
1763
1764bool InstCombinerImpl::shouldOptimizeCast(CastInst *CI) {
1765 Value *CastSrc = CI->getOperand(i_nocapture: 0);
1766
1767 // Noop casts and casts of constants should be eliminated trivially.
1768 if (CI->getSrcTy() == CI->getDestTy() || isa<Constant>(Val: CastSrc))
1769 return false;
1770
1771 // If this cast is paired with another cast that can be eliminated, we prefer
1772 // to have it eliminated.
1773 if (const auto *PrecedingCI = dyn_cast<CastInst>(Val: CastSrc))
1774 if (isEliminableCastPair(CI1: PrecedingCI, CI2: CI))
1775 return false;
1776
1777 return true;
1778}
1779
1780/// Fold {and,or,xor} (cast X), C.
1781static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast,
1782 InstCombinerImpl &IC) {
1783 Constant *C = dyn_cast<Constant>(Val: Logic.getOperand(i_nocapture: 1));
1784 if (!C)
1785 return nullptr;
1786
1787 auto LogicOpc = Logic.getOpcode();
1788 Type *DestTy = Logic.getType();
1789 Type *SrcTy = Cast->getSrcTy();
1790
1791 // Move the logic operation ahead of a zext or sext if the constant is
1792 // unchanged in the smaller source type. Performing the logic in a smaller
1793 // type may provide more information to later folds, and the smaller logic
1794 // instruction may be cheaper (particularly in the case of vectors).
1795 Value *X;
1796 auto &DL = IC.getDataLayout();
1797 if (match(V: Cast, P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: X))))) {
1798 PreservedCastFlags Flags;
1799 if (Constant *TruncC = getLosslessUnsignedTrunc(C, DestTy: SrcTy, DL, Flags: &Flags)) {
1800 // LogicOpc (zext X), C --> zext (LogicOpc X, C)
1801 Value *NewOp = IC.Builder.CreateBinOp(Opc: LogicOpc, LHS: X, RHS: TruncC);
1802 auto *ZExt = new ZExtInst(NewOp, DestTy);
1803 ZExt->setNonNeg(Flags.NNeg);
1804 ZExt->andIRFlags(V: Cast);
1805 return ZExt;
1806 }
1807 }
1808
1809 if (match(V: Cast, P: m_OneUse(SubPattern: m_SExtLike(Op: m_Value(V&: X))))) {
1810 if (Constant *TruncC = getLosslessSignedTrunc(C, DestTy: SrcTy, DL)) {
1811 // LogicOpc (sext X), C --> sext (LogicOpc X, C)
1812 Value *NewOp = IC.Builder.CreateBinOp(Opc: LogicOpc, LHS: X, RHS: TruncC);
1813 return new SExtInst(NewOp, DestTy);
1814 }
1815 }
1816
1817 return nullptr;
1818}
1819
1820/// Fold {and,or,xor} (cast X), Y.
1821Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
1822 auto LogicOpc = I.getOpcode();
1823 assert(I.isBitwiseLogicOp() && "Unexpected opcode for bitwise logic folding");
1824
1825 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
1826
1827 // fold bitwise(A >> BW - 1, zext(icmp)) (BW is the scalar bits of the
1828 // type of A)
1829 // -> bitwise(zext(A < 0), zext(icmp))
1830 // -> zext(bitwise(A < 0, icmp))
1831 auto FoldBitwiseICmpZeroWithICmp = [&](Value *Op0,
1832 Value *Op1) -> Instruction * {
1833 Value *A;
1834 bool IsMatched =
1835 match(V: Op0,
1836 P: m_OneUse(SubPattern: m_LShr(
1837 L: m_Value(V&: A),
1838 R: m_SpecificInt(V: Op0->getType()->getScalarSizeInBits() - 1)))) &&
1839 match(V: Op1, P: m_OneUse(SubPattern: m_ZExt(Op: m_ICmp(L: m_Value(), R: m_Value()))));
1840
1841 if (!IsMatched)
1842 return nullptr;
1843
1844 auto *ICmpL =
1845 Builder.CreateICmpSLT(LHS: A, RHS: Constant::getNullValue(Ty: A->getType()));
1846 auto *ICmpR = cast<ZExtInst>(Val: Op1)->getOperand(i_nocapture: 0);
1847 auto *BitwiseOp = Builder.CreateBinOp(Opc: LogicOpc, LHS: ICmpL, RHS: ICmpR);
1848
1849 return new ZExtInst(BitwiseOp, Op0->getType());
1850 };
1851
1852 if (auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1853 return Ret;
1854
1855 if (auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1856 return Ret;
1857
1858 CastInst *Cast0 = dyn_cast<CastInst>(Val: Op0);
1859 if (!Cast0)
1860 return nullptr;
1861
1862 // This must be a cast from an integer or integer vector source type to allow
1863 // transformation of the logic operation to the source type.
1864 Type *DestTy = I.getType();
1865 Type *SrcTy = Cast0->getSrcTy();
1866 if (!SrcTy->isIntOrIntVectorTy())
1867 return nullptr;
1868
1869 if (Instruction *Ret = foldLogicCastConstant(Logic&: I, Cast: Cast0, IC&: *this))
1870 return Ret;
1871
1872 CastInst *Cast1 = dyn_cast<CastInst>(Val: Op1);
1873 if (!Cast1)
1874 return nullptr;
1875
1876 // Both operands of the logic operation are casts. The casts must be the
1877 // same kind for reduction.
1878 Instruction::CastOps CastOpcode = Cast0->getOpcode();
1879 if (CastOpcode != Cast1->getOpcode())
1880 return nullptr;
1881
1882 // Can't fold it profitably if no one of casts has one use.
1883 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
1884 return nullptr;
1885
1886 Value *X, *Y;
1887 if (match(V: Cast0, P: m_ZExtOrSExt(Op: m_Value(V&: X))) &&
1888 match(V: Cast1, P: m_ZExtOrSExt(Op: m_Value(V&: Y)))) {
1889 // Cast the narrower source to the wider source type.
1890 unsigned XNumBits = X->getType()->getScalarSizeInBits();
1891 unsigned YNumBits = Y->getType()->getScalarSizeInBits();
1892 if (XNumBits != YNumBits) {
1893 // Cast the narrower source to the wider source type only if both of casts
1894 // have one use to avoid creating an extra instruction.
1895 if (!Cast0->hasOneUse() || !Cast1->hasOneUse())
1896 return nullptr;
1897
1898 // If the source types do not match, but the casts are matching extends,
1899 // we can still narrow the logic op.
1900 if (XNumBits < YNumBits) {
1901 X = Builder.CreateCast(Op: CastOpcode, V: X, DestTy: Y->getType());
1902 } else if (YNumBits < XNumBits) {
1903 Y = Builder.CreateCast(Op: CastOpcode, V: Y, DestTy: X->getType());
1904 }
1905 }
1906
1907 // Do the logic op in the intermediate width, then widen more.
1908 Value *NarrowLogic = Builder.CreateBinOp(Opc: LogicOpc, LHS: X, RHS: Y, Name: I.getName());
1909 auto *Disjoint = dyn_cast<PossiblyDisjointInst>(Val: &I);
1910 auto *NewDisjoint = dyn_cast<PossiblyDisjointInst>(Val: NarrowLogic);
1911 if (Disjoint && NewDisjoint)
1912 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1913 return CastInst::Create(CastOpcode, S: NarrowLogic, Ty: DestTy);
1914 }
1915
1916 // If the src type of casts are different, give up for other cast opcodes.
1917 if (SrcTy != Cast1->getSrcTy())
1918 return nullptr;
1919
1920 Value *Cast0Src = Cast0->getOperand(i_nocapture: 0);
1921 Value *Cast1Src = Cast1->getOperand(i_nocapture: 0);
1922
1923 // fold logic(cast(A), cast(B)) -> cast(logic(A, B))
1924 if (shouldOptimizeCast(CI: Cast0) && shouldOptimizeCast(CI: Cast1)) {
1925 Value *NewOp = Builder.CreateBinOp(Opc: LogicOpc, LHS: Cast0Src, RHS: Cast1Src,
1926 Name: I.getName());
1927 auto *NewCast = CastInst::Create(CastOpcode, S: NewOp, Ty: DestTy);
1928 if (auto *NewTrunc = dyn_cast<TruncInst>(Val: NewCast)) {
1929 auto *Trunc0 = cast<TruncInst>(Val: Cast0);
1930 auto *Trunc1 = cast<TruncInst>(Val: Cast1);
1931 NewTrunc->setHasNoUnsignedWrap(
1932 LogicOpc == Instruction::And
1933 ? Trunc0->hasNoUnsignedWrap() || Trunc1->hasNoUnsignedWrap()
1934 : Trunc0->hasNoUnsignedWrap() && Trunc1->hasNoUnsignedWrap());
1935 NewTrunc->setHasNoSignedWrap(Trunc0->hasNoSignedWrap() &&
1936 Trunc1->hasNoSignedWrap());
1937 }
1938 return NewCast;
1939 }
1940
1941 return nullptr;
1942}
1943
1944static Instruction *foldAndToXor(BinaryOperator &I,
1945 InstCombiner::BuilderTy &Builder) {
1946 assert(I.getOpcode() == Instruction::And);
1947 Value *Op0 = I.getOperand(i_nocapture: 0);
1948 Value *Op1 = I.getOperand(i_nocapture: 1);
1949 Value *A, *B;
1950
1951 // Operand complexity canonicalization guarantees that the 'or' is Op0.
1952 // (A | B) & ~(A & B) --> A ^ B
1953 // (A | B) & ~(B & A) --> A ^ B
1954 if (match(V: &I, P: m_BinOp(L: m_Or(L: m_Value(V&: A), R: m_Value(V&: B)),
1955 R: m_Not(V: m_c_And(L: m_Deferred(V: A), R: m_Deferred(V: B))))))
1956 return BinaryOperator::CreateXor(V1: A, V2: B);
1957
1958 // (A | ~B) & (~A | B) --> ~(A ^ B)
1959 // (A | ~B) & (B | ~A) --> ~(A ^ B)
1960 // (~B | A) & (~A | B) --> ~(A ^ B)
1961 // (~B | A) & (B | ~A) --> ~(A ^ B)
1962 if (Op0->hasOneUse() || Op1->hasOneUse())
1963 if (match(V: &I, P: m_BinOp(L: m_c_Or(L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B))),
1964 R: m_c_Or(L: m_Not(V: m_Deferred(V: A)), R: m_Deferred(V: B)))))
1965 return BinaryOperator::CreateNot(Op: Builder.CreateXor(LHS: A, RHS: B));
1966
1967 return nullptr;
1968}
1969
1970static Instruction *foldOrToXor(BinaryOperator &I,
1971 InstCombiner::BuilderTy &Builder) {
1972 assert(I.getOpcode() == Instruction::Or);
1973 Value *Op0 = I.getOperand(i_nocapture: 0);
1974 Value *Op1 = I.getOperand(i_nocapture: 1);
1975 Value *A, *B;
1976
1977 // Operand complexity canonicalization guarantees that the 'and' is Op0.
1978 // (A & B) | ~(A | B) --> ~(A ^ B)
1979 // (A & B) | ~(B | A) --> ~(A ^ B)
1980 if (Op0->hasOneUse() || Op1->hasOneUse())
1981 if (match(V: Op0, P: m_And(L: m_Value(V&: A), R: m_Value(V&: B))) &&
1982 match(V: Op1, P: m_Not(V: m_c_Or(L: m_Specific(V: A), R: m_Specific(V: B)))))
1983 return BinaryOperator::CreateNot(Op: Builder.CreateXor(LHS: A, RHS: B));
1984
1985 // Operand complexity canonicalization guarantees that the 'xor' is Op0.
1986 // (A ^ B) | ~(A | B) --> ~(A & B)
1987 // (A ^ B) | ~(B | A) --> ~(A & B)
1988 if (Op0->hasOneUse() || Op1->hasOneUse())
1989 if (match(V: Op0, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))) &&
1990 match(V: Op1, P: m_Not(V: m_c_Or(L: m_Specific(V: A), R: m_Specific(V: B)))))
1991 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: A, RHS: B));
1992
1993 // (A & ~B) | (~A & B) --> A ^ B
1994 // (A & ~B) | (B & ~A) --> A ^ B
1995 // (~B & A) | (~A & B) --> A ^ B
1996 // (~B & A) | (B & ~A) --> A ^ B
1997 if (match(V: Op0, P: m_c_And(L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B)))) &&
1998 match(V: Op1, P: m_c_And(L: m_Not(V: m_Specific(V: A)), R: m_Specific(V: B))))
1999 return BinaryOperator::CreateXor(V1: A, V2: B);
2000
2001 return nullptr;
2002}
2003
2004/// Return true if a constant shift amount is always less than the specified
2005/// bit-width. If not, the shift could create poison in the narrower type.
2006static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth) {
2007 APInt Threshold(C->getType()->getScalarSizeInBits(), BitWidth);
2008 return match(V: C, P: m_SpecificInt_ICMP(Predicate: ICmpInst::ICMP_ULT, Threshold));
2009}
2010
2011/// Try to use narrower ops (sink zext ops) for an 'and' with binop operand and
2012/// a common zext operand: and (binop (zext X), C), (zext X).
2013Instruction *InstCombinerImpl::narrowMaskedBinOp(BinaryOperator &And) {
2014 // This transform could also apply to {or, and, xor}, but there are better
2015 // folds for those cases, so we don't expect those patterns here. AShr is not
2016 // handled because it should always be transformed to LShr in this sequence.
2017 // The subtract transform is different because it has a constant on the left.
2018 // Add/mul commute the constant to RHS; sub with constant RHS becomes add.
2019 Value *Op0 = And.getOperand(i_nocapture: 0), *Op1 = And.getOperand(i_nocapture: 1);
2020 Constant *C;
2021 if (!match(V: Op0, P: m_OneUse(SubPattern: m_Add(L: m_Specific(V: Op1), R: m_Constant(C)))) &&
2022 !match(V: Op0, P: m_OneUse(SubPattern: m_Mul(L: m_Specific(V: Op1), R: m_Constant(C)))) &&
2023 !match(V: Op0, P: m_OneUse(SubPattern: m_LShr(L: m_Specific(V: Op1), R: m_Constant(C)))) &&
2024 !match(V: Op0, P: m_OneUse(SubPattern: m_Shl(L: m_Specific(V: Op1), R: m_Constant(C)))) &&
2025 !match(V: Op0, P: m_OneUse(SubPattern: m_Sub(L: m_Constant(C), R: m_Specific(V: Op1)))))
2026 return nullptr;
2027
2028 Value *X;
2029 if (!match(V: Op1, P: m_ZExt(Op: m_Value(V&: X))) || Op1->hasNUsesOrMore(N: 3))
2030 return nullptr;
2031
2032 Type *Ty = And.getType();
2033 if (!isa<VectorType>(Val: Ty) && !shouldChangeType(From: Ty, To: X->getType()))
2034 return nullptr;
2035
2036 // If we're narrowing a shift, the shift amount must be safe (less than the
2037 // width) in the narrower type. If the shift amount is greater, instsimplify
2038 // usually handles that case, but we can't guarantee/assert it.
2039 Instruction::BinaryOps Opc = cast<BinaryOperator>(Val: Op0)->getOpcode();
2040 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
2041 if (!canNarrowShiftAmt(C, BitWidth: X->getType()->getScalarSizeInBits()))
2042 return nullptr;
2043
2044 // and (sub C, (zext X)), (zext X) --> zext (and (sub C', X), X)
2045 // and (binop (zext X), C), (zext X) --> zext (and (binop X, C'), X)
2046 Value *NewC = ConstantExpr::getTrunc(C, Ty: X->getType());
2047 Value *NewBO = Opc == Instruction::Sub ? Builder.CreateBinOp(Opc, LHS: NewC, RHS: X)
2048 : Builder.CreateBinOp(Opc, LHS: X, RHS: NewC);
2049 return new ZExtInst(Builder.CreateAnd(LHS: NewBO, RHS: X), Ty);
2050}
2051
2052/// Try folding relatively complex patterns for both And and Or operations
2053/// with all And and Or swapped.
2054static Instruction *foldComplexAndOrPatterns(BinaryOperator &I,
2055 InstCombiner::BuilderTy &Builder) {
2056 const Instruction::BinaryOps Opcode = I.getOpcode();
2057 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2058
2059 // Flip the logic operation.
2060 const Instruction::BinaryOps FlippedOpcode =
2061 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2062
2063 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
2064 Value *A, *B, *C, *X, *Y, *Dummy;
2065
2066 // Match following expressions:
2067 // (~(A | B) & C)
2068 // (~(A & B) | C)
2069 // Captures X = ~(A | B) or ~(A & B)
2070 const auto matchNotOrAnd =
2071 [Opcode, FlippedOpcode](Value *Op, auto m_A, auto m_B, auto m_C,
2072 Value *&X, bool CountUses = false) -> bool {
2073 if (CountUses && !Op->hasOneUse())
2074 return false;
2075
2076 if (match(Op,
2077 m_c_BinOp(FlippedOpcode,
2078 m_Value(X, m_Not(m_c_BinOp(Opcode, m_A, m_B))), m_C)))
2079 return !CountUses || X->hasOneUse();
2080
2081 return false;
2082 };
2083
2084 // (~(A | B) & C) | ... --> ...
2085 // (~(A & B) | C) & ... --> ...
2086 // TODO: One use checks are conservative. We just need to check that a total
2087 // number of multiple used values does not exceed reduction
2088 // in operations.
2089 if (matchNotOrAnd(Op0, m_Value(V&: A), m_Value(V&: B), m_Value(V&: C), X)) {
2090 // (~(A | B) & C) | (~(A | C) & B) --> (B ^ C) & ~A
2091 // (~(A & B) | C) & (~(A & C) | B) --> ~((B ^ C) & A)
2092 if (matchNotOrAnd(Op1, m_Specific(V: A), m_Specific(V: C), m_Specific(V: B), Dummy,
2093 true)) {
2094 Value *Xor = Builder.CreateXor(LHS: B, RHS: C);
2095 return (Opcode == Instruction::Or)
2096 ? BinaryOperator::CreateAnd(V1: Xor, V2: Builder.CreateNot(V: A))
2097 : BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: Xor, RHS: A));
2098 }
2099
2100 // (~(A | B) & C) | (~(B | C) & A) --> (A ^ C) & ~B
2101 // (~(A & B) | C) & (~(B & C) | A) --> ~((A ^ C) & B)
2102 if (matchNotOrAnd(Op1, m_Specific(V: B), m_Specific(V: C), m_Specific(V: A), Dummy,
2103 true)) {
2104 Value *Xor = Builder.CreateXor(LHS: A, RHS: C);
2105 return (Opcode == Instruction::Or)
2106 ? BinaryOperator::CreateAnd(V1: Xor, V2: Builder.CreateNot(V: B))
2107 : BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: Xor, RHS: B));
2108 }
2109
2110 // (~(A | B) & C) | ~(A | C) --> ~((B & C) | A)
2111 // (~(A & B) | C) & ~(A & C) --> ~((B | C) & A)
2112 if (match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_OneUse(
2113 SubPattern: m_c_BinOp(Opcode, L: m_Specific(V: A), R: m_Specific(V: C)))))))
2114 return BinaryOperator::CreateNot(Op: Builder.CreateBinOp(
2115 Opc: Opcode, LHS: Builder.CreateBinOp(Opc: FlippedOpcode, LHS: B, RHS: C), RHS: A));
2116
2117 // (~(A | B) & C) | ~(B | C) --> ~((A & C) | B)
2118 // (~(A & B) | C) & ~(B & C) --> ~((A | C) & B)
2119 if (match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_OneUse(
2120 SubPattern: m_c_BinOp(Opcode, L: m_Specific(V: B), R: m_Specific(V: C)))))))
2121 return BinaryOperator::CreateNot(Op: Builder.CreateBinOp(
2122 Opc: Opcode, LHS: Builder.CreateBinOp(Opc: FlippedOpcode, LHS: A, RHS: C), RHS: B));
2123
2124 // (~(A | B) & C) | ~(C | (A ^ B)) --> ~((A | B) & (C | (A ^ B)))
2125 // Note, the pattern with swapped and/or is not handled because the
2126 // result is more undefined than a source:
2127 // (~(A & B) | C) & ~(C & (A ^ B)) --> (A ^ B ^ C) | ~(A | C) is invalid.
2128 if (Opcode == Instruction::Or && Op0->hasOneUse() &&
2129 match(V: Op1,
2130 P: m_OneUse(SubPattern: m_Not(V: m_Value(
2131 V&: Y, P: m_c_BinOp(Opcode, L: m_Specific(V: C),
2132 R: m_c_Xor(L: m_Specific(V: A), R: m_Specific(V: B)))))))) {
2133 // X = ~(A | B)
2134 // Y = (C | (A ^ B)
2135 Value *Or = cast<BinaryOperator>(Val: X)->getOperand(i_nocapture: 0);
2136 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: Or, RHS: Y));
2137 }
2138 }
2139
2140 // (~A & B & C) | ... --> ...
2141 // (~A | B | C) | ... --> ...
2142 // TODO: One use checks are conservative. We just need to check that a total
2143 // number of multiple used values does not exceed reduction
2144 // in operations.
2145 if (match(V: Op0,
2146 P: m_OneUse(SubPattern: m_c_BinOp(Opcode: FlippedOpcode,
2147 L: m_BinOp(Opcode: FlippedOpcode, L: m_Value(V&: B), R: m_Value(V&: C)),
2148 R: m_Value(V&: X, P: m_Not(V: m_Value(V&: A)))))) ||
2149 match(V: Op0, P: m_OneUse(SubPattern: m_c_BinOp(Opcode: FlippedOpcode,
2150 L: m_c_BinOp(Opcode: FlippedOpcode, L: m_Value(V&: C),
2151 R: m_Value(V&: X, P: m_Not(V: m_Value(V&: A)))),
2152 R: m_Value(V&: B))))) {
2153 // X = ~A
2154 // (~A & B & C) | ~(A | B | C) --> ~(A | (B ^ C))
2155 // (~A | B | C) & ~(A & B & C) --> (~A | (B ^ C))
2156 if (match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_c_BinOp(
2157 Opcode, L: m_c_BinOp(Opcode, L: m_Specific(V: A), R: m_Specific(V: B)),
2158 R: m_Specific(V: C))))) ||
2159 match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_c_BinOp(
2160 Opcode, L: m_c_BinOp(Opcode, L: m_Specific(V: B), R: m_Specific(V: C)),
2161 R: m_Specific(V: A))))) ||
2162 match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_c_BinOp(
2163 Opcode, L: m_c_BinOp(Opcode, L: m_Specific(V: A), R: m_Specific(V: C)),
2164 R: m_Specific(V: B)))))) {
2165 Value *Xor = Builder.CreateXor(LHS: B, RHS: C);
2166 return (Opcode == Instruction::Or)
2167 ? BinaryOperator::CreateNot(Op: Builder.CreateOr(LHS: Xor, RHS: A))
2168 : BinaryOperator::CreateOr(V1: Xor, V2: X);
2169 }
2170
2171 // (~A & B & C) | ~(A | B) --> (C | ~B) & ~A
2172 // (~A | B | C) & ~(A & B) --> (C & ~B) | ~A
2173 if (match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_OneUse(
2174 SubPattern: m_c_BinOp(Opcode, L: m_Specific(V: A), R: m_Specific(V: B)))))))
2175 return BinaryOperator::Create(
2176 Op: FlippedOpcode, S1: Builder.CreateBinOp(Opc: Opcode, LHS: C, RHS: Builder.CreateNot(V: B)),
2177 S2: X);
2178
2179 // (~A & B & C) | ~(A | C) --> (B | ~C) & ~A
2180 // (~A | B | C) & ~(A & C) --> (B & ~C) | ~A
2181 if (match(V: Op1, P: m_OneUse(SubPattern: m_Not(V: m_OneUse(
2182 SubPattern: m_c_BinOp(Opcode, L: m_Specific(V: A), R: m_Specific(V: C)))))))
2183 return BinaryOperator::Create(
2184 Op: FlippedOpcode, S1: Builder.CreateBinOp(Opc: Opcode, LHS: B, RHS: Builder.CreateNot(V: C)),
2185 S2: X);
2186 }
2187
2188 return nullptr;
2189}
2190
2191/// Try to reassociate a pair of binops so that values with one use only are
2192/// part of the same instruction. This may enable folds that are limited with
2193/// multi-use restrictions and makes it more likely to match other patterns that
2194/// are looking for a common operand.
2195static Instruction *reassociateForUses(BinaryOperator &BO,
2196 InstCombinerImpl::BuilderTy &Builder) {
2197 Instruction::BinaryOps Opcode = BO.getOpcode();
2198 Value *X, *Y, *Z;
2199 if (match(V: &BO,
2200 P: m_c_BinOp(Opcode, L: m_OneUse(SubPattern: m_BinOp(Opcode, L: m_Value(V&: X), R: m_Value(V&: Y))),
2201 R: m_OneUse(SubPattern: m_Value(V&: Z))))) {
2202 if (!isa<Constant>(Val: X) && !isa<Constant>(Val: Y) && !isa<Constant>(Val: Z)) {
2203 // (X op Y) op Z --> (Y op Z) op X
2204 if (!X->hasOneUse()) {
2205 Value *YZ = Builder.CreateBinOp(Opc: Opcode, LHS: Y, RHS: Z);
2206 return BinaryOperator::Create(Op: Opcode, S1: YZ, S2: X);
2207 }
2208 // (X op Y) op Z --> (X op Z) op Y
2209 if (!Y->hasOneUse()) {
2210 Value *XZ = Builder.CreateBinOp(Opc: Opcode, LHS: X, RHS: Z);
2211 return BinaryOperator::Create(Op: Opcode, S1: XZ, S2: Y);
2212 }
2213 }
2214 }
2215
2216 return nullptr;
2217}
2218
2219// Match
2220// (X + C2) | C
2221// (X + C2) ^ C
2222// (X + C2) & C
2223// and convert to do the bitwise logic first:
2224// (X | C) + C2
2225// (X ^ C) + C2
2226// (X & C) + C2
2227// iff bits affected by logic op are lower than last bit affected by math op
2228static Instruction *canonicalizeLogicFirst(BinaryOperator &I,
2229 InstCombiner::BuilderTy &Builder) {
2230 Type *Ty = I.getType();
2231 Instruction::BinaryOps OpC = I.getOpcode();
2232 Value *Op0 = I.getOperand(i_nocapture: 0);
2233 Value *Op1 = I.getOperand(i_nocapture: 1);
2234 Value *X;
2235 const APInt *C, *C2;
2236
2237 if (!(match(V: Op0, P: m_OneUse(SubPattern: m_Add(L: m_Value(V&: X), R: m_APInt(Res&: C2)))) &&
2238 match(V: Op1, P: m_APInt(Res&: C))))
2239 return nullptr;
2240
2241 unsigned Width = Ty->getScalarSizeInBits();
2242 unsigned LastOneMath = Width - C2->countr_zero();
2243
2244 switch (OpC) {
2245 case Instruction::And:
2246 if (C->countl_one() < LastOneMath)
2247 return nullptr;
2248 break;
2249 case Instruction::Xor:
2250 case Instruction::Or:
2251 if (C->countl_zero() < LastOneMath)
2252 return nullptr;
2253 break;
2254 default:
2255 llvm_unreachable("Unexpected BinaryOp!");
2256 }
2257
2258 Value *NewBinOp = Builder.CreateBinOp(Opc: OpC, LHS: X, RHS: ConstantInt::get(Ty, V: *C));
2259 return BinaryOperator::CreateWithCopiedFlags(Opc: Instruction::Add, V1: NewBinOp,
2260 V2: ConstantInt::get(Ty, V: *C2), CopyO: Op0);
2261}
2262
2263// binop(shift(ShiftedC1, ShAmt), shift(ShiftedC2, add(ShAmt, AddC))) ->
2264// shift(binop(ShiftedC1, shift(ShiftedC2, AddC)), ShAmt)
2265// where both shifts are the same and AddC is a valid shift amount.
2266Instruction *InstCombinerImpl::foldBinOpOfDisplacedShifts(BinaryOperator &I) {
2267 assert((I.isBitwiseLogicOp() || I.getOpcode() == Instruction::Add) &&
2268 "Unexpected opcode");
2269
2270 Value *ShAmt;
2271 Constant *ShiftedC1, *ShiftedC2, *AddC;
2272 Type *Ty = I.getType();
2273 unsigned BitWidth = Ty->getScalarSizeInBits();
2274 if (!match(V: &I, P: m_c_BinOp(L: m_Shift(L: m_ImmConstant(C&: ShiftedC1), R: m_Value(V&: ShAmt)),
2275 R: m_Shift(L: m_ImmConstant(C&: ShiftedC2),
2276 R: m_AddLike(L: m_Deferred(V: ShAmt),
2277 R: m_ImmConstant(C&: AddC))))))
2278 return nullptr;
2279
2280 // Make sure the add constant is a valid shift amount.
2281 if (!match(V: AddC,
2282 P: m_SpecificInt_ICMP(Predicate: ICmpInst::ICMP_ULT, Threshold: APInt(BitWidth, BitWidth))))
2283 return nullptr;
2284
2285 // Avoid constant expressions.
2286 auto *Op0Inst = dyn_cast<Instruction>(Val: I.getOperand(i_nocapture: 0));
2287 auto *Op1Inst = dyn_cast<Instruction>(Val: I.getOperand(i_nocapture: 1));
2288 if (!Op0Inst || !Op1Inst)
2289 return nullptr;
2290
2291 // Both shifts must be the same.
2292 Instruction::BinaryOps ShiftOp =
2293 static_cast<Instruction::BinaryOps>(Op0Inst->getOpcode());
2294 if (ShiftOp != Op1Inst->getOpcode())
2295 return nullptr;
2296
2297 // For adds, only left shifts are supported.
2298 if (I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2299 return nullptr;
2300
2301 Value *NewC = Builder.CreateBinOp(
2302 Opc: I.getOpcode(), LHS: ShiftedC1, RHS: Builder.CreateBinOp(Opc: ShiftOp, LHS: ShiftedC2, RHS: AddC));
2303 return BinaryOperator::Create(Op: ShiftOp, S1: NewC, S2: ShAmt);
2304}
2305
2306// Fold and/or/xor with two equal intrinsic IDs:
2307// bitwise(fshl (A, B, ShAmt), fshl(C, D, ShAmt))
2308// -> fshl(bitwise(A, C), bitwise(B, D), ShAmt)
2309// bitwise(fshr (A, B, ShAmt), fshr(C, D, ShAmt))
2310// -> fshr(bitwise(A, C), bitwise(B, D), ShAmt)
2311// bitwise(bswap(A), bswap(B)) -> bswap(bitwise(A, B))
2312// bitwise(bswap(A), C) -> bswap(bitwise(A, bswap(C)))
2313// bitwise(bitreverse(A), bitreverse(B)) -> bitreverse(bitwise(A, B))
2314// bitwise(bitreverse(A), C) -> bitreverse(bitwise(A, bitreverse(C)))
2315static Instruction *
2316foldBitwiseLogicWithIntrinsics(BinaryOperator &I,
2317 InstCombiner::BuilderTy &Builder) {
2318 assert(I.isBitwiseLogicOp() && "Should and/or/xor");
2319 if (!I.getOperand(i_nocapture: 0)->hasOneUse())
2320 return nullptr;
2321 IntrinsicInst *X = dyn_cast<IntrinsicInst>(Val: I.getOperand(i_nocapture: 0));
2322 if (!X)
2323 return nullptr;
2324
2325 IntrinsicInst *Y = dyn_cast<IntrinsicInst>(Val: I.getOperand(i_nocapture: 1));
2326 if (Y && (!Y->hasOneUse() || X->getIntrinsicID() != Y->getIntrinsicID()))
2327 return nullptr;
2328
2329 Intrinsic::ID IID = X->getIntrinsicID();
2330 const APInt *RHSC;
2331 // Try to match constant RHS.
2332 if (!Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2333 !match(V: I.getOperand(i_nocapture: 1), P: m_APInt(Res&: RHSC))))
2334 return nullptr;
2335
2336 switch (IID) {
2337 case Intrinsic::fshl:
2338 case Intrinsic::fshr: {
2339 if (X->getOperand(i_nocapture: 2) != Y->getOperand(i_nocapture: 2))
2340 return nullptr;
2341 Value *NewOp0 =
2342 Builder.CreateBinOp(Opc: I.getOpcode(), LHS: X->getOperand(i_nocapture: 0), RHS: Y->getOperand(i_nocapture: 0));
2343 Value *NewOp1 =
2344 Builder.CreateBinOp(Opc: I.getOpcode(), LHS: X->getOperand(i_nocapture: 1), RHS: Y->getOperand(i_nocapture: 1));
2345 Function *F =
2346 Intrinsic::getOrInsertDeclaration(M: I.getModule(), id: IID, OverloadTys: I.getType());
2347 return CallInst::Create(Func: F, Args: {NewOp0, NewOp1, X->getOperand(i_nocapture: 2)});
2348 }
2349 case Intrinsic::bswap:
2350 case Intrinsic::bitreverse: {
2351 Value *NewOp0 = Builder.CreateBinOp(
2352 Opc: I.getOpcode(), LHS: X->getOperand(i_nocapture: 0),
2353 RHS: Y ? Y->getOperand(i_nocapture: 0)
2354 : ConstantInt::get(Ty: I.getType(), V: IID == Intrinsic::bswap
2355 ? RHSC->byteSwap()
2356 : RHSC->reverseBits()));
2357 Function *F =
2358 Intrinsic::getOrInsertDeclaration(M: I.getModule(), id: IID, OverloadTys: I.getType());
2359 return CallInst::Create(Func: F, Args: {NewOp0});
2360 }
2361 default:
2362 return nullptr;
2363 }
2364}
2365
2366// Try to simplify V by replacing occurrences of Op with RepOp, but only look
2367// through bitwise operations. In particular, for X | Y we try to replace Y with
2368// 0 inside X and for X & Y we try to replace Y with -1 inside X.
2369// Return the simplified result of X if successful, and nullptr otherwise.
2370// If SimplifyOnly is true, no new instructions will be created.
2371static Value *simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp,
2372 bool SimplifyOnly,
2373 InstCombinerImpl &IC,
2374 unsigned Depth = 0) {
2375 if (Op == RepOp)
2376 return nullptr;
2377
2378 if (V == Op)
2379 return RepOp;
2380
2381 auto *I = dyn_cast<BinaryOperator>(Val: V);
2382 if (!I || !I->isBitwiseLogicOp() || Depth >= 3)
2383 return nullptr;
2384
2385 if (!I->hasOneUse())
2386 SimplifyOnly = true;
2387
2388 Value *NewOp0 = simplifyAndOrWithOpReplaced(V: I->getOperand(i_nocapture: 0), Op, RepOp,
2389 SimplifyOnly, IC, Depth: Depth + 1);
2390 Value *NewOp1 = simplifyAndOrWithOpReplaced(V: I->getOperand(i_nocapture: 1), Op, RepOp,
2391 SimplifyOnly, IC, Depth: Depth + 1);
2392 if (!NewOp0 && !NewOp1)
2393 return nullptr;
2394
2395 if (!NewOp0)
2396 NewOp0 = I->getOperand(i_nocapture: 0);
2397 if (!NewOp1)
2398 NewOp1 = I->getOperand(i_nocapture: 1);
2399
2400 if (Value *Res = simplifyBinOp(Opcode: I->getOpcode(), LHS: NewOp0, RHS: NewOp1,
2401 Q: IC.getSimplifyQuery().getWithInstruction(I)))
2402 return Res;
2403
2404 if (SimplifyOnly)
2405 return nullptr;
2406 return IC.Builder.CreateBinOp(Opc: I->getOpcode(), LHS: NewOp0, RHS: NewOp1);
2407}
2408
2409/// The pattern div_ceil(X, P) * P, where P is a power of 2, lowers to the
2410/// following conditional round-up: (X + select(C, 0, Pow2)) & -Pow2, where
2411/// C is X % Pow2 == 0. This may be simplified to (X + (Pow2-1)) & -Pow2.
2412static Instruction *
2413foldRoundUpToPow2Alignment(BinaryOperator &I,
2414 InstCombiner::BuilderTy &Builder) {
2415 const APInt *NegP;
2416 Value *Add;
2417 if (!match(V: &I, P: m_And(L: m_Value(V&: Add), R: m_NegatedPower2(V&: NegP))))
2418 return nullptr;
2419
2420 Value *X, *Cond;
2421 APInt Mask = ~*NegP;
2422
2423 // Match the pattern. Ensure the true arm of the select is zero, and the false
2424 // one is the Pow2.
2425 if (!match(V: Add,
2426 P: m_OneUse(SubPattern: m_c_Add(L: m_Value(V&: X), R: m_Select(C: m_Value(V&: Cond), L: m_ZeroInt(),
2427 R: m_SpecificInt(V: -*NegP))))))
2428 return nullptr;
2429
2430 // icmp ne should have already been canonicalized to the eq form for this
2431 // pattern.
2432 if (!match(V: Cond, P: m_SpecificICmp(MatchPred: ICmpInst::ICMP_EQ,
2433 L: m_And(L: m_Specific(V: X), R: m_SpecificInt(V: Mask)),
2434 R: m_Zero())))
2435 return nullptr;
2436
2437 Type *Ty = I.getType();
2438 Value *NewAdd = Builder.CreateAdd(LHS: X, RHS: ConstantInt::get(Ty, V: Mask));
2439 return BinaryOperator::CreateAnd(V1: NewAdd, V2: ConstantInt::get(Ty, V: *NegP));
2440}
2441
2442/// Reassociate and/or expressions to see if we can fold the inner and/or ops.
2443/// TODO: Make this recursive; it's a little tricky because an arbitrary
2444/// number of and/or instructions might have to be created.
2445Value *InstCombinerImpl::reassociateBooleanAndOr(Value *LHS, Value *X, Value *Y,
2446 Instruction &I, bool IsAnd,
2447 bool RHSIsLogical) {
2448 Instruction::BinaryOps Opcode = IsAnd ? Instruction::And : Instruction::Or;
2449 Value *Folded = nullptr;
2450 // LHS bop (X lop Y) --> (LHS bop X) lop Y
2451 // LHS bop (X bop Y) --> (LHS bop X) bop Y
2452 if (Value *Res = foldBooleanAndOr(LHS, RHS: X, I, IsAnd, /*IsLogical=*/false))
2453 Folded = RHSIsLogical ? Builder.CreateLogicalOp(Opc: Opcode, Cond1: Res, Cond2: Y)
2454 : Builder.CreateBinOp(Opc: Opcode, LHS: Res, RHS: Y);
2455 // LHS bop (X bop Y) --> X bop (LHS bop Y)
2456 // LHS bop (X lop Y) --> X lop (LHS bop Y)
2457 else if (Value *Res = foldBooleanAndOr(LHS, RHS: Y, I, IsAnd, /*IsLogical=*/false))
2458 Folded = RHSIsLogical ? Builder.CreateLogicalOp(Opc: Opcode, Cond1: X, Cond2: Res)
2459 : Builder.CreateBinOp(Opc: Opcode, LHS: X, RHS: Res);
2460 if (SelectInst *SI = dyn_cast_or_null<SelectInst>(Val: Folded); SI != nullptr)
2461 // If the bop I was originally a lop, we could recover branch weight
2462 // information using that lop's weights. However, InstCombine usually
2463 // replaces the lop with a bop by the time we get here, deleting the branch
2464 // weight information. Therefore, we can only assume unknown branch weights.
2465 // TODO: see if it's possible to recover branch weight information from the
2466 // original lop (https://github.com/llvm/llvm-project/issues/183864).
2467 setExplicitlyUnknownBranchWeightsIfProfiled(I&: *SI, DEBUG_TYPE,
2468 F: I.getFunction());
2469 return Folded;
2470}
2471
2472// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
2473// here. We should standardize that construct where it is needed or choose some
2474// other way to ensure that commutated variants of patterns are not missed.
2475Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
2476 Type *Ty = I.getType();
2477
2478 if (Value *V = simplifyAndInst(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1),
2479 Q: SQ.getWithInstruction(I: &I)))
2480 return replaceInstUsesWith(I, V);
2481
2482 if (SimplifyAssociativeOrCommutative(I))
2483 return &I;
2484
2485 if (Instruction *X = foldVectorBinop(Inst&: I))
2486 return X;
2487
2488 if (Instruction *Phi = foldBinopWithPhiOperands(BO&: I))
2489 return Phi;
2490
2491 // See if we can simplify any instructions used by the instruction whose sole
2492 // purpose is to compute bits we don't care about.
2493 if (SimplifyDemandedInstructionBits(Inst&: I))
2494 return &I;
2495
2496 // Do this before using distributive laws to catch simple and/or/not patterns.
2497 if (Instruction *Xor = foldAndToXor(I, Builder))
2498 return Xor;
2499
2500 if (Instruction *X = foldComplexAndOrPatterns(I, Builder))
2501 return X;
2502
2503 // (A|B)&(A|C) -> A|(B&C) etc
2504 if (Value *V = foldUsingDistributiveLaws(I))
2505 return replaceInstUsesWith(I, V);
2506
2507 if (Instruction *R = foldBinOpShiftWithShift(I))
2508 return R;
2509
2510 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
2511
2512 Value *X, *Y;
2513 const APInt *C;
2514 if ((match(V: Op0, P: m_OneUse(SubPattern: m_LogicalShift(L: m_One(), R: m_Value(V&: X)))) ||
2515 (match(V: Op0, P: m_OneUse(SubPattern: m_Shl(L: m_APInt(Res&: C), R: m_Value(V&: X)))) && (*C)[0])) &&
2516 match(V: Op1, P: m_One())) {
2517 // (1 >> X) & 1 --> zext(X == 0)
2518 // (C << X) & 1 --> zext(X == 0), when C is odd
2519 Value *IsZero = Builder.CreateICmpEQ(LHS: X, RHS: ConstantInt::get(Ty, V: 0));
2520 return new ZExtInst(IsZero, Ty);
2521 }
2522
2523 // (-(X & 1)) & Y --> (X & 1) == 0 ? 0 : Y
2524 Value *Neg;
2525 if (match(V: &I,
2526 P: m_c_And(L: m_Value(V&: Neg, P: m_OneUse(SubPattern: m_Neg(V: m_And(L: m_Value(), R: m_One())))),
2527 R: m_Value(V&: Y)))) {
2528 Value *Cmp = Builder.CreateIsNull(Arg: Neg);
2529 return createSelectInstWithUnknownProfile(C: Cmp,
2530 S1: ConstantInt::getNullValue(Ty), S2: Y);
2531 }
2532
2533 // Canonicalize:
2534 // (X +/- Y) & Y --> ~X & Y when Y is a power of 2.
2535 if (match(V: &I, P: m_c_And(L: m_Value(V&: Y), R: m_OneUse(SubPattern: m_CombineOr(
2536 Ps: m_c_Add(L: m_Value(V&: X), R: m_Deferred(V: Y)),
2537 Ps: m_Sub(L: m_Value(V&: X), R: m_Deferred(V: Y)))))) &&
2538 isKnownToBeAPowerOfTwo(V: Y, /*OrZero*/ true, CxtI: &I))
2539 return BinaryOperator::CreateAnd(V1: Builder.CreateNot(V: X), V2: Y);
2540
2541 if (match(V: Op1, P: m_APInt(Res&: C))) {
2542 const APInt *XorC;
2543 if (match(V: Op0, P: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: X), R: m_APInt(Res&: XorC))))) {
2544 // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
2545 Constant *NewC = ConstantInt::get(Ty, V: *C & *XorC);
2546 Value *And = Builder.CreateAnd(LHS: X, RHS: Op1);
2547 And->takeName(V: Op0);
2548 return BinaryOperator::CreateXor(V1: And, V2: NewC);
2549 }
2550
2551 const APInt *OrC;
2552 if (match(V: Op0, P: m_OneUse(SubPattern: m_Or(L: m_Value(V&: X), R: m_APInt(Res&: OrC))))) {
2553 // (X | C1) & C2 --> (X & C2^(C1&C2)) | (C1&C2)
2554 // NOTE: This reduces the number of bits set in the & mask, which
2555 // can expose opportunities for store narrowing for scalars.
2556 // NOTE: SimplifyDemandedBits should have already removed bits from C1
2557 // that aren't set in C2. Meaning we can replace (C1&C2) with C1 in
2558 // above, but this feels safer.
2559 APInt Together = *C & *OrC;
2560 Value *And = Builder.CreateAnd(LHS: X, RHS: ConstantInt::get(Ty, V: Together ^ *C));
2561 And->takeName(V: Op0);
2562 return BinaryOperator::CreateOr(V1: And, V2: ConstantInt::get(Ty, V: Together));
2563 }
2564
2565 unsigned Width = Ty->getScalarSizeInBits();
2566 const APInt *ShiftC;
2567 if (match(V: Op0, P: m_OneUse(SubPattern: m_SExt(Op: m_AShr(L: m_Value(V&: X), R: m_APInt(Res&: ShiftC))))) &&
2568 ShiftC->ult(RHS: Width)) {
2569 if (*C == APInt::getLowBitsSet(numBits: Width, loBitsSet: Width - ShiftC->getZExtValue())) {
2570 // We are clearing high bits that were potentially set by sext+ashr:
2571 // and (sext (ashr X, ShiftC)), C --> lshr (sext X), ShiftC
2572 Value *Sext = Builder.CreateSExt(V: X, DestTy: Ty);
2573 Constant *ShAmtC = ConstantInt::get(Ty, V: ShiftC->zext(width: Width));
2574 return BinaryOperator::CreateLShr(V1: Sext, V2: ShAmtC);
2575 }
2576 }
2577
2578 // If this 'and' clears the sign-bits added by ashr, replace with lshr:
2579 // and (ashr X, ShiftC), C --> lshr X, ShiftC
2580 if (match(V: Op0, P: m_AShr(L: m_Value(V&: X), R: m_APInt(Res&: ShiftC))) && ShiftC->ult(RHS: Width) &&
2581 C->isMask(numBits: Width - ShiftC->getZExtValue()))
2582 return BinaryOperator::CreateLShr(V1: X, V2: ConstantInt::get(Ty, V: *ShiftC));
2583
2584 const APInt *AddC;
2585 if (match(V: Op0, P: m_Add(L: m_Value(V&: X), R: m_APInt(Res&: AddC)))) {
2586 // If we are masking the result of the add down to exactly one bit and
2587 // the constant we are adding has no bits set below that bit, then the
2588 // add is flipping a single bit. Example:
2589 // (X + 4) & 4 --> (X & 4) ^ 4
2590 if (Op0->hasOneUse() && C->isPowerOf2() && (*AddC & (*C - 1)) == 0) {
2591 assert((*C & *AddC) != 0 && "Expected common bit");
2592 Value *NewAnd = Builder.CreateAnd(LHS: X, RHS: Op1);
2593 return BinaryOperator::CreateXor(V1: NewAnd, V2: Op1);
2594 }
2595 }
2596
2597 // ((C1 OP zext(X)) & C2) -> zext((C1 OP X) & C2) if C2 fits in the
2598 // bitwidth of X and OP behaves well when given trunc(C1) and X.
2599 auto isNarrowableBinOpcode = [](BinaryOperator *B) {
2600 switch (B->getOpcode()) {
2601 case Instruction::Xor:
2602 case Instruction::Or:
2603 case Instruction::Mul:
2604 case Instruction::Add:
2605 case Instruction::Sub:
2606 return true;
2607 default:
2608 return false;
2609 }
2610 };
2611 BinaryOperator *BO;
2612 if (match(V: Op0, P: m_OneUse(SubPattern: m_BinOp(I&: BO))) && isNarrowableBinOpcode(BO)) {
2613 Instruction::BinaryOps BOpcode = BO->getOpcode();
2614 Value *X;
2615 const APInt *C1;
2616 // TODO: The one-use restrictions could be relaxed a little if the AND
2617 // is going to be removed.
2618 // Try to narrow the 'and' and a binop with constant operand:
2619 // and (bo (zext X), C1), C --> zext (and (bo X, TruncC1), TruncC)
2620 if (match(V: BO, P: m_c_BinOp(L: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: X))), R: m_APInt(Res&: C1))) &&
2621 C->isIntN(N: X->getType()->getScalarSizeInBits())) {
2622 unsigned XWidth = X->getType()->getScalarSizeInBits();
2623 Constant *TruncC1 = ConstantInt::get(Ty: X->getType(), V: C1->trunc(width: XWidth));
2624 Value *BinOp = isa<ZExtInst>(Val: BO->getOperand(i_nocapture: 0))
2625 ? Builder.CreateBinOp(Opc: BOpcode, LHS: X, RHS: TruncC1)
2626 : Builder.CreateBinOp(Opc: BOpcode, LHS: TruncC1, RHS: X);
2627 Constant *TruncC = ConstantInt::get(Ty: X->getType(), V: C->trunc(width: XWidth));
2628 Value *And = Builder.CreateAnd(LHS: BinOp, RHS: TruncC);
2629 return new ZExtInst(And, Ty);
2630 }
2631
2632 // Similar to above: if the mask matches the zext input width, then the
2633 // 'and' can be eliminated, so we can truncate the other variable op:
2634 // and (bo (zext X), Y), C --> zext (bo X, (trunc Y))
2635 if (isa<Instruction>(Val: BO->getOperand(i_nocapture: 0)) &&
2636 match(V: BO->getOperand(i_nocapture: 0), P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: X)))) &&
2637 C->isMask(numBits: X->getType()->getScalarSizeInBits())) {
2638 Y = BO->getOperand(i_nocapture: 1);
2639 Value *TrY = Builder.CreateTrunc(V: Y, DestTy: X->getType(), Name: Y->getName() + ".tr");
2640 Value *NewBO =
2641 Builder.CreateBinOp(Opc: BOpcode, LHS: X, RHS: TrY, Name: BO->getName() + ".narrow");
2642 return new ZExtInst(NewBO, Ty);
2643 }
2644 // and (bo Y, (zext X)), C --> zext (bo (trunc Y), X)
2645 if (isa<Instruction>(Val: BO->getOperand(i_nocapture: 1)) &&
2646 match(V: BO->getOperand(i_nocapture: 1), P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: X)))) &&
2647 C->isMask(numBits: X->getType()->getScalarSizeInBits())) {
2648 Y = BO->getOperand(i_nocapture: 0);
2649 Value *TrY = Builder.CreateTrunc(V: Y, DestTy: X->getType(), Name: Y->getName() + ".tr");
2650 Value *NewBO =
2651 Builder.CreateBinOp(Opc: BOpcode, LHS: TrY, RHS: X, Name: BO->getName() + ".narrow");
2652 return new ZExtInst(NewBO, Ty);
2653 }
2654 }
2655
2656 // This is intentionally placed after the narrowing transforms for
2657 // efficiency (transform directly to the narrow logic op if possible).
2658 // If the mask is only needed on one incoming arm, push the 'and' op up.
2659 if (match(V: Op0, P: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: X), R: m_Value(V&: Y)))) ||
2660 match(V: Op0, P: m_OneUse(SubPattern: m_Or(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
2661 APInt NotAndMask(~(*C));
2662 BinaryOperator::BinaryOps BinOp = cast<BinaryOperator>(Val: Op0)->getOpcode();
2663 if (MaskedValueIsZero(V: X, Mask: NotAndMask, CxtI: &I)) {
2664 // Not masking anything out for the LHS, move mask to RHS.
2665 // and ({x}or X, Y), C --> {x}or X, (and Y, C)
2666 Value *NewRHS = Builder.CreateAnd(LHS: Y, RHS: Op1, Name: Y->getName() + ".masked");
2667 return BinaryOperator::Create(Op: BinOp, S1: X, S2: NewRHS);
2668 }
2669 if (!isa<Constant>(Val: Y) && MaskedValueIsZero(V: Y, Mask: NotAndMask, CxtI: &I)) {
2670 // Not masking anything out for the RHS, move mask to LHS.
2671 // and ({x}or X, Y), C --> {x}or (and X, C), Y
2672 Value *NewLHS = Builder.CreateAnd(LHS: X, RHS: Op1, Name: X->getName() + ".masked");
2673 return BinaryOperator::Create(Op: BinOp, S1: NewLHS, S2: Y);
2674 }
2675 }
2676
2677 // When the mask is a power-of-2 constant and op0 is a shifted-power-of-2
2678 // constant, test if the shift amount equals the offset bit index:
2679 // (ShiftC << X) & C --> X == (log2(C) - log2(ShiftC)) ? C : 0
2680 // (ShiftC >> X) & C --> X == (log2(ShiftC) - log2(C)) ? C : 0
2681 if (C->isPowerOf2() &&
2682 match(V: Op0, P: m_OneUse(SubPattern: m_LogicalShift(L: m_Power2(V&: ShiftC), R: m_Value(V&: X))))) {
2683 int Log2ShiftC = ShiftC->exactLogBase2();
2684 int Log2C = C->exactLogBase2();
2685 bool IsShiftLeft =
2686 cast<BinaryOperator>(Val: Op0)->getOpcode() == Instruction::Shl;
2687 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2688 assert(BitNum >= 0 && "Expected demanded bits to handle impossible mask");
2689 Value *Cmp = Builder.CreateICmpEQ(LHS: X, RHS: ConstantInt::get(Ty, V: BitNum));
2690 return createSelectInstWithUnknownProfile(C: Cmp, S1: ConstantInt::get(Ty, V: *C),
2691 S2: ConstantInt::getNullValue(Ty));
2692 }
2693
2694 Constant *C1, *C2;
2695 const APInt *C3 = C;
2696 Value *X;
2697 if (C3->isPowerOf2()) {
2698 Constant *Log2C3 = ConstantInt::get(Ty, V: C3->countr_zero());
2699 if (match(V: Op0, P: m_OneUse(SubPattern: m_LShr(L: m_Shl(L: m_ImmConstant(C&: C1), R: m_Value(V&: X)),
2700 R: m_ImmConstant(C&: C2)))) &&
2701 match(V: C1, P: m_Power2())) {
2702 Constant *Log2C1 = ConstantExpr::getExactLogBase2(C: C1);
2703 Constant *LshrC = ConstantExpr::getAdd(C1: C2, C2: Log2C3);
2704 KnownBits KnownLShrc = computeKnownBits(V: LshrC, CxtI: nullptr);
2705 if (KnownLShrc.getMaxValue().ult(RHS: Width)) {
2706 // iff C1,C3 is pow2 and C2 + cttz(C3) < BitWidth:
2707 // ((C1 << X) >> C2) & C3 -> X == (cttz(C3)+C2-cttz(C1)) ? C3 : 0
2708 Constant *CmpC = ConstantExpr::getSub(C1: LshrC, C2: Log2C1);
2709 Value *Cmp = Builder.CreateICmpEQ(LHS: X, RHS: CmpC);
2710 return createSelectInstWithUnknownProfile(
2711 C: Cmp, S1: ConstantInt::get(Ty, V: *C3), S2: ConstantInt::getNullValue(Ty));
2712 }
2713 }
2714
2715 if (match(V: Op0, P: m_OneUse(SubPattern: m_Shl(L: m_LShr(L: m_ImmConstant(C&: C1), R: m_Value(V&: X)),
2716 R: m_ImmConstant(C&: C2)))) &&
2717 match(V: C1, P: m_Power2())) {
2718 Constant *Log2C1 = ConstantExpr::getExactLogBase2(C: C1);
2719 Constant *Cmp =
2720 ConstantFoldCompareInstOperands(Predicate: ICmpInst::ICMP_ULT, LHS: Log2C3, RHS: C2, DL);
2721 if (Cmp && Cmp->isNullValue()) {
2722 // iff C1,C3 is pow2 and Log2(C3) >= C2:
2723 // ((C1 >> X) << C2) & C3 -> X == (cttz(C1)+C2-cttz(C3)) ? C3 : 0
2724 Constant *ShlC = ConstantExpr::getAdd(C1: C2, C2: Log2C1);
2725 Constant *CmpC = ConstantExpr::getSub(C1: ShlC, C2: Log2C3);
2726 Value *Cmp = Builder.CreateICmpEQ(LHS: X, RHS: CmpC);
2727 return createSelectInstWithUnknownProfile(
2728 C: Cmp, S1: ConstantInt::get(Ty, V: *C3), S2: ConstantInt::getNullValue(Ty));
2729 }
2730 }
2731 }
2732 }
2733
2734 // If we are clearing the sign bit of a floating-point value, convert this to
2735 // fabs, then cast back to integer.
2736 //
2737 // This is a generous interpretation for noimplicitfloat, this is not a true
2738 // floating-point operation.
2739 //
2740 // Assumes any IEEE-represented type has the sign bit in the high bit.
2741 // TODO: Unify with APInt matcher. This version allows undef unlike m_APInt
2742 Value *CastOp;
2743 if (match(V: Op0, P: m_ElementWiseBitCast(Op: m_Value(V&: CastOp))) &&
2744 match(V: Op1, P: m_MaxSignedValue()) &&
2745 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
2746 Kind: Attribute::NoImplicitFloat)) {
2747 Type *EltTy = CastOp->getType()->getScalarType();
2748 if (EltTy->isFloatingPointTy() &&
2749 APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
2750 Value *FAbs = Builder.CreateFAbs(V: CastOp);
2751 return new BitCastInst(FAbs, I.getType());
2752 }
2753 }
2754
2755 // and(shl(zext(X), Y), SignMask) -> and(sext(X), SignMask)
2756 // where Y is a valid shift amount.
2757 if (match(V: &I, P: m_And(L: m_OneUse(SubPattern: m_Shl(L: m_ZExt(Op: m_Value(V&: X)), R: m_Value(V&: Y))),
2758 R: m_SignMask())) &&
2759 match(V: Y, P: m_SpecificInt_ICMP(
2760 Predicate: ICmpInst::Predicate::ICMP_EQ,
2761 Threshold: APInt(Ty->getScalarSizeInBits(),
2762 Ty->getScalarSizeInBits() -
2763 X->getType()->getScalarSizeInBits())))) {
2764 auto *SExt = Builder.CreateSExt(V: X, DestTy: Ty, Name: X->getName() + ".signext");
2765 return BinaryOperator::CreateAnd(V1: SExt, V2: Op1);
2766 }
2767
2768 if (Instruction *Z = narrowMaskedBinOp(And&: I))
2769 return Z;
2770
2771 if (I.getType()->isIntOrIntVectorTy(BitWidth: 1)) {
2772 if (auto *SI0 = dyn_cast<SelectInst>(Val: Op0)) {
2773 if (auto *R =
2774 foldAndOrOfSelectUsingImpliedCond(Op: Op1, SI&: *SI0, /* IsAnd */ true))
2775 return R;
2776 }
2777 if (auto *SI1 = dyn_cast<SelectInst>(Val: Op1)) {
2778 if (auto *R =
2779 foldAndOrOfSelectUsingImpliedCond(Op: Op0, SI&: *SI1, /* IsAnd */ true))
2780 return R;
2781 }
2782 }
2783
2784 if (Instruction *FoldedLogic = foldBinOpIntoSelectOrPhi(I))
2785 return FoldedLogic;
2786
2787 if (Instruction *DeMorgan = matchDeMorgansLaws(I, IC&: *this))
2788 return DeMorgan;
2789
2790 {
2791 Value *A, *B, *C;
2792 // A & ~(A ^ B) --> A & B
2793 if (match(V: Op1, P: m_Not(V: m_c_Xor(L: m_Specific(V: Op0), R: m_Value(V&: B)))))
2794 return BinaryOperator::CreateAnd(V1: Op0, V2: B);
2795 // ~(A ^ B) & A --> A & B
2796 if (match(V: Op0, P: m_Not(V: m_c_Xor(L: m_Specific(V: Op1), R: m_Value(V&: B)))))
2797 return BinaryOperator::CreateAnd(V1: Op1, V2: B);
2798
2799 // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C
2800 if (match(V: Op0, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))) &&
2801 match(V: Op1, P: m_Xor(L: m_Xor(L: m_Specific(V: B), R: m_Value(V&: C)), R: m_Specific(V: A)))) {
2802 Value *NotC = Op1->hasOneUse()
2803 ? Builder.CreateNot(V: C)
2804 : getFreelyInverted(V: C, WillInvertAllUses: C->hasOneUse(), Builder: &Builder);
2805 if (NotC != nullptr)
2806 return BinaryOperator::CreateAnd(V1: Op0, V2: NotC);
2807 }
2808
2809 // ((A ^ C) ^ B) & (B ^ A) -> (B ^ A) & ~C
2810 if (match(V: Op0, P: m_Xor(L: m_Xor(L: m_Value(V&: A), R: m_Value(V&: C)), R: m_Value(V&: B))) &&
2811 match(V: Op1, P: m_Xor(L: m_Specific(V: B), R: m_Specific(V: A)))) {
2812 Value *NotC = Op0->hasOneUse()
2813 ? Builder.CreateNot(V: C)
2814 : getFreelyInverted(V: C, WillInvertAllUses: C->hasOneUse(), Builder: &Builder);
2815 if (NotC != nullptr)
2816 return BinaryOperator::CreateAnd(V1: Op1, V2: NotC);
2817 }
2818
2819 // (A | B) & (~A ^ B) -> A & B
2820 // (A | B) & (B ^ ~A) -> A & B
2821 // (B | A) & (~A ^ B) -> A & B
2822 // (B | A) & (B ^ ~A) -> A & B
2823 if (match(V: Op1, P: m_c_Xor(L: m_Not(V: m_Value(V&: A)), R: m_Value(V&: B))) &&
2824 match(V: Op0, P: m_c_Or(L: m_Specific(V: A), R: m_Specific(V: B))))
2825 return BinaryOperator::CreateAnd(V1: A, V2: B);
2826
2827 // (~A ^ B) & (A | B) -> A & B
2828 // (~A ^ B) & (B | A) -> A & B
2829 // (B ^ ~A) & (A | B) -> A & B
2830 // (B ^ ~A) & (B | A) -> A & B
2831 if (match(V: Op0, P: m_c_Xor(L: m_Not(V: m_Value(V&: A)), R: m_Value(V&: B))) &&
2832 match(V: Op1, P: m_c_Or(L: m_Specific(V: A), R: m_Specific(V: B))))
2833 return BinaryOperator::CreateAnd(V1: A, V2: B);
2834
2835 // (~A | B) & (A ^ B) -> ~A & B
2836 // (~A | B) & (B ^ A) -> ~A & B
2837 // (B | ~A) & (A ^ B) -> ~A & B
2838 // (B | ~A) & (B ^ A) -> ~A & B
2839 if (match(V: Op0, P: m_c_Or(L: m_Not(V: m_Value(V&: A)), R: m_Value(V&: B))) &&
2840 match(V: Op1, P: m_c_Xor(L: m_Specific(V: A), R: m_Specific(V: B))))
2841 return BinaryOperator::CreateAnd(V1: Builder.CreateNot(V: A), V2: B);
2842
2843 // (A ^ B) & (~A | B) -> ~A & B
2844 // (B ^ A) & (~A | B) -> ~A & B
2845 // (A ^ B) & (B | ~A) -> ~A & B
2846 // (B ^ A) & (B | ~A) -> ~A & B
2847 if (match(V: Op1, P: m_c_Or(L: m_Not(V: m_Value(V&: A)), R: m_Value(V&: B))) &&
2848 match(V: Op0, P: m_c_Xor(L: m_Specific(V: A), R: m_Specific(V: B))))
2849 return BinaryOperator::CreateAnd(V1: Builder.CreateNot(V: A), V2: B);
2850 }
2851
2852 if (Value *Res =
2853 foldBooleanAndOr(LHS: Op0, RHS: Op1, I, /*IsAnd=*/true, /*IsLogical=*/false))
2854 return replaceInstUsesWith(I, V: Res);
2855
2856 if (match(V: Op1, P: m_OneUse(SubPattern: m_LogicalAnd(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
2857 bool IsLogical = isa<SelectInst>(Val: Op1);
2858 if (auto *V = reassociateBooleanAndOr(LHS: Op0, X, Y, I, /*IsAnd=*/true,
2859 /*RHSIsLogical=*/IsLogical))
2860 return replaceInstUsesWith(I, V);
2861 }
2862 if (match(V: Op0, P: m_OneUse(SubPattern: m_LogicalAnd(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
2863 bool IsLogical = isa<SelectInst>(Val: Op0);
2864 if (auto *V = reassociateBooleanAndOr(LHS: Op1, X, Y, I, /*IsAnd=*/true,
2865 /*RHSIsLogical=*/IsLogical))
2866 return replaceInstUsesWith(I, V);
2867 }
2868
2869 if (Instruction *FoldedFCmps = reassociateFCmps(BO&: I, Builder))
2870 return FoldedFCmps;
2871
2872 if (Instruction *CastedAnd = foldCastedBitwiseLogic(I))
2873 return CastedAnd;
2874
2875 if (Instruction *Sel = foldBinopOfSextBoolToSelect(I))
2876 return Sel;
2877
2878 // and(sext(A), B) / and(B, sext(A)) --> A ? B : 0, where A is i1 or <N x i1>.
2879 // TODO: Move this into foldBinopOfSextBoolToSelect as a more generalized fold
2880 // with binop identity constant. But creating a select with non-constant
2881 // arm may not be reversible due to poison semantics. Is that a good
2882 // canonicalization?
2883 Value *A, *B;
2884 if (match(V: &I, P: m_c_And(L: m_SExt(Op: m_Value(V&: A)), R: m_Value(V&: B))) &&
2885 A->getType()->isIntOrIntVectorTy(BitWidth: 1))
2886 return createSelectInstWithUnknownProfile(C: A, S1: B, S2: Constant::getNullValue(Ty));
2887
2888 // Similarly, a 'not' of the bool translates to a swap of the select arms:
2889 // ~sext(A) & B / B & ~sext(A) --> A ? 0 : B
2890 if (match(V: &I, P: m_c_And(L: m_Not(V: m_SExt(Op: m_Value(V&: A))), R: m_Value(V&: B))) &&
2891 A->getType()->isIntOrIntVectorTy(BitWidth: 1))
2892 return createSelectInstWithUnknownProfile(C: A, S1: Constant::getNullValue(Ty), S2: B);
2893
2894 // and(zext(A), B) -> A ? (B & 1) : 0
2895 if (match(V: &I, P: m_c_And(L: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: A))), R: m_Value(V&: B))) &&
2896 A->getType()->isIntOrIntVectorTy(BitWidth: 1))
2897 return createSelectInstWithUnknownProfile(
2898 C: A, S1: Builder.CreateAnd(LHS: B, RHS: ConstantInt::get(Ty, V: 1)),
2899 S2: Constant::getNullValue(Ty));
2900
2901 // (-1 + A) & B --> A ? 0 : B where A is 0/1.
2902 if (match(V: &I, P: m_c_And(L: m_OneUse(SubPattern: m_Add(L: m_ZExtOrSelf(Op: m_Value(V&: A)), R: m_AllOnes())),
2903 R: m_Value(V&: B)))) {
2904 if (A->getType()->isIntOrIntVectorTy(BitWidth: 1))
2905 return createSelectInstWithUnknownProfile(C: A, S1: Constant::getNullValue(Ty),
2906 S2: B);
2907 if (computeKnownBits(V: A, CxtI: &I).countMaxActiveBits() <= 1) {
2908 return createSelectInstWithUnknownProfile(
2909 C: Builder.CreateICmpEQ(LHS: A, RHS: Constant::getNullValue(Ty: A->getType())), S1: B,
2910 S2: Constant::getNullValue(Ty));
2911 }
2912 }
2913
2914 // (iN X s>> (N-1)) & Y --> (X s< 0) ? Y : 0 -- with optional sext
2915 if (match(V: &I, P: m_c_And(L: m_OneUse(SubPattern: m_SExtOrSelf(
2916 Op: m_AShr(L: m_Value(V&: X), R: m_APIntAllowPoison(Res&: C)))),
2917 R: m_Value(V&: Y))) &&
2918 *C == X->getType()->getScalarSizeInBits() - 1) {
2919 Value *IsNeg = Builder.CreateIsNeg(Arg: X, Name: "isneg");
2920 return createSelectInstWithUnknownProfile(C: IsNeg, S1: Y,
2921 S2: ConstantInt::getNullValue(Ty));
2922 }
2923 // If there's a 'not' of the shifted value, swap the select operands:
2924 // ~(iN X s>> (N-1)) & Y --> (X s< 0) ? 0 : Y -- with optional sext
2925 if (match(V: &I, P: m_c_And(L: m_OneUse(SubPattern: m_SExtOrSelf(
2926 Op: m_Not(V: m_AShr(L: m_Value(V&: X), R: m_APIntAllowPoison(Res&: C))))),
2927 R: m_Value(V&: Y))) &&
2928 *C == X->getType()->getScalarSizeInBits() - 1) {
2929 Value *IsNeg = Builder.CreateIsNeg(Arg: X, Name: "isneg");
2930 return createSelectInstWithUnknownProfile(C: IsNeg,
2931 S1: ConstantInt::getNullValue(Ty), S2: Y);
2932 }
2933
2934 // (~x) & y --> ~(x | (~y)) iff that gets rid of inversions
2935 if (sinkNotIntoOtherHandOfLogicalOp(I))
2936 return &I;
2937
2938 // An and recurrence w/loop invariant step is equivelent to (and start, step)
2939 PHINode *PN = nullptr;
2940 Value *Start = nullptr, *Step = nullptr;
2941 if (matchSimpleRecurrence(I: &I, P&: PN, Start, Step) && DT.dominates(Def: Step, User: PN))
2942 return replaceInstUsesWith(I, V: Builder.CreateAnd(LHS: Start, RHS: Step));
2943
2944 if (Instruction *R = reassociateForUses(BO&: I, Builder))
2945 return R;
2946
2947 if (Instruction *Canonicalized = canonicalizeLogicFirst(I, Builder))
2948 return Canonicalized;
2949
2950 if (Instruction *Folded = foldLogicOfIsFPClass(BO&: I, Op0, Op1))
2951 return Folded;
2952
2953 if (Instruction *Res = foldBinOpOfDisplacedShifts(I))
2954 return Res;
2955
2956 if (Instruction *Res = foldBitwiseLogicWithIntrinsics(I, Builder))
2957 return Res;
2958
2959 if (Value *V =
2960 simplifyAndOrWithOpReplaced(V: Op0, Op: Op1, RepOp: Constant::getAllOnesValue(Ty),
2961 /*SimplifyOnly*/ false, IC&: *this))
2962 return BinaryOperator::CreateAnd(V1: V, V2: Op1);
2963 if (Value *V =
2964 simplifyAndOrWithOpReplaced(V: Op1, Op: Op0, RepOp: Constant::getAllOnesValue(Ty),
2965 /*SimplifyOnly*/ false, IC&: *this))
2966 return BinaryOperator::CreateAnd(V1: Op0, V2: V);
2967
2968 if (Instruction *Res = foldRoundUpToPow2Alignment(I, Builder))
2969 return Res;
2970
2971 return nullptr;
2972}
2973
2974Instruction *InstCombinerImpl::matchBSwapOrBitReverse(Instruction &I,
2975 bool MatchBSwaps,
2976 bool MatchBitReversals) {
2977 SmallVector<Instruction *, 4> Insts;
2978 if (!recognizeBSwapOrBitReverseIdiom(I: &I, MatchBSwaps, MatchBitReversals,
2979 InsertedInsts&: Insts))
2980 return nullptr;
2981 Instruction *LastInst = Insts.pop_back_val();
2982 LastInst->removeFromParent();
2983
2984 for (auto *Inst : Insts) {
2985 Inst->setDebugLoc(I.getDebugLoc());
2986 Worklist.push(I: Inst);
2987 }
2988 return LastInst;
2989}
2990
2991std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2992InstCombinerImpl::convertOrOfShiftsToFunnelShift(Instruction &Or) {
2993 // TODO: Can we reduce the code duplication between this and the related
2994 // rotate matching code under visitSelect and visitTrunc?
2995 assert(Or.getOpcode() == BinaryOperator::Or && "Expecting or instruction");
2996
2997 unsigned Width = Or.getType()->getScalarSizeInBits();
2998
2999 Instruction *Or0, *Or1;
3000 if (!match(V: Or.getOperand(i: 0), P: m_Instruction(I&: Or0)) ||
3001 !match(V: Or.getOperand(i: 1), P: m_Instruction(I&: Or1)))
3002 return std::nullopt;
3003
3004 bool IsFshl = true; // Sub on LSHR.
3005 SmallVector<Value *, 3> FShiftArgs;
3006
3007 // First, find an or'd pair of opposite shifts:
3008 // or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)
3009 if (isa<BinaryOperator>(Val: Or0) && isa<BinaryOperator>(Val: Or1)) {
3010 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
3011 if (!match(V: Or0,
3012 P: m_OneUse(SubPattern: m_LogicalShift(L: m_Value(V&: ShVal0), R: m_Value(V&: ShAmt0)))) ||
3013 !match(V: Or1,
3014 P: m_OneUse(SubPattern: m_LogicalShift(L: m_Value(V&: ShVal1), R: m_Value(V&: ShAmt1)))) ||
3015 Or0->getOpcode() == Or1->getOpcode())
3016 return std::nullopt;
3017
3018 // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
3019 if (Or0->getOpcode() == BinaryOperator::LShr) {
3020 std::swap(a&: Or0, b&: Or1);
3021 std::swap(a&: ShVal0, b&: ShVal1);
3022 std::swap(a&: ShAmt0, b&: ShAmt1);
3023 }
3024 assert(Or0->getOpcode() == BinaryOperator::Shl &&
3025 Or1->getOpcode() == BinaryOperator::LShr &&
3026 "Illegal or(shift,shift) pair");
3027
3028 // Match the shift amount operands for a funnel shift pattern. This always
3029 // matches a subtraction on the R operand.
3030 auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
3031 // Check for constant shift amounts that sum to the bitwidth.
3032 const APInt *LI, *RI;
3033 if (match(V: L, P: m_APIntAllowPoison(Res&: LI)) && match(V: R, P: m_APIntAllowPoison(Res&: RI)))
3034 if (LI->ult(RHS: Width) && RI->ult(RHS: Width) && (*LI + *RI) == Width)
3035 return ConstantInt::get(Ty: L->getType(), V: *LI);
3036
3037 Constant *LC, *RC;
3038 if (match(V: L, P: m_Constant(C&: LC)) && match(V: R, P: m_Constant(C&: RC)) &&
3039 match(V: L,
3040 P: m_SpecificInt_ICMP(Predicate: ICmpInst::ICMP_ULT, Threshold: APInt(Width, Width))) &&
3041 match(V: R,
3042 P: m_SpecificInt_ICMP(Predicate: ICmpInst::ICMP_ULT, Threshold: APInt(Width, Width))) &&
3043 match(V: ConstantExpr::getAdd(C1: LC, C2: RC), P: m_SpecificIntAllowPoison(V: Width)))
3044 return ConstantExpr::mergeUndefsWith(C: LC, Other: RC);
3045
3046 // (shl ShVal, X) | (lshr ShVal, (Width - x)) iff X < Width.
3047 // We limit this to X < Width in case the backend re-expands the
3048 // intrinsic, and has to reintroduce a shift modulo operation (InstCombine
3049 // might remove it after this fold). This still doesn't guarantee that the
3050 // final codegen will match this original pattern.
3051 if (match(V: R, P: m_OneUse(SubPattern: m_Sub(L: m_SpecificInt(V: Width), R: m_Specific(V: L))))) {
3052 KnownBits KnownL = computeKnownBits(V: L, CxtI: &Or);
3053 return KnownL.getMaxValue().ult(RHS: Width) ? L : nullptr;
3054 }
3055
3056 // For non-constant cases, the following patterns currently only work for
3057 // rotation patterns.
3058 // TODO: Add general funnel-shift compatible patterns.
3059 if (ShVal0 != ShVal1)
3060 return nullptr;
3061
3062 // For non-constant cases we don't support non-pow2 shift masks.
3063 // TODO: Is it worth matching urem as well?
3064 if (!isPowerOf2_32(Value: Width))
3065 return nullptr;
3066
3067 // The shift amount may be masked with negation:
3068 // (shl ShVal, (X & (Width - 1))) | (lshr ShVal, ((-X) & (Width - 1)))
3069 Value *X;
3070 unsigned Mask = Width - 1;
3071 if (match(V: L, P: m_And(L: m_Value(V&: X), R: m_SpecificInt(V: Mask))) &&
3072 match(V: R, P: m_And(L: m_Neg(V: m_Specific(V: X)), R: m_SpecificInt(V: Mask))))
3073 return X;
3074
3075 // (shl ShVal,(X+1) & (Width-1)) | (lshr ShVal,((X & (Width-1)) ^
3076 // (Width-1)))
3077 {
3078 Value *XPlusOne = nullptr;
3079 if (match(V: L, P: m_And(L: m_Value(V&: XPlusOne, P: m_Add(L: m_Value(V&: X), R: m_One())),
3080 R: m_SpecificInt(V: Mask))) &&
3081 match(V: R, P: m_Xor(L: m_And(L: m_Specific(V: X), R: m_SpecificInt(V: Mask)),
3082 R: m_SpecificInt(V: Mask))))
3083 return XPlusOne;
3084 }
3085
3086 // (shl ShVal, X) | (lshr ShVal, ((-X) & (Width - 1)))
3087 if (match(V: R, P: m_And(L: m_Neg(V: m_Specific(V: L)), R: m_SpecificInt(V: Mask))))
3088 return L;
3089
3090 // Similar to above, but the shift amount may be extended after masking,
3091 // so return the extended value as the parameter for the intrinsic.
3092 if (match(V: L, P: m_ZExt(Op: m_And(L: m_Value(V&: X), R: m_SpecificInt(V: Mask)))) &&
3093 match(V: R,
3094 P: m_And(L: m_Neg(V: m_ZExt(Op: m_And(L: m_Specific(V: X), R: m_SpecificInt(V: Mask)))),
3095 R: m_SpecificInt(V: Mask))))
3096 return L;
3097
3098 if (match(V: L, P: m_ZExt(Op: m_And(L: m_Value(V&: X), R: m_SpecificInt(V: Mask)))) &&
3099 match(V: R, P: m_ZExt(Op: m_And(L: m_Neg(V: m_Specific(V: X)), R: m_SpecificInt(V: Mask)))))
3100 return L;
3101
3102 return nullptr;
3103 };
3104
3105 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3106 if (!ShAmt) {
3107 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3108 IsFshl = false; // Sub on SHL.
3109 }
3110 if (!ShAmt)
3111 return std::nullopt;
3112
3113 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3114 } else if (isa<ZExtInst>(Val: Or0) || isa<ZExtInst>(Val: Or1)) {
3115 // If there are two 'or' instructions concat variables in opposite order:
3116 //
3117 // Slot1 and Slot2 are all zero bits.
3118 // | Slot1 | Low | Slot2 | High |
3119 // LowHigh = or (shl (zext Low), ZextLowShlAmt), (zext High)
3120 // | Slot2 | High | Slot1 | Low |
3121 // HighLow = or (shl (zext High), ZextHighShlAmt), (zext Low)
3122 //
3123 // the latter 'or' can be safely convert to
3124 // -> HighLow = fshl LowHigh, LowHigh, ZextHighShlAmt
3125 // if ZextLowShlAmt + ZextHighShlAmt == Width.
3126 if (!isa<ZExtInst>(Val: Or1))
3127 std::swap(a&: Or0, b&: Or1);
3128
3129 Value *High, *ZextHigh, *Low;
3130 const APInt *ZextHighShlAmt;
3131 if (!match(V: Or0,
3132 P: m_OneUse(SubPattern: m_Shl(L: m_Value(V&: ZextHigh), R: m_APInt(Res&: ZextHighShlAmt)))))
3133 return std::nullopt;
3134
3135 if (!match(V: Or1, P: m_ZExt(Op: m_Value(V&: Low))) ||
3136 !match(V: ZextHigh, P: m_ZExt(Op: m_Value(V&: High))))
3137 return std::nullopt;
3138
3139 unsigned HighSize = High->getType()->getScalarSizeInBits();
3140 unsigned LowSize = Low->getType()->getScalarSizeInBits();
3141 // Make sure High does not overlap with Low and most significant bits of
3142 // High aren't shifted out.
3143 if (ZextHighShlAmt->ult(RHS: LowSize) || ZextHighShlAmt->ugt(RHS: Width - HighSize))
3144 return std::nullopt;
3145
3146 for (User *U : ZextHigh->users()) {
3147 Value *X, *Y;
3148 if (!match(V: U, P: m_Or(L: m_Value(V&: X), R: m_Value(V&: Y))))
3149 continue;
3150
3151 if (!isa<ZExtInst>(Val: Y))
3152 std::swap(a&: X, b&: Y);
3153
3154 const APInt *ZextLowShlAmt;
3155 if (!match(V: X, P: m_Shl(L: m_Specific(V: Or1), R: m_APInt(Res&: ZextLowShlAmt))) ||
3156 !match(V: Y, P: m_Specific(V: ZextHigh)) || !DT.dominates(Def: U, User: &Or))
3157 continue;
3158
3159 // HighLow is good concat. If sum of two shifts amount equals to Width,
3160 // LowHigh must also be a good concat.
3161 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3162 continue;
3163
3164 // Low must not overlap with High and most significant bits of Low must
3165 // not be shifted out.
3166 assert(ZextLowShlAmt->uge(HighSize) &&
3167 ZextLowShlAmt->ule(Width - LowSize) && "Invalid concat");
3168
3169 // We cannot reuse the result if it may produce poison.
3170 // Drop poison generating flags in the expression tree.
3171 // Or
3172 cast<Instruction>(Val: U)->dropPoisonGeneratingFlags();
3173 // Shl
3174 cast<Instruction>(Val: X)->dropPoisonGeneratingFlags();
3175
3176 FShiftArgs = {U, U, ConstantInt::get(Ty: Or0->getType(), V: *ZextHighShlAmt)};
3177 break;
3178 }
3179 }
3180
3181 if (FShiftArgs.empty())
3182 return std::nullopt;
3183
3184 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3185 return std::make_pair(x&: IID, y&: FShiftArgs);
3186}
3187
3188/// Match UB-safe variants of the funnel shift intrinsic.
3189static Instruction *matchFunnelShift(Instruction &Or, InstCombinerImpl &IC) {
3190 if (auto Opt = IC.convertOrOfShiftsToFunnelShift(Or)) {
3191 auto [IID, FShiftArgs] = *Opt;
3192 Function *F =
3193 Intrinsic::getOrInsertDeclaration(M: Or.getModule(), id: IID, OverloadTys: Or.getType());
3194 return CallInst::Create(Func: F, Args: FShiftArgs);
3195 }
3196
3197 return nullptr;
3198}
3199
3200/// Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
3201static Value *matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder) {
3202 assert(Or.getOpcode() == Instruction::Or && "bswap requires an 'or'");
3203 Value *Op0 = Or.getOperand(i: 0), *Op1 = Or.getOperand(i: 1);
3204 Type *Ty = Or.getType();
3205
3206 unsigned Width = Ty->getScalarSizeInBits();
3207 if ((Width & 1) != 0)
3208 return nullptr;
3209 unsigned HalfWidth = Width / 2;
3210
3211 // Canonicalize zext (lower half) to LHS.
3212 if (!isa<ZExtInst>(Val: Op0))
3213 std::swap(a&: Op0, b&: Op1);
3214
3215 // Find lower/upper half.
3216 Value *LowerSrc, *ShlVal, *UpperSrc;
3217 const APInt *C;
3218 if (!match(V: Op0, P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: LowerSrc)))) ||
3219 !match(V: Op1, P: m_OneUse(SubPattern: m_Shl(L: m_Value(V&: ShlVal), R: m_APInt(Res&: C)))) ||
3220 !match(V: ShlVal, P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: UpperSrc)))))
3221 return nullptr;
3222 if (*C != HalfWidth || LowerSrc->getType() != UpperSrc->getType() ||
3223 LowerSrc->getType()->getScalarSizeInBits() != HalfWidth)
3224 return nullptr;
3225
3226 auto ConcatIntrinsicCalls = [&](Intrinsic::ID id, Value *Lo, Value *Hi) {
3227 Value *NewLower = Builder.CreateZExt(V: Lo, DestTy: Ty);
3228 Value *NewUpper = Builder.CreateZExt(V: Hi, DestTy: Ty);
3229 NewUpper = Builder.CreateShl(LHS: NewUpper, RHS: HalfWidth);
3230 Value *BinOp = Builder.CreateDisjointOr(LHS: NewLower, RHS: NewUpper);
3231 return Builder.CreateIntrinsic(ID: id, OverloadTypes: Ty, Args: BinOp);
3232 };
3233
3234 // BSWAP: Push the concat down, swapping the lower/upper sources.
3235 // concat(bswap(x),bswap(y)) -> bswap(concat(x,y))
3236 Value *LowerBSwap, *UpperBSwap;
3237 if (match(V: LowerSrc, P: m_BSwap(Op0: m_Value(V&: LowerBSwap))) &&
3238 match(V: UpperSrc, P: m_BSwap(Op0: m_Value(V&: UpperBSwap))))
3239 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3240
3241 // BITREVERSE: Push the concat down, swapping the lower/upper sources.
3242 // concat(bitreverse(x),bitreverse(y)) -> bitreverse(concat(x,y))
3243 Value *LowerBRev, *UpperBRev;
3244 if (match(V: LowerSrc, P: m_BitReverse(Op0: m_Value(V&: LowerBRev))) &&
3245 match(V: UpperSrc, P: m_BitReverse(Op0: m_Value(V&: UpperBRev))))
3246 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3247
3248 // iX ext split: extending or(zext(x),shl(zext(y),bw/2) pattern
3249 // to consume sext/ashr:
3250 // or(zext(sext(x)),shl(zext(sext(ashr(x,xbw-1))),bw/2)
3251 // or(zext(x),shl(zext(ashr(x,xbw-1)),bw/2)
3252 Value *X;
3253 if (match(V: LowerSrc, P: m_SExtOrSelf(Op: m_Value(V&: X))) &&
3254 match(V: UpperSrc,
3255 P: m_SExtOrSelf(Op: m_AShr(
3256 L: m_Specific(V: X),
3257 R: m_SpecificInt(V: X->getType()->getScalarSizeInBits() - 1)))))
3258 return Builder.CreateSExt(V: X, DestTy: Ty);
3259
3260 return nullptr;
3261}
3262
3263/// If all elements of two constant vectors are 0/-1 and inverses, return true.
3264static bool areInverseVectorBitmasks(Constant *C1, Constant *C2) {
3265 unsigned NumElts = cast<FixedVectorType>(Val: C1->getType())->getNumElements();
3266 for (unsigned i = 0; i != NumElts; ++i) {
3267 Constant *EltC1 = C1->getAggregateElement(Elt: i);
3268 Constant *EltC2 = C2->getAggregateElement(Elt: i);
3269 if (!EltC1 || !EltC2)
3270 return false;
3271
3272 // One element must be all ones, and the other must be all zeros.
3273 if (!((match(V: EltC1, P: m_Zero()) && match(V: EltC2, P: m_AllOnes())) ||
3274 (match(V: EltC2, P: m_Zero()) && match(V: EltC1, P: m_AllOnes()))))
3275 return false;
3276 }
3277 return true;
3278}
3279
3280/// We have an expression of the form (A & C) | (B & D). If A is a scalar or
3281/// vector composed of all-zeros or all-ones values and is the bitwise 'not' of
3282/// B, it can be used as the condition operand of a select instruction.
3283/// We will detect (A & C) | ~(B | D) when the flag ABIsTheSame enabled.
3284Value *InstCombinerImpl::getSelectCondition(Value *A, Value *B,
3285 bool ABIsTheSame) {
3286 // We may have peeked through bitcasts in the caller.
3287 // Exit immediately if we don't have (vector) integer types.
3288 Type *Ty = A->getType();
3289 if (!Ty->isIntOrIntVectorTy() || !B->getType()->isIntOrIntVectorTy())
3290 return nullptr;
3291
3292 // If A is the 'not' operand of B and has enough signbits, we have our answer.
3293 if (ABIsTheSame ? (A == B) : match(V: B, P: m_Not(V: m_Specific(V: A)))) {
3294 // If these are scalars or vectors of i1, A can be used directly.
3295 if (Ty->isIntOrIntVectorTy(BitWidth: 1))
3296 return A;
3297
3298 // If we look through a vector bitcast, the caller will bitcast the operands
3299 // to match the condition's number of bits (N x i1).
3300 // To make this poison-safe, disallow bitcast from wide element to narrow
3301 // element. That could allow poison in lanes where it was not present in the
3302 // original code.
3303 A = peekThroughBitcast(V: A);
3304 if (A->getType()->isIntOrIntVectorTy()) {
3305 unsigned NumSignBits = ComputeNumSignBits(Op: A);
3306 if (NumSignBits == A->getType()->getScalarSizeInBits() &&
3307 NumSignBits <= Ty->getScalarSizeInBits())
3308 return Builder.CreateTrunc(V: A, DestTy: CmpInst::makeCmpResultType(opnd_type: A->getType()));
3309 }
3310 return nullptr;
3311 }
3312
3313 // TODO: add support for sext and constant case
3314 if (ABIsTheSame)
3315 return nullptr;
3316
3317 // If both operands are constants, see if the constants are inverse bitmasks.
3318 Constant *AConst, *BConst;
3319 if (match(V: A, P: m_Constant(C&: AConst)) && match(V: B, P: m_Constant(C&: BConst)))
3320 if (AConst == ConstantExpr::getNot(C: BConst) &&
3321 ComputeNumSignBits(Op: A) == Ty->getScalarSizeInBits())
3322 return Builder.CreateZExtOrTrunc(V: A, DestTy: CmpInst::makeCmpResultType(opnd_type: Ty));
3323
3324 // Look for more complex patterns. The 'not' op may be hidden behind various
3325 // casts. Look through sexts and bitcasts to find the booleans.
3326 Value *Cond;
3327 Value *NotB;
3328 if (match(V: A, P: m_SExt(Op: m_Value(V&: Cond))) &&
3329 Cond->getType()->isIntOrIntVectorTy(BitWidth: 1)) {
3330 // A = sext i1 Cond; B = sext (not (i1 Cond))
3331 if (match(V: B, P: m_SExt(Op: m_Not(V: m_Specific(V: Cond)))))
3332 return Cond;
3333
3334 // A = sext i1 Cond; B = not ({bitcast} (sext (i1 Cond)))
3335 // TODO: The one-use checks are unnecessary or misplaced. If the caller
3336 // checked for uses on logic ops/casts, that should be enough to
3337 // make this transform worthwhile.
3338 if (match(V: B, P: m_OneUse(SubPattern: m_Not(V: m_Value(V&: NotB))))) {
3339 NotB = peekThroughBitcast(V: NotB, OneUseOnly: true);
3340 if (match(V: NotB, P: m_SExt(Op: m_Specific(V: Cond))))
3341 return Cond;
3342 }
3343 }
3344
3345 // All scalar (and most vector) possibilities should be handled now.
3346 // Try more matches that only apply to non-splat constant vectors.
3347 if (!Ty->isVectorTy())
3348 return nullptr;
3349
3350 // If both operands are xor'd with constants using the same sexted boolean
3351 // operand, see if the constants are inverse bitmasks.
3352 // TODO: Use ConstantExpr::getNot()?
3353 if (match(V: A, P: (m_Xor(L: m_SExt(Op: m_Value(V&: Cond)), R: m_Constant(C&: AConst)))) &&
3354 match(V: B, P: (m_Xor(L: m_SExt(Op: m_Specific(V: Cond)), R: m_Constant(C&: BConst)))) &&
3355 Cond->getType()->isIntOrIntVectorTy(BitWidth: 1) &&
3356 areInverseVectorBitmasks(C1: AConst, C2: BConst)) {
3357 AConst = ConstantExpr::getTrunc(C: AConst, Ty: CmpInst::makeCmpResultType(opnd_type: Ty));
3358 return Builder.CreateXor(LHS: Cond, RHS: AConst);
3359 }
3360 return nullptr;
3361}
3362
3363/// We have an expression of the form (A & B) | (C & D). Try to simplify this
3364/// to "A' ? B : D", where A' is a boolean or vector of booleans.
3365/// When InvertFalseVal is set to true, we try to match the pattern
3366/// where we have peeked through a 'not' op and A and C are the same:
3367/// (A & B) | ~(A | D) --> (A & B) | (~A & ~D) --> A' ? B : ~D
3368Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *B, Value *C,
3369 Value *D, bool InvertFalseVal) {
3370 // The potential condition of the select may be bitcasted. In that case, look
3371 // through its bitcast and the corresponding bitcast of the 'not' condition.
3372 Type *OrigType = A->getType();
3373 A = peekThroughBitcast(V: A, OneUseOnly: true);
3374 C = peekThroughBitcast(V: C, OneUseOnly: true);
3375 if (Value *Cond = getSelectCondition(A, B: C, ABIsTheSame: InvertFalseVal)) {
3376 // ((bc Cond) & B) | ((bc ~Cond) & D) --> bc (select Cond, (bc B), (bc D))
3377 // If this is a vector, we may need to cast to match the condition's length.
3378 // The bitcasts will either all exist or all not exist. The builder will
3379 // not create unnecessary casts if the types already match.
3380 Type *SelTy = A->getType();
3381 if (auto *VecTy = dyn_cast<VectorType>(Val: Cond->getType())) {
3382 // For a fixed or scalable vector get N from <{vscale x} N x iM>
3383 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3384 // For a fixed or scalable vector, get the size in bits of N x iM; for a
3385 // scalar this is just M.
3386 unsigned SelEltSize = SelTy->getPrimitiveSizeInBits().getKnownMinValue();
3387 Type *EltTy = Builder.getIntNTy(N: SelEltSize / Elts);
3388 SelTy = VectorType::get(ElementType: EltTy, EC: VecTy->getElementCount());
3389 }
3390 Value *BitcastB = Builder.CreateBitCast(V: B, DestTy: SelTy);
3391 if (InvertFalseVal)
3392 D = Builder.CreateNot(V: D);
3393 Value *BitcastD = Builder.CreateBitCast(V: D, DestTy: SelTy);
3394 Value *Select = Builder.CreateSelect(C: Cond, True: BitcastB, False: BitcastD);
3395 return Builder.CreateBitCast(V: Select, DestTy: OrigType);
3396 }
3397
3398 return nullptr;
3399}
3400
3401// (icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1)))
3402// (icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1)))
3403static Value *foldAndOrOfICmpEqConstantAndICmp(CmpPredicate PredL, Value *LHS0,
3404 Value *LHS1, bool LHSOneUse,
3405 CmpPredicate PredR, Value *RHS0,
3406 Value *RHS1, bool RHSOneUse,
3407 bool IsAnd, bool IsLogical,
3408 IRBuilderBase &Builder) {
3409 if (IsAnd) {
3410 PredL = CmpPredicate::getInverse(P: PredL);
3411 PredR = CmpPredicate::getInverse(P: PredR);
3412 }
3413
3414 const APInt *CInt;
3415 if (PredL != ICmpInst::ICMP_EQ || !match(V: LHS1, P: m_APIntAllowPoison(Res&: CInt)) ||
3416 !LHS0->getType()->isIntOrIntVectorTy() || !(LHSOneUse || RHSOneUse))
3417 return nullptr;
3418
3419 auto MatchRHSOp = [LHS0, CInt](const Value *RHSOp) {
3420 return match(V: RHSOp,
3421 P: m_Add(L: m_Specific(V: LHS0), R: m_SpecificIntAllowPoison(V: -*CInt))) ||
3422 (CInt->isZero() && RHSOp == LHS0);
3423 };
3424
3425 Value *Other;
3426 if (PredR == ICmpInst::ICMP_ULT && MatchRHSOp(RHS1))
3427 Other = RHS0;
3428 else if (PredR == ICmpInst::ICMP_UGT && MatchRHSOp(RHS0))
3429 Other = RHS1;
3430 else
3431 return nullptr;
3432
3433 if (IsLogical)
3434 Other = Builder.CreateFreeze(V: Other);
3435
3436 return Builder.CreateICmp(
3437 P: IsAnd ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_UGE,
3438 LHS: Builder.CreateSub(LHS: LHS0, RHS: ConstantInt::get(Ty: LHS0->getType(), V: *CInt + 1)),
3439 RHS: Other);
3440}
3441
3442/// Fold (icmp)&(icmp) or (icmp)|(icmp) if possible.
3443/// If IsLogical is true, then the and/or is in select form and the transform
3444/// must be poison-safe.
3445Value *InstCombinerImpl::foldAndOrOfICmps(Value *LHS, Value *RHS,
3446 Instruction &I, bool IsAnd,
3447 bool IsLogical) {
3448 CmpPredicate PredL, PredR;
3449 Value *LHS0, *LHS1, *RHS0, *RHS1;
3450 if (!match(V: LHS, P: m_ICmpLike(Pred&: PredL, L: m_Value(V&: LHS0), R: m_Value(V&: LHS1))) ||
3451 !match(V: RHS, P: m_ICmpLike(Pred&: PredR, L: m_Value(V&: RHS0), R: m_Value(V&: RHS1))))
3452 return nullptr;
3453
3454 bool LHSOneUse = LHS->hasOneUse();
3455 bool RHSOneUse = RHS->hasOneUse();
3456
3457 const SimplifyQuery Q = SQ.getWithInstruction(I: &I);
3458
3459 const APInt *LHSC = nullptr, *RHSC = nullptr;
3460 match(V: LHS1, P: m_APInt(Res&: LHSC));
3461 match(V: RHS1, P: m_APInt(Res&: RHSC));
3462
3463 // (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
3464 // (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
3465 if (predicatesFoldable(P1: PredL, P2: PredR)) {
3466 if (LHS0 == RHS1 && LHS1 == RHS0) {
3467 PredL = ICmpInst::getSwappedPredicate(pred: PredL);
3468 std::swap(a&: LHS0, b&: LHS1);
3469 }
3470 if (LHS0 == RHS0 && LHS1 == RHS1) {
3471 unsigned Code = IsAnd ? getICmpCode(Pred: PredL) & getICmpCode(Pred: PredR)
3472 : getICmpCode(Pred: PredL) | getICmpCode(Pred: PredR);
3473 bool IsSigned = ICmpInst::isSigned(Pred: PredL) || ICmpInst::isSigned(Pred: PredR);
3474 return getNewICmpValue(Code, Sign: IsSigned, LHS: LHS0, RHS: LHS1, Builder);
3475 }
3476 }
3477
3478 if (Value *V = foldAndOrOfICmpEqConstantAndICmp(PredL, LHS0, LHS1, LHSOneUse,
3479 PredR, RHS0, RHS1, RHSOneUse,
3480 IsAnd, IsLogical, Builder))
3481 return V;
3482 // We can treat logical like bitwise here, because both operands are used on
3483 // the LHS, and as such poison from both will propagate.
3484 if (Value *V = foldAndOrOfICmpEqConstantAndICmp(
3485 PredL: PredR, LHS0: RHS0, LHS1: RHS1, LHSOneUse: RHSOneUse, PredR: PredL, RHS0: LHS0, RHS1: LHS1, RHSOneUse: LHSOneUse, IsAnd,
3486 /*IsLogical*/ false, Builder))
3487 return V;
3488
3489 if (Value *V = foldAndOrOfICmpsWithConstEq(PredL, LHS0, LHS1, LHS, PredR,
3490 RHS0, RHS1, RHSOneUse, IsAnd,
3491 IsLogical, Builder, Q, I))
3492 return V;
3493 // We can convert this case to bitwise and, because both operands are used
3494 // on the LHS, and as such poison from both will propagate.
3495 // Can not handle RHS = trunc nuw as it is not same as icmp ne 0 for all
3496 // values
3497 if (isa<ICmpInst>(Val: RHS))
3498 if (Value *V = foldAndOrOfICmpsWithConstEq(
3499 PredL: PredR, LHS0: RHS0, LHS1: RHS1, LHS: RHS, PredR: PredL, RHS0: LHS0, RHS1: LHS1, RHSOneUse: LHSOneUse, IsAnd,
3500 /*IsLogical=*/false, Builder, Q, I)) {
3501 // If RHS is still used, we should drop samesign flag.
3502 if (IsLogical && PredR.hasSameSign() && !RHS->use_empty()) {
3503 auto *CmpR = cast<ICmpInst>(Val: RHS);
3504 CmpR->setSameSign(false);
3505 addToWorklist(I: CmpR);
3506 }
3507 return V;
3508 }
3509
3510 if (Value *V = foldIsPowerOf2OrZero(PredL, LHS0, LHS1, PredR, RHS0, RHS1,
3511 IsAnd, Builder, IC&: *this))
3512 return V;
3513 if (Value *V = foldIsPowerOf2OrZero(PredL: PredR, LHS0: RHS0, LHS1: RHS1, PredR: PredL, RHS0: LHS0, RHS1: LHS1,
3514 IsAnd, Builder, IC&: *this))
3515 return V;
3516
3517 // TODO: One of these directions is fine with logical and/or, the other could
3518 // be supported by inserting freeze.
3519 if (!IsLogical) {
3520 // E.g. (icmp slt x, 0) | (icmp sgt x, n) --> icmp ugt x, n
3521 // E.g. (icmp sge x, 0) & (icmp slt x, n) --> icmp ult x, n
3522 if (Value *V = simplifyRangeCheck(PredL, LHS0, LHS1, PredR, RHS0, RHS1, CxtI: &I,
3523 /*Inverted=*/!IsAnd))
3524 return V;
3525
3526 // E.g. (icmp sgt x, n) | (icmp slt x, 0) --> icmp ugt x, n
3527 // E.g. (icmp slt x, n) & (icmp sge x, 0) --> icmp ult x, n
3528 if (Value *V = simplifyRangeCheck(PredL: PredR, LHS0: RHS0, LHS1: RHS1, PredR: PredL, RHS0: LHS0, RHS1: LHS1, CxtI: &I,
3529 /*Inverted=*/!IsAnd))
3530 return V;
3531 }
3532
3533 // TODO: Add conjugated or fold, check whether it is safe for logical and/or.
3534 if (IsAnd && !IsLogical)
3535 if (Value *V = foldSignedTruncationCheck(PredL, LHS0, LHS1, PredR, RHS0,
3536 RHS1, CxtI&: I, Builder))
3537 return V;
3538
3539 if (Value *V = foldIsPowerOf2(PredL, LHS0, LHS1, PredR, RHS0, RHS1, JoinedByAnd: IsAnd,
3540 Builder, IC&: *this))
3541 return V;
3542
3543 if (Value *V = foldPowerOf2AndShiftedMask(Cmp0: LHS, Cmp1: RHS, JoinedByAnd: IsAnd, Builder))
3544 return V;
3545
3546 // TODO: Verify whether this is safe for logical and/or.
3547 if (!IsLogical) {
3548 if (Value *X = foldUnsignedUnderflowCheck(PredL, LHS0, LHS1, LHSOneUse,
3549 PredR, RHS0, RHS1, RHSOneUse,
3550 IsAnd, Q, Builder))
3551 return X;
3552 if (Value *X = foldUnsignedUnderflowCheck(PredL: PredR, LHS0: RHS0, LHS1: RHS1, LHSOneUse: RHSOneUse,
3553 PredR: PredL, RHS0: LHS0, RHS1: LHS1, RHSOneUse: LHSOneUse,
3554 IsAnd, Q, Builder))
3555 return X;
3556 }
3557
3558 // (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
3559 // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
3560 // TODO: Remove this and below when foldLogOpOfMaskedICmps can handle undefs.
3561 if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
3562 PredL.dropSameSign() == PredR.dropSameSign() &&
3563 match(V: LHS1, P: m_ZeroInt()) && match(V: RHS1, P: m_ZeroInt()) &&
3564 LHS0->getType() == RHS0->getType() &&
3565 (!IsLogical || isGuaranteedNotToBePoison(V: RHS0))) {
3566 Value *NewOr = Builder.CreateOr(LHS: LHS0, RHS: RHS0);
3567 return Builder.CreateICmp(P: PredL, LHS: NewOr,
3568 RHS: Constant::getNullValue(Ty: NewOr->getType()));
3569 }
3570
3571 // (icmp ne A, -1) | (icmp ne B, -1) --> (icmp ne (A&B), -1)
3572 // (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)
3573 if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
3574 PredL.dropSameSign() == PredR.dropSameSign() &&
3575 match(V: LHS1, P: m_AllOnes()) && match(V: RHS1, P: m_AllOnes()) &&
3576 LHS0->getType() == RHS0->getType() &&
3577 (!IsLogical || isGuaranteedNotToBePoison(V: RHS0))) {
3578 Value *NewAnd = Builder.CreateAnd(LHS: LHS0, RHS: RHS0);
3579 return Builder.CreateICmp(P: PredL, LHS: NewAnd,
3580 RHS: Constant::getAllOnesValue(Ty: LHS0->getType()));
3581 }
3582
3583 if (!IsLogical)
3584 if (Value *V = foldAndOrOfICmpsWithPow2AndWithZero(
3585 Builder, PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0, RHS1, RHSOneUse,
3586 IsAnd, Q))
3587 return V;
3588
3589 // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
3590 if (!LHSC || !RHSC)
3591 return nullptr;
3592
3593 // (trunc x) == C1 & (and x, CA) == C2 -> (and x, CA|CMAX) == C1|C2
3594 // (trunc x) != C1 | (and x, CA) != C2 -> (and x, CA|CMAX) != C1|C2
3595 // where CMAX is the all ones value for the truncated type,
3596 // iff the lower bits of C2 and CA are zero.
3597 if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
3598 PredL.dropSameSign() == PredR.dropSameSign() && LHSOneUse && RHSOneUse) {
3599 Value *V;
3600 const APInt *AndC, *SmallC = nullptr, *BigC = nullptr;
3601
3602 // (trunc x) == C1 & (and x, CA) == C2
3603 // (and x, CA) == C2 & (trunc x) == C1
3604 if (match(V: RHS0, P: m_Trunc(Op: m_Value(V))) &&
3605 match(V: LHS0, P: m_And(L: m_Specific(V), R: m_APInt(Res&: AndC)))) {
3606 SmallC = RHSC;
3607 BigC = LHSC;
3608 } else if (match(V: LHS0, P: m_Trunc(Op: m_Value(V))) &&
3609 match(V: RHS0, P: m_And(L: m_Specific(V), R: m_APInt(Res&: AndC)))) {
3610 SmallC = LHSC;
3611 BigC = RHSC;
3612 }
3613
3614 if (SmallC && BigC) {
3615 unsigned BigBitSize = BigC->getBitWidth();
3616 unsigned SmallBitSize = SmallC->getBitWidth();
3617
3618 // Check that the low bits are zero.
3619 APInt Low = APInt::getLowBitsSet(numBits: BigBitSize, loBitsSet: SmallBitSize);
3620 if ((Low & *AndC).isZero() && (Low & *BigC).isZero()) {
3621 Value *NewAnd = Builder.CreateAnd(LHS: V, RHS: Low | *AndC);
3622 APInt N = SmallC->zext(width: BigBitSize) | *BigC;
3623 Value *NewVal = ConstantInt::get(Ty: NewAnd->getType(), V: N);
3624 return Builder.CreateICmp(P: PredL, LHS: NewAnd, RHS: NewVal);
3625 }
3626 }
3627 }
3628
3629 // Match naive pattern (and its inverted form) for checking if two values
3630 // share same sign. An example of the pattern:
3631 // (icmp slt (X & Y), 0) | (icmp sgt (X | Y), -1) -> (icmp sgt (X ^ Y), -1)
3632 // Inverted form (example):
3633 // (icmp slt (X | Y), 0) & (icmp sgt (X & Y), -1) -> (icmp slt (X ^ Y), 0)
3634 bool TrueIfSignedL, TrueIfSignedR;
3635 if (isSignBitCheck(Pred: PredL, RHS: *LHSC, TrueIfSigned&: TrueIfSignedL) &&
3636 isSignBitCheck(Pred: PredR, RHS: *RHSC, TrueIfSigned&: TrueIfSignedR) &&
3637 (RHS->hasOneUse() || LHS->hasOneUse())) {
3638 Value *X, *Y;
3639 if (IsAnd) {
3640 if ((TrueIfSignedL && !TrueIfSignedR &&
3641 match(V: LHS0, P: m_Or(L: m_Value(V&: X), R: m_Value(V&: Y))) &&
3642 match(V: RHS0, P: m_c_And(L: m_Specific(V: X), R: m_Specific(V: Y)))) ||
3643 (!TrueIfSignedL && TrueIfSignedR &&
3644 match(V: LHS0, P: m_And(L: m_Value(V&: X), R: m_Value(V&: Y))) &&
3645 match(V: RHS0, P: m_c_Or(L: m_Specific(V: X), R: m_Specific(V: Y))))) {
3646 Value *NewXor = Builder.CreateXor(LHS: X, RHS: Y);
3647 return Builder.CreateIsNeg(Arg: NewXor);
3648 }
3649 } else {
3650 if ((TrueIfSignedL && !TrueIfSignedR &&
3651 match(V: LHS0, P: m_And(L: m_Value(V&: X), R: m_Value(V&: Y))) &&
3652 match(V: RHS0, P: m_c_Or(L: m_Specific(V: X), R: m_Specific(V: Y)))) ||
3653 (!TrueIfSignedL && TrueIfSignedR &&
3654 match(V: LHS0, P: m_Or(L: m_Value(V&: X), R: m_Value(V&: Y))) &&
3655 match(V: RHS0, P: m_c_And(L: m_Specific(V: X), R: m_Specific(V: Y))))) {
3656 Value *NewXor = Builder.CreateXor(LHS: X, RHS: Y);
3657 return Builder.CreateIsNotNeg(Arg: NewXor);
3658 }
3659 }
3660 }
3661
3662 // (X & ExpMask) != 0 && (X & ExpMask) != ExpMask -> isnormal(X)
3663 // (X & ExpMask) == 0 || (X & ExpMask) == ExpMask -> !isnormal(X)
3664 Value *X;
3665 const APInt *MaskC;
3666 if (LHS0 == RHS0 && PredL.dropSameSign() == PredR.dropSameSign() &&
3667 PredL == (IsAnd ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ) &&
3668 !I.getFunction()->hasFnAttribute(Kind: Attribute::NoImplicitFloat) &&
3669 LHSOneUse && RHSOneUse &&
3670 match(V: LHS0, P: m_And(L: m_ElementWiseBitCast(Op: m_Value(V&: X)), R: m_APInt(Res&: MaskC))) &&
3671 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3672 APFloat(X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3673 .isPosInfinity() &&
3674 ((LHSC->isZero() && *RHSC == *MaskC) ||
3675 (RHSC->isZero() && *LHSC == *MaskC)))
3676 return Builder.createIsFPClass(FPNum: X, Test: IsAnd ? FPClassTest::fcNormal
3677 : ~FPClassTest::fcNormal);
3678
3679 return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0,
3680 RHS1, RHSOneUse, IsAnd);
3681}
3682
3683/// If IsLogical is true, then the and/or is in select form and the transform
3684/// must be poison-safe.
3685Value *InstCombinerImpl::foldBooleanAndOr(Value *LHS, Value *RHS,
3686 Instruction &I, bool IsAnd,
3687 bool IsLogical) {
3688 if (!LHS->getType()->isIntOrIntVectorTy(BitWidth: 1))
3689 return nullptr;
3690
3691 // handle (roughly):
3692 // (icmp ne (A & B), C) | (icmp ne (A & D), E)
3693 // (icmp eq (A & B), C) & (icmp eq (A & D), E)
3694 if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, IsAnd, IsLogical, Builder,
3695 Q: SQ.getWithInstruction(I: &I)))
3696 return V;
3697
3698 if (Value *Res = foldAndOrOfICmps(LHS, RHS, I, IsAnd, IsLogical))
3699 return Res;
3700
3701 if (auto *LHSCmp = dyn_cast<FCmpInst>(Val: LHS))
3702 if (auto *RHSCmp = dyn_cast<FCmpInst>(Val: RHS))
3703 if (Value *Res = foldLogicOfFCmps(LHS: LHSCmp, RHS: RHSCmp, IsAnd, IsLogicalSelect: IsLogical))
3704 return Res;
3705
3706 if (Value *Res = foldEqOfParts(Cmp0: LHS, Cmp1: RHS, IsAnd))
3707 return Res;
3708
3709 return nullptr;
3710}
3711
3712static Value *foldOrOfInversions(BinaryOperator &I,
3713 InstCombiner::BuilderTy &Builder) {
3714 assert(I.getOpcode() == Instruction::Or &&
3715 "Simplification only supports or at the moment.");
3716
3717 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3718 if (!match(V: I.getOperand(i_nocapture: 0), P: m_And(L: m_Value(V&: Cmp1), R: m_Value(V&: Cmp2))) ||
3719 !match(V: I.getOperand(i_nocapture: 1), P: m_And(L: m_Value(V&: Cmp3), R: m_Value(V&: Cmp4))))
3720 return nullptr;
3721
3722 // Check if any two pairs of the and operations are inversions of each other.
3723 if (isKnownInversion(X: Cmp1, Y: Cmp3) && isKnownInversion(X: Cmp2, Y: Cmp4))
3724 return Builder.CreateXor(LHS: Cmp1, RHS: Cmp4);
3725 if (isKnownInversion(X: Cmp1, Y: Cmp4) && isKnownInversion(X: Cmp2, Y: Cmp3))
3726 return Builder.CreateXor(LHS: Cmp1, RHS: Cmp3);
3727
3728 return nullptr;
3729}
3730
3731/// Match \p V as "shufflevector -> bitcast" or "extractelement -> zext -> shl"
3732/// patterns, which extract vector elements and pack them in the same relative
3733/// positions.
3734///
3735/// \p Vec is the underlying vector being extracted from.
3736/// \p Mask is a bitmask identifying which packed elements are obtained from the
3737/// vector.
3738/// \p VecOffset is the vector element corresponding to index 0 of the
3739/// mask.
3740static bool matchSubIntegerPackFromVector(Value *V, Value *&Vec,
3741 int64_t &VecOffset,
3742 SmallBitVector &Mask,
3743 const DataLayout &DL) {
3744 // First try to match extractelement -> zext -> shl
3745 uint64_t VecIdx, ShlAmt;
3746 if (match(V, P: m_ShlOrSelf(L: m_ZExtOrSelf(Op: m_ExtractElt(Val: m_Value(V&: Vec),
3747 Idx: m_ConstantInt(V&: VecIdx))),
3748 R&: ShlAmt))) {
3749 auto *VecTy = dyn_cast<FixedVectorType>(Val: Vec->getType());
3750 if (!VecTy)
3751 return false;
3752 auto *EltTy = dyn_cast<IntegerType>(Val: VecTy->getElementType());
3753 if (!EltTy)
3754 return false;
3755
3756 const unsigned EltBitWidth = EltTy->getBitWidth();
3757 const unsigned TargetBitWidth = V->getType()->getIntegerBitWidth();
3758 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3759 return false;
3760 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3761 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3762
3763 const unsigned MaskIdx =
3764 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3765
3766 VecOffset = static_cast<int64_t>(VecIdx) - static_cast<int64_t>(MaskIdx);
3767 Mask.resize(N: TargetEltWidth);
3768 Mask.set(MaskIdx);
3769 return true;
3770 }
3771
3772 // Now try to match a bitcasted subvector.
3773 Instruction *SrcVecI;
3774 if (!match(V, P: m_BitCast(Op: m_Instruction(I&: SrcVecI))))
3775 return false;
3776
3777 auto *SrcTy = dyn_cast<FixedVectorType>(Val: SrcVecI->getType());
3778 if (!SrcTy)
3779 return false;
3780
3781 Mask.resize(N: SrcTy->getNumElements());
3782
3783 // First check for a subvector obtained from a shufflevector.
3784 if (isa<ShuffleVectorInst>(Val: SrcVecI)) {
3785 Constant *ConstVec;
3786 ArrayRef<int> ShuffleMask;
3787 if (!match(V: SrcVecI, P: m_Shuffle(v1: m_Value(V&: Vec), v2: m_Constant(C&: ConstVec),
3788 mask: m_Mask(ShuffleMask))))
3789 return false;
3790
3791 auto *VecTy = dyn_cast<FixedVectorType>(Val: Vec->getType());
3792 if (!VecTy)
3793 return false;
3794
3795 const unsigned NumVecElts = VecTy->getNumElements();
3796 bool FoundVecOffset = false;
3797 for (unsigned Idx = 0; Idx < ShuffleMask.size(); ++Idx) {
3798 if (ShuffleMask[Idx] == PoisonMaskElem)
3799 return false;
3800 const unsigned ShuffleIdx = ShuffleMask[Idx];
3801 if (ShuffleIdx >= NumVecElts) {
3802 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3803 auto *ConstElt =
3804 dyn_cast<ConstantInt>(Val: ConstVec->getAggregateElement(Elt: ConstIdx));
3805 if (!ConstElt || !ConstElt->isNullValue())
3806 return false;
3807 continue;
3808 }
3809
3810 if (FoundVecOffset) {
3811 if (VecOffset + Idx != ShuffleIdx)
3812 return false;
3813 } else {
3814 if (ShuffleIdx < Idx)
3815 return false;
3816 VecOffset = ShuffleIdx - Idx;
3817 FoundVecOffset = true;
3818 }
3819 Mask.set(Idx);
3820 }
3821 return FoundVecOffset;
3822 }
3823
3824 // Check for a subvector obtained as an (insertelement V, 0, idx)
3825 uint64_t InsertIdx;
3826 if (!match(V: SrcVecI,
3827 P: m_InsertElt(Val: m_Value(V&: Vec), Elt: m_Zero(), Idx: m_ConstantInt(V&: InsertIdx))))
3828 return false;
3829
3830 auto *VecTy = dyn_cast<FixedVectorType>(Val: Vec->getType());
3831 if (!VecTy)
3832 return false;
3833 VecOffset = 0;
3834 bool AlreadyInsertedMaskedElt = Mask.test(Idx: InsertIdx);
3835 Mask.set();
3836 if (!AlreadyInsertedMaskedElt)
3837 Mask.reset(Idx: InsertIdx);
3838 return true;
3839}
3840
3841/// Try to fold the join of two scalar integers whose contents are packed
3842/// elements of the same vector.
3843static Instruction *foldIntegerPackFromVector(Instruction &I,
3844 InstCombiner::BuilderTy &Builder,
3845 const DataLayout &DL) {
3846 assert(I.getOpcode() == Instruction::Or);
3847 Value *LhsVec, *RhsVec;
3848 int64_t LhsVecOffset, RhsVecOffset;
3849 SmallBitVector Mask;
3850 if (!matchSubIntegerPackFromVector(V: I.getOperand(i: 0), Vec&: LhsVec, VecOffset&: LhsVecOffset,
3851 Mask, DL))
3852 return nullptr;
3853 if (!matchSubIntegerPackFromVector(V: I.getOperand(i: 1), Vec&: RhsVec, VecOffset&: RhsVecOffset,
3854 Mask, DL))
3855 return nullptr;
3856 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3857 return nullptr;
3858
3859 // Convert into shufflevector -> bitcast;
3860 const unsigned ZeroVecIdx =
3861 cast<FixedVectorType>(Val: LhsVec->getType())->getNumElements();
3862 SmallVector<int> ShuffleMask(Mask.size(), ZeroVecIdx);
3863 for (unsigned Idx : Mask.set_bits()) {
3864 assert(LhsVecOffset + Idx >= 0);
3865 ShuffleMask[Idx] = LhsVecOffset + Idx;
3866 }
3867
3868 Value *MaskedVec = Builder.CreateShuffleVector(
3869 V1: LhsVec, V2: Constant::getNullValue(Ty: LhsVec->getType()), Mask: ShuffleMask,
3870 Name: I.getName() + ".v");
3871 return CastInst::Create(Instruction::BitCast, S: MaskedVec, Ty: I.getType());
3872}
3873
3874/// Match \p V as "lshr -> mask -> zext -> shl".
3875///
3876/// \p Int is the underlying integer being extracted from.
3877/// \p Mask is a bitmask identifying which bits of the integer are being
3878/// extracted. \p Offset identifies which bit of the result \p V corresponds to
3879/// the least significant bit of \p Int
3880static bool matchZExtedSubInteger(Value *V, Value *&Int, APInt &Mask,
3881 uint64_t &Offset, bool &IsShlNUW,
3882 bool &IsShlNSW) {
3883 Value *ShlOp0;
3884 uint64_t ShlAmt = 0;
3885 if (!match(V, P: m_OneUse(SubPattern: m_Shl(L: m_Value(V&: ShlOp0), R: m_ConstantInt(V&: ShlAmt)))))
3886 return false;
3887
3888 IsShlNUW = cast<BinaryOperator>(Val: V)->hasNoUnsignedWrap();
3889 IsShlNSW = cast<BinaryOperator>(Val: V)->hasNoSignedWrap();
3890
3891 Value *ZExtOp0;
3892 if (!match(V: ShlOp0, P: m_OneUse(SubPattern: m_ZExt(Op: m_Value(V&: ZExtOp0)))))
3893 return false;
3894
3895 Value *MaskedOp0;
3896 const APInt *ShiftedMaskConst = nullptr;
3897 if (!match(V: ZExtOp0, P: m_CombineOr(Ps: m_OneUse(SubPattern: m_And(L: m_Value(V&: MaskedOp0),
3898 R: m_APInt(Res&: ShiftedMaskConst))),
3899 Ps: m_Value(V&: MaskedOp0))))
3900 return false;
3901
3902 uint64_t LShrAmt = 0;
3903 if (!match(V: MaskedOp0,
3904 P: m_CombineOr(Ps: m_OneUse(SubPattern: m_LShr(L: m_Value(V&: Int), R: m_ConstantInt(V&: LShrAmt))),
3905 Ps: m_Value(V&: Int))))
3906 return false;
3907
3908 if (LShrAmt > ShlAmt)
3909 return false;
3910 Offset = ShlAmt - LShrAmt;
3911
3912 Mask = ShiftedMaskConst ? ShiftedMaskConst->shl(shiftAmt: LShrAmt)
3913 : APInt::getBitsSetFrom(
3914 numBits: Int->getType()->getScalarSizeInBits(), loBit: LShrAmt);
3915
3916 return true;
3917}
3918
3919/// Try to fold the join of two scalar integers whose bits are unpacked and
3920/// zexted from the same source integer.
3921static Value *foldIntegerRepackThroughZExt(Value *Lhs, Value *Rhs,
3922 InstCombiner::BuilderTy &Builder) {
3923
3924 Value *LhsInt, *RhsInt;
3925 APInt LhsMask, RhsMask;
3926 uint64_t LhsOffset, RhsOffset;
3927 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3928 if (!matchZExtedSubInteger(V: Lhs, Int&: LhsInt, Mask&: LhsMask, Offset&: LhsOffset, IsShlNUW&: IsLhsShlNUW,
3929 IsShlNSW&: IsLhsShlNSW))
3930 return nullptr;
3931 if (!matchZExtedSubInteger(V: Rhs, Int&: RhsInt, Mask&: RhsMask, Offset&: RhsOffset, IsShlNUW&: IsRhsShlNUW,
3932 IsShlNSW&: IsRhsShlNSW))
3933 return nullptr;
3934 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3935 return nullptr;
3936
3937 APInt Mask = LhsMask | RhsMask;
3938
3939 Type *DestTy = Lhs->getType();
3940 Value *Res = Builder.CreateShl(
3941 LHS: Builder.CreateZExt(
3942 V: Builder.CreateAnd(LHS: LhsInt, RHS: Mask, Name: LhsInt->getName() + ".mask"), DestTy,
3943 Name: LhsInt->getName() + ".zext"),
3944 RHS: ConstantInt::get(Ty: DestTy, V: LhsOffset), Name: "", HasNUW: IsLhsShlNUW && IsRhsShlNUW,
3945 HasNSW: IsLhsShlNSW && IsRhsShlNSW);
3946 Res->takeName(V: Lhs);
3947 return Res;
3948}
3949
3950// A decomposition of ((X & Mask) * Factor). The NUW / NSW bools
3951// track these properities for preservation. Note that we can decompose
3952// equivalent select form of this expression (e.g. (!(X & Mask) ? 0 : Mask *
3953// Factor))
3954struct DecomposedBitMaskMul {
3955 Value *X;
3956 APInt Factor;
3957 APInt Mask;
3958 bool NUW;
3959 bool NSW;
3960
3961 bool isCombineableWith(const DecomposedBitMaskMul Other) {
3962 return X == Other.X && !Mask.intersects(RHS: Other.Mask) &&
3963 Factor == Other.Factor;
3964 }
3965};
3966
3967static std::optional<DecomposedBitMaskMul> matchBitmaskMul(Value *V) {
3968 Instruction *Op = dyn_cast<Instruction>(Val: V);
3969 if (!Op)
3970 return std::nullopt;
3971
3972 // Decompose (A & N) * C) into BitMaskMul
3973 Value *Original = nullptr;
3974 const APInt *Mask = nullptr;
3975 const APInt *MulConst = nullptr;
3976 if (match(V: Op, P: m_Mul(L: m_And(L: m_Value(V&: Original), R: m_APInt(Res&: Mask)),
3977 R: m_APInt(Res&: MulConst)))) {
3978 if (MulConst->isZero() || Mask->isZero())
3979 return std::nullopt;
3980
3981 return std::optional<DecomposedBitMaskMul>(
3982 {.X: Original, .Factor: *MulConst, .Mask: *Mask,
3983 .NUW: cast<BinaryOperator>(Val: Op)->hasNoUnsignedWrap(),
3984 .NSW: cast<BinaryOperator>(Val: Op)->hasNoSignedWrap()});
3985 }
3986
3987 Value *Cond = nullptr;
3988 const APInt *EqZero = nullptr, *NeZero = nullptr;
3989
3990 // Decompose ((A & N) ? 0 : N * C) into BitMaskMul
3991 if (match(V: Op, P: m_Select(C: m_Value(V&: Cond), L: m_APInt(Res&: EqZero), R: m_APInt(Res&: NeZero)))) {
3992 auto ICmpDecompose =
3993 decomposeBitTest(Cond, /*LookThroughTrunc=*/true,
3994 /*AllowNonZeroC=*/false, /*DecomposeBitMask=*/DecomposeAnd: true);
3995 if (!ICmpDecompose.has_value())
3996 return std::nullopt;
3997
3998 // decomposeBitTest may provide a scalar bit test for a vector select.
3999 // Ensure the types match.
4000 if (ICmpDecompose->X->getType() != V->getType())
4001 return std::nullopt;
4002
4003 assert(ICmpInst::isEquality(ICmpDecompose->Pred) &&
4004 ICmpDecompose->C.isZero());
4005
4006 if (ICmpDecompose->Pred == ICmpInst::ICMP_NE)
4007 std::swap(a&: EqZero, b&: NeZero);
4008
4009 if (!EqZero->isZero() || NeZero->isZero())
4010 return std::nullopt;
4011
4012 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero())
4013 return std::nullopt;
4014
4015 if (!NeZero->urem(RHS: ICmpDecompose->Mask).isZero())
4016 return std::nullopt;
4017
4018 return std::optional<DecomposedBitMaskMul>(
4019 {.X: ICmpDecompose->X, .Factor: NeZero->udiv(RHS: ICmpDecompose->Mask),
4020 .Mask: ICmpDecompose->Mask, /*NUW=*/false, /*NSW=*/false});
4021 }
4022
4023 return std::nullopt;
4024}
4025
4026/// (A & N) * C + (A & M) * C -> (A & (N + M)) & C
4027/// This also accepts the equivalent select form of (A & N) * C
4028/// expressions i.e. !(A & N) ? 0 : N * C)
4029static Value *foldBitmaskMul(Value *Op0, Value *Op1,
4030 InstCombiner::BuilderTy &Builder) {
4031 auto Decomp1 = matchBitmaskMul(V: Op1);
4032 if (!Decomp1)
4033 return nullptr;
4034
4035 auto Decomp0 = matchBitmaskMul(V: Op0);
4036 if (!Decomp0)
4037 return nullptr;
4038
4039 if (Decomp0->isCombineableWith(Other: *Decomp1)) {
4040 Value *NewAnd = Builder.CreateAnd(
4041 LHS: Decomp0->X,
4042 RHS: ConstantInt::get(Ty: Decomp0->X->getType(), V: Decomp0->Mask + Decomp1->Mask));
4043
4044 return Builder.CreateMul(
4045 LHS: NewAnd, RHS: ConstantInt::get(Ty: NewAnd->getType(), V: Decomp1->Factor), Name: "",
4046 HasNUW: Decomp0->NUW && Decomp1->NUW, HasNSW: Decomp0->NSW && Decomp1->NSW);
4047 }
4048
4049 return nullptr;
4050}
4051
4052Value *InstCombinerImpl::foldDisjointOr(Value *LHS, Value *RHS) {
4053 if (Value *Res = foldBitmaskMul(Op0: LHS, Op1: RHS, Builder))
4054 return Res;
4055 if (Value *Res = foldIntegerRepackThroughZExt(Lhs: LHS, Rhs: RHS, Builder))
4056 return Res;
4057
4058 return nullptr;
4059}
4060
4061Value *InstCombinerImpl::reassociateDisjointOr(Value *LHS, Value *RHS) {
4062
4063 Value *X, *Y;
4064 if (match(V: RHS, P: m_OneUse(SubPattern: m_DisjointOr(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
4065 if (Value *Res = foldDisjointOr(LHS, RHS: X))
4066 return Builder.CreateDisjointOr(LHS: Res, RHS: Y);
4067 if (Value *Res = foldDisjointOr(LHS, RHS: Y))
4068 return Builder.CreateDisjointOr(LHS: Res, RHS: X);
4069 }
4070
4071 if (match(V: LHS, P: m_OneUse(SubPattern: m_DisjointOr(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
4072 if (Value *Res = foldDisjointOr(LHS: X, RHS))
4073 return Builder.CreateDisjointOr(LHS: Res, RHS: Y);
4074 if (Value *Res = foldDisjointOr(LHS: Y, RHS))
4075 return Builder.CreateDisjointOr(LHS: Res, RHS: X);
4076 }
4077
4078 return nullptr;
4079}
4080
4081/// Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2))
4082/// --> (ugt x (c2/c1)). This code checks whether a multiplication of two
4083/// unsigned numbers (one is a constant) is mathematically greater than a
4084/// second constant.
4085static Value *foldOrUnsignedUMulOverflowICmp(BinaryOperator &I,
4086 InstCombiner::BuilderTy &Builder,
4087 const DataLayout &DL) {
4088 Value *WOV, *X;
4089 const APInt *C1, *C2;
4090 if (match(V: &I,
4091 P: m_c_Or(L: m_ExtractValue<1>(
4092 V: m_Value(V&: WOV, P: m_Intrinsic<Intrinsic::umul_with_overflow>(
4093 Ops: m_Value(V&: X), Ops: m_APInt(Res&: C1)))),
4094 R: m_OneUse(SubPattern: m_SpecificCmp(MatchPred: ICmpInst::ICMP_UGT,
4095 L: m_ExtractValue<0>(V: m_Deferred(V: WOV)),
4096 R: m_APInt(Res&: C2))))) &&
4097 !C1->isZero()) {
4098 Constant *NewC = ConstantInt::get(Ty: X->getType(), V: C2->udiv(RHS: *C1));
4099 return Builder.CreateICmp(P: ICmpInst::ICMP_UGT, LHS: X, RHS: NewC);
4100 }
4101 return nullptr;
4102}
4103
4104/// Fold select(X >s 0, 0, -X) | smax(X, 0) --> abs(X)
4105/// select(X <s 0, -X, 0) | smax(X, 0) --> abs(X)
4106static Value *FoldOrOfSelectSmaxToAbs(BinaryOperator &I,
4107 InstCombiner::BuilderTy &Builder) {
4108 Value *X;
4109 Value *Sel;
4110 if (match(V: &I,
4111 P: m_c_Or(L: m_Value(V&: Sel), R: m_OneUse(SubPattern: m_SMax(Op0: m_Value(V&: X), Op1: m_ZeroInt()))))) {
4112 auto NegX = m_Neg(V: m_Specific(V: X));
4113 if (match(V: Sel, P: m_Select(C: m_SpecificICmp(MatchPred: ICmpInst::ICMP_SGT, L: m_Specific(V: X),
4114 R: m_ZeroInt()),
4115 L: m_ZeroInt(), R: NegX)) ||
4116 match(V: Sel, P: m_Select(C: m_SpecificICmp(MatchPred: ICmpInst::ICMP_SLT, L: m_Specific(V: X),
4117 R: m_ZeroInt()),
4118 L: NegX, R: m_ZeroInt())))
4119 return Builder.CreateBinaryIntrinsic(ID: Intrinsic::abs, LHS: X,
4120 RHS: Builder.getFalse());
4121 }
4122 return nullptr;
4123}
4124
4125Instruction *InstCombinerImpl::FoldOrOfLogicalAnds(Value *Op0, Value *Op1) {
4126 Value *C, *A, *B;
4127 // (C && A) || (!C && B)
4128 // (C && A) || (B && !C)
4129 // (A && C) || (!C && B)
4130 // (A && C) || (B && !C) (may require freeze)
4131 //
4132 // => select C, A, B
4133 if (match(V: Op1, P: m_c_LogicalAnd(L: m_Not(V: m_Value(V&: C)), R: m_Value(V&: B))) &&
4134 match(V: Op0, P: m_c_LogicalAnd(L: m_Specific(V: C), R: m_Value(V&: A)))) {
4135 auto *SelOp0 = dyn_cast<SelectInst>(Val: Op0);
4136 auto *SelOp1 = dyn_cast<SelectInst>(Val: Op1);
4137
4138 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4139 match(V: SelOp1->getTrueValue(),
4140 P: m_Not(V: m_Specific(V: SelOp0->getTrueValue())));
4141 if (MayNeedFreeze)
4142 C = Builder.CreateFreeze(V: C);
4143 if (!ProfcheckDisableMetadataFixes) {
4144 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
4145 if (match(V: Op0, P: m_LogicalAnd(L: m_Specific(V: C), R: m_Value(V&: A2))) && SelOp0) {
4146 return SelectInst::Create(C, S1: A, S2: B, NameStr: "", InsertBefore: nullptr, MDFrom: SelOp0);
4147 } else if (match(V: Op1, P: m_LogicalAnd(L: m_Not(V: m_Value(V&: C2)), R: m_Value(V&: B2))) &&
4148 SelOp1) {
4149 SelectInst *NewSI = SelectInst::Create(C, S1: A, S2: B, NameStr: "", InsertBefore: nullptr, MDFrom: SelOp1);
4150 NewSI->swapProfMetadata();
4151 return NewSI;
4152 } else {
4153 return createSelectInstWithUnknownProfile(C, S1: A, S2: B);
4154 }
4155 }
4156 return SelectInst::Create(C, S1: A, S2: B);
4157 }
4158
4159 // (!C && A) || (C && B)
4160 // (A && !C) || (C && B)
4161 // (!C && A) || (B && C)
4162 // (A && !C) || (B && C) (may require freeze)
4163 //
4164 // => select C, B, A
4165 if (match(V: Op0, P: m_c_LogicalAnd(L: m_Not(V: m_Value(V&: C)), R: m_Value(V&: A))) &&
4166 match(V: Op1, P: m_c_LogicalAnd(L: m_Specific(V: C), R: m_Value(V&: B)))) {
4167 auto *SelOp0 = dyn_cast<SelectInst>(Val: Op0);
4168 auto *SelOp1 = dyn_cast<SelectInst>(Val: Op1);
4169 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4170 match(V: SelOp0->getTrueValue(),
4171 P: m_Not(V: m_Specific(V: SelOp1->getTrueValue())));
4172 if (MayNeedFreeze)
4173 C = Builder.CreateFreeze(V: C);
4174 if (!ProfcheckDisableMetadataFixes) {
4175 Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
4176 if (match(V: Op0, P: m_LogicalAnd(L: m_Not(V: m_Value(V&: C2)), R: m_Value(V&: A2))) && SelOp0) {
4177 SelectInst *NewSI = SelectInst::Create(C, S1: B, S2: A, NameStr: "", InsertBefore: nullptr, MDFrom: SelOp0);
4178 NewSI->swapProfMetadata();
4179 return NewSI;
4180 } else if (match(V: Op1, P: m_LogicalAnd(L: m_Specific(V: C), R: m_Value(V&: B2))) &&
4181 SelOp1) {
4182 return SelectInst::Create(C, S1: B, S2: A, NameStr: "", InsertBefore: nullptr, MDFrom: SelOp1);
4183 } else {
4184 return createSelectInstWithUnknownProfile(C, S1: B, S2: A);
4185 }
4186 }
4187 return SelectInst::Create(C, S1: B, S2: A);
4188 }
4189
4190 return nullptr;
4191}
4192
4193// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
4194// here. We should standardize that construct where it is needed or choose some
4195// other way to ensure that commutated variants of patterns are not missed.
4196Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
4197 if (Value *V = simplifyOrInst(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1),
4198 Q: SQ.getWithInstruction(I: &I)))
4199 return replaceInstUsesWith(I, V);
4200
4201 if (SimplifyAssociativeOrCommutative(I))
4202 return &I;
4203
4204 if (Instruction *X = foldVectorBinop(Inst&: I))
4205 return X;
4206
4207 if (Instruction *Phi = foldBinopWithPhiOperands(BO&: I))
4208 return Phi;
4209
4210 // See if we can simplify any instructions used by the instruction whose sole
4211 // purpose is to compute bits we don't care about.
4212 if (SimplifyDemandedInstructionBits(Inst&: I))
4213 return &I;
4214
4215 // Do this before using distributive laws to catch simple and/or/not patterns.
4216 if (Instruction *Xor = foldOrToXor(I, Builder))
4217 return Xor;
4218
4219 if (Instruction *X = foldComplexAndOrPatterns(I, Builder))
4220 return X;
4221
4222 if (Instruction *X = foldIntegerPackFromVector(I, Builder, DL))
4223 return X;
4224
4225 // (A & B) | (C & D) -> A ^ D where A == ~C && B == ~D
4226 // (A & B) | (C & D) -> A ^ C where A == ~D && B == ~C
4227 if (Value *V = foldOrOfInversions(I, Builder))
4228 return replaceInstUsesWith(I, V);
4229
4230 // (A&B)|(A&C) -> A&(B|C) etc
4231 if (Value *V = foldUsingDistributiveLaws(I))
4232 return replaceInstUsesWith(I, V);
4233
4234 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
4235 Type *Ty = I.getType();
4236 if (Ty->isIntOrIntVectorTy(BitWidth: 1)) {
4237 if (auto *SI0 = dyn_cast<SelectInst>(Val: Op0)) {
4238 if (auto *R =
4239 foldAndOrOfSelectUsingImpliedCond(Op: Op1, SI&: *SI0, /* IsAnd */ false))
4240 return R;
4241 }
4242 if (auto *SI1 = dyn_cast<SelectInst>(Val: Op1)) {
4243 if (auto *R =
4244 foldAndOrOfSelectUsingImpliedCond(Op: Op0, SI&: *SI1, /* IsAnd */ false))
4245 return R;
4246 }
4247 }
4248
4249 if (Instruction *FoldedLogic = foldBinOpIntoSelectOrPhi(I))
4250 return FoldedLogic;
4251
4252 if (Instruction *FoldedLogic = foldBinOpSelectBinOp(Op&: I))
4253 return FoldedLogic;
4254
4255 if (Instruction *BitOp = matchBSwapOrBitReverse(I, /*MatchBSwaps*/ true,
4256 /*MatchBitReversals*/ true))
4257 return BitOp;
4258
4259 if (Instruction *Funnel = matchFunnelShift(Or&: I, IC&: *this))
4260 return Funnel;
4261
4262 if (Value *Concat = matchOrConcat(Or&: I, Builder))
4263 return replaceInstUsesWith(I, V: Concat);
4264
4265 if (Instruction *R = foldBinOpShiftWithShift(I))
4266 return R;
4267
4268 if (Instruction *R = tryFoldInstWithCtpopWithNot(I: &I))
4269 return R;
4270
4271 if (cast<PossiblyDisjointInst>(Val&: I).isDisjoint()) {
4272 if (Instruction *R =
4273 foldAddLikeCommutative(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1),
4274 /*NSW=*/true, /*NUW=*/true))
4275 return R;
4276 if (Instruction *R =
4277 foldAddLikeCommutative(LHS: I.getOperand(i_nocapture: 1), RHS: I.getOperand(i_nocapture: 0),
4278 /*NSW=*/true, /*NUW=*/true))
4279 return R;
4280
4281 if (Value *Res = foldDisjointOr(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1)))
4282 return replaceInstUsesWith(I, V: Res);
4283
4284 if (Value *Res = reassociateDisjointOr(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1)))
4285 return replaceInstUsesWith(I, V: Res);
4286 }
4287
4288 Value *X, *Y;
4289 const APInt *CV;
4290 if (match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: X), R: m_APInt(Res&: CV))), R: m_Value(V&: Y))) &&
4291 !CV->isAllOnes() && MaskedValueIsZero(V: Y, Mask: *CV, CxtI: &I)) {
4292 // (X ^ C) | Y -> (X | Y) ^ C iff Y & C == 0
4293 // The check for a 'not' op is for efficiency (if Y is known zero --> ~X).
4294 Value *Or = Builder.CreateOr(LHS: X, RHS: Y);
4295 return BinaryOperator::CreateXor(V1: Or, V2: ConstantInt::get(Ty, V: *CV));
4296 }
4297
4298 // If the operands have no common bits set:
4299 // or (mul X, Y), X --> add (mul X, Y), X --> mul X, (Y + 1)
4300 if (match(V: &I, P: m_c_DisjointOr(L: m_OneUse(SubPattern: m_Mul(L: m_Value(V&: X), R: m_Value(V&: Y))),
4301 R: m_Deferred(V: X)))) {
4302 Value *IncrementY = Builder.CreateAdd(LHS: Y, RHS: ConstantInt::get(Ty, V: 1));
4303 return BinaryOperator::CreateMul(V1: X, V2: IncrementY);
4304 }
4305
4306 // Canonicalization to achieve lowering to Bit Manipulation Instructions (BMI)
4307 // ~X | (X-1) => ~(X & -X)
4308 Value *Op;
4309 if (match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_Not(V: m_Value(V&: Op))),
4310 R: m_OneUse(SubPattern: m_Add(L: m_Deferred(V: Op), R: m_AllOnes()))))) {
4311 Value *NegX = Builder.CreateNeg(V: Op);
4312 Value *And = Builder.CreateAnd(LHS: Op, RHS: NegX);
4313 return BinaryOperator::CreateNot(Op: And);
4314 }
4315
4316 // (C && A) || (C && B) => select C, A, B (and similar cases)
4317 //
4318 // Note: This is the same transformation used in `foldSelectOfBools`,
4319 // except that it's an `or` instead of `select`.
4320 if (I.getType()->isIntOrIntVectorTy(BitWidth: 1) &&
4321 (Op0->hasOneUse() || Op1->hasOneUse())) {
4322 if (Instruction *V = FoldOrOfLogicalAnds(Op0, Op1)) {
4323 return V;
4324 }
4325 }
4326
4327 // (A & C) | (B & D)
4328 Value *A, *B, *C, *D;
4329 if (match(V: Op0, P: m_And(L: m_Value(V&: A), R: m_Value(V&: C))) &&
4330 match(V: Op1, P: m_And(L: m_Value(V&: B), R: m_Value(V&: D)))) {
4331
4332 // (A & C0) | (B & C1)
4333 const APInt *C0, *C1;
4334 if (match(V: C, P: m_APInt(Res&: C0)) && match(V: D, P: m_APInt(Res&: C1))) {
4335 Value *X;
4336 if (*C0 == ~*C1) {
4337 // ((X | B) & MaskC) | (B & ~MaskC) -> (X & MaskC) | B
4338 if (match(V: A, P: m_c_Or(L: m_Value(V&: X), R: m_Specific(V: B))))
4339 return BinaryOperator::CreateOr(V1: Builder.CreateAnd(LHS: X, RHS: *C0), V2: B);
4340 // (A & MaskC) | ((X | A) & ~MaskC) -> (X & ~MaskC) | A
4341 if (match(V: B, P: m_c_Or(L: m_Specific(V: A), R: m_Value(V&: X))))
4342 return BinaryOperator::CreateOr(V1: Builder.CreateAnd(LHS: X, RHS: *C1), V2: A);
4343
4344 // ((X ^ B) & MaskC) | (B & ~MaskC) -> (X & MaskC) ^ B
4345 if (match(V: A, P: m_c_Xor(L: m_Value(V&: X), R: m_Specific(V: B))))
4346 return BinaryOperator::CreateXor(V1: Builder.CreateAnd(LHS: X, RHS: *C0), V2: B);
4347 // (A & MaskC) | ((X ^ A) & ~MaskC) -> (X & ~MaskC) ^ A
4348 if (match(V: B, P: m_c_Xor(L: m_Specific(V: A), R: m_Value(V&: X))))
4349 return BinaryOperator::CreateXor(V1: Builder.CreateAnd(LHS: X, RHS: *C1), V2: A);
4350 }
4351
4352 if ((*C0 & *C1).isZero()) {
4353 // ((X | B) & C0) | (B & C1) --> (X | B) & (C0 | C1)
4354 // iff (C0 & C1) == 0 and (X & ~C0) == 0
4355 if (match(V: A, P: m_c_Or(L: m_Value(V&: X), R: m_Specific(V: B))) &&
4356 MaskedValueIsZero(V: X, Mask: ~*C0, CxtI: &I)) {
4357 Constant *C01 = ConstantInt::get(Ty, V: *C0 | *C1);
4358 return BinaryOperator::CreateAnd(V1: A, V2: C01);
4359 }
4360 // (A & C0) | ((X | A) & C1) --> (X | A) & (C0 | C1)
4361 // iff (C0 & C1) == 0 and (X & ~C1) == 0
4362 if (match(V: B, P: m_c_Or(L: m_Value(V&: X), R: m_Specific(V: A))) &&
4363 MaskedValueIsZero(V: X, Mask: ~*C1, CxtI: &I)) {
4364 Constant *C01 = ConstantInt::get(Ty, V: *C0 | *C1);
4365 return BinaryOperator::CreateAnd(V1: B, V2: C01);
4366 }
4367 // ((X | C2) & C0) | ((X | C3) & C1) --> (X | C2 | C3) & (C0 | C1)
4368 // iff (C0 & C1) == 0 and (C2 & ~C0) == 0 and (C3 & ~C1) == 0.
4369 const APInt *C2, *C3;
4370 if (match(V: A, P: m_Or(L: m_Value(V&: X), R: m_APInt(Res&: C2))) &&
4371 match(V: B, P: m_Or(L: m_Specific(V: X), R: m_APInt(Res&: C3))) &&
4372 (*C2 & ~*C0).isZero() && (*C3 & ~*C1).isZero()) {
4373 Value *Or = Builder.CreateOr(LHS: X, RHS: *C2 | *C3, Name: "bitfield");
4374 Constant *C01 = ConstantInt::get(Ty, V: *C0 | *C1);
4375 return BinaryOperator::CreateAnd(V1: Or, V2: C01);
4376 }
4377 }
4378
4379 // ((trunc (lshr X, S)) & C0) | ((lshr (trunc X), S) & C1)
4380 // --> ((trunc (lshr X, S)) & (C0 | C1)) (and similar cases)
4381 // A = trunc (lshr X, S) B = lshr (trunc X), S
4382 const APInt *ShiftAmt;
4383 if (match(V: A, P: m_Trunc(Op: m_LShr(L: m_Value(V&: X), R: m_APInt(Res&: ShiftAmt)))) &&
4384 match(V: B, P: m_LShr(L: m_Trunc(Op: m_Specific(V: X)), R: m_SpecificInt(V: *ShiftAmt))) &&
4385 ShiftAmt->ult(RHS: A->getType()->getScalarSizeInBits()) &&
4386 C1->isIntN(N: A->getType()->getScalarSizeInBits() -
4387 ShiftAmt->getZExtValue())) {
4388 return BinaryOperator::CreateAnd(
4389 V1: A, V2: ConstantInt::get(Ty: I.getType(), V: *C0 | *C1));
4390 }
4391 // A = lshr (trunc X), S
4392 // B = trunc (lshr X, S)
4393 if (match(V: B, P: m_Trunc(Op: m_LShr(L: m_Value(V&: X), R: m_APInt(Res&: ShiftAmt)))) &&
4394 match(V: A, P: m_LShr(L: m_Trunc(Op: m_Specific(V: X)), R: m_SpecificInt(V: *ShiftAmt))) &&
4395 ShiftAmt->ult(RHS: A->getType()->getScalarSizeInBits()) &&
4396 C0->isIntN(N: A->getType()->getScalarSizeInBits() -
4397 ShiftAmt->getZExtValue())) {
4398 return BinaryOperator::CreateAnd(
4399 V1: B, V2: ConstantInt::get(Ty: I.getType(), V: *C0 | *C1));
4400 }
4401 }
4402
4403 // Don't try to form a select if it's unlikely that we'll get rid of at
4404 // least one of the operands. A select is generally more expensive than the
4405 // 'or' that it is replacing.
4406 if (Op0->hasOneUse() || Op1->hasOneUse()) {
4407 // (Cond & C) | (~Cond & D) -> Cond ? C : D, and commuted variants.
4408 if (Value *V = matchSelectFromAndOr(A, B: C, C: B, D))
4409 return replaceInstUsesWith(I, V);
4410 if (Value *V = matchSelectFromAndOr(A, B: C, C: D, D: B))
4411 return replaceInstUsesWith(I, V);
4412 if (Value *V = matchSelectFromAndOr(A: C, B: A, C: B, D))
4413 return replaceInstUsesWith(I, V);
4414 if (Value *V = matchSelectFromAndOr(A: C, B: A, C: D, D: B))
4415 return replaceInstUsesWith(I, V);
4416 if (Value *V = matchSelectFromAndOr(A: B, B: D, C: A, D: C))
4417 return replaceInstUsesWith(I, V);
4418 if (Value *V = matchSelectFromAndOr(A: B, B: D, C, D: A))
4419 return replaceInstUsesWith(I, V);
4420 if (Value *V = matchSelectFromAndOr(A: D, B, C: A, D: C))
4421 return replaceInstUsesWith(I, V);
4422 if (Value *V = matchSelectFromAndOr(A: D, B, C, D: A))
4423 return replaceInstUsesWith(I, V);
4424 }
4425 }
4426
4427 if (match(V: Op0, P: m_And(L: m_Value(V&: A), R: m_Value(V&: C))) &&
4428 match(V: Op1, P: m_Not(V: m_Or(L: m_Value(V&: B), R: m_Value(V&: D)))) &&
4429 (Op0->hasOneUse() || Op1->hasOneUse())) {
4430 // (Cond & C) | ~(Cond | D) -> Cond ? C : ~D
4431 if (Value *V = matchSelectFromAndOr(A, B: C, C: B, D, InvertFalseVal: true))
4432 return replaceInstUsesWith(I, V);
4433 if (Value *V = matchSelectFromAndOr(A, B: C, C: D, D: B, InvertFalseVal: true))
4434 return replaceInstUsesWith(I, V);
4435 if (Value *V = matchSelectFromAndOr(A: C, B: A, C: B, D, InvertFalseVal: true))
4436 return replaceInstUsesWith(I, V);
4437 if (Value *V = matchSelectFromAndOr(A: C, B: A, C: D, D: B, InvertFalseVal: true))
4438 return replaceInstUsesWith(I, V);
4439 }
4440
4441 // (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C
4442 if (match(V: Op0, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))))
4443 if (match(V: Op1,
4444 P: m_c_Xor(L: m_c_Xor(L: m_Specific(V: B), R: m_Value(V&: C)), R: m_Specific(V: A))) ||
4445 match(V: Op1, P: m_c_Xor(L: m_c_Xor(L: m_Specific(V: A), R: m_Value(V&: C)), R: m_Specific(V: B))))
4446 return BinaryOperator::CreateOr(V1: Op0, V2: C);
4447
4448 // ((B ^ C) ^ A) | (A ^ B) -> (A ^ B) | C
4449 if (match(V: Op1, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))))
4450 if (match(V: Op0,
4451 P: m_c_Xor(L: m_c_Xor(L: m_Specific(V: B), R: m_Value(V&: C)), R: m_Specific(V: A))) ||
4452 match(V: Op0, P: m_c_Xor(L: m_c_Xor(L: m_Specific(V: A), R: m_Value(V&: C)), R: m_Specific(V: B))))
4453 return BinaryOperator::CreateOr(V1: Op1, V2: C);
4454
4455 if (Instruction *DeMorgan = matchDeMorgansLaws(I, IC&: *this))
4456 return DeMorgan;
4457
4458 // Canonicalize xor to the RHS.
4459 bool SwappedForXor = false;
4460 if (match(V: Op0, P: m_Xor(L: m_Value(), R: m_Value()))) {
4461 std::swap(a&: Op0, b&: Op1);
4462 SwappedForXor = true;
4463 }
4464
4465 if (match(V: Op1, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B)))) {
4466 // (A | ?) | (A ^ B) --> (A | ?) | B
4467 // (B | ?) | (A ^ B) --> (B | ?) | A
4468 if (match(V: Op0, P: m_c_Or(L: m_Specific(V: A), R: m_Value())))
4469 return BinaryOperator::CreateOr(V1: Op0, V2: B);
4470 if (match(V: Op0, P: m_c_Or(L: m_Specific(V: B), R: m_Value())))
4471 return BinaryOperator::CreateOr(V1: Op0, V2: A);
4472
4473 // (A & B) | (A ^ B) --> A | B
4474 // (B & A) | (A ^ B) --> A | B
4475 if (match(V: Op0, P: m_c_And(L: m_Specific(V: A), R: m_Specific(V: B))))
4476 return BinaryOperator::CreateOr(V1: A, V2: B);
4477
4478 // ~A | (A ^ B) --> ~(A & B)
4479 // ~B | (A ^ B) --> ~(A & B)
4480 // The swap above should always make Op0 the 'not'.
4481 if ((Op0->hasOneUse() || Op1->hasOneUse()) &&
4482 (match(V: Op0, P: m_Not(V: m_Specific(V: A))) || match(V: Op0, P: m_Not(V: m_Specific(V: B)))))
4483 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: A, RHS: B));
4484
4485 // Same as above, but peek through an 'and' to the common operand:
4486 // ~(A & ?) | (A ^ B) --> ~((A & ?) & B)
4487 // ~(B & ?) | (A ^ B) --> ~((B & ?) & A)
4488 Instruction *And;
4489 if ((Op0->hasOneUse() || Op1->hasOneUse()) &&
4490 match(V: Op0,
4491 P: m_Not(V: m_Instruction(I&: And, P: m_c_And(L: m_Specific(V: A), R: m_Value())))))
4492 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: And, RHS: B));
4493 if ((Op0->hasOneUse() || Op1->hasOneUse()) &&
4494 match(V: Op0,
4495 P: m_Not(V: m_Instruction(I&: And, P: m_c_And(L: m_Specific(V: B), R: m_Value())))))
4496 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: And, RHS: A));
4497
4498 // (~A | C) | (A ^ B) --> ~(A & B) | C
4499 // (~B | C) | (A ^ B) --> ~(A & B) | C
4500 if (Op0->hasOneUse() && Op1->hasOneUse() &&
4501 (match(V: Op0, P: m_c_Or(L: m_Not(V: m_Specific(V: A)), R: m_Value(V&: C))) ||
4502 match(V: Op0, P: m_c_Or(L: m_Not(V: m_Specific(V: B)), R: m_Value(V&: C))))) {
4503 Value *Nand = Builder.CreateNot(V: Builder.CreateAnd(LHS: A, RHS: B), Name: "nand");
4504 return BinaryOperator::CreateOr(V1: Nand, V2: C);
4505 }
4506 }
4507
4508 if (SwappedForXor)
4509 std::swap(a&: Op0, b&: Op1);
4510
4511 if (Value *Res =
4512 foldBooleanAndOr(LHS: Op0, RHS: Op1, I, /*IsAnd=*/false, /*IsLogical=*/false))
4513 return replaceInstUsesWith(I, V: Res);
4514
4515 if (match(V: Op1, P: m_OneUse(SubPattern: m_LogicalOr(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
4516 bool IsLogical = isa<SelectInst>(Val: Op1);
4517 if (auto *V = reassociateBooleanAndOr(LHS: Op0, X, Y, I, /*IsAnd=*/false,
4518 /*RHSIsLogical=*/IsLogical))
4519 return replaceInstUsesWith(I, V);
4520 }
4521 if (match(V: Op0, P: m_OneUse(SubPattern: m_LogicalOr(L: m_Value(V&: X), R: m_Value(V&: Y))))) {
4522 bool IsLogical = isa<SelectInst>(Val: Op0);
4523 if (auto *V = reassociateBooleanAndOr(LHS: Op1, X, Y, I, /*IsAnd=*/false,
4524 /*RHSIsLogical=*/IsLogical))
4525 return replaceInstUsesWith(I, V);
4526 }
4527
4528 if (Instruction *FoldedFCmps = reassociateFCmps(BO&: I, Builder))
4529 return FoldedFCmps;
4530
4531 if (Instruction *CastedOr = foldCastedBitwiseLogic(I))
4532 return CastedOr;
4533
4534 if (Instruction *Sel = foldBinopOfSextBoolToSelect(I))
4535 return Sel;
4536
4537 // or(sext(A), B) / or(B, sext(A)) --> A ? -1 : B, where A is i1 or <N x i1>.
4538 // TODO: Move this into foldBinopOfSextBoolToSelect as a more generalized fold
4539 // with binop identity constant. But creating a select with non-constant
4540 // arm may not be reversible due to poison semantics. Is that a good
4541 // canonicalization?
4542 if (match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_SExt(Op: m_Value(V&: A))), R: m_Value(V&: B))) &&
4543 A->getType()->isIntOrIntVectorTy(BitWidth: 1))
4544 return createSelectInstWithUnknownProfile(
4545 C: A, S1: ConstantInt::getAllOnesValue(Ty), S2: B);
4546
4547 // Note: If we've gotten to the point of visiting the outer OR, then the
4548 // inner one couldn't be simplified. If it was a constant, then it won't
4549 // be simplified by a later pass either, so we try swapping the inner/outer
4550 // ORs in the hopes that we'll be able to simplify it this way.
4551 // (X|C) | V --> (X|V) | C
4552 // Pass the disjoint flag in the following two patterns:
4553 // 1. or-disjoint (or-disjoint X, C), V -->
4554 // or-disjoint (or-disjoint X, V), C
4555 //
4556 // 2. or-disjoint (or X, C), V -->
4557 // or (or-disjoint X, V), C
4558 ConstantInt *CI;
4559 if (Op0->hasOneUse() && !match(V: Op1, P: m_ConstantInt()) &&
4560 match(V: Op0, P: m_Or(L: m_Value(V&: A), R: m_ConstantInt(CI)))) {
4561 bool IsDisjointOuter = cast<PossiblyDisjointInst>(Val&: I).isDisjoint();
4562 bool IsDisjointInner = cast<PossiblyDisjointInst>(Val: Op0)->isDisjoint();
4563 Value *Inner = Builder.CreateOr(LHS: A, RHS: Op1, Name: "", /*IsDisjoint=*/IsDisjointOuter);
4564 Inner->takeName(V: Op0);
4565 return IsDisjointOuter && IsDisjointInner
4566 ? BinaryOperator::CreateDisjointOr(V1: Inner, V2: CI)
4567 : BinaryOperator::CreateOr(V1: Inner, V2: CI);
4568 }
4569
4570 // Change (or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D))
4571 // Since this OR statement hasn't been optimized further yet, we hope
4572 // that this transformation will allow the new ORs to be optimized.
4573 {
4574 Value *X = nullptr, *Y = nullptr;
4575 if (Op0->hasOneUse() && Op1->hasOneUse() &&
4576 match(V: Op0, P: m_Select(C: m_Value(V&: X), L: m_Value(V&: A), R: m_Value(V&: B))) &&
4577 match(V: Op1, P: m_Select(C: m_Value(V&: Y), L: m_Value(V&: C), R: m_Value(V&: D))) && X == Y) {
4578 Value *orTrue = Builder.CreateOr(LHS: A, RHS: C);
4579 Value *orFalse = Builder.CreateOr(LHS: B, RHS: D);
4580 return SelectInst::Create(C: X, S1: orTrue, S2: orFalse);
4581 }
4582 }
4583
4584 // or(ashr(subNSW(Y, X), ScalarSizeInBits(Y) - 1), X) --> X s> Y ? -1 : X.
4585 {
4586 Value *X, *Y;
4587 if (match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_AShr(
4588 L: m_NSWSub(L: m_Value(V&: Y), R: m_Value(V&: X)),
4589 R: m_SpecificInt(V: Ty->getScalarSizeInBits() - 1))),
4590 R: m_Deferred(V: X)))) {
4591 Value *NewICmpInst = Builder.CreateICmpSGT(LHS: X, RHS: Y);
4592 Value *AllOnes = ConstantInt::getAllOnesValue(Ty);
4593 return createSelectInstWithUnknownProfile(C: NewICmpInst, S1: AllOnes, S2: X);
4594 }
4595 }
4596
4597 {
4598 // ((A & B) ^ A) | ((A & B) ^ B) -> A ^ B
4599 // (A ^ (A & B)) | (B ^ (A & B)) -> A ^ B
4600 // ((A & B) ^ B) | ((A & B) ^ A) -> A ^ B
4601 // (B ^ (A & B)) | (A ^ (A & B)) -> A ^ B
4602 const auto TryXorOpt = [&](Value *Lhs, Value *Rhs) -> Instruction * {
4603 if (match(V: Lhs, P: m_c_Xor(L: m_And(L: m_Value(V&: A), R: m_Value(V&: B)), R: m_Deferred(V: A))) &&
4604 match(V: Rhs,
4605 P: m_c_Xor(L: m_And(L: m_Specific(V: A), R: m_Specific(V: B)), R: m_Specific(V: B)))) {
4606 return BinaryOperator::CreateXor(V1: A, V2: B);
4607 }
4608 return nullptr;
4609 };
4610
4611 if (Instruction *Result = TryXorOpt(Op0, Op1))
4612 return Result;
4613 if (Instruction *Result = TryXorOpt(Op1, Op0))
4614 return Result;
4615 }
4616
4617 if (Instruction *V =
4618 canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
4619 return V;
4620
4621 CmpPredicate Pred;
4622 Value *Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4623 // Check if the OR weakens the overflow condition for umul.with.overflow by
4624 // treating any non-zero result as overflow. In that case, we overflow if both
4625 // umul.with.overflow operands are != 0, as in that case the result can only
4626 // be 0, iff the multiplication overflows.
4627 if (match(V: &I, P: m_c_Or(L: m_Value(V&: Ov, P: m_ExtractValue<1>(V: m_Value(V&: UMulWithOv))),
4628 R: m_Value(V&: MulIsNotZero,
4629 P: m_SpecificICmp(
4630 MatchPred: ICmpInst::ICMP_NE,
4631 L: m_Value(V&: Mul, P: m_ExtractValue<0>(
4632 V: m_Deferred(V: UMulWithOv))),
4633 R: m_ZeroInt())))) &&
4634 (Ov->hasOneUse() || (MulIsNotZero->hasOneUse() && Mul->hasOneUse()))) {
4635 Value *A, *B;
4636 if (match(V: UMulWithOv, P: m_Intrinsic<Intrinsic::umul_with_overflow>(
4637 Ops: m_Value(V&: A), Ops: m_Value(V&: B)))) {
4638 Value *NotNullA = Builder.CreateIsNotNull(Arg: A);
4639 Value *NotNullB = Builder.CreateIsNotNull(Arg: B);
4640 return BinaryOperator::CreateAnd(V1: NotNullA, V2: NotNullB);
4641 }
4642 }
4643
4644 /// Res, Overflow = xxx_with_overflow X, C1
4645 /// Try to canonicalize the pattern "Overflow | icmp pred Res, C2" into
4646 /// "Overflow | icmp pred X, C2 +/- C1".
4647 const WithOverflowInst *WO;
4648 const Value *WOV;
4649 const APInt *C1, *C2;
4650 if (match(V: &I, P: m_c_Or(L: m_Value(V&: Ov, P: m_ExtractValue<1>(
4651 V: m_Value(V&: WOV, P: m_WithOverflowInst(I&: WO)))),
4652 R: m_OneUse(SubPattern: m_ICmp(Pred, L: m_ExtractValue<0>(V: m_Deferred(V: WOV)),
4653 R: m_APInt(Res&: C2))))) &&
4654 (WO->getBinaryOp() == Instruction::Add ||
4655 WO->getBinaryOp() == Instruction::Sub) &&
4656 (ICmpInst::isEquality(P: Pred) ||
4657 WO->isSigned() == ICmpInst::isSigned(Pred)) &&
4658 match(V: WO->getRHS(), P: m_APInt(Res&: C1))) {
4659 bool Overflow;
4660 APInt NewC = WO->getBinaryOp() == Instruction::Add
4661 ? (ICmpInst::isSigned(Pred) ? C2->ssub_ov(RHS: *C1, Overflow)
4662 : C2->usub_ov(RHS: *C1, Overflow))
4663 : (ICmpInst::isSigned(Pred) ? C2->sadd_ov(RHS: *C1, Overflow)
4664 : C2->uadd_ov(RHS: *C1, Overflow));
4665 if (!Overflow || ICmpInst::isEquality(P: Pred)) {
4666 Value *NewCmp = Builder.CreateICmp(
4667 P: Pred, LHS: WO->getLHS(), RHS: ConstantInt::get(Ty: WO->getLHS()->getType(), V: NewC));
4668 return BinaryOperator::CreateOr(V1: Ov, V2: NewCmp);
4669 }
4670 }
4671
4672 // Try to fold the pattern "Overflow | icmp pred Res, C2" into a single
4673 // comparison instruction for umul.with.overflow.
4674 if (Value *R = foldOrUnsignedUMulOverflowICmp(I, Builder, DL))
4675 return replaceInstUsesWith(I, V: R);
4676
4677 // (~x) | y --> ~(x & (~y)) iff that gets rid of inversions
4678 if (sinkNotIntoOtherHandOfLogicalOp(I))
4679 return &I;
4680
4681 // Improve "get low bit mask up to and including bit X" pattern:
4682 // (1 << X) | ((1 << X) + -1) --> -1 l>> (bitwidth(x) - 1 - X)
4683 if (match(V: &I, P: m_c_Or(L: m_Add(L: m_Shl(L: m_One(), R: m_Value(V&: X)), R: m_AllOnes()),
4684 R: m_Shl(L: m_One(), R: m_Deferred(V: X)))) &&
4685 match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_Value()), R: m_Value()))) {
4686 Value *Sub = Builder.CreateSub(
4687 LHS: ConstantInt::get(Ty, V: Ty->getScalarSizeInBits() - 1), RHS: X);
4688 return BinaryOperator::CreateLShr(V1: Constant::getAllOnesValue(Ty), V2: Sub);
4689 }
4690
4691 // An or recurrence w/loop invariant step is equivelent to (or start, step)
4692 PHINode *PN = nullptr;
4693 Value *Start = nullptr, *Step = nullptr;
4694 if (matchSimpleRecurrence(I: &I, P&: PN, Start, Step) && DT.dominates(Def: Step, User: PN))
4695 return replaceInstUsesWith(I, V: Builder.CreateOr(LHS: Start, RHS: Step));
4696
4697 // (A & B) | (C | D) or (C | D) | (A & B)
4698 // Can be combined if C or D is of type (A/B & X)
4699 if (match(V: &I, P: m_c_Or(L: m_OneUse(SubPattern: m_And(L: m_Value(V&: A), R: m_Value(V&: B))),
4700 R: m_OneUse(SubPattern: m_Or(L: m_Value(V&: C), R: m_Value(V&: D)))))) {
4701 // (A & B) | (C | ?) -> C | (? | (A & B))
4702 // (A & B) | (C | ?) -> C | (? | (A & B))
4703 // (A & B) | (C | ?) -> C | (? | (A & B))
4704 // (A & B) | (C | ?) -> C | (? | (A & B))
4705 // (C | ?) | (A & B) -> C | (? | (A & B))
4706 // (C | ?) | (A & B) -> C | (? | (A & B))
4707 // (C | ?) | (A & B) -> C | (? | (A & B))
4708 // (C | ?) | (A & B) -> C | (? | (A & B))
4709 if (match(V: D, P: m_OneUse(SubPattern: m_c_And(L: m_Specific(V: A), R: m_Value()))) ||
4710 match(V: D, P: m_OneUse(SubPattern: m_c_And(L: m_Specific(V: B), R: m_Value()))))
4711 return BinaryOperator::CreateOr(
4712 V1: C, V2: Builder.CreateOr(LHS: D, RHS: Builder.CreateAnd(LHS: A, RHS: B)));
4713 // (A & B) | (? | D) -> (? | (A & B)) | D
4714 // (A & B) | (? | D) -> (? | (A & B)) | D
4715 // (A & B) | (? | D) -> (? | (A & B)) | D
4716 // (A & B) | (? | D) -> (? | (A & B)) | D
4717 // (? | D) | (A & B) -> (? | (A & B)) | D
4718 // (? | D) | (A & B) -> (? | (A & B)) | D
4719 // (? | D) | (A & B) -> (? | (A & B)) | D
4720 // (? | D) | (A & B) -> (? | (A & B)) | D
4721 if (match(V: C, P: m_OneUse(SubPattern: m_c_And(L: m_Specific(V: A), R: m_Value()))) ||
4722 match(V: C, P: m_OneUse(SubPattern: m_c_And(L: m_Specific(V: B), R: m_Value()))))
4723 return BinaryOperator::CreateOr(
4724 V1: Builder.CreateOr(LHS: C, RHS: Builder.CreateAnd(LHS: A, RHS: B)), V2: D);
4725 }
4726
4727 if (Instruction *R = reassociateForUses(BO&: I, Builder))
4728 return R;
4729
4730 if (Instruction *Canonicalized = canonicalizeLogicFirst(I, Builder))
4731 return Canonicalized;
4732
4733 if (Instruction *Folded = foldLogicOfIsFPClass(BO&: I, Op0, Op1))
4734 return Folded;
4735
4736 if (Instruction *Res = foldBinOpOfDisplacedShifts(I))
4737 return Res;
4738
4739 // If we are setting the sign bit of a floating-point value, convert
4740 // this to fneg(fabs), then cast back to integer.
4741 //
4742 // If the result isn't immediately cast back to a float, this will increase
4743 // the number of instructions. This is still probably a better canonical form
4744 // as it enables FP value tracking.
4745 //
4746 // Assumes any IEEE-represented type has the sign bit in the high bit.
4747 //
4748 // This is generous interpretation of noimplicitfloat, this is not a true
4749 // floating-point operation.
4750 Value *CastOp;
4751 if (match(V: Op0, P: m_ElementWiseBitCast(Op: m_Value(V&: CastOp))) &&
4752 match(V: Op1, P: m_SignMask()) &&
4753 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
4754 Kind: Attribute::NoImplicitFloat)) {
4755 Type *EltTy = CastOp->getType()->getScalarType();
4756 if (EltTy->isFloatingPointTy() &&
4757 APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
4758 Value *FAbs = Builder.CreateFAbs(V: CastOp);
4759 Value *FNegFAbs = Builder.CreateFNeg(V: FAbs);
4760 return new BitCastInst(FNegFAbs, I.getType());
4761 }
4762 }
4763
4764 // (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2
4765 if (match(V: Op0, P: m_OneUse(SubPattern: m_And(L: m_Value(V&: X), R: m_APInt(Res&: C1)))) &&
4766 match(V: Op1, P: m_APInt(Res&: C2))) {
4767 KnownBits KnownX = computeKnownBits(V: X, CxtI: &I);
4768 if ((KnownX.One & *C2) == *C2)
4769 return BinaryOperator::CreateAnd(V1: X, V2: ConstantInt::get(Ty, V: *C1 | *C2));
4770 }
4771
4772 if (Instruction *Res = foldBitwiseLogicWithIntrinsics(I, Builder))
4773 return Res;
4774
4775 if (Value *V =
4776 simplifyAndOrWithOpReplaced(V: Op0, Op: Op1, RepOp: Constant::getNullValue(Ty),
4777 /*SimplifyOnly*/ false, IC&: *this))
4778 return BinaryOperator::CreateOr(V1: V, V2: Op1);
4779 if (Value *V =
4780 simplifyAndOrWithOpReplaced(V: Op1, Op: Op0, RepOp: Constant::getNullValue(Ty),
4781 /*SimplifyOnly*/ false, IC&: *this))
4782 return BinaryOperator::CreateOr(V1: Op0, V2: V);
4783
4784 if (cast<PossiblyDisjointInst>(Val&: I).isDisjoint())
4785 if (Value *V = SimplifyAddWithRemainder(I))
4786 return replaceInstUsesWith(I, V);
4787
4788 if (Value *Res = FoldOrOfSelectSmaxToAbs(I, Builder))
4789 return replaceInstUsesWith(I, V: Res);
4790
4791 // signum: or (ashr X, BW-1), zext (icmp ne|sgt X, 0) --> scmp(X, 0)
4792 // The ashr already supplies -1 for negative X, so any predicate that
4793 // produces 1 for positive X and 0 for X == 0 yields the same result here.
4794 {
4795 Value *X;
4796 CmpPredicate SignPred;
4797 unsigned BitWidth = Ty->getScalarSizeInBits();
4798 if (match(V: &I,
4799 P: m_c_Or(L: m_AShr(L: m_Value(V&: X), R: m_SpecificIntAllowPoison(V: BitWidth - 1)),
4800 R: m_ZExt(Op: m_ICmp(Pred&: SignPred, L: m_Deferred(V: X), R: m_ZeroInt())))) &&
4801 (SignPred == ICmpInst::ICMP_NE || SignPred == ICmpInst::ICMP_SGT) &&
4802 (Op0->hasOneUse() || Op1->hasOneUse()))
4803 return replaceInstUsesWith(
4804 I, V: Builder.CreateIntrinsic(RetTy: Ty, ID: Intrinsic::scmp,
4805 Args: {X, Constant::getNullValue(Ty)}));
4806 }
4807
4808 return nullptr;
4809}
4810
4811/// A ^ B can be specified using other logic ops in a variety of patterns. We
4812/// can fold these early and efficiently by morphing an existing instruction.
4813static Instruction *foldXorToXor(BinaryOperator &I,
4814 InstCombiner::BuilderTy &Builder) {
4815 assert(I.getOpcode() == Instruction::Xor);
4816 Value *Op0 = I.getOperand(i_nocapture: 0);
4817 Value *Op1 = I.getOperand(i_nocapture: 1);
4818 Value *A, *B;
4819
4820 // There are 4 commuted variants for each of the basic patterns.
4821
4822 // (A & B) ^ (A | B) -> A ^ B
4823 // (A & B) ^ (B | A) -> A ^ B
4824 // (A | B) ^ (A & B) -> A ^ B
4825 // (A | B) ^ (B & A) -> A ^ B
4826 if (match(V: &I, P: m_c_Xor(L: m_And(L: m_Value(V&: A), R: m_Value(V&: B)),
4827 R: m_c_Or(L: m_Deferred(V: A), R: m_Deferred(V: B)))))
4828 return BinaryOperator::CreateXor(V1: A, V2: B);
4829
4830 // (A | ~B) ^ (~A | B) -> A ^ B
4831 // (~B | A) ^ (~A | B) -> A ^ B
4832 // (~A | B) ^ (A | ~B) -> A ^ B
4833 // (B | ~A) ^ (A | ~B) -> A ^ B
4834 if (match(V: &I, P: m_Xor(L: m_c_Or(L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B))),
4835 R: m_c_Or(L: m_Not(V: m_Deferred(V: A)), R: m_Deferred(V: B)))))
4836 return BinaryOperator::CreateXor(V1: A, V2: B);
4837
4838 // (A & ~B) ^ (~A & B) -> A ^ B
4839 // (~B & A) ^ (~A & B) -> A ^ B
4840 // (~A & B) ^ (A & ~B) -> A ^ B
4841 // (B & ~A) ^ (A & ~B) -> A ^ B
4842 if (match(V: &I, P: m_Xor(L: m_c_And(L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B))),
4843 R: m_c_And(L: m_Not(V: m_Deferred(V: A)), R: m_Deferred(V: B)))))
4844 return BinaryOperator::CreateXor(V1: A, V2: B);
4845
4846 // For the remaining cases we need to get rid of one of the operands.
4847 if (!Op0->hasOneUse() && !Op1->hasOneUse())
4848 return nullptr;
4849
4850 // (A | B) ^ ~(A & B) -> ~(A ^ B)
4851 // (A | B) ^ ~(B & A) -> ~(A ^ B)
4852 // (A & B) ^ ~(A | B) -> ~(A ^ B)
4853 // (A & B) ^ ~(B | A) -> ~(A ^ B)
4854 // Complexity sorting ensures the not will be on the right side.
4855 if ((match(V: Op0, P: m_Or(L: m_Value(V&: A), R: m_Value(V&: B))) &&
4856 match(V: Op1, P: m_Not(V: m_c_And(L: m_Specific(V: A), R: m_Specific(V: B))))) ||
4857 (match(V: Op0, P: m_And(L: m_Value(V&: A), R: m_Value(V&: B))) &&
4858 match(V: Op1, P: m_Not(V: m_c_Or(L: m_Specific(V: A), R: m_Specific(V: B))))))
4859 return BinaryOperator::CreateNot(Op: Builder.CreateXor(LHS: A, RHS: B));
4860
4861 return nullptr;
4862}
4863
4864Value *InstCombinerImpl::foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS,
4865 BinaryOperator &I) {
4866 assert(I.getOpcode() == Instruction::Xor && I.getOperand(0) == LHS &&
4867 I.getOperand(1) == RHS && "Should be 'xor' with these operands");
4868
4869 ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
4870 Value *LHS0 = LHS->getOperand(i_nocapture: 0), *LHS1 = LHS->getOperand(i_nocapture: 1);
4871 Value *RHS0 = RHS->getOperand(i_nocapture: 0), *RHS1 = RHS->getOperand(i_nocapture: 1);
4872
4873 if (predicatesFoldable(P1: PredL, P2: PredR)) {
4874 if (LHS0 == RHS1 && LHS1 == RHS0) {
4875 std::swap(a&: LHS0, b&: LHS1);
4876 PredL = ICmpInst::getSwappedPredicate(pred: PredL);
4877 }
4878 if (LHS0 == RHS0 && LHS1 == RHS1) {
4879 // (icmp1 A, B) ^ (icmp2 A, B) --> (icmp3 A, B)
4880 unsigned Code = getICmpCode(Pred: PredL) ^ getICmpCode(Pred: PredR);
4881 bool IsSigned = LHS->isSigned() || RHS->isSigned();
4882 return getNewICmpValue(Code, Sign: IsSigned, LHS: LHS0, RHS: LHS1, Builder);
4883 }
4884 }
4885
4886 const APInt *LC, *RC;
4887 if (match(V: LHS1, P: m_APInt(Res&: LC)) && match(V: RHS1, P: m_APInt(Res&: RC)) &&
4888 LHS0->getType() == RHS0->getType() &&
4889 LHS0->getType()->isIntOrIntVectorTy()) {
4890 // Convert xor of signbit tests to signbit test of xor'd values:
4891 // (X > -1) ^ (Y > -1) --> (X ^ Y) < 0
4892 // (X < 0) ^ (Y < 0) --> (X ^ Y) < 0
4893 // (X > -1) ^ (Y < 0) --> (X ^ Y) > -1
4894 // (X < 0) ^ (Y > -1) --> (X ^ Y) > -1
4895 bool TrueIfSignedL, TrueIfSignedR;
4896 if ((LHS->hasOneUse() || RHS->hasOneUse()) &&
4897 isSignBitCheck(Pred: PredL, RHS: *LC, TrueIfSigned&: TrueIfSignedL) &&
4898 isSignBitCheck(Pred: PredR, RHS: *RC, TrueIfSigned&: TrueIfSignedR)) {
4899 Value *XorLR = Builder.CreateXor(LHS: LHS0, RHS: RHS0);
4900 return TrueIfSignedL == TrueIfSignedR ? Builder.CreateIsNeg(Arg: XorLR) :
4901 Builder.CreateIsNotNeg(Arg: XorLR);
4902 }
4903
4904 // Fold (icmp pred1 X, C1) ^ (icmp pred2 X, C2)
4905 // into a single comparison using range-based reasoning.
4906 if (LHS0 == RHS0) {
4907 ConstantRange CR1 = ConstantRange::makeExactICmpRegion(Pred: PredL, Other: *LC);
4908 ConstantRange CR2 = ConstantRange::makeExactICmpRegion(Pred: PredR, Other: *RC);
4909 auto CRUnion = CR1.exactUnionWith(CR: CR2);
4910 auto CRIntersect = CR1.exactIntersectWith(CR: CR2);
4911 if (CRUnion && CRIntersect)
4912 if (auto CR = CRUnion->exactIntersectWith(CR: CRIntersect->inverse())) {
4913 if (CR->isFullSet())
4914 return ConstantInt::getTrue(Ty: I.getType());
4915 if (CR->isEmptySet())
4916 return ConstantInt::getFalse(Ty: I.getType());
4917
4918 CmpInst::Predicate NewPred;
4919 APInt NewC, Offset;
4920 CR->getEquivalentICmp(Pred&: NewPred, RHS&: NewC, Offset);
4921
4922 if ((Offset.isZero() && (LHS->hasOneUse() || RHS->hasOneUse())) ||
4923 (LHS->hasOneUse() && RHS->hasOneUse())) {
4924 Value *NewV = LHS0;
4925 Type *Ty = LHS0->getType();
4926 if (!Offset.isZero())
4927 NewV = Builder.CreateAdd(LHS: NewV, RHS: ConstantInt::get(Ty, V: Offset));
4928 return Builder.CreateICmp(P: NewPred, LHS: NewV,
4929 RHS: ConstantInt::get(Ty, V: NewC));
4930 }
4931 }
4932 }
4933
4934 // Fold (icmp eq/ne (X & Pow2), 0) ^ (icmp eq/ne (Y & Pow2), 0) into
4935 // (icmp eq/ne ((X ^ Y) & Pow2), 0)
4936 Value *X, *Y, *Pow2;
4937 if (ICmpInst::isEquality(P: PredL) && ICmpInst::isEquality(P: PredR) &&
4938 LC->isZero() && RC->isZero() && LHS->hasOneUse() && RHS->hasOneUse() &&
4939 match(V: LHS0, P: m_And(L: m_Value(V&: X), R: m_Value(V&: Pow2))) &&
4940 match(V: RHS0, P: m_And(L: m_Value(V&: Y), R: m_Specific(V: Pow2))) &&
4941 isKnownToBeAPowerOfTwo(V: Pow2, /*OrZero=*/true, CxtI: &I)) {
4942 Value *Xor = Builder.CreateXor(LHS: X, RHS: Y);
4943 Value *And = Builder.CreateAnd(LHS: Xor, RHS: Pow2);
4944 return Builder.CreateICmp(P: PredL == PredR ? ICmpInst::ICMP_NE
4945 : ICmpInst::ICMP_EQ,
4946 LHS: And, RHS: ConstantInt::getNullValue(Ty: Xor->getType()));
4947 }
4948 }
4949
4950 // Instead of trying to imitate the folds for and/or, decompose this 'xor'
4951 // into those logic ops. That is, try to turn this into an and-of-icmps
4952 // because we have many folds for that pattern.
4953 //
4954 // This is based on a truth table definition of xor:
4955 // X ^ Y --> (X | Y) & !(X & Y)
4956 if (Value *OrICmp = simplifyBinOp(Opcode: Instruction::Or, LHS, RHS, Q: SQ)) {
4957 // TODO: If OrICmp is true, then the definition of xor simplifies to !(X&Y).
4958 // TODO: If OrICmp is false, the whole thing is false (InstSimplify?).
4959 if (Value *AndICmp = simplifyBinOp(Opcode: Instruction::And, LHS, RHS, Q: SQ)) {
4960 // TODO: Independently handle cases where the 'and' side is a constant.
4961 ICmpInst *X = nullptr, *Y = nullptr;
4962 if (OrICmp == LHS && AndICmp == RHS) {
4963 // (LHS | RHS) & !(LHS & RHS) --> LHS & !RHS --> X & !Y
4964 X = LHS;
4965 Y = RHS;
4966 }
4967 if (OrICmp == RHS && AndICmp == LHS) {
4968 // !(LHS & RHS) & (LHS | RHS) --> !LHS & RHS --> !Y & X
4969 X = RHS;
4970 Y = LHS;
4971 }
4972 if (X && Y && (Y->hasOneUse() || canFreelyInvertAllUsersOf(V: Y, IgnoredUser: &I))) {
4973 // Invert the predicate of 'Y', thus inverting its output.
4974 Y->setPredicate(Y->getInversePredicate());
4975 // So, are there other uses of Y?
4976 if (!Y->hasOneUse()) {
4977 // We need to adapt other uses of Y though. Get a value that matches
4978 // the original value of Y before inversion. While this increases
4979 // immediate instruction count, we have just ensured that all the
4980 // users are freely-invertible, so that 'not' *will* get folded away.
4981 BuilderTy::InsertPointGuard Guard(Builder);
4982 // Set insertion point to right after the Y.
4983 Builder.SetInsertPoint(TheBB: Y->getParent(), IP: ++(Y->getIterator()));
4984 Value *NotY = Builder.CreateNot(V: Y, Name: Y->getName() + ".not");
4985 // Replace all uses of Y (excluding the one in NotY!) with NotY.
4986 Worklist.pushUsersToWorkList(I&: *Y);
4987 Y->replaceUsesWithIf(New: NotY,
4988 ShouldReplace: [NotY](Use &U) { return U.getUser() != NotY; });
4989 }
4990 // All done.
4991 return Builder.CreateAnd(LHS, RHS);
4992 }
4993 }
4994 }
4995
4996 return nullptr;
4997}
4998
4999/// If we have a masked merge, in the canonical form of:
5000/// (assuming that A only has one use.)
5001/// | A | |B|
5002/// ((x ^ y) & M) ^ y
5003/// | D |
5004/// * If M is inverted:
5005/// | D |
5006/// ((x ^ y) & ~M) ^ y
5007/// We can canonicalize by swapping the final xor operand
5008/// to eliminate the 'not' of the mask.
5009/// ((x ^ y) & M) ^ x
5010/// * If M is a constant, and D has one use, we transform to 'and' / 'or' ops
5011/// because that shortens the dependency chain and improves analysis:
5012/// (x & M) | (y & ~M)
5013static Instruction *visitMaskedMerge(BinaryOperator &I,
5014 InstCombiner::BuilderTy &Builder) {
5015 Value *B, *X, *D;
5016 Value *M;
5017 if (!match(V: &I, P: m_c_Xor(L: m_Value(V&: B),
5018 R: m_OneUse(SubPattern: m_c_And(
5019 L: m_Value(V&: D, P: m_c_Xor(L: m_Deferred(V: B), R: m_Value(V&: X))),
5020 R: m_Value(V&: M))))))
5021 return nullptr;
5022
5023 Value *NotM;
5024 if (match(V: M, P: m_Not(V: m_Value(V&: NotM)))) {
5025 // De-invert the mask and swap the value in B part.
5026 Value *NewA = Builder.CreateAnd(LHS: D, RHS: NotM);
5027 return BinaryOperator::CreateXor(V1: NewA, V2: X);
5028 }
5029
5030 Constant *C;
5031 if (D->hasOneUse() && match(V: M, P: m_Constant(C))) {
5032 // Propagating undef is unsafe. Clamp undef elements to -1.
5033 Type *EltTy = C->getType()->getScalarType();
5034 C = Constant::replaceUndefsWith(C, Replacement: ConstantInt::getAllOnesValue(Ty: EltTy));
5035 // Unfold.
5036 Value *LHS = Builder.CreateAnd(LHS: X, RHS: C);
5037 Value *NotC = Builder.CreateNot(V: C);
5038 Value *RHS = Builder.CreateAnd(LHS: B, RHS: NotC);
5039 return BinaryOperator::CreateOr(V1: LHS, V2: RHS);
5040 }
5041
5042 return nullptr;
5043}
5044
5045static Instruction *foldNotXor(BinaryOperator &I,
5046 InstCombiner::BuilderTy &Builder) {
5047 Value *X, *Y;
5048 // FIXME: one-use check is not needed in general, but currently we are unable
5049 // to fold 'not' into 'icmp', if that 'icmp' has multiple uses. (D35182)
5050 if (!match(V: &I, P: m_Not(V: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: X), R: m_Value(V&: Y))))))
5051 return nullptr;
5052
5053 auto hasCommonOperand = [](Value *A, Value *B, Value *C, Value *D) {
5054 return A == C || A == D || B == C || B == D;
5055 };
5056
5057 Value *A, *B, *C, *D;
5058 // Canonicalize ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?)
5059 // 4 commuted variants
5060 if (match(V: X, P: m_And(L: m_Value(V&: A), R: m_Value(V&: B))) &&
5061 match(V: Y, P: m_Or(L: m_Value(V&: C), R: m_Value(V&: D))) && hasCommonOperand(A, B, C, D)) {
5062 Value *NotY = Builder.CreateNot(V: Y);
5063 return BinaryOperator::CreateOr(V1: X, V2: NotY);
5064 };
5065
5066 // Canonicalize ~((A | ?) ^ (A & B)) -> (A & B) | ~(A | ?)
5067 // 4 commuted variants
5068 if (match(V: Y, P: m_And(L: m_Value(V&: A), R: m_Value(V&: B))) &&
5069 match(V: X, P: m_Or(L: m_Value(V&: C), R: m_Value(V&: D))) && hasCommonOperand(A, B, C, D)) {
5070 Value *NotX = Builder.CreateNot(V: X);
5071 return BinaryOperator::CreateOr(V1: Y, V2: NotX);
5072 };
5073
5074 return nullptr;
5075}
5076
5077/// Canonicalize a shifty way to code absolute value to the more common pattern
5078/// that uses negation and select.
5079static Instruction *canonicalizeAbs(BinaryOperator &Xor,
5080 InstCombiner::BuilderTy &Builder) {
5081 assert(Xor.getOpcode() == Instruction::Xor && "Expected an xor instruction.");
5082
5083 // There are 4 potential commuted variants. Move the 'ashr' candidate to Op1.
5084 // We're relying on the fact that we only do this transform when the shift has
5085 // exactly 2 uses and the add has exactly 1 use (otherwise, we might increase
5086 // instructions).
5087 Value *Op0 = Xor.getOperand(i_nocapture: 0), *Op1 = Xor.getOperand(i_nocapture: 1);
5088 if (Op0->hasNUses(N: 2))
5089 std::swap(a&: Op0, b&: Op1);
5090
5091 Type *Ty = Xor.getType();
5092 Value *A;
5093 const APInt *ShAmt;
5094 if (match(V: Op1, P: m_AShr(L: m_Value(V&: A), R: m_APInt(Res&: ShAmt))) &&
5095 Op1->hasNUses(N: 2) && *ShAmt == Ty->getScalarSizeInBits() - 1 &&
5096 match(V: Op0, P: m_OneUse(SubPattern: m_c_Add(L: m_Specific(V: A), R: m_Specific(V: Op1))))) {
5097 // Op1 = ashr i32 A, 31 ; smear the sign bit
5098 // xor (add A, Op1), Op1 ; add -1 and flip bits if negative
5099 // --> (A < 0) ? -A : A
5100 Value *IsNeg = Builder.CreateIsNeg(Arg: A);
5101 // Copy the nsw flags from the add to the negate.
5102 auto *Add = cast<BinaryOperator>(Val: Op0);
5103 Value *NegA = Add->hasNoUnsignedWrap()
5104 ? Constant::getNullValue(Ty: A->getType())
5105 : Builder.CreateNeg(V: A, Name: "", HasNSW: Add->hasNoSignedWrap());
5106 return SelectInst::Create(C: IsNeg, S1: NegA, S2: A);
5107 }
5108 return nullptr;
5109}
5110
5111static bool canFreelyInvert(InstCombiner &IC, Value *Op,
5112 Instruction *IgnoredUser) {
5113 auto *I = dyn_cast<Instruction>(Val: Op);
5114 return I && I->getInsertionPointAfterDef() &&
5115 IC.isFreeToInvert(V: I, /*WillInvertAllUses=*/true) &&
5116 IC.canFreelyInvertAllUsersOf(V: I, IgnoredUser);
5117}
5118
5119static Value *freelyInvert(InstCombinerImpl &IC, Value *Op,
5120 Instruction *IgnoredUser) {
5121 auto *I = cast<Instruction>(Val: Op);
5122 auto InsertPt = I->getInsertionPointAfterDef();
5123 assert(InsertPt &&
5124 "freelyInvert requires an instruction with a valid insertion point");
5125 IC.Builder.SetInsertPoint(*InsertPt);
5126 Value *NotOp = IC.Builder.CreateNot(V: Op, Name: Op->getName() + ".not");
5127 Op->replaceUsesWithIf(New: NotOp,
5128 ShouldReplace: [NotOp](Use &U) { return U.getUser() != NotOp; });
5129 IC.freelyInvertAllUsersOf(V: NotOp, IgnoredUser);
5130 return NotOp;
5131}
5132
5133// Transform
5134// z = ~(x &/| y)
5135// into:
5136// z = ((~x) |/& (~y))
5137// iff both x and y are free to invert and all uses of z can be freely updated.
5138bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
5139 Value *Op0, *Op1;
5140 if (!match(V: &I, P: m_LogicalOp(L: m_Value(V&: Op0), R: m_Value(V&: Op1))))
5141 return false;
5142
5143 // If this logic op has not been simplified yet, just bail out and let that
5144 // happen first. Otherwise, the code below may wrongly invert.
5145 if (Op0 == Op1)
5146 return false;
5147
5148 // If one of the operands is a user of the other,
5149 // freelyInvert->freelyInvertAllUsersOf will change the operands of I, which
5150 // may cause miscompilation.
5151 if (match(V: Op0, P: m_Not(V: m_Specific(V: Op1))) || match(V: Op1, P: m_Not(V: m_Specific(V: Op0))))
5152 return false;
5153
5154 Instruction::BinaryOps NewOpc =
5155 match(V: &I, P: m_LogicalAnd()) ? Instruction::Or : Instruction::And;
5156 bool IsBinaryOp = isa<BinaryOperator>(Val: I);
5157
5158 // Can our users be adapted?
5159 if (!InstCombiner::canFreelyInvertAllUsersOf(V: &I, /*IgnoredUser=*/nullptr))
5160 return false;
5161
5162 // And can the operands be adapted?
5163 if (!canFreelyInvert(IC&: *this, Op: Op0, IgnoredUser: &I) || !canFreelyInvert(IC&: *this, Op: Op1, IgnoredUser: &I))
5164 return false;
5165
5166 Op0 = freelyInvert(IC&: *this, Op: Op0, IgnoredUser: &I);
5167 Op1 = freelyInvert(IC&: *this, Op: Op1, IgnoredUser: &I);
5168
5169 auto InsertPt = I.getInsertionPointAfterDef();
5170 assert(InsertPt && "sinkNotIntoLogicalOp requires an instruction with a "
5171 "valid insertion point");
5172 Builder.SetInsertPoint(*InsertPt);
5173 Value *NewLogicOp;
5174 if (IsBinaryOp) {
5175 NewLogicOp = Builder.CreateBinOp(Opc: NewOpc, LHS: Op0, RHS: Op1, Name: I.getName() + ".not");
5176 } else {
5177 NewLogicOp =
5178 Builder.CreateLogicalOp(Opc: NewOpc, Cond1: Op0, Cond2: Op1, Name: I.getName() + ".not", MDFrom: &I);
5179 if (SelectInst *SI = dyn_cast<SelectInst>(Val: NewLogicOp))
5180 SI->swapProfMetadata();
5181 }
5182
5183 replaceInstUsesWith(I, V: NewLogicOp);
5184 // We can not just create an outer `not`, it will most likely be immediately
5185 // folded back, reconstructing our initial pattern, and causing an
5186 // infinite combine loop, so immediately manually fold it away.
5187 freelyInvertAllUsersOf(V: NewLogicOp);
5188 return true;
5189}
5190
5191// Transform
5192// z = (~x) &/| y
5193// into:
5194// z = ~(x |/& (~y))
5195// iff y is free to invert and all uses of z can be freely updated.
5196bool InstCombinerImpl::sinkNotIntoOtherHandOfLogicalOp(Instruction &I) {
5197 Value *Op0, *Op1;
5198 if (!match(V: &I, P: m_LogicalOp(L: m_Value(V&: Op0), R: m_Value(V&: Op1))))
5199 return false;
5200 Instruction::BinaryOps NewOpc =
5201 match(V: &I, P: m_LogicalAnd()) ? Instruction::Or : Instruction::And;
5202 bool IsBinaryOp = isa<BinaryOperator>(Val: I);
5203
5204 Value *NotOp0 = nullptr;
5205 Value *NotOp1 = nullptr;
5206 Value **OpToInvert = nullptr;
5207 if (match(V: Op0, P: m_Not(V: m_Value(V&: NotOp0))) && canFreelyInvert(IC&: *this, Op: Op1, IgnoredUser: &I)) {
5208 Op0 = NotOp0;
5209 OpToInvert = &Op1;
5210 } else if (match(V: Op1, P: m_Not(V: m_Value(V&: NotOp1))) &&
5211 canFreelyInvert(IC&: *this, Op: Op0, IgnoredUser: &I)) {
5212 Op1 = NotOp1;
5213 OpToInvert = &Op0;
5214 } else
5215 return false;
5216
5217 // And can our users be adapted?
5218 if (!InstCombiner::canFreelyInvertAllUsersOf(V: &I, /*IgnoredUser=*/nullptr))
5219 return false;
5220
5221 *OpToInvert = freelyInvert(IC&: *this, Op: *OpToInvert, IgnoredUser: &I);
5222
5223 Builder.SetInsertPoint(*I.getInsertionPointAfterDef());
5224 Value *NewBinOp;
5225 if (IsBinaryOp)
5226 NewBinOp = Builder.CreateBinOp(Opc: NewOpc, LHS: Op0, RHS: Op1, Name: I.getName() + ".not");
5227 else
5228 NewBinOp = Builder.CreateLogicalOp(Opc: NewOpc, Cond1: Op0, Cond2: Op1, Name: I.getName() + ".not");
5229 replaceInstUsesWith(I, V: NewBinOp);
5230 // We can not just create an outer `not`, it will most likely be immediately
5231 // folded back, reconstructing our initial pattern, and causing an
5232 // infinite combine loop, so immediately manually fold it away.
5233 freelyInvertAllUsersOf(V: NewBinOp);
5234 return true;
5235}
5236
5237Instruction *InstCombinerImpl::foldNot(BinaryOperator &I) {
5238 Value *NotOp;
5239 if (!match(V: &I, P: m_Not(V: m_Value(V&: NotOp))))
5240 return nullptr;
5241
5242 // Apply DeMorgan's Law for 'nand' / 'nor' logic with an inverted operand.
5243 // We must eliminate the and/or (one-use) for these transforms to not increase
5244 // the instruction count.
5245 //
5246 // ~(~X & Y) --> (X | ~Y)
5247 // ~(Y & ~X) --> (X | ~Y)
5248 //
5249 // Note: The logical matches do not check for the commuted patterns because
5250 // those are handled via SimplifySelectsFeedingBinaryOp().
5251 Type *Ty = I.getType();
5252 Value *X, *Y;
5253 if (match(V: NotOp, P: m_OneUse(SubPattern: m_c_And(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))) {
5254 Value *NotY = Builder.CreateNot(V: Y, Name: Y->getName() + ".not");
5255 return BinaryOperator::CreateOr(V1: X, V2: NotY);
5256 }
5257 if (match(V: NotOp, P: m_OneUse(SubPattern: m_LogicalAnd(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))) {
5258 Value *NotY = Builder.CreateNot(V: Y, Name: Y->getName() + ".not");
5259 SelectInst *SI = SelectInst::Create(C: X, S1: ConstantInt::getTrue(Ty), S2: NotY, NameStr: "",
5260 InsertBefore: nullptr, MDFrom: cast<Instruction>(Val: NotOp));
5261 SI->swapProfMetadata();
5262 return SI;
5263 }
5264
5265 // ~(~X | Y) --> (X & ~Y)
5266 // ~(Y | ~X) --> (X & ~Y)
5267 if (match(V: NotOp, P: m_OneUse(SubPattern: m_c_Or(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))) {
5268 Value *NotY = Builder.CreateNot(V: Y, Name: Y->getName() + ".not");
5269 return BinaryOperator::CreateAnd(V1: X, V2: NotY);
5270 }
5271 if (match(V: NotOp, P: m_OneUse(SubPattern: m_LogicalOr(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))) {
5272 Value *NotY = Builder.CreateNot(V: Y, Name: Y->getName() + ".not");
5273 SelectInst *SI = SelectInst::Create(C: X, S1: NotY, S2: ConstantInt::getFalse(Ty), NameStr: "",
5274 InsertBefore: nullptr, MDFrom: cast<Instruction>(Val: NotOp));
5275 SI->swapProfMetadata();
5276 return SI;
5277 }
5278
5279 // Is this a 'not' (~) fed by a binary operator?
5280 BinaryOperator *NotVal;
5281 if (match(V: NotOp, P: m_BinOp(I&: NotVal))) {
5282 // ~((-X) | Y) --> (X - 1) & (~Y)
5283 if (match(V: NotVal,
5284 P: m_OneUse(SubPattern: m_c_Or(L: m_OneUse(SubPattern: m_Neg(V: m_Value(V&: X))), R: m_Value(V&: Y))))) {
5285 Value *DecX = Builder.CreateAdd(LHS: X, RHS: ConstantInt::getAllOnesValue(Ty));
5286 Value *NotY = Builder.CreateNot(V: Y);
5287 return BinaryOperator::CreateAnd(V1: DecX, V2: NotY);
5288 }
5289
5290 // ~(~X >>s Y) --> (X >>s Y)
5291 if (match(V: NotVal, P: m_AShr(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))
5292 return BinaryOperator::CreateAShr(V1: X, V2: Y);
5293
5294 // Treat lshr with non-negative operand as ashr.
5295 // ~(~X >>u Y) --> (X >>s Y) iff X is known negative
5296 if (match(V: NotVal, P: m_LShr(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))) &&
5297 isKnownNegative(V: X, SQ: SQ.getWithInstruction(I: NotVal)))
5298 return BinaryOperator::CreateAShr(V1: X, V2: Y);
5299
5300 // Bit-hack form of a signbit test for iN type:
5301 // ~(X >>s (N - 1)) --> sext i1 (X > -1) to iN
5302 unsigned FullShift = Ty->getScalarSizeInBits() - 1;
5303 if (match(V: NotVal, P: m_OneUse(SubPattern: m_AShr(L: m_Value(V&: X), R: m_SpecificInt(V: FullShift))))) {
5304 Value *IsNotNeg = Builder.CreateIsNotNeg(Arg: X, Name: "isnotneg");
5305 return new SExtInst(IsNotNeg, Ty);
5306 }
5307
5308 // If we are inverting a right-shifted constant, we may be able to eliminate
5309 // the 'not' by inverting the constant and using the opposite shift type.
5310 // Canonicalization rules ensure that only a negative constant uses 'ashr',
5311 // but we must check that in case that transform has not fired yet.
5312
5313 // ~(C >>s Y) --> ~C >>u Y (when inverting the replicated sign bits)
5314 Constant *C;
5315 if (match(V: NotVal, P: m_AShr(L: m_Constant(C), R: m_Value(V&: Y))) &&
5316 match(V: C, P: m_Negative()))
5317 return BinaryOperator::CreateLShr(V1: ConstantExpr::getNot(C), V2: Y);
5318
5319 // ~(C >>u Y) --> ~C >>s Y (when inverting the replicated sign bits)
5320 if (match(V: NotVal, P: m_LShr(L: m_Constant(C), R: m_Value(V&: Y))) &&
5321 match(V: C, P: m_NonNegative()))
5322 return BinaryOperator::CreateAShr(V1: ConstantExpr::getNot(C), V2: Y);
5323
5324 // ~(X + C) --> ~C - X
5325 if (match(V: NotVal, P: m_Add(L: m_Value(V&: X), R: m_ImmConstant(C))))
5326 return BinaryOperator::CreateSub(V1: ConstantExpr::getNot(C), V2: X);
5327
5328 // ~(X - Y) --> ~X + Y
5329 // FIXME: is it really beneficial to sink the `not` here?
5330 if (match(V: NotVal, P: m_Sub(L: m_Value(V&: X), R: m_Value(V&: Y))))
5331 if (isa<Constant>(Val: X) || NotVal->hasOneUse())
5332 return BinaryOperator::CreateAdd(V1: Builder.CreateNot(V: X), V2: Y);
5333
5334 // ~(~X + Y) --> X - Y
5335 if (match(V: NotVal, P: m_c_Add(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y))))
5336 return BinaryOperator::CreateWithCopiedFlags(Opc: Instruction::Sub, V1: X, V2: Y,
5337 CopyO: NotVal);
5338 }
5339
5340 // not (cmp A, B) = !cmp A, B
5341 CmpPredicate Pred;
5342 if (match(V: NotOp, P: m_Cmp(Pred, L: m_Value(), R: m_Value())) &&
5343 (NotOp->hasOneUse() ||
5344 InstCombiner::canFreelyInvertAllUsersOf(V: cast<Instruction>(Val: NotOp),
5345 /*IgnoredUser=*/nullptr))) {
5346 cast<CmpInst>(Val: NotOp)->setPredicate(CmpInst::getInversePredicate(pred: Pred));
5347 freelyInvertAllUsersOf(V: NotOp);
5348 return &I;
5349 }
5350
5351 // not (bitcast (cmp A, B) --> bitcast (!cmp A, B)
5352 if (match(V: NotOp, P: m_OneUse(SubPattern: m_BitCast(Op: m_Value(V&: X)))) &&
5353 match(V: X, P: m_OneUse(SubPattern: m_Cmp(Pred, L: m_Value(), R: m_Value())))) {
5354 cast<CmpInst>(Val: X)->setPredicate(CmpInst::getInversePredicate(pred: Pred));
5355 return new BitCastInst(X, Ty);
5356 }
5357
5358 // Move a 'not' ahead of casts of a bool to enable logic reduction:
5359 // not (bitcast (sext i1 X)) --> bitcast (sext (not i1 X))
5360 if (match(V: NotOp, P: m_OneUse(SubPattern: m_BitCast(Op: m_OneUse(SubPattern: m_SExt(Op: m_Value(V&: X)))))) &&
5361 X->getType()->isIntOrIntVectorTy(BitWidth: 1)) {
5362 Type *SextTy = cast<BitCastOperator>(Val: NotOp)->getSrcTy();
5363 Value *NotX = Builder.CreateNot(V: X);
5364 Value *Sext = Builder.CreateSExt(V: NotX, DestTy: SextTy);
5365 return new BitCastInst(Sext, Ty);
5366 }
5367
5368 if (auto *NotOpI = dyn_cast<Instruction>(Val: NotOp))
5369 if (sinkNotIntoLogicalOp(I&: *NotOpI))
5370 return &I;
5371
5372 // Eliminate a bitwise 'not' op of 'not' min/max by inverting the min/max:
5373 // ~min(~X, ~Y) --> max(X, Y)
5374 // ~max(~X, Y) --> min(X, ~Y)
5375 auto *II = dyn_cast<IntrinsicInst>(Val: NotOp);
5376 if (II && II->hasOneUse()) {
5377 if (match(V: NotOp, P: m_c_MaxOrMin(L: m_Not(V: m_Value(V&: X)), R: m_Value(V&: Y)))) {
5378 Intrinsic::ID InvID = getInverseMinMaxIntrinsic(MinMaxID: II->getIntrinsicID());
5379 Value *NotY = Builder.CreateNot(V: Y);
5380 Value *InvMaxMin = Builder.CreateBinaryIntrinsic(ID: InvID, LHS: X, RHS: NotY);
5381 return replaceInstUsesWith(I, V: InvMaxMin);
5382 }
5383
5384 if (II->getIntrinsicID() == Intrinsic::is_fpclass) {
5385 ConstantInt *ClassMask = cast<ConstantInt>(Val: II->getArgOperand(i: 1));
5386 II->setArgOperand(
5387 i: 1, v: ConstantInt::get(Ty: ClassMask->getType(),
5388 V: ~ClassMask->getZExtValue() & fcAllFlags));
5389 return replaceInstUsesWith(I, V: II);
5390 }
5391 }
5392
5393 if (NotOp->hasOneUse()) {
5394 // Pull 'not' into operands of select if both operands are one-use compares
5395 // or one is one-use compare and the other one is a constant.
5396 // Inverting the predicates eliminates the 'not' operation.
5397 // Example:
5398 // not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) -->
5399 // select ?, (cmp InvTPred, ?, ?), (cmp InvFPred, ?, ?)
5400 // not (select ?, (cmp TPred, ?, ?), true -->
5401 // select ?, (cmp InvTPred, ?, ?), false
5402 if (auto *Sel = dyn_cast<SelectInst>(Val: NotOp)) {
5403 Value *TV = Sel->getTrueValue();
5404 Value *FV = Sel->getFalseValue();
5405 auto *CmpT = dyn_cast<CmpInst>(Val: TV);
5406 auto *CmpF = dyn_cast<CmpInst>(Val: FV);
5407 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(Val: TV);
5408 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(Val: FV);
5409 if (InvertibleT && InvertibleF) {
5410 if (CmpT)
5411 CmpT->setPredicate(CmpT->getInversePredicate());
5412 else
5413 Sel->setTrueValue(ConstantExpr::getNot(C: cast<Constant>(Val: TV)));
5414 if (CmpF)
5415 CmpF->setPredicate(CmpF->getInversePredicate());
5416 else
5417 Sel->setFalseValue(ConstantExpr::getNot(C: cast<Constant>(Val: FV)));
5418 return replaceInstUsesWith(I, V: Sel);
5419 }
5420 }
5421 }
5422
5423 if (Instruction *NewXor = foldNotXor(I, Builder))
5424 return NewXor;
5425
5426 // TODO: Could handle multi-use better by checking if all uses of NotOp (other
5427 // than I) can be inverted.
5428 if (Value *R = getFreelyInverted(V: NotOp, WillInvertAllUses: NotOp->hasOneUse(), Builder: &Builder))
5429 return replaceInstUsesWith(I, V: R);
5430
5431 return nullptr;
5432}
5433
5434// ((X + C) & M) ^ M --> (~C − X) & M
5435static Instruction *foldMaskedAddXorPattern(BinaryOperator &I,
5436 InstCombiner::BuilderTy &Builder) {
5437 Value *X, *Mask;
5438 Constant *AddC;
5439 BinaryOperator *AddInst;
5440 if (match(V: &I,
5441 P: m_Xor(L: m_OneUse(SubPattern: m_And(L: m_OneUse(SubPattern: m_CombineAnd(
5442 Ps: m_BinOp(I&: AddInst),
5443 Ps: m_Add(L: m_Value(V&: X), R: m_ImmConstant(C&: AddC)))),
5444 R: m_Value(V&: Mask))),
5445 R: m_Deferred(V: Mask)))) {
5446 Value *NotC = Builder.CreateNot(V: AddC);
5447 Value *NewSub = Builder.CreateSub(LHS: NotC, RHS: X, Name: "", HasNUW: AddInst->hasNoUnsignedWrap(),
5448 HasNSW: AddInst->hasNoSignedWrap());
5449 return BinaryOperator::CreateAnd(V1: NewSub, V2: Mask);
5450 }
5451
5452 return nullptr;
5453}
5454
5455// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
5456// here. We should standardize that construct where it is needed or choose some
5457// other way to ensure that commutated variants of patterns are not missed.
5458Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
5459 if (Value *V = simplifyXorInst(LHS: I.getOperand(i_nocapture: 0), RHS: I.getOperand(i_nocapture: 1),
5460 Q: SQ.getWithInstruction(I: &I)))
5461 return replaceInstUsesWith(I, V);
5462
5463 if (SimplifyAssociativeOrCommutative(I))
5464 return &I;
5465
5466 if (Instruction *X = foldVectorBinop(Inst&: I))
5467 return X;
5468
5469 if (Instruction *Phi = foldBinopWithPhiOperands(BO&: I))
5470 return Phi;
5471
5472 if (Instruction *NewXor = foldXorToXor(I, Builder))
5473 return NewXor;
5474
5475 // (A&B)^(A&C) -> A&(B^C) etc
5476 if (Value *V = foldUsingDistributiveLaws(I))
5477 return replaceInstUsesWith(I, V);
5478
5479 // See if we can simplify any instructions used by the instruction whose sole
5480 // purpose is to compute bits we don't care about.
5481 if (SimplifyDemandedInstructionBits(Inst&: I))
5482 return &I;
5483
5484 if (Instruction *R = foldNot(I))
5485 return R;
5486
5487 if (Instruction *R = foldBinOpShiftWithShift(I))
5488 return R;
5489
5490 Value *Op0 = I.getOperand(i_nocapture: 0), *Op1 = I.getOperand(i_nocapture: 1);
5491 Value *X, *Y, *M;
5492
5493 // (X | Y) ^ M -> (X ^ M) ^ Y
5494 // (X | Y) ^ M -> (Y ^ M) ^ X
5495 if (match(V: &I, P: m_c_Xor(L: m_OneUse(SubPattern: m_DisjointOr(L: m_Value(V&: X), R: m_Value(V&: Y))),
5496 R: m_Value(V&: M)))) {
5497 if (Value *XorAC = simplifyXorInst(LHS: X, RHS: M, Q: SQ.getWithInstruction(I: &I)))
5498 return BinaryOperator::CreateXor(V1: XorAC, V2: Y);
5499
5500 if (Value *XorBC = simplifyXorInst(LHS: Y, RHS: M, Q: SQ.getWithInstruction(I: &I)))
5501 return BinaryOperator::CreateXor(V1: XorBC, V2: X);
5502 }
5503
5504 // Fold (X & M) ^ (Y & ~M) -> (X & M) | (Y & ~M)
5505 // This it a special case in haveNoCommonBitsSet, but the computeKnownBits
5506 // calls in there are unnecessary as SimplifyDemandedInstructionBits should
5507 // have already taken care of those cases.
5508 if (match(V: &I, P: m_c_Xor(L: m_c_And(L: m_Not(V: m_Value(V&: M)), R: m_Value()),
5509 R: m_c_And(L: m_Deferred(V: M), R: m_Value())))) {
5510 if (isGuaranteedNotToBeUndef(V: M))
5511 return BinaryOperator::CreateDisjointOr(V1: Op0, V2: Op1);
5512 else
5513 return BinaryOperator::CreateOr(V1: Op0, V2: Op1);
5514 }
5515
5516 if (Instruction *Xor = visitMaskedMerge(I, Builder))
5517 return Xor;
5518
5519 Constant *C1;
5520 if (match(V: Op1, P: m_Constant(C&: C1))) {
5521 Constant *C2;
5522
5523 if (match(V: Op0, P: m_OneUse(SubPattern: m_Or(L: m_Value(V&: X), R: m_ImmConstant(C&: C2)))) &&
5524 match(V: C1, P: m_ImmConstant())) {
5525 // (X | C2) ^ C1 --> (X & ~C2) ^ (C1^C2)
5526 C2 = Constant::replaceUndefsWith(
5527 C: C2, Replacement: Constant::getAllOnesValue(Ty: C2->getType()->getScalarType()));
5528 Value *And = Builder.CreateAnd(
5529 LHS: X, RHS: Constant::mergeUndefsWith(C: ConstantExpr::getNot(C: C2), Other: C1));
5530 return BinaryOperator::CreateXor(
5531 V1: And, V2: Constant::mergeUndefsWith(C: ConstantExpr::getXor(C1, C2), Other: C1));
5532 }
5533
5534 // Use DeMorgan and reassociation to eliminate a 'not' op.
5535 if (match(V: Op0, P: m_OneUse(SubPattern: m_Or(L: m_Not(V: m_Value(V&: X)), R: m_Constant(C&: C2))))) {
5536 // (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1
5537 Value *And = Builder.CreateAnd(LHS: X, RHS: ConstantExpr::getNot(C: C2));
5538 return BinaryOperator::CreateXor(V1: And, V2: ConstantExpr::getNot(C: C1));
5539 }
5540 if (match(V: Op0, P: m_OneUse(SubPattern: m_And(L: m_Not(V: m_Value(V&: X)), R: m_Constant(C&: C2))))) {
5541 // (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1
5542 Value *Or = Builder.CreateOr(LHS: X, RHS: ConstantExpr::getNot(C: C2));
5543 return BinaryOperator::CreateXor(V1: Or, V2: ConstantExpr::getNot(C: C1));
5544 }
5545
5546 // Convert xor ([trunc] (ashr X, BW-1)), C =>
5547 // select(X >s -1, C, ~C)
5548 // The ashr creates "AllZeroOrAllOne's", which then optionally inverses the
5549 // constant depending on whether this input is less than 0.
5550 const APInt *CA;
5551 if (match(V: Op0, P: m_OneUse(SubPattern: m_TruncOrSelf(
5552 Op: m_AShr(L: m_Value(V&: X), R: m_APIntAllowPoison(Res&: CA))))) &&
5553 *CA == X->getType()->getScalarSizeInBits() - 1 &&
5554 !match(V: C1, P: m_AllOnes())) {
5555 assert(!C1->isNullValue() && "Unexpected xor with 0");
5556 Value *IsNotNeg = Builder.CreateIsNotNeg(Arg: X);
5557 return createSelectInstWithUnknownProfile(C: IsNotNeg, S1: Op1,
5558 S2: Builder.CreateNot(V: Op1));
5559 }
5560 }
5561
5562 Type *Ty = I.getType();
5563 {
5564 const APInt *RHSC;
5565 if (match(V: Op1, P: m_APInt(Res&: RHSC))) {
5566 Value *X;
5567 const APInt *C;
5568 // (C - X) ^ signmaskC --> (C + signmaskC) - X
5569 if (RHSC->isSignMask() && match(V: Op0, P: m_Sub(L: m_APInt(Res&: C), R: m_Value(V&: X))))
5570 return BinaryOperator::CreateSub(V1: ConstantInt::get(Ty, V: *C + *RHSC), V2: X);
5571
5572 // (X + C) ^ signmaskC --> X + (C + signmaskC)
5573 if (RHSC->isSignMask() && match(V: Op0, P: m_Add(L: m_Value(V&: X), R: m_APInt(Res&: C))))
5574 return BinaryOperator::CreateAdd(V1: X, V2: ConstantInt::get(Ty, V: *C + *RHSC));
5575
5576 // (X | C) ^ RHSC --> X ^ (C ^ RHSC) iff X & C == 0
5577 if (match(V: Op0, P: m_Or(L: m_Value(V&: X), R: m_APInt(Res&: C))) &&
5578 MaskedValueIsZero(V: X, Mask: *C, CxtI: &I))
5579 return BinaryOperator::CreateXor(V1: X, V2: ConstantInt::get(Ty, V: *C ^ *RHSC));
5580
5581 // When X is a power-of-two or zero and zero input is poison:
5582 // ctlz(i32 X) ^ 31 --> cttz(X)
5583 // cttz(i32 X) ^ 31 --> ctlz(X)
5584 auto *II = dyn_cast<IntrinsicInst>(Val: Op0);
5585 if (II && II->hasOneUse() && *RHSC == Ty->getScalarSizeInBits() - 1) {
5586 Intrinsic::ID IID = II->getIntrinsicID();
5587 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5588 match(V: II->getArgOperand(i: 1), P: m_One()) &&
5589 isKnownToBeAPowerOfTwo(V: II->getArgOperand(i: 0), /*OrZero */ true)) {
5590 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5591 Function *F =
5592 Intrinsic::getOrInsertDeclaration(M: II->getModule(), id: IID, OverloadTys: Ty);
5593 return CallInst::Create(Func: F, Args: {II->getArgOperand(i: 0), Builder.getTrue()});
5594 }
5595 }
5596
5597 // If RHSC is inverting the remaining bits of shifted X,
5598 // canonicalize to a 'not' before the shift to help SCEV and codegen:
5599 // (X << C) ^ RHSC --> ~X << C
5600 if (match(V: Op0, P: m_OneUse(SubPattern: m_Shl(L: m_Value(V&: X), R: m_APInt(Res&: C)))) &&
5601 *RHSC == APInt::getAllOnes(numBits: Ty->getScalarSizeInBits()).shl(ShiftAmt: *C)) {
5602 Value *NotX = Builder.CreateNot(V: X);
5603 return BinaryOperator::CreateShl(V1: NotX, V2: ConstantInt::get(Ty, V: *C));
5604 }
5605 // (X >>u C) ^ RHSC --> ~X >>u C
5606 if (match(V: Op0, P: m_OneUse(SubPattern: m_LShr(L: m_Value(V&: X), R: m_APInt(Res&: C)))) &&
5607 *RHSC == APInt::getAllOnes(numBits: Ty->getScalarSizeInBits()).lshr(ShiftAmt: *C)) {
5608 Value *NotX = Builder.CreateNot(V: X);
5609 return BinaryOperator::CreateLShr(V1: NotX, V2: ConstantInt::get(Ty, V: *C));
5610 }
5611 // TODO: We could handle 'ashr' here as well. That would be matching
5612 // a 'not' op and moving it before the shift. Doing that requires
5613 // preventing the inverse fold in canShiftBinOpWithConstantRHS().
5614 }
5615
5616 // If we are XORing the sign bit of a floating-point value, convert
5617 // this to fneg, then cast back to integer.
5618 //
5619 // This is generous interpretation of noimplicitfloat, this is not a true
5620 // floating-point operation.
5621 //
5622 // Assumes any IEEE-represented type has the sign bit in the high bit.
5623 // TODO: Unify with APInt matcher. This version allows undef unlike m_APInt
5624 Value *CastOp;
5625 if (match(V: Op0, P: m_ElementWiseBitCast(Op: m_Value(V&: CastOp))) &&
5626 match(V: Op1, P: m_SignMask()) &&
5627 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
5628 Kind: Attribute::NoImplicitFloat)) {
5629 Type *EltTy = CastOp->getType()->getScalarType();
5630 if (EltTy->isFloatingPointTy() &&
5631 APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
5632 Value *FNeg = Builder.CreateFNeg(V: CastOp);
5633 return new BitCastInst(FNeg, I.getType());
5634 }
5635 }
5636 }
5637
5638 // FIXME: This should not be limited to scalar (pull into APInt match above).
5639 {
5640 Value *X;
5641 ConstantInt *C1, *C2, *C3;
5642 // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
5643 if (match(V: Op1, P: m_ConstantInt(CI&: C3)) &&
5644 match(V: Op0, P: m_LShr(L: m_Xor(L: m_Value(V&: X), R: m_ConstantInt(CI&: C1)),
5645 R: m_ConstantInt(CI&: C2))) &&
5646 Op0->hasOneUse()) {
5647 // fold (C1 >> C2) ^ C3
5648 APInt FoldConst = C1->getValue().lshr(ShiftAmt: C2->getValue());
5649 FoldConst ^= C3->getValue();
5650 // Prepare the two operands.
5651 auto *Opnd0 = Builder.CreateLShr(LHS: X, RHS: C2);
5652 Opnd0->takeName(V: Op0);
5653 return BinaryOperator::CreateXor(V1: Opnd0, V2: ConstantInt::get(Ty, V: FoldConst));
5654 }
5655 }
5656
5657 if (Instruction *FoldedLogic = foldBinOpIntoSelectOrPhi(I))
5658 return FoldedLogic;
5659
5660 if (Instruction *FoldedLogic = foldBinOpSelectBinOp(Op&: I))
5661 return FoldedLogic;
5662
5663 // Y ^ (X | Y) --> X & ~Y
5664 // Y ^ (Y | X) --> X & ~Y
5665 if (match(V: Op1, P: m_OneUse(SubPattern: m_c_Or(L: m_Value(V&: X), R: m_Specific(V: Op0)))))
5666 return BinaryOperator::CreateAnd(V1: X, V2: Builder.CreateNot(V: Op0));
5667 // (X | Y) ^ Y --> X & ~Y
5668 // (Y | X) ^ Y --> X & ~Y
5669 if (match(V: Op0, P: m_OneUse(SubPattern: m_c_Or(L: m_Value(V&: X), R: m_Specific(V: Op1)))))
5670 return BinaryOperator::CreateAnd(V1: X, V2: Builder.CreateNot(V: Op1));
5671
5672 // Y ^ (X & Y) --> ~X & Y
5673 // Y ^ (Y & X) --> ~X & Y
5674 if (match(V: Op1, P: m_OneUse(SubPattern: m_c_And(L: m_Value(V&: X), R: m_Specific(V: Op0)))))
5675 return BinaryOperator::CreateAnd(V1: Op0, V2: Builder.CreateNot(V: X));
5676 // (X & Y) ^ Y --> ~X & Y
5677 // (Y & X) ^ Y --> ~X & Y
5678 // Canonical form is (X & C) ^ C; don't touch that.
5679 // TODO: A 'not' op is better for analysis and codegen, but demanded bits must
5680 // be fixed to prefer that (otherwise we get infinite looping).
5681 if (!match(V: Op1, P: m_Constant()) &&
5682 match(V: Op0, P: m_OneUse(SubPattern: m_c_And(L: m_Value(V&: X), R: m_Specific(V: Op1)))))
5683 return BinaryOperator::CreateAnd(V1: Op1, V2: Builder.CreateNot(V: X));
5684
5685 Value *A, *B, *C;
5686 // (A ^ B) ^ (A | C) --> (~A & C) ^ B -- There are 4 commuted variants.
5687 if (match(V: &I, P: m_c_Xor(L: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))),
5688 R: m_OneUse(SubPattern: m_c_Or(L: m_Deferred(V: A), R: m_Value(V&: C))))))
5689 return BinaryOperator::CreateXor(
5690 V1: Builder.CreateAnd(LHS: Builder.CreateNot(V: A), RHS: C), V2: B);
5691
5692 // (A ^ B) ^ (B | C) --> (~B & C) ^ A -- There are 4 commuted variants.
5693 if (match(V: &I, P: m_c_Xor(L: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))),
5694 R: m_OneUse(SubPattern: m_c_Or(L: m_Deferred(V: B), R: m_Value(V&: C))))))
5695 return BinaryOperator::CreateXor(
5696 V1: Builder.CreateAnd(LHS: Builder.CreateNot(V: B), RHS: C), V2: A);
5697
5698 // (A & B) ^ (A ^ B) -> (A | B)
5699 if (match(V: Op0, P: m_And(L: m_Value(V&: A), R: m_Value(V&: B))) &&
5700 match(V: Op1, P: m_c_Xor(L: m_Specific(V: A), R: m_Specific(V: B))))
5701 return BinaryOperator::CreateOr(V1: A, V2: B);
5702 // (A ^ B) ^ (A & B) -> (A | B)
5703 if (match(V: Op0, P: m_Xor(L: m_Value(V&: A), R: m_Value(V&: B))) &&
5704 match(V: Op1, P: m_c_And(L: m_Specific(V: A), R: m_Specific(V: B))))
5705 return BinaryOperator::CreateOr(V1: A, V2: B);
5706
5707 // (A & ~B) ^ ~A -> ~(A & B)
5708 // (~B & A) ^ ~A -> ~(A & B)
5709 if (match(V: Op0, P: m_c_And(L: m_Value(V&: A), R: m_Not(V: m_Value(V&: B)))) &&
5710 match(V: Op1, P: m_Not(V: m_Specific(V: A))))
5711 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: A, RHS: B));
5712
5713 // (~A & B) ^ A --> A | B -- There are 4 commuted variants.
5714 if (match(V: &I, P: m_c_Xor(L: m_c_And(L: m_Not(V: m_Value(V&: A)), R: m_Value(V&: B)), R: m_Deferred(V: A))))
5715 return BinaryOperator::CreateOr(V1: A, V2: B);
5716
5717 // (~A | B) ^ A --> ~(A & B)
5718 if (match(V: Op0, P: m_OneUse(SubPattern: m_c_Or(L: m_Not(V: m_Specific(V: Op1)), R: m_Value(V&: B)))))
5719 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: Op1, RHS: B));
5720
5721 // A ^ (~A | B) --> ~(A & B)
5722 if (match(V: Op1, P: m_OneUse(SubPattern: m_c_Or(L: m_Not(V: m_Specific(V: Op0)), R: m_Value(V&: B)))))
5723 return BinaryOperator::CreateNot(Op: Builder.CreateAnd(LHS: Op0, RHS: B));
5724
5725 // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
5726 // TODO: Loosen one-use restriction if common operand is a constant.
5727 Value *D;
5728 if (match(V: Op0, P: m_OneUse(SubPattern: m_Or(L: m_Value(V&: A), R: m_Value(V&: B)))) &&
5729 match(V: Op1, P: m_OneUse(SubPattern: m_Or(L: m_Value(V&: C), R: m_Value(V&: D))))) {
5730 if (B == C || B == D)
5731 std::swap(a&: A, b&: B);
5732 if (A == C)
5733 std::swap(a&: C, b&: D);
5734 if (A == D) {
5735 Value *NotA = Builder.CreateNot(V: A);
5736 return BinaryOperator::CreateAnd(V1: Builder.CreateXor(LHS: B, RHS: C), V2: NotA);
5737 }
5738 }
5739
5740 // (A & B) ^ (A | C) --> A ? ~B : C -- There are 4 commuted variants.
5741 if (I.getType()->isIntOrIntVectorTy(BitWidth: 1) &&
5742 match(V: &I, P: m_c_Xor(L: m_OneUse(SubPattern: m_LogicalAnd(L: m_Value(V&: A), R: m_Value(V&: B))),
5743 R: m_OneUse(SubPattern: m_LogicalOr(L: m_Value(V&: C), R: m_Value(V&: D)))))) {
5744 bool NeedFreeze = isa<SelectInst>(Val: Op0) && isa<SelectInst>(Val: Op1) && B == D;
5745 Instruction *MDFrom = cast<Instruction>(Val: Op0);
5746 if (B == C || B == D) {
5747 std::swap(a&: A, b&: B);
5748 MDFrom = B == C ? cast<Instruction>(Val: Op1) : nullptr;
5749 }
5750 if (A == C)
5751 std::swap(a&: C, b&: D);
5752 if (A == D) {
5753 if (NeedFreeze)
5754 A = Builder.CreateFreeze(V: A);
5755 Value *NotB = Builder.CreateNot(V: B);
5756 return MDFrom == nullptr
5757 ? createSelectInstWithUnknownProfile(C: A, S1: NotB, S2: C)
5758 : SelectInst::Create(C: A, S1: NotB, S2: C, NameStr: "", InsertBefore: nullptr, MDFrom);
5759 }
5760 }
5761
5762 if (auto *LHS = dyn_cast<ICmpInst>(Val: I.getOperand(i_nocapture: 0)))
5763 if (auto *RHS = dyn_cast<ICmpInst>(Val: I.getOperand(i_nocapture: 1)))
5764 if (Value *V = foldXorOfICmps(LHS, RHS, I))
5765 return replaceInstUsesWith(I, V);
5766
5767 if (Instruction *CastedXor = foldCastedBitwiseLogic(I))
5768 return CastedXor;
5769
5770 if (Instruction *Abs = canonicalizeAbs(Xor&: I, Builder))
5771 return Abs;
5772
5773 // Otherwise, if all else failed, try to hoist the xor-by-constant:
5774 // (X ^ C) ^ Y --> (X ^ Y) ^ C
5775 // Just like we do in other places, we completely avoid the fold
5776 // for constantexprs, at least to avoid endless combine loop.
5777 if (match(V: &I, P: m_c_Xor(L: m_OneUse(SubPattern: m_Xor(L: m_Value(V&: X, P: m_Unless(P: m_ConstantExpr())),
5778 R: m_ImmConstant(C&: C1))),
5779 R: m_Value(V&: Y))))
5780 return BinaryOperator::CreateXor(V1: Builder.CreateXor(LHS: X, RHS: Y), V2: C1);
5781
5782 if (Instruction *R = reassociateForUses(BO&: I, Builder))
5783 return R;
5784
5785 if (Instruction *Canonicalized = canonicalizeLogicFirst(I, Builder))
5786 return Canonicalized;
5787
5788 if (Instruction *Folded = foldLogicOfIsFPClass(BO&: I, Op0, Op1))
5789 return Folded;
5790
5791 if (Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(I))
5792 return Folded;
5793
5794 if (Instruction *Res = foldBinOpOfDisplacedShifts(I))
5795 return Res;
5796
5797 if (Instruction *Res = foldBitwiseLogicWithIntrinsics(I, Builder))
5798 return Res;
5799
5800 if (Instruction *Res = foldMaskedAddXorPattern(I, Builder))
5801 return Res;
5802
5803 return nullptr;
5804}
5805