llvm.org GIT mirror llvm / 1933132
Revert r300932 and r300930. It seems that r300930 was creating an infinite loop in dag-combine when compling the following file: MultiSource/Benchmarks/MiBench/consumer-typeset/z21.c git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300940 91177308-0d34-0410-b5e6-96231b3b80d8 Akira Hatanaka 3 years ago
9 changed file(s) with 59 addition(s) and 281 deletion(s). Raw diff Collapse all Expand all
23872387 New = N;
23882388 return true;
23892389 }
2390
2391 /// Check to see if the specified operand of the specified instruction is a
2392 /// constant integer. If so, check to see if there are any bits set in the
2393 /// constant that are not demanded. If so, shrink the constant and return
2394 /// true.
2395 bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
2396
2397 /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
2398 /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
2399 /// generalized for targets with other types of implicit widening casts.
2400 bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
2401 const SDLoc &dl);
2402
2403 /// Helper for SimplifyDemandedBits that can simplify an operation with
2404 /// multiple uses. This function uses TLI.SimplifyDemandedBits to
2405 /// simplify Operand \p OpIdx of \p User and then updated \p User with
2406 /// the simplified version. No other uses of \p OpIdx are updated.
2407 /// If \p User is the only user of \p OpIdx, this function behaves exactly
2408 /// like TLI.SimplifyDemandedBits except that it also updates the DAG by
2409 /// calling DCI.CommitTargetLoweringOpt.
2410 bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
2411 const APInt &Demanded, DAGCombinerInfo &DCI);
23902412 };
2391
2392 /// Check to see if the specified operand of the specified instruction is a
2393 /// constant integer. If so, check to see if there are any bits set in the
2394 /// constant that are not demanded. If so, shrink the constant and return
2395 /// true.
2396 bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
2397 TargetLoweringOpt &TLO) const;
2398
2399 // Target hook to do target-specific const optimization, which is called by
2400 // ShrinkDemandedConstant. This function should return true if the target
2401 // doesn't want ShrinkDemandedConstant to further optimize the constant.
2402 virtual bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
2403 TargetLoweringOpt &TLO) const {
2404 return false;
2405 }
2406
2407 /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
2408 /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
2409 /// generalized for targets with other types of implicit widening casts.
2410 bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
2411 TargetLoweringOpt &TLO) const;
2412
2413 /// Helper for SimplifyDemandedBits that can simplify an operation with
2414 /// multiple uses. This function simplifies operand \p OpIdx of \p User and
2415 /// then updates \p User with the simplified version. No other uses of
2416 /// \p OpIdx are updated. If \p User is the only user of \p OpIdx, this
2417 /// function behaves exactly like function SimplifyDemandedBits declared
2418 /// below except that it also updates the DAG by calling
2419 /// DCI.CommitTargetLoweringOpt.
2420 bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, const APInt &Demanded,
2421 DAGCombinerInfo &DCI, TargetLoweringOpt &TLO) const;
24222413
24232414 /// Look at Op. At this point, we know that only the DemandedMask bits of the
24242415 /// result of Op are ever used downstream. If we can use this information to
341341 /// If the specified instruction has a constant integer operand and there are
342342 /// bits set in that constant that are not demanded, then clear those bits and
343343 /// return true.
344 bool TargetLowering::ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
345 TargetLoweringOpt &TLO) const {
346 SelectionDAG &DAG = TLO.DAG;
344 bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
345 SDValue Op, const APInt &Demanded) {
347346 SDLoc DL(Op);
348347 unsigned Opcode = Op.getOpcode();
349
350 // Do target-specific constant optimization.
351 if (targetShrinkDemandedConstant(Op, Demanded, TLO))
352 return TLO.New.getNode();
353348
354349 // FIXME: ISD::SELECT, ISD::SELECT_CC
355350 switch (Opcode) {
371366 EVT VT = Op.getValueType();
372367 SDValue NewC = DAG.getConstant(Demanded & C, DL, VT);
373368 SDValue NewOp = DAG.getNode(Opcode, DL, VT, Op.getOperand(0), NewC);
374 return TLO.CombineTo(Op, NewOp);
369 return CombineTo(Op, NewOp);
375370 }
376371
377372 break;
384379 /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
385380 /// This uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
386381 /// generalized for targets with other types of implicit widening casts.
387 bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
388 const APInt &Demanded,
389 TargetLoweringOpt &TLO) const {
382 bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
383 unsigned BitWidth,
384 const APInt &Demanded,
385 const SDLoc &dl) {
390386 assert(Op.getNumOperands() == 2 &&
391387 "ShrinkDemandedOp only supports binary operators!");
392388 assert(Op.getNode()->getNumValues() == 1 &&
393389 "ShrinkDemandedOp only supports nodes with one result!");
394
395 SelectionDAG &DAG = TLO.DAG;
396 SDLoc dl(Op);
397390
398391 // Early return, as this function cannot handle vector types.
399392 if (Op.getValueType().isVector())
424417 bool NeedZext = DemandedSize > SmallVTBits;
425418 SDValue Z = DAG.getNode(NeedZext ? ISD::ZERO_EXTEND : ISD::ANY_EXTEND,
426419 dl, Op.getValueType(), X);
427 return TLO.CombineTo(Op, Z);
420 return CombineTo(Op, Z);
428421 }
429422 }
430423 return false;
431424 }
432425
433426 bool
434 TargetLowering::SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
435 const APInt &Demanded,
436 DAGCombinerInfo &DCI,
437 TargetLoweringOpt &TLO) const {
427 TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
428 unsigned OpIdx,
429 const APInt &Demanded,
430 DAGCombinerInfo &DCI) {
431 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
438432 SDValue Op = User->getOperand(OpIdx);
439433 APInt KnownZero, KnownOne;
440434
441 if (!SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
442 TLO, 0, true))
435 if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
436 *this, 0, true))
443437 return false;
444438
445439
451445 // with the value 'x', which will give us:
452446 // Old = i32 and x, 0xffffff
453447 // New = x
454 if (TLO.Old.hasOneUse()) {
448 if (Old.hasOneUse()) {
455449 // For the one use case, we just commit the change.
456 DCI.CommitTargetLoweringOpt(TLO);
450 DCI.CommitTargetLoweringOpt(*this);
457451 return true;
458452 }
459453
461455 // AssumeSingleUse flag is not propogated to recursive calls of
462456 // SimplifyDemanded bits, so the only node with multiple use that
463457 // it will attempt to combine will be opt.
464 assert(TLO.Old == Op);
458 assert(Old == Op);
465459
466460 SmallVector NewOps;
467461 for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
468462 if (i == OpIdx) {
469 NewOps.push_back(TLO.New);
463 NewOps.push_back(New);
470464 continue;
471465 }
472466 NewOps.push_back(User->getOperand(i));
473467 }
474 TLO.DAG.UpdateNodeOperands(User, NewOps);
468 DAG.UpdateNodeOperands(User, NewOps);
475469 // Op has less users now, so we may be able to perform additional combines
476470 // with it.
477471 DCI.AddToWorklist(Op.getNode());
590584
591585 // If any of the set bits in the RHS are known zero on the LHS, shrink
592586 // the constant.
593 if (ShrinkDemandedConstant(Op, ~LHSZero & NewMask, TLO))
587 if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & NewMask))
594588 return true;
595589
596590 // Bitwise-not (xor X, -1) is a special case: we don't usually shrink its
625619 if ((NewMask & (KnownZero|KnownZero2)) == NewMask)
626620 return TLO.CombineTo(Op, TLO.DAG.getConstant(0, dl, Op.getValueType()));
627621 // If the RHS is a constant, see if we can simplify it.
628 if (ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask, TLO))
622 if (TLO.ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask))
629623 return true;
630624 // If the operation can be done in a smaller type, do so.
631 if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
625 if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
632626 return true;
633627
634628 // Output known-1 bits are only known if set in both the LHS & RHS.
659653 if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask))
660654 return TLO.CombineTo(Op, Op.getOperand(1));
661655 // If the RHS is a constant, see if we can simplify it.
662 if (ShrinkDemandedConstant(Op, NewMask, TLO))
656 if (TLO.ShrinkDemandedConstant(Op, NewMask))
663657 return true;
664658 // If the operation can be done in a smaller type, do so.
665 if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
659 if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
666660 return true;
667661
668662 // Output known-0 bits are only known if clear in both the LHS & RHS.
687681 if ((KnownZero2 & NewMask) == NewMask)
688682 return TLO.CombineTo(Op, Op.getOperand(1));
689683 // If the operation can be done in a smaller type, do so.
690 if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
684 if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
691685 return true;
692686
693687 // If all of the unknown bits are known to be zero on one side or the other
732726 }
733727 // If it already has all the bits set, nothing to change
734728 // but don't shrink either!
735 } else if (ShrinkDemandedConstant(Op, NewMask, TLO)) {
729 } else if (TLO.ShrinkDemandedConstant(Op, NewMask)) {
736730 return true;
737731 }
738732 }
751745 assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
752746
753747 // If the operands are constants, see if we can simplify them.
754 if (ShrinkDemandedConstant(Op, NewMask, TLO))
748 if (TLO.ShrinkDemandedConstant(Op, NewMask))
755749 return true;
756750
757751 // Only known if known in both the LHS and RHS.
769763 assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
770764
771765 // If the operands are constants, see if we can simplify them.
772 if (ShrinkDemandedConstant(Op, NewMask, TLO))
766 if (TLO.ShrinkDemandedConstant(Op, NewMask))
773767 return true;
774768
775769 // Only known if known in both the LHS and RHS.
12891283 SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2,
12901284 KnownOne2, TLO, Depth+1) ||
12911285 // See if the operation should be performed at a smaller bit width.
1292 ShrinkDemandedOp(Op, BitWidth, NewMask, TLO)) {
1286 TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) {
12931287 const SDNodeFlags *Flags = Op.getNode()->getFlags();
12941288 if (Flags->hasNoSignedWrap() || Flags->hasNoUnsignedWrap()) {
12951289 // Disable the nsw and nuw flags. We can no longer guarantee that we
9090
9191 STATISTIC(NumTailCalls, "Number of tail calls");
9292 STATISTIC(NumShiftInserts, "Number of vector shift inserts");
93 STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
9493
9594 static cl::opt
9695 EnableAArch64SlrGeneration("aarch64-shift-insert-generation", cl::Hidden,
104103 "aarch64-elf-ldtls-generation", cl::Hidden,
105104 cl::desc("Allow AArch64 Local Dynamic TLS code generation"),
106105 cl::init(false));
107
108 static cl::opt
109 EnableOptimizeLogicalImm("aarch64-enable-logical-imm", cl::Hidden,
110 cl::desc("Enable AArch64 logical imm instruction "
111 "optimization"),
112 cl::init(true));
113106
114107 /// Value type used for condition codes.
115108 static const MVT MVT_CC = MVT::i32;
791784 if (!VT.isVector())
792785 return MVT::i32;
793786 return VT.changeVectorElementTypeToInteger();
794 }
795
796 static bool optimizeLogicalImm(SDValue Op, unsigned Size, uint64_t Imm,
797 const APInt &Demanded,
798 TargetLowering::TargetLoweringOpt &TLO,
799 unsigned NewOpc) {
800 uint64_t OldImm = Imm, NewImm, Enc;
801 uint64_t Mask = ((uint64_t)(-1LL) >> (64 - Size));
802
803 // Return if the immediate is already a bimm32 or bimm64.
804 if (AArch64_AM::isLogicalImmediate(Imm & Mask, Size))
805 return false;
806
807 unsigned EltSize = Size;
808 uint64_t DemandedBits = Demanded.getZExtValue();
809
810 // Clear bits that are not demanded.
811 Imm &= DemandedBits;
812
813 while (true) {
814 // The goal here is to set the non-demanded bits in a way that minimizes
815 // the number of switching between 0 and 1. In order to achieve this goal,
816 // we set the non-demanded bits to the value of the preceding demanded bits.
817 // For example, if we have an immediate 0bx10xx0x1 ('x' indicates a
818 // non-demanded bit), we copy bit0 (1) to the least significant 'x',
819 // bit2 (0) to 'xx', and bit6 (1) to the most significant 'x'.
820 // The final result is 0b11000011.
821 uint64_t NonDemandedBits = ~DemandedBits;
822 uint64_t InvertedImm = ~Imm & DemandedBits;
823 uint64_t RotatedImm =
824 ((InvertedImm << 1) | (InvertedImm >> (EltSize - 1) & 1)) &
825 NonDemandedBits;
826 uint64_t Sum = RotatedImm + NonDemandedBits;
827 bool Carry = NonDemandedBits & ~Sum & (1ULL << (EltSize - 1));
828 uint64_t Ones = (Sum + Carry) & NonDemandedBits;
829 NewImm = (Imm | Ones) & Mask;
830
831 // If NewImm or its bitwise NOT is a shifted mask, it is a bitmask immediate
832 // or all-ones or all-zeros, in which case we can stop searching. Otherwise,
833 // we halve the element size and continue the search.
834 if (isShiftedMask_64(NewImm) || isShiftedMask_64(~(NewImm | ~Mask)))
835 break;
836
837 // We cannot shrink the element size any further if it is 2-bits.
838 if (EltSize == 2)
839 return false;
840
841 EltSize /= 2;
842 Mask >>= EltSize;
843 uint64_t Hi = Imm >> EltSize, DemandedBitsHi = DemandedBits >> EltSize;
844
845 // Return if there is mismatch in any of the demanded bits of Imm and Hi.
846 if (((Imm ^ Hi) & (DemandedBits & DemandedBitsHi) & Mask) != 0)
847 return false;
848
849 // Merge the upper and lower halves of Imm and DemandedBits.
850 Imm |= Hi;
851 DemandedBits |= DemandedBitsHi;
852 }
853
854 ++NumOptimizedImms;
855
856 // Replicate the element across the register width.
857 while (EltSize < Size) {
858 NewImm |= NewImm << EltSize;
859 EltSize *= 2;
860 }
861
862 (void)OldImm;
863 assert(((OldImm ^ NewImm) & Demanded.getZExtValue()) == 0 &&
864 "demanded bits should never be altered");
865
866 // Create the new constant immediate node.
867 EVT VT = Op.getValueType();
868 unsigned Population = countPopulation(NewImm);
869 SDLoc DL(Op);
870
871 // If the new constant immediate is all-zeros or all-ones, let the target
872 // independent DAG combine optimize this node.
873 if (Population == 0 || Population == Size)
874 return TLO.CombineTo(Op.getOperand(1), TLO.DAG.getConstant(NewImm, DL, VT));
875
876 // Otherwise, create a machine node so that target independent DAG combine
877 // doesn't undo this optimization.
878 Enc = AArch64_AM::encodeLogicalImmediate(NewImm, Size);
879 SDValue EncConst = TLO.DAG.getTargetConstant(Enc, DL, VT);
880 SDValue New(
881 TLO.DAG.getMachineNode(NewOpc, DL, VT, Op.getOperand(0), EncConst), 0);
882
883 return TLO.CombineTo(Op, New);
884 }
885
886 bool AArch64TargetLowering::targetShrinkDemandedConstant(
887 SDValue Op, const APInt &Demanded, TargetLoweringOpt &TLO) const {
888 // Delay this optimization to as late as possible.
889 if (!TLO.LegalOps)
890 return false;
891
892 if (!EnableOptimizeLogicalImm)
893 return false;
894
895 EVT VT = Op.getValueType();
896 if (VT.isVector())
897 return false;
898
899 unsigned Size = VT.getSizeInBits();
900 assert((Size == 32 || Size == 64) &&
901 "i32 or i64 is expected after legalization.");
902
903 // Exit early if we demand all bits.
904 if (Demanded.countPopulation() == Size)
905 return false;
906
907 unsigned NewOpc;
908 switch (Op.getOpcode()) {
909 default:
910 return false;
911 case ISD::AND:
912 NewOpc = Size == 32 ? AArch64::ANDWri : AArch64::ANDXri;
913 break;
914 case ISD::OR:
915 NewOpc = Size == 32 ? AArch64::ORRWri : AArch64::ORRXri;
916 break;
917 case ISD::XOR:
918 NewOpc = Size == 32 ? AArch64::EORWri : AArch64::EORXri;
919 break;
920 }
921 ConstantSDNode *C = dyn_cast(Op.getOperand(1));
922 if (!C)
923 return false;
924 uint64_t Imm = C->getZExtValue();
925 return optimizeLogicalImm(Op, Size, Imm, Demanded, TLO, NewOpc);
926787 }
927788
928789 /// computeKnownBitsForTargetNode - Determine which of the bits specified in
253253 APInt &KnownOne, const APInt &DemandedElts,
254254 const SelectionDAG &DAG,
255255 unsigned Depth = 0) const override;
256
257 bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
258 TargetLoweringOpt &TLO) const override;
259256
260257 MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override;
261258
23142314
23152315 SelectionDAG &DAG = DCI.DAG;
23162316 SDValue Op = Node24->getOperand(OpIdx);
2317 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23182317 EVT VT = Op.getValueType();
23192318
23202319 APInt Demanded = APInt::getLowBitsSet(VT.getSizeInBits(), 24);
23212320 APInt KnownZero, KnownOne;
23222321 TargetLowering::TargetLoweringOpt TLO(DAG, true, true);
2323 if (TLI.SimplifyDemandedBits(Node24, OpIdx, Demanded, DCI, TLO))
2322 if (TLO.SimplifyDemandedBits(Node24, OpIdx, Demanded, DCI))
23242323 return true;
23252324
23262325 return false;
33613360 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
33623361 !DCI.isBeforeLegalizeOps());
33633362 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
3364 if (TLI.ShrinkDemandedConstant(BitsFrom, Demanded, TLO) ||
3363 if (TLO.ShrinkDemandedConstant(BitsFrom, Demanded) ||
33653364 TLI.SimplifyDemandedBits(BitsFrom, Demanded,
33663365 KnownZero, KnownOne, TLO)) {
33673366 DCI.CommitTargetLoweringOpt(TLO);
46954695 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
46964696 !DCI.isBeforeLegalizeOps());
46974697 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4698 if (TLI.ShrinkDemandedConstant(Src, Demanded, TLO) ||
4698 if (TLO.ShrinkDemandedConstant(Src, Demanded) ||
46994699 TLI.SimplifyDemandedBits(Src, Demanded, KnownZero, KnownOne, TLO)) {
47004700 DCI.CommitTargetLoweringOpt(TLO);
47014701 }
3020630206 APInt KnownZero, KnownOne;
3020730207 TargetLowering::TargetLoweringOpt TLO(DAG, DCI.isBeforeLegalize(),
3020830208 DCI.isBeforeLegalizeOps());
30209 if (TLI.ShrinkDemandedConstant(Cond, DemandedMask, TLO) ||
30209 if (TLO.ShrinkDemandedConstant(Cond, DemandedMask) ||
3021030210 TLI.SimplifyDemandedBits(Cond, DemandedMask, KnownZero, KnownOne,
3021130211 TLO)) {
3021230212 // If we changed the computation somewhere in the DAG, this change will
3377633776 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
3377733777 !DCI.isBeforeLegalizeOps());
3377833778 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
33779 if (TLI.ShrinkDemandedConstant(Op1, DemandedMask, TLO) ||
33779 if (TLO.ShrinkDemandedConstant(Op1, DemandedMask) ||
3378033780 TLI.SimplifyDemandedBits(Op1, DemandedMask, KnownZero, KnownOne, TLO))
3378133781 DCI.CommitTargetLoweringOpt(TLO);
3378233782 }
16041604 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
16051605 !DCI.isBeforeLegalizeOps());
16061606 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1607 if (TLI.ShrinkDemandedConstant(OutVal, DemandedMask, TLO) ||
1607 if (TLO.ShrinkDemandedConstant(OutVal, DemandedMask) ||
16081608 TLI.SimplifyDemandedBits(OutVal, DemandedMask, KnownZero, KnownOne,
16091609 TLO))
16101610 DCI.CommitTargetLoweringOpt(TLO);
16211621 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
16221622 !DCI.isBeforeLegalizeOps());
16231623 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1624 if (TLI.ShrinkDemandedConstant(Time, DemandedMask, TLO) ||
1624 if (TLO.ShrinkDemandedConstant(Time, DemandedMask) ||
16251625 TLI.SimplifyDemandedBits(Time, DemandedMask, KnownZero, KnownOne,
16261626 TLO))
16271627 DCI.CommitTargetLoweringOpt(TLO);
+0
-64
test/CodeGen/AArch64/optimize-imm.ll less more
None ; RUN: llc -o - %s -mtriple=aarch64-- | FileCheck %s
1
2 ; CHECK-LABEL: and1:
3 ; CHECK: and {{w[0-9]+}}, w0, #0xfffffffd
4
5 define void @and1(i32 %a, i8* nocapture %p) {
6 entry:
7 %and = and i32 %a, 253
8 %conv = trunc i32 %and to i8
9 store i8 %conv, i8* %p, align 1
10 ret void
11 }
12
13 ; (a & 0x3dfd) | 0xffffc000
14 ;
15 ; CHECK-LABEL: and2:
16 ; CHECK: and {{w[0-9]+}}, w0, #0xfdfdfdfd
17
18 define i32 @and2(i32 %a) {
19 entry:
20 %and = and i32 %a, 15869
21 %or = or i32 %and, -16384
22 ret i32 %or
23 }
24
25 ; (a & 0x19) | 0xffffffc0
26 ;
27 ; CHECK-LABEL: and3:
28 ; CHECK: and {{w[0-9]+}}, w0, #0x99999999
29
30 define i32 @and3(i32 %a) {
31 entry:
32 %and = and i32 %a, 25
33 %or = or i32 %and, -64
34 ret i32 %or
35 }
36
37 ; (a & 0xc5600) | 0xfff1f1ff
38 ;
39 ; CHECK-LABEL: and4:
40 ; CHECK: and {{w[0-9]+}}, w0, #0xfffc07ff
41
42 define i32 @and4(i32 %a) {
43 entry:
44 %and = and i32 %a, 787968
45 %or = or i32 %and, -921089
46 ret i32 %or
47 }
48
49 ; Make sure we don't shrink or optimize an XOR's immediate operand if the
50 ; immediate is -1. Instruction selection turns (and ((xor $mask, -1), $v0)) into
51 ; a BIC.
52
53 ; CHECK-LABEL: xor1:
54 ; CHECK: orr [[R0:w[0-9]+]], wzr, #0x38
55 ; CHECK: bic {{w[0-9]+}}, [[R0]], w0, lsl #3
56
57 define i32 @xor1(i32 %a) {
58 entry:
59 %shl = shl i32 %a, 3
60 %xor = and i32 %shl, 56
61 %and = xor i32 %xor, 56
62 ret i32 %and
63 }