LLVM 24.0.0git
ARMISelLowering.cpp
Go to the documentation of this file.
1//===- ARMISelLowering.cpp - ARM DAG Lowering Implementation --------------===//
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 defines the interfaces that ARM uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMISelLowering.h"
15#include "ARMBaseInstrInfo.h"
16#include "ARMBaseRegisterInfo.h"
17#include "ARMCallingConv.h"
20#include "ARMPerfectShuffle.h"
21#include "ARMRegisterInfo.h"
22#include "ARMSelectionDAGInfo.h"
23#include "ARMSubtarget.h"
27#include "Utils/ARMBaseInfo.h"
28#include "llvm/ADT/APFloat.h"
29#include "llvm/ADT/APInt.h"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/BitVector.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/STLExtras.h"
36#include "llvm/ADT/Statistic.h"
38#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/Twine.h"
67#include "llvm/IR/Attributes.h"
68#include "llvm/IR/CallingConv.h"
69#include "llvm/IR/Constant.h"
70#include "llvm/IR/Constants.h"
71#include "llvm/IR/DataLayout.h"
72#include "llvm/IR/DebugLoc.h"
74#include "llvm/IR/Function.h"
75#include "llvm/IR/GlobalAlias.h"
76#include "llvm/IR/GlobalValue.h"
78#include "llvm/IR/IRBuilder.h"
79#include "llvm/IR/InlineAsm.h"
80#include "llvm/IR/Instruction.h"
83#include "llvm/IR/Intrinsics.h"
84#include "llvm/IR/IntrinsicsARM.h"
85#include "llvm/IR/Module.h"
86#include "llvm/IR/Type.h"
87#include "llvm/IR/User.h"
88#include "llvm/IR/Value.h"
89#include "llvm/MC/MCInstrDesc.h"
91#include "llvm/MC/MCSchedule.h"
98#include "llvm/Support/Debug.h"
106#include <algorithm>
107#include <cassert>
108#include <cstdint>
109#include <iterator>
110#include <limits>
111#include <optional>
112#include <tuple>
113#include <utility>
114#include <vector>
115
116using namespace llvm;
117using namespace llvm::SDPatternMatch;
118
119#define DEBUG_TYPE "arm-isel"
120
121STATISTIC(NumTailCalls, "Number of tail calls");
122STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
123STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
124STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
125STATISTIC(NumConstpoolPromoted,
126 "Number of constants with their storage promoted into constant pools");
127
128static cl::opt<bool>
129ARMInterworking("arm-interworking", cl::Hidden,
130 cl::desc("Enable / disable ARM interworking (for debugging only)"),
131 cl::init(true));
132
134 "arm-promote-constant", cl::Hidden,
135 cl::desc("Enable / disable promotion of unnamed_addr constants into "
136 "constant pools"),
137 cl::init(false)); // FIXME: set to true by default once PR32780 is fixed
139 "arm-promote-constant-max-size", cl::Hidden,
140 cl::desc("Maximum size of constant to promote into a constant pool"),
141 cl::init(64));
143 "arm-promote-constant-max-total", cl::Hidden,
144 cl::desc("Maximum size of ALL constants to promote into a constant pool"),
145 cl::init(128));
146
148MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden,
149 cl::desc("Maximum interleave factor for MVE VLDn to generate."),
150 cl::init(2));
151
153 "arm-max-base-updates-to-check", cl::Hidden,
154 cl::desc("Maximum number of base-updates to check generating postindex."),
155 cl::init(64));
156
157/// Value type used for "flags" operands / results (either CPSR or FPSCR_NZCV).
158constexpr MVT FlagsVT = MVT::i32;
159
160// The APCS parameter registers.
161static const MCPhysReg GPRArgRegs[] = {
162 ARM::R0, ARM::R1, ARM::R2, ARM::R3
163};
164
166 SelectionDAG &DAG, const SDLoc &DL) {
168 assert(Arg.ArgVT.bitsLT(MVT::i32));
169 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
170 SDValue Ext =
172 MVT::i32, Trunc);
173 return Ext;
174}
175
176void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
177 if (VT != PromotedLdStVT) {
179 AddPromotedToType (ISD::LOAD, VT, PromotedLdStVT);
180
182 AddPromotedToType (ISD::STORE, VT, PromotedLdStVT);
183 }
184
185 MVT ElemTy = VT.getVectorElementType();
186 if (ElemTy != MVT::f64)
190 if (ElemTy == MVT::i32) {
195 } else {
200 }
209 if (VT.isInteger()) {
213 }
214
215 // Neon does not support vector divide/remainder operations.
224
225 if (!VT.isFloatingPoint() && VT != MVT::v2i64 && VT != MVT::v1i64)
226 for (auto Opcode : {ISD::ABS, ISD::ABDS, ISD::ABDU, ISD::SMIN, ISD::SMAX,
228 setOperationAction(Opcode, VT, Legal);
229 if (!VT.isFloatingPoint())
230 for (auto Opcode : {ISD::SADDSAT, ISD::UADDSAT, ISD::SSUBSAT, ISD::USUBSAT})
231 setOperationAction(Opcode, VT, Legal);
232}
233
234void ARMTargetLowering::addDRTypeForNEON(MVT VT) {
235 addRegisterClass(VT, &ARM::DPRRegClass);
236 addTypeForNEON(VT, MVT::f64);
237}
238
239void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
240 addRegisterClass(VT, &ARM::DPairRegClass);
241 addTypeForNEON(VT, MVT::v2f64);
242}
243
244void ARMTargetLowering::setAllExpand(MVT VT) {
245 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
247
248 // We support these really simple operations even on types where all
249 // the actual arithmetic has to be broken down into simpler
250 // operations or turned into library calls.
255}
256
257void ARMTargetLowering::addAllExtLoads(const MVT From, const MVT To,
258 LegalizeAction Action) {
259 setLoadExtAction(ISD::EXTLOAD, From, To, Action);
260 setLoadExtAction(ISD::ZEXTLOAD, From, To, Action);
261 setLoadExtAction(ISD::SEXTLOAD, From, To, Action);
262}
263
264void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
265 const MVT IntTypes[] = { MVT::v16i8, MVT::v8i16, MVT::v4i32 };
266
267 for (auto VT : IntTypes) {
268 addRegisterClass(VT, &ARM::MQPRRegClass);
299
300 // No native support for these.
310
311 // Vector reductions
321
322 if (!HasMVEFP) {
327 } else {
330 }
331
332 // Pre and Post inc are supported on loads and stores
333 for (unsigned im = (unsigned)ISD::PRE_INC;
334 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
339 }
340 }
341
342 const MVT FloatTypes[] = { MVT::v8f16, MVT::v4f32 };
343 for (auto VT : FloatTypes) {
344 addRegisterClass(VT, &ARM::MQPRRegClass);
345 if (!HasMVEFP)
346 setAllExpand(VT);
347
348 // These are legal or custom whether we have MVE.fp or not
361
362 // Pre and Post inc are supported on loads and stores
363 for (unsigned im = (unsigned)ISD::PRE_INC;
364 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
369 }
370
371 if (HasMVEFP) {
374 for (auto Op :
379 }
384
385 // No native support for these.
400 }
401 }
402
403 // Custom Expand smaller than legal vector reductions to prevent false zero
404 // items being added.
413
414 // We 'support' these types up to bitcast/load/store level, regardless of
415 // MVE integer-only / float support. Only doing FP data processing on the FP
416 // vector types is inhibited at integer-only level.
417 const MVT LongTypes[] = { MVT::v2i64, MVT::v2f64 };
418 for (auto VT : LongTypes) {
419 addRegisterClass(VT, &ARM::MQPRRegClass);
420 setAllExpand(VT);
426 }
428
429 // We can do bitwise operations on v2i64 vectors
430 setOperationAction(ISD::AND, MVT::v2i64, Legal);
431 setOperationAction(ISD::OR, MVT::v2i64, Legal);
432 setOperationAction(ISD::XOR, MVT::v2i64, Legal);
433
434 // It is legal to extload from v4i8 to v4i16 or v4i32.
435 addAllExtLoads(MVT::v8i16, MVT::v8i8, Legal);
436 addAllExtLoads(MVT::v4i32, MVT::v4i16, Legal);
437 addAllExtLoads(MVT::v4i32, MVT::v4i8, Legal);
438
439 // It is legal to sign extend from v4i8/v4i16 to v4i32 or v8i8 to v8i16.
445
446 // Some truncating stores are legal too.
447 setTruncStoreAction(MVT::v4i32, MVT::v4i16, Legal);
448 setTruncStoreAction(MVT::v4i32, MVT::v4i8, Legal);
449 setTruncStoreAction(MVT::v8i16, MVT::v8i8, Legal);
450
451 // Pre and Post inc on these are legal, given the correct extends
452 for (unsigned im = (unsigned)ISD::PRE_INC;
453 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
454 for (auto VT : {MVT::v8i8, MVT::v4i8, MVT::v4i16}) {
459 }
460 }
461
462 // Predicate types
463 const MVT pTypes[] = {MVT::v16i1, MVT::v8i1, MVT::v4i1, MVT::v2i1};
464 for (auto VT : pTypes) {
465 addRegisterClass(VT, &ARM::VCCRRegClass);
480
481 if (!HasMVEFP) {
486 }
487 }
491 setOperationAction(ISD::OR, MVT::v2i1, Expand);
497
506}
507
509 return static_cast<const ARMBaseTargetMachine &>(getTargetMachine());
510}
511
513 const ARMSubtarget &STI)
514 : TargetLowering(TM_, STI), Subtarget(&STI),
515 RegInfo(Subtarget->getRegisterInfo()),
516 Itins(Subtarget->getInstrItineraryData()) {
517 const auto &TM = static_cast<const ARMBaseTargetMachine &>(TM_);
518
521
522 const Triple &TT = TM.getTargetTriple();
523
524 if (Subtarget->isThumb1Only())
525 addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
526 else
527 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
528
529 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only() &&
530 Subtarget->hasFPRegs()) {
531 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
532 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
533
534 if (!Subtarget->hasVFP2Base()) {
535 setAllExpand(MVT::f32);
536 } else {
539
542 setOperationAction(Op, MVT::f32, Legal);
543 }
544 if (!Subtarget->hasFP64()) {
545 setAllExpand(MVT::f64);
546 } else {
549 setOperationAction(Op, MVT::f64, Legal);
550
552 }
553 }
554
555 if (Subtarget->hasFullFP16()) {
558 setOperationAction(Op, MVT::f16, Legal);
559
560 addRegisterClass(MVT::f16, &ARM::HPRRegClass);
563
568 }
569
570 if (Subtarget->hasBF16()) {
571 addRegisterClass(MVT::bf16, &ARM::HPRRegClass);
572 setAllExpand(MVT::bf16);
573 if (!Subtarget->hasFullFP16())
577 } else {
582 }
583
585 for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
586 setTruncStoreAction(VT, InnerVT, Expand);
587 addAllExtLoads(VT, InnerVT, Expand);
588 }
589
592
594 }
595
596 if (!Subtarget->isThumb1Only() && !Subtarget->hasV8_1MMainlineOps())
598
599 if (!Subtarget->hasV8_1MMainlineOps())
601
602 if (!Subtarget->isThumb1Only())
604
607
610
611 if (Subtarget->hasMVEIntegerOps())
612 addMVEVectorTypes(Subtarget->hasMVEFloatOps());
613
614 // Combine low-overhead loop intrinsics so that we can lower i1 types.
615 if (Subtarget->hasLOB()) {
617 }
618
619 if (Subtarget->hasNEON()) {
620 addDRTypeForNEON(MVT::v2f32);
621 addDRTypeForNEON(MVT::v8i8);
622 addDRTypeForNEON(MVT::v4i16);
623 addDRTypeForNEON(MVT::v2i32);
624 addDRTypeForNEON(MVT::v1i64);
625
626 addQRTypeForNEON(MVT::v4f32);
627 addQRTypeForNEON(MVT::v2f64);
628 addQRTypeForNEON(MVT::v16i8);
629 addQRTypeForNEON(MVT::v8i16);
630 addQRTypeForNEON(MVT::v4i32);
631 addQRTypeForNEON(MVT::v2i64);
632
633 if (Subtarget->hasFullFP16()) {
634 addQRTypeForNEON(MVT::v8f16);
635 addDRTypeForNEON(MVT::v4f16);
636 }
637
638 if (Subtarget->hasBF16()) {
639 addQRTypeForNEON(MVT::v8bf16);
640 addDRTypeForNEON(MVT::v4bf16);
641 }
642 }
643
644 if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) {
645 // v2f64 is legal so that QR subregs can be extracted as f64 elements, but
646 // none of Neon, MVE or VFP supports any arithmetic operations on it.
647 setOperationAction(ISD::FADD, MVT::v2f64, Expand);
648 setOperationAction(ISD::FSUB, MVT::v2f64, Expand);
649 setOperationAction(ISD::FMUL, MVT::v2f64, Expand);
650 // FIXME: Code duplication: FDIV and FREM are expanded always, see
651 // ARMTargetLowering::addTypeForNEON method for details.
652 setOperationAction(ISD::FDIV, MVT::v2f64, Expand);
653 setOperationAction(ISD::FREM, MVT::v2f64, Expand);
654 // FIXME: Create unittest.
655 // In another words, find a way when "copysign" appears in DAG with vector
656 // operands.
658 // FIXME: Code duplication: SETCC has custom operation action, see
659 // ARMTargetLowering::addTypeForNEON method for details.
661 // FIXME: Create unittest for FNEG and for FABS.
662 setOperationAction(ISD::FNEG, MVT::v2f64, Expand);
663 setOperationAction(ISD::FABS, MVT::v2f64, Expand);
665 setOperationAction(ISD::FSIN, MVT::v2f64, Expand);
666 setOperationAction(ISD::FCOS, MVT::v2f64, Expand);
667 setOperationAction(ISD::FTAN, MVT::v2f64, Expand);
668 setOperationAction(ISD::FPOW, MVT::v2f64, Expand);
669 setOperationAction(ISD::FLOG, MVT::v2f64, Expand);
672 setOperationAction(ISD::FEXP, MVT::v2f64, Expand);
681 setOperationAction(ISD::FMA, MVT::v2f64, Expand);
682 }
683
684 if (Subtarget->hasNEON()) {
685 // The same with v4f32. But keep in mind that vadd, vsub, vmul are natively
686 // supported for v4f32.
688 setOperationAction(ISD::FSIN, MVT::v4f32, Expand);
689 setOperationAction(ISD::FCOS, MVT::v4f32, Expand);
690 setOperationAction(ISD::FTAN, MVT::v4f32, Expand);
691 setOperationAction(ISD::FPOW, MVT::v4f32, Expand);
692 setOperationAction(ISD::FLOG, MVT::v4f32, Expand);
695 setOperationAction(ISD::FEXP, MVT::v4f32, Expand);
704
705 // Mark v2f32 intrinsics.
707 setOperationAction(ISD::FSIN, MVT::v2f32, Expand);
708 setOperationAction(ISD::FCOS, MVT::v2f32, Expand);
709 setOperationAction(ISD::FTAN, MVT::v2f32, Expand);
710 setOperationAction(ISD::FPOW, MVT::v2f32, Expand);
711 setOperationAction(ISD::FLOG, MVT::v2f32, Expand);
714 setOperationAction(ISD::FEXP, MVT::v2f32, Expand);
723
726 setOperationAction(Op, MVT::v4f16, Expand);
727 setOperationAction(Op, MVT::v8f16, Expand);
728 }
729
730 // Neon does not support some operations on v1i64 and v2i64 types.
731 setOperationAction(ISD::MUL, MVT::v1i64, Expand);
732 // Custom handling for some quad-vector types to detect VMULL.
733 setOperationAction(ISD::MUL, MVT::v8i16, Custom);
734 setOperationAction(ISD::MUL, MVT::v4i32, Custom);
735 setOperationAction(ISD::MUL, MVT::v2i64, Custom);
736 // Custom handling for some vector types to avoid expensive expansions
737 setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
739 setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
741 // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
742 // a destination type that is wider than the source, and nor does
743 // it have a FP_TO_[SU]INT instruction with a narrower destination than
744 // source.
753
756
757 // NEON does not have single instruction CTPOP for vectors with element
758 // types wider than 8-bits. However, custom lowering can leverage the
759 // v8i8/v16i8 vcnt instruction.
766
767 setOperationAction(ISD::CTLZ, MVT::v1i64, Expand);
768 setOperationAction(ISD::CTLZ, MVT::v2i64, Expand);
769
770 // NEON does not have single instruction CTTZ for vectors.
772 setOperationAction(ISD::CTTZ, MVT::v4i16, Custom);
773 setOperationAction(ISD::CTTZ, MVT::v2i32, Custom);
774 setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
775
776 setOperationAction(ISD::CTTZ, MVT::v16i8, Custom);
777 setOperationAction(ISD::CTTZ, MVT::v8i16, Custom);
778 setOperationAction(ISD::CTTZ, MVT::v4i32, Custom);
779 setOperationAction(ISD::CTTZ, MVT::v2i64, Custom);
780
785
790
794 }
795
796 // NEON only has FMA instructions as of VFP4.
797 if (!Subtarget->hasVFP4Base()) {
798 setOperationAction(ISD::FMA, MVT::v2f32, Expand);
799 setOperationAction(ISD::FMA, MVT::v4f32, Expand);
800 }
801
804
805 // It is legal to extload from v4i8 to v4i16 or v4i32.
806 for (MVT Ty : {MVT::v8i8, MVT::v4i8, MVT::v2i8, MVT::v4i16, MVT::v2i16,
807 MVT::v2i32}) {
812 }
813 }
814
815 for (auto VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v16i8, MVT::v8i16,
816 MVT::v4i32}) {
821 }
822 }
823
824 if (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) {
831 }
832 if (Subtarget->hasMVEIntegerOps()) {
835 ISD::SETCC});
836 }
837 if (Subtarget->hasMVEFloatOps()) {
839 }
840
841 if (!Subtarget->hasFP64()) {
842 // When targeting a floating-point unit with only single-precision
843 // operations, f64 is legal for the few double-precision instructions which
844 // are present However, no double-precision operations other than moves,
845 // loads and stores are provided by the hardware.
882 }
883
884 // STRICT_(U/S)INT_TO_FP specifically use the input MVT to register with
885 // setOperationAction() as opposed to other opcodes that use the output MVT
886 // All inputs should be i32 due to type legalization
889
892
893 if (!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) {
896 if (Subtarget->hasFullFP16()) {
899 }
900 } else {
902 }
903
904 if (!Subtarget->hasFP16()) {
907 } else {
910 }
911
912 computeRegisterProperties(Subtarget->getRegisterInfo());
913
914 // ARM does not have floating-point extending loads.
915 for (MVT VT : MVT::fp_valuetypes()) {
916 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
917 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
918 setLoadExtAction(ISD::EXTLOAD, VT, MVT::bf16, Expand);
919 }
920
921 // ... or truncating stores
922 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
923 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
924 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
925 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
926 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
927
928 // ARM does not have i1 sign extending load.
929 for (MVT VT : MVT::integer_valuetypes())
931
932 // ARM supports all 4 flavors of integer indexed load / store.
933 if (!Subtarget->isThumb1Only()) {
934 for (unsigned im = (unsigned)ISD::PRE_INC;
936 setIndexedLoadAction(im, MVT::i1, Legal);
937 setIndexedLoadAction(im, MVT::i8, Legal);
938 setIndexedLoadAction(im, MVT::i16, Legal);
939 setIndexedLoadAction(im, MVT::i32, Legal);
940 setIndexedStoreAction(im, MVT::i1, Legal);
941 setIndexedStoreAction(im, MVT::i8, Legal);
942 setIndexedStoreAction(im, MVT::i16, Legal);
943 setIndexedStoreAction(im, MVT::i32, Legal);
944 }
945 } else {
946 // Thumb-1 has limited post-inc load/store support - LDM r0!, {r1}.
949 }
950
951 // Custom loads/stores to possible use __aeabi_uread/write*
952 if (TT.isTargetAEABI() && !Subtarget->allowsUnalignedMem()) {
957 }
958
963
964 if (!Subtarget->isThumb1Only()) {
967 }
968
973 if (Subtarget->hasDSP()) {
982 }
983 if (Subtarget->hasBaseDSP()) {
986 }
987
988 // i64 operation support.
991 if (Subtarget->isThumb1Only()) {
994 }
995 if (Subtarget->isThumb1Only() || !Subtarget->hasV6Ops()
996 || (Subtarget->isThumb2() && !Subtarget->hasDSP()))
998
1008
1009 // MVE lowers 64 bit shifts to lsll and lsrl
1010 // assuming that ISD::SRL and SRA of i64 are already marked custom
1011 if (Subtarget->hasMVEIntegerOps())
1013
1014 // Expand to __aeabi_l{lsl,lsr,asr} calls for Thumb1.
1015 if (Subtarget->isThumb1Only()) {
1019 }
1020
1021 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops())
1023
1024 // ARM does not have ROTL.
1029 }
1031 // TODO: These two should be set to LibCall, but this currently breaks
1032 // the Linux kernel build. See #101786.
1035 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
1038 }
1039
1040 // @llvm.readcyclecounter requires the Performance Monitors extension.
1041 // Default to the 0 expansion on unsupported platforms.
1042 // FIXME: Technically there are older ARM CPUs that have
1043 // implementation-specific ways of obtaining this information.
1044 if (Subtarget->hasPerfMon())
1046
1047 // Only ARMv6 has BSWAP.
1048 if (!Subtarget->hasV6Ops())
1050
1051 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
1052 : Subtarget->hasDivideInARMMode();
1053 if (!hasDivide) {
1054 // These are expanded into libcalls if the cpu doesn't have HW divider.
1057 }
1058
1059 if (TT.isOSWindows() && !Subtarget->hasDivideInThumbMode()) {
1062
1065 }
1066
1069
1070 // Register based DivRem for AEABI (RTABI 4.2)
1071 if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
1072 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isOSWindows()) {
1075 HasStandaloneRem = false;
1076
1081 } else {
1084 }
1085
1090
1091 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1093
1094 // Use the default implementation.
1096 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1098 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1101
1102 if (TT.isOSWindows())
1104 else
1106
1107 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
1108 // the default expansion.
1109 InsertFencesForAtomic = false;
1110 if (Subtarget->hasAnyDataBarrier() &&
1111 (!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps())) {
1112 // ATOMIC_FENCE needs custom lowering; the others should have been expanded
1113 // to ldrex/strex loops already.
1115 if (!Subtarget->isThumb() || !Subtarget->isMClass())
1117
1118 // On v8, we have particularly efficient implementations of atomic fences
1119 // if they can be combined with nearby atomic loads and stores.
1120 if (!Subtarget->hasAcquireRelease() ||
1121 getTargetMachine().getOptLevel() == CodeGenOptLevel::None) {
1122 // Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
1123 InsertFencesForAtomic = true;
1124 }
1125 } else {
1126 // If there's anything we can use as a barrier, go through custom lowering
1127 // for ATOMIC_FENCE.
1128 // If target has DMB in thumb, Fences can be inserted.
1129 if (Subtarget->hasDataBarrier())
1130 InsertFencesForAtomic = true;
1131
1133 Subtarget->hasAnyDataBarrier() ? Custom : Expand);
1134
1135 // Set them all for libcall, which will force libcalls.
1148 // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the
1149 // Unordered/Monotonic case.
1150 if (!InsertFencesForAtomic) {
1153 }
1154 }
1155
1156 // Compute supported atomic widths.
1157 if (TT.isOSLinux() || (!Subtarget->isMClass() && Subtarget->hasV6Ops())) {
1158 // For targets where __sync_* routines are reliably available, we use them
1159 // if necessary.
1160 //
1161 // ARM Linux always supports 64-bit atomics through kernel-assisted atomic
1162 // routines (kernel 3.1 or later). FIXME: Not with compiler-rt?
1163 //
1164 // ARMv6 targets have native instructions in ARM mode. For Thumb mode,
1165 // such targets should provide __sync_* routines, which use the ARM mode
1166 // instructions. (ARMv6 doesn't have dmb, but it has an equivalent
1167 // encoding; see ARMISD::MEMBARRIER_MCR.)
1169 } else if ((Subtarget->isMClass() && Subtarget->hasV8MBaselineOps()) ||
1170 Subtarget->hasForced32BitAtomics()) {
1171 // Cortex-M (besides Cortex-M0) have 32-bit atomics.
1173 } else {
1174 // We can't assume anything about other targets; just use libatomic
1175 // routines.
1177 }
1178
1180
1182
1183 // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
1184 if (!Subtarget->hasV6Ops()) {
1187 }
1189
1190 if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() &&
1191 !Subtarget->isThumb1Only()) {
1192 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
1193 // iff target supports vfp2.
1203 }
1204
1205 // We want to custom lower some of our intrinsics.
1210
1220 if (Subtarget->hasFullFP16()) {
1224 }
1225
1227
1230 if (Subtarget->hasFullFP16())
1234 setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1235
1236 // We don't support sin/cos/fmod/copysign/pow
1245 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
1246 !Subtarget->isThumb1Only()) {
1249 }
1252
1253 if (!Subtarget->hasVFP4Base()) {
1256 }
1257
1258 // Various VFP goodness
1259 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
1260 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1261 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
1266 }
1267
1268 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
1269 if (!Subtarget->hasFP16()) {
1274 }
1275
1276 // Strict floating-point comparisons need custom lowering.
1283 }
1284
1285 // FP-ARMv8 implements a lot of rounding-like FP operations.
1286 if (Subtarget->hasFPARMv8Base()) {
1287 for (auto Op :
1294 setOperationAction(Op, MVT::f32, Legal);
1295
1296 if (Subtarget->hasFP64())
1297 setOperationAction(Op, MVT::f64, Legal);
1298 }
1299
1300 if (Subtarget->hasNEON()) {
1305 }
1306 }
1307
1308 // FP16 often need to be promoted to call lib functions
1309 // clang-format off
1310 if (Subtarget->hasFullFP16()) {
1314
1315 for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1329 setOperationAction(Op, MVT::f16, Promote);
1330 }
1331
1332 // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1333 // because the result type is integer.
1335 setOperationAction(Op, MVT::f16, Custom);
1336
1342 setOperationAction(Op, MVT::f16, Legal);
1343 }
1344 // clang-format on
1345 }
1346
1347 if (Subtarget->hasNEON()) {
1348 // vmin and vmax aren't available in a scalar form, so we can use
1349 // a NEON instruction with an undef lane instead.
1358
1359 if (Subtarget->hasV8Ops()) {
1360 for (auto Op :
1364 setOperationAction(Op, MVT::v2f32, Legal);
1365 setOperationAction(Op, MVT::v4f32, Legal);
1366 }
1367 }
1368
1369 if (Subtarget->hasFullFP16()) {
1374
1379
1380 for (auto Op :
1384 setOperationAction(Op, MVT::v4f16, Legal);
1385 setOperationAction(Op, MVT::v8f16, Legal);
1386 }
1387 }
1388 }
1389
1390 // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined. MinGW has
1391 // it, but it's just a wrapper around ldexp.
1392 if (TT.isOSWindows()) {
1394 if (isOperationExpand(Op, MVT::f32))
1395 setOperationAction(Op, MVT::f32, Promote);
1396 }
1397
1398 // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
1399 // isn't legal.
1401 if (isOperationExpand(Op, MVT::f16))
1402 setOperationAction(Op, MVT::f16, Promote);
1403
1404 // We have target-specific dag combine patterns for the following nodes:
1405 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
1408
1409 if (Subtarget->hasMVEIntegerOps())
1411
1412 if (Subtarget->hasV6Ops())
1414 if (Subtarget->isThumb1Only())
1416 // Attempt to lower smin/smax to ssat/usat
1417 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) ||
1418 Subtarget->isThumb2()) {
1420 }
1421
1423
1424 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1425 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
1427 else
1429
1430 //// temporary - rewrite interface to use type
1433 MaxStoresPerMemcpy = 4; // For @llvm.memcpy -> sequence of stores
1435 MaxStoresPerMemmove = 4; // For @llvm.memmove -> sequence of stores
1437
1438 // On ARM arguments smaller than 4 bytes are extended, so all arguments
1439 // are at least 4 bytes aligned.
1441
1442 // Prefer likely predicted branches to selects on out-of-order cores.
1443 PredictableSelectIsExpensive = Subtarget->getSchedModel().isOutOfOrder();
1444
1446 Align::fromLog2(Subtarget->getPreferBranchLogAlignment()));
1448 Align::fromLog2(Subtarget->getPreferBranchLogAlignment()));
1449
1450 setMinFunctionAlignment(Subtarget->isThumb() ? Align(2) : Align(4));
1451
1452 IsStrictFPEnabled = true;
1453}
1454
1456 return Subtarget->useSoftFloat();
1457}
1458
1460 return !Subtarget->isThumb1Only() && VT.getSizeInBits() <= 32;
1461}
1462
1463// FIXME: It might make sense to define the representative register class as the
1464// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
1465// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
1466// SPR's representative would be DPR_VFP2. This should work well if register
1467// pressure tracking were modified such that a register use would increment the
1468// pressure of the register class's representative and all of it's super
1469// classes' representatives transitively. We have not implemented this because
1470// of the difficulty prior to coalescing of modeling operand register classes
1471// due to the common occurrence of cross class copies and subregister insertions
1472// and extractions.
1473std::pair<const TargetRegisterClass *, uint8_t>
1475 MVT VT) const {
1476 const TargetRegisterClass *RRC = nullptr;
1477 uint8_t Cost = 1;
1478 switch (VT.SimpleTy) {
1479 default:
1481 // Use DPR as representative register class for all floating point
1482 // and vector types. Since there are 32 SPR registers and 32 DPR registers so
1483 // the cost is 1 for both f32 and f64.
1484 case MVT::f32: case MVT::f64: case MVT::v8i8: case MVT::v4i16:
1485 case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
1486 RRC = &ARM::DPRRegClass;
1487 // When NEON is used for SP, only half of the register file is available
1488 // because operations that define both SP and DP results will be constrained
1489 // to the VFP2 class (D0-D15). We currently model this constraint prior to
1490 // coalescing by double-counting the SP regs. See the FIXME above.
1491 if (Subtarget->useNEONForSinglePrecisionFP())
1492 Cost = 2;
1493 break;
1494 case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
1495 case MVT::v4f32: case MVT::v2f64:
1496 RRC = &ARM::DPRRegClass;
1497 Cost = 2;
1498 break;
1499 case MVT::v4i64:
1500 RRC = &ARM::DPRRegClass;
1501 Cost = 4;
1502 break;
1503 case MVT::v8i64:
1504 RRC = &ARM::DPRRegClass;
1505 Cost = 8;
1506 break;
1507 }
1508 return std::make_pair(RRC, Cost);
1509}
1510
1512 EVT VT) const {
1513 if (!VT.isVector())
1514 return getPointerTy(DL);
1515
1516 // MVE has a predicate register.
1517 if (Subtarget->hasMVEIntegerOps())
1518 return EVT::getVectorVT(C, MVT::i1, VT.getVectorElementCount());
1519
1521}
1522
1523/// getRegClassFor - Return the register class that should be used for the
1524/// specified value type.
1525const TargetRegisterClass *
1526ARMTargetLowering::getRegClassFor(MVT VT, bool isDivergent) const {
1527 (void)isDivergent;
1528 // Map v4i64 to QQ registers but do not make the type legal. Similarly map
1529 // v8i64 to QQQQ registers. v4i64 and v8i64 are only used for REG_SEQUENCE to
1530 // load / store 4 to 8 consecutive NEON D registers, or 2 to 4 consecutive
1531 // MVE Q registers.
1532 if (Subtarget->hasNEON()) {
1533 if (VT == MVT::v4i64)
1534 return &ARM::QQPRRegClass;
1535 if (VT == MVT::v8i64)
1536 return &ARM::QQQQPRRegClass;
1537 }
1538 if (Subtarget->hasMVEIntegerOps()) {
1539 if (VT == MVT::v4i64)
1540 return &ARM::MQQPRRegClass;
1541 if (VT == MVT::v8i64)
1542 return &ARM::MQQQQPRRegClass;
1543 }
1545}
1546
1547// memcpy, and other memory intrinsics, typically tries to use LDM/STM if the
1548// source/dest is aligned and the copy size is large enough. We therefore want
1549// to align such objects passed to memory intrinsics.
1551 Align &PrefAlign) const {
1552 if (!isa<MemIntrinsic>(CI))
1553 return false;
1554 MinSize = 8;
1555 // On ARM11 onwards (excluding M class) 8-byte aligned LDM is typically 1
1556 // cycle faster than 4-byte aligned LDM.
1557 PrefAlign =
1558 (Subtarget->hasV6Ops() && !Subtarget->isMClass() ? Align(8) : Align(4));
1559 return true;
1560}
1561
1562// Create a fast isel object.
1564 FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo,
1565 const LibcallLoweringInfo *libcallLowering) const {
1566 return ARM::createFastISel(funcInfo, libInfo, libcallLowering);
1567}
1568
1570 unsigned NumVals = N->getNumValues();
1571 if (!NumVals)
1572 return Sched::RegPressure;
1573
1574 for (unsigned i = 0; i != NumVals; ++i) {
1575 EVT VT = N->getValueType(i);
1576 if (VT == MVT::Glue || VT == MVT::Other)
1577 continue;
1578 if (VT.isFloatingPoint() || VT.isVector())
1579 return Sched::ILP;
1580 }
1581
1582 if (!N->isMachineOpcode())
1583 return Sched::RegPressure;
1584
1585 // Load are scheduled for latency even if there instruction itinerary
1586 // is not available.
1587 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
1588 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1589
1590 if (MCID.getNumDefs() == 0)
1591 return Sched::RegPressure;
1592 if (!Itins->isEmpty() &&
1593 Itins->getOperandCycle(MCID.getSchedClass(), 0) > 2U)
1594 return Sched::ILP;
1595
1596 return Sched::RegPressure;
1597}
1598
1599//===----------------------------------------------------------------------===//
1600// Lowering Code
1601//===----------------------------------------------------------------------===//
1602
1603static bool isSRL16(const SDValue &Op) {
1604 if (Op.getOpcode() != ISD::SRL)
1605 return false;
1606 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1607 return Const->getZExtValue() == 16;
1608 return false;
1609}
1610
1611static bool isSRA16(const SDValue &Op) {
1612 if (Op.getOpcode() != ISD::SRA)
1613 return false;
1614 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1615 return Const->getZExtValue() == 16;
1616 return false;
1617}
1618
1619static bool isSHL16(const SDValue &Op) {
1620 if (Op.getOpcode() != ISD::SHL)
1621 return false;
1622 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1623 return Const->getZExtValue() == 16;
1624 return false;
1625}
1626
1627// Check for a signed 16-bit value. We special case SRA because it makes it
1628// more simple when also looking for SRAs that aren't sign extending a
1629// smaller value. Without the check, we'd need to take extra care with
1630// checking order for some operations.
1631static bool isS16(const SDValue &Op, SelectionDAG &DAG) {
1632 if (isSRA16(Op))
1633 return isSHL16(Op.getOperand(0));
1634 return DAG.ComputeNumSignBits(Op) == 17;
1635}
1636
1637/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
1639 switch (CC) {
1640 default: llvm_unreachable("Unknown condition code!");
1641 case ISD::SETNE: return ARMCC::NE;
1642 case ISD::SETEQ: return ARMCC::EQ;
1643 case ISD::SETGT: return ARMCC::GT;
1644 case ISD::SETGE: return ARMCC::GE;
1645 case ISD::SETLT: return ARMCC::LT;
1646 case ISD::SETLE: return ARMCC::LE;
1647 case ISD::SETUGT: return ARMCC::HI;
1648 case ISD::SETUGE: return ARMCC::HS;
1649 case ISD::SETULT: return ARMCC::LO;
1650 case ISD::SETULE: return ARMCC::LS;
1651 }
1652}
1653
1654/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
1656 ARMCC::CondCodes &CondCode2) {
1657 CondCode2 = ARMCC::AL;
1658 switch (CC) {
1659 default: llvm_unreachable("Unknown FP condition!");
1660 case ISD::SETEQ:
1661 case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
1662 case ISD::SETGT:
1663 case ISD::SETOGT: CondCode = ARMCC::GT; break;
1664 case ISD::SETGE:
1665 case ISD::SETOGE: CondCode = ARMCC::GE; break;
1666 case ISD::SETOLT: CondCode = ARMCC::MI; break;
1667 case ISD::SETOLE: CondCode = ARMCC::LS; break;
1668 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
1669 case ISD::SETO: CondCode = ARMCC::VC; break;
1670 case ISD::SETUO: CondCode = ARMCC::VS; break;
1671 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
1672 case ISD::SETUGT: CondCode = ARMCC::HI; break;
1673 case ISD::SETUGE: CondCode = ARMCC::PL; break;
1674 case ISD::SETLT:
1675 case ISD::SETULT: CondCode = ARMCC::LT; break;
1676 case ISD::SETLE:
1677 case ISD::SETULE: CondCode = ARMCC::LE; break;
1678 case ISD::SETNE:
1679 case ISD::SETUNE: CondCode = ARMCC::NE; break;
1680 }
1681}
1682
1683//===----------------------------------------------------------------------===//
1684// Calling Convention Implementation
1685//===----------------------------------------------------------------------===//
1686
1687/// getEffectiveCallingConv - Get the effective calling convention, taking into
1688/// account presence of floating point hardware and calling convention
1689/// limitations, such as support for variadic functions.
1692 bool isVarArg) const {
1693 switch (CC) {
1694 default:
1695 // Unknown CCs are rejected when calling convention lowering is required.
1698 case CallingConv::GHC:
1700 return CC;
1706 case CallingConv::Swift:
1709 case CallingConv::C:
1710 case CallingConv::Tail:
1711 if (!Subtarget->isAAPCS_ABI())
1712 return CallingConv::ARM_APCS;
1713 else if (Subtarget->isTargetHardFloat() && !isVarArg)
1715 else
1717 case CallingConv::Fast:
1719 if (!Subtarget->isAAPCS_ABI()) {
1720 if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() && !isVarArg)
1721 return CallingConv::Fast;
1722 return CallingConv::ARM_APCS;
1723 } else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1724 !Subtarget->useSoftFloat() && !isVarArg)
1726 else
1728 }
1729}
1730
1732 bool isVarArg) const {
1733 return CCAssignFnForNode(CC, false, isVarArg);
1734}
1735
1737 bool isVarArg) const {
1738 return CCAssignFnForNode(CC, true, isVarArg);
1739}
1740
1741/// CCAssignFnForNode - Selects the correct CCAssignFn for the given
1742/// CallingConvention.
1743CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
1744 bool Return,
1745 bool isVarArg) const {
1746 switch (getEffectiveCallingConv(CC, isVarArg)) {
1747 default:
1748 report_fatal_error("Unsupported calling convention");
1750 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1752 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1754 return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1755 case CallingConv::Fast:
1756 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1757 case CallingConv::GHC:
1758 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1760 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1762 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1764 return (Return ? RetCC_ARM_AAPCS : CC_ARM_Win32_CFGuard_Check);
1765 }
1766}
1767
1768SDValue ARMTargetLowering::MoveToHPR(const SDLoc &dl, SelectionDAG &DAG,
1769 MVT LocVT, MVT ValVT, SDValue Val) const {
1770 Val = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocVT.getSizeInBits()),
1771 Val);
1772 if (Subtarget->hasFullFP16()) {
1773 Val = DAG.getNode(ARMISD::VMOVhr, dl, ValVT, Val);
1774 } else {
1775 Val = DAG.getNode(ISD::TRUNCATE, dl,
1776 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1777 Val = DAG.getNode(ISD::BITCAST, dl, ValVT, Val);
1778 }
1779 return Val;
1780}
1781
1782SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
1783 MVT LocVT, MVT ValVT,
1784 SDValue Val) const {
1785 if (Subtarget->hasFullFP16()) {
1786 Val = DAG.getNode(ARMISD::VMOVrh, dl,
1787 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1788 } else {
1789 Val = DAG.getNode(ISD::BITCAST, dl,
1790 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1791 Val = DAG.getNode(ISD::ZERO_EXTEND, dl,
1792 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1793 }
1794 return DAG.getNode(ISD::BITCAST, dl, LocVT, Val);
1795}
1796
1797/// LowerCallResult - Lower the result values of a call into the
1798/// appropriate copies out of appropriate physical registers.
1799SDValue ARMTargetLowering::LowerCallResult(
1800 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
1801 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1802 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
1803 SDValue ThisVal, bool isCmseNSCall) const {
1804 // Assign locations to each value returned by this call.
1806 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1807 *DAG.getContext());
1808 CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, isVarArg));
1809
1810 // Copy all of the result registers out of their specified physreg.
1811 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1812 CCValAssign VA = RVLocs[i];
1813
1814 // Pass 'this' value directly from the argument to return value, to avoid
1815 // reg unit interference
1816 if (i == 0 && isThisReturn) {
1817 assert(!VA.needsCustom() && VA.getLocVT() == MVT::i32 &&
1818 "unexpected return calling convention register assignment");
1819 InVals.push_back(ThisVal);
1820 continue;
1821 }
1822
1823 SDValue Val;
1824 if (VA.needsCustom() &&
1825 (VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2f64)) {
1826 // Handle f64 or half of a v2f64.
1827 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1828 InGlue);
1829 Chain = Lo.getValue(1);
1830 InGlue = Lo.getValue(2);
1831 VA = RVLocs[++i]; // skip ahead to next loc
1832 SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1833 InGlue);
1834 Chain = Hi.getValue(1);
1835 InGlue = Hi.getValue(2);
1836 if (!Subtarget->isLittle())
1837 std::swap (Lo, Hi);
1838 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1839
1840 if (VA.getLocVT() == MVT::v2f64) {
1841 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
1842 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1843 DAG.getConstant(0, dl, MVT::i32));
1844
1845 VA = RVLocs[++i]; // skip ahead to next loc
1846 Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1847 Chain = Lo.getValue(1);
1848 InGlue = Lo.getValue(2);
1849 VA = RVLocs[++i]; // skip ahead to next loc
1850 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1851 Chain = Hi.getValue(1);
1852 InGlue = Hi.getValue(2);
1853 if (!Subtarget->isLittle())
1854 std::swap (Lo, Hi);
1855 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1856 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1857 DAG.getConstant(1, dl, MVT::i32));
1858 }
1859 } else {
1860 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(),
1861 InGlue);
1862 Chain = Val.getValue(1);
1863 InGlue = Val.getValue(2);
1864 }
1865
1866 switch (VA.getLocInfo()) {
1867 default: llvm_unreachable("Unknown loc info!");
1868 case CCValAssign::Full: break;
1869 case CCValAssign::BCvt:
1870 Val = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), Val);
1871 break;
1872 }
1873
1874 // f16 arguments have their size extended to 4 bytes and passed as if they
1875 // had been copied to the LSBs of a 32-bit register.
1876 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
1877 if (VA.needsCustom() &&
1878 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
1879 Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
1880
1881 // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
1882 // is less than 32 bits must be sign- or zero-extended after the call for
1883 // security reasons. Although the ABI mandates an extension done by the
1884 // callee, the latter cannot be trusted to follow the rules of the ABI.
1885 const ISD::InputArg &Arg = Ins[VA.getValNo()];
1886 if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
1887 VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
1888 Val = handleCMSEValue(Val, Arg, DAG, dl);
1889
1890 InVals.push_back(Val);
1891 }
1892
1893 return Chain;
1894}
1895
1896std::pair<SDValue, MachinePointerInfo> ARMTargetLowering::computeAddrForCallArg(
1897 const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA, SDValue StackPtr,
1898 bool IsTailCall, int SPDiff) const {
1899 SDValue DstAddr;
1900 MachinePointerInfo DstInfo;
1901 int32_t Offset = VA.getLocMemOffset();
1903
1904 if (IsTailCall) {
1905 Offset += SPDiff;
1906 auto PtrVT = getPointerTy(DAG.getDataLayout());
1907 int Size = VA.getLocVT().getFixedSizeInBits() / 8;
1908 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
1909 DstAddr = DAG.getFrameIndex(FI, PtrVT);
1910 DstInfo =
1912 } else {
1913 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1914 DstAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
1915 StackPtr, PtrOff);
1916 DstInfo =
1918 }
1919
1920 return std::make_pair(DstAddr, DstInfo);
1921}
1922
1923// Returns the type of copying which is required to set up a byval argument to
1924// a tail-called function. This isn't needed for non-tail calls, because they
1925// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
1926// avoid clobbering another argument (CopyViaTemp), and sometimes can be
1927// optimised to zero copies when forwarding an argument from the caller's
1928// caller (NoCopy).
1929ARMTargetLowering::ByValCopyKind ARMTargetLowering::ByValNeedsCopyForTailCall(
1930 SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
1931 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1932 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
1933
1934 // Globals are always safe to copy from.
1936 return CopyOnce;
1937
1938 // Can only analyse frame index nodes, conservatively assume we need a
1939 // temporary.
1940 auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
1941 auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
1942 if (!SrcFrameIdxNode || !DstFrameIdxNode)
1943 return CopyViaTemp;
1944
1945 int SrcFI = SrcFrameIdxNode->getIndex();
1946 int DstFI = DstFrameIdxNode->getIndex();
1947 assert(MFI.isFixedObjectIndex(DstFI) &&
1948 "byval passed in non-fixed stack slot");
1949
1950 int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
1951 int64_t DstOffset = MFI.getObjectOffset(DstFI);
1952
1953 // If the source is in the local frame, then the copy to the argument memory
1954 // is always valid.
1955 bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
1956 if (!FixedSrc ||
1957 (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
1958 return CopyOnce;
1959
1960 // In the case of byval arguments split between registers and the stack,
1961 // computeAddrForCallArg returns a FrameIndex which corresponds only to the
1962 // stack portion, but the Src SDValue will refer to the full value, including
1963 // the local stack memory that the register portion gets stored into. We only
1964 // need to compare them for equality, so normalise on the full value version.
1965 uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
1966 DstOffset -= RegSize;
1967
1968 // If the value is already in the correct location, then no copying is
1969 // needed. If not, then we need to copy via a temporary.
1970 if (SrcOffset == DstOffset)
1971 return NoCopy;
1972 else
1973 return CopyViaTemp;
1974}
1975
1976void ARMTargetLowering::PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG,
1977 SDValue Chain, SDValue &Arg,
1978 RegsToPassVector &RegsToPass,
1979 CCValAssign &VA, CCValAssign &NextVA,
1980 SDValue &StackPtr,
1981 SmallVectorImpl<SDValue> &MemOpChains,
1982 bool IsTailCall,
1983 int SPDiff) const {
1984 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
1985 DAG.getVTList(MVT::i32, MVT::i32), Arg);
1986 unsigned id = Subtarget->isLittle() ? 0 : 1;
1987 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
1988
1989 if (NextVA.isRegLoc())
1990 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
1991 else {
1992 assert(NextVA.isMemLoc());
1993 if (!StackPtr.getNode())
1994 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP,
1996
1997 SDValue DstAddr;
1998 MachinePointerInfo DstInfo;
1999 std::tie(DstAddr, DstInfo) =
2000 computeAddrForCallArg(dl, DAG, NextVA, StackPtr, IsTailCall, SPDiff);
2001 MemOpChains.push_back(
2002 DAG.getStore(Chain, dl, fmrrd.getValue(1 - id), DstAddr, DstInfo));
2003 }
2004}
2005
2006static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
2007 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
2009}
2010
2011/// LowerCall - Lowering a call into a callseq_start <-
2012/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
2013/// nodes.
2014SDValue
2015ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2016 SmallVectorImpl<SDValue> &InVals) const {
2017 SelectionDAG &DAG = CLI.DAG;
2018 SDLoc &dl = CLI.DL;
2019 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2020 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2021 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2022 SDValue Chain = CLI.Chain;
2023 SDValue Callee = CLI.Callee;
2024 bool &isTailCall = CLI.IsTailCall;
2025 CallingConv::ID CallConv = CLI.CallConv;
2026 bool doesNotRet = CLI.DoesNotReturn;
2027 bool isVarArg = CLI.IsVarArg;
2028 const CallBase *CB = CLI.CB;
2029
2031 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2032 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2033 MachineFunction::CallSiteInfo CSInfo;
2034 bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
2035 bool isThisReturn = false;
2036 bool isCmseNSCall = false;
2037 bool isSibCall = false;
2038 bool PreferIndirect = false;
2039 bool GuardWithBTI = false;
2040
2041 // Analyze operands of the call, assigning locations to each operand.
2043 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
2044 *DAG.getContext());
2045 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, isVarArg));
2046
2047 // Lower 'returns_twice' calls to a pseudo-instruction.
2048 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) &&
2049 !Subtarget->noBTIAtReturnTwice())
2050 GuardWithBTI = AFI->branchTargetEnforcement();
2051
2052 // Set type id for call site info.
2053 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
2054
2055 // Determine whether this is a non-secure function call.
2056 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
2057 isCmseNSCall = true;
2058
2059 // Disable tail calls if they're not supported.
2060 if (!Subtarget->supportsTailCall())
2061 isTailCall = false;
2062
2063 // For both the non-secure calls and the returns from a CMSE entry function,
2064 // the function needs to do some extra work after the call, or before the
2065 // return, respectively, thus it cannot end with a tail call
2066 if (isCmseNSCall || AFI->isCmseNSEntryFunction())
2067 isTailCall = false;
2068
2069 if (isa<GlobalAddressSDNode>(Callee)) {
2070 // If we're optimizing for minimum size and the function is called three or
2071 // more times in this block, we can improve codesize by calling indirectly
2072 // as BLXr has a 16-bit encoding.
2073 auto *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
2074 if (CLI.CB) {
2075 auto *BB = CLI.CB->getParent();
2076 PreferIndirect = Subtarget->isThumb() && Subtarget->hasMinSize() &&
2077 count_if(GV->users(), [&BB](const User *U) {
2078 return isa<Instruction>(U) &&
2079 cast<Instruction>(U)->getParent() == BB;
2080 }) > 2;
2081 }
2082 }
2083 if (isTailCall) {
2084 // Check if it's really possible to do a tail call.
2085 isTailCall =
2086 IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
2087
2088 if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
2089 CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
2090 isSibCall = true;
2091
2092 // We don't support GuaranteedTailCallOpt for ARM, only automatically
2093 // detected sibcalls.
2094 if (isTailCall)
2095 ++NumTailCalls;
2096 }
2097
2098 if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
2099 report_fatal_error("failed to perform tail call elimination on a call "
2100 "site marked musttail");
2101
2102 // Get a count of how many bytes are to be pushed on the stack.
2103 unsigned NumBytes = CCInfo.getStackSize();
2104
2105 // SPDiff is the byte offset of the call's argument area from the callee's.
2106 // Stores to callee stack arguments will be placed in FixedStackSlots offset
2107 // by this amount for a tail call. In a sibling call it must be 0 because the
2108 // caller will deallocate the entire stack and the callee still expects its
2109 // arguments to begin at SP+0. Completely unused for non-tail calls.
2110 int SPDiff = 0;
2111
2112 if (isTailCall && !isSibCall) {
2113 auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
2114 unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
2115
2116 // Since callee will pop argument stack as a tail call, we must keep the
2117 // popped size 16-byte aligned.
2118 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
2119 assert(StackAlign && "data layout string is missing stack alignment");
2120 NumBytes = alignTo(NumBytes, *StackAlign);
2121
2122 // SPDiff will be negative if this tail call requires more space than we
2123 // would automatically have in our incoming argument space. Positive if we
2124 // can actually shrink the stack.
2125 SPDiff = NumReusableBytes - NumBytes;
2126
2127 // If this call requires more stack than we have available from
2128 // LowerFormalArguments, tell FrameLowering to reserve space for it.
2129 if (SPDiff < 0 && AFI->getArgRegsSaveSize() < (unsigned)-SPDiff)
2130 AFI->setArgRegsSaveSize(-SPDiff);
2131 }
2132
2133 if (isSibCall) {
2134 // For sibling tail calls, memory operands are available in our caller's stack.
2135 NumBytes = 0;
2136 } else {
2137 // Adjust the stack pointer for the new arguments...
2138 // These operations are automatically eliminated by the prolog/epilog pass
2139 Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
2140 }
2141
2142 SDValue StackPtr =
2143 DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy(DAG.getDataLayout()));
2144
2145 RegsToPassVector RegsToPass;
2146 SmallVector<SDValue, 8> MemOpChains;
2147
2148 // A musttail call in a variadic function must receive the caller's unnamed
2149 // register arguments unchanged. The forwarded set is disjoint from the named
2150 // arguments handled below.
2151 if (isVarArg && CLI.CB && CLI.CB->isMustTailCall()) {
2152 const auto &Forwards = AFI->getForwardedMustTailRegParms();
2153 for (const ForwardedRegister &F : Forwards) {
2154 SDValue Val = DAG.getCopyFromReg(Chain, dl, F.VReg, F.VT);
2155 RegsToPass.push_back(std::make_pair(F.PReg, Val));
2156 }
2157 }
2158
2159 // If we are doing a tail-call, any byval arguments will be written to stack
2160 // space which was used for incoming arguments. If any the values being used
2161 // are incoming byval arguments to this function, then they might be
2162 // overwritten by the stores of the outgoing arguments. To avoid this, we
2163 // need to make a temporary copy of them in local stack space, then copy back
2164 // to the argument area.
2165 DenseMap<unsigned, SDValue> ByValTemporaries;
2166 SDValue ByValTempChain;
2167 if (isTailCall) {
2168 SmallVector<SDValue, 8> ByValCopyChains;
2169 for (const CCValAssign &VA : ArgLocs) {
2170 unsigned ArgIdx = VA.getValNo();
2171 SDValue Src = OutVals[ArgIdx];
2172 ISD::ArgFlagsTy Flags = Outs[ArgIdx].Flags;
2173
2174 if (!Flags.isByVal())
2175 continue;
2176
2177 SDValue Dst;
2178 MachinePointerInfo DstInfo;
2179 std::tie(Dst, DstInfo) =
2180 computeAddrForCallArg(dl, DAG, VA, SDValue(), true, SPDiff);
2181 ByValCopyKind Copy = ByValNeedsCopyForTailCall(DAG, Src, Dst, Flags);
2182
2183 if (Copy == NoCopy) {
2184 // If the argument is already at the correct offset on the stack
2185 // (because we are forwarding a byval argument from our caller), we
2186 // don't need any copying.
2187 continue;
2188 } else if (Copy == CopyOnce) {
2189 // If the argument is in our local stack frame, no other argument
2190 // preparation can clobber it, so we can copy it to the final location
2191 // later.
2192 ByValTemporaries[ArgIdx] = Src;
2193 } else {
2194 assert(Copy == CopyViaTemp && "unexpected enum value");
2195 // If we might be copying this argument from the outgoing argument
2196 // stack area, we need to copy via a temporary in the local stack
2197 // frame.
2198 int TempFrameIdx = MFI.CreateStackObject(
2199 Flags.getByValSize(), Flags.getNonZeroByValAlign(), false);
2200 SDValue Temp =
2201 DAG.getFrameIndex(TempFrameIdx, getPointerTy(DAG.getDataLayout()));
2202
2203 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
2204 SDValue AlignNode =
2205 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2206
2207 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2208 SDValue Ops[] = {Chain, Temp, Src, SizeNode, AlignNode};
2209 ByValCopyChains.push_back(
2210 DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs, Ops));
2211 ByValTemporaries[ArgIdx] = Temp;
2212 }
2213 }
2214 if (!ByValCopyChains.empty())
2215 ByValTempChain =
2216 DAG.getNode(ISD::TokenFactor, dl, MVT::Other, ByValCopyChains);
2217 }
2218
2219 // During a tail call, stores to the argument area must happen after all of
2220 // the function's incoming arguments have been loaded because they may alias.
2221 // This is done by folding in a TokenFactor from LowerFormalArguments, but
2222 // there's no point in doing so repeatedly so this tracks whether that's
2223 // happened yet.
2224 bool AfterFormalArgLoads = false;
2225
2226 // Walk the register/memloc assignments, inserting copies/loads. In the case
2227 // of tail call optimization, arguments are handled later.
2228 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size();
2229 i != e;
2230 ++i, ++realArgIdx) {
2231 CCValAssign &VA = ArgLocs[i];
2232 SDValue Arg = OutVals[realArgIdx];
2233 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
2234 bool isByVal = Flags.isByVal();
2235
2236 // Promote the value if needed.
2237 switch (VA.getLocInfo()) {
2238 default: llvm_unreachable("Unknown loc info!");
2239 case CCValAssign::Full: break;
2240 case CCValAssign::SExt:
2241 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
2242 break;
2243 case CCValAssign::ZExt:
2244 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
2245 break;
2246 case CCValAssign::AExt:
2247 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
2248 break;
2249 case CCValAssign::BCvt:
2250 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2251 break;
2252 }
2253
2254 if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
2255 Chain = DAG.getStackArgumentTokenFactor(Chain);
2256 if (ByValTempChain) {
2257 // In case of large byval copies, re-using the stackframe for tail-calls
2258 // can lead to overwriting incoming arguments on the stack. Force
2259 // loading these stack arguments before the copy to avoid that.
2260 SmallVector<SDValue, 8> IncomingLoad;
2261 for (unsigned I = 0; I < OutVals.size(); ++I) {
2262 if (Outs[I].Flags.isByVal())
2263 continue;
2264
2265 SDValue OutVal = OutVals[I];
2266 LoadSDNode *OutLN = dyn_cast_or_null<LoadSDNode>(OutVal);
2267 if (!OutLN)
2268 continue;
2269
2270 FrameIndexSDNode *FIN =
2272 if (!FIN)
2273 continue;
2274
2275 if (!MFI.isFixedObjectIndex(FIN->getIndex()))
2276 continue;
2277
2278 for (const CCValAssign &VA : ArgLocs) {
2279 if (VA.isMemLoc())
2280 IncomingLoad.push_back(OutVal.getValue(1));
2281 }
2282 }
2283
2284 // Update the chain to force loads for potentially clobbered argument
2285 // loads to happen before the byval copy.
2286 if (!IncomingLoad.empty()) {
2287 IncomingLoad.push_back(Chain);
2288 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, IncomingLoad);
2289 }
2290
2291 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chain,
2292 ByValTempChain);
2293 }
2294 AfterFormalArgLoads = true;
2295 }
2296
2297 // f16 arguments have their size extended to 4 bytes and passed as if they
2298 // had been copied to the LSBs of a 32-bit register.
2299 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
2300 if (VA.needsCustom() &&
2301 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16)) {
2302 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2303 } else {
2304 // f16 arguments could have been extended prior to argument lowering.
2305 // Mask them arguments if this is a CMSE nonsecure call.
2306 auto ArgVT = Outs[realArgIdx].ArgVT;
2307 if (isCmseNSCall && (ArgVT == MVT::f16)) {
2308 auto LocBits = VA.getLocVT().getSizeInBits();
2309 auto MaskValue = APInt::getLowBitsSet(LocBits, ArgVT.getSizeInBits());
2310 SDValue Mask =
2311 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2312 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2313 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2314 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2315 }
2316 }
2317
2318 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
2319 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
2320 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2321 DAG.getConstant(0, dl, MVT::i32));
2322 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2323 DAG.getConstant(1, dl, MVT::i32));
2324
2325 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
2326 StackPtr, MemOpChains, isTailCall, SPDiff);
2327
2328 VA = ArgLocs[++i]; // skip ahead to next loc
2329 if (VA.isRegLoc()) {
2330 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
2331 StackPtr, MemOpChains, isTailCall, SPDiff);
2332 } else {
2333 assert(VA.isMemLoc());
2334 SDValue DstAddr;
2335 MachinePointerInfo DstInfo;
2336 std::tie(DstAddr, DstInfo) =
2337 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2338 MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
2339 }
2340 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
2341 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
2342 StackPtr, MemOpChains, isTailCall, SPDiff);
2343 } else if (VA.isRegLoc()) {
2344 if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
2345 Outs[0].VT == MVT::i32) {
2346 assert(VA.getLocVT() == MVT::i32 &&
2347 "unexpected calling convention register assignment");
2348 assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
2349 "unexpected use of 'returned'");
2350 isThisReturn = true;
2351 }
2352 const TargetOptions &Options = DAG.getTarget().Options;
2353 if (Options.EmitCallSiteInfo)
2354 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
2355 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2356 } else if (isByVal) {
2357 assert(VA.isMemLoc());
2358 unsigned offset = 0;
2359
2360 // True if this byval aggregate will be split between registers
2361 // and memory.
2362 unsigned ByValArgsCount = CCInfo.getInRegsParamsCount();
2363 unsigned CurByValIdx = CCInfo.getInRegsParamsProcessed();
2364
2365 SDValue ByValSrc;
2366 bool NeedsStackCopy;
2367 if (auto It = ByValTemporaries.find(realArgIdx);
2368 It != ByValTemporaries.end()) {
2369 ByValSrc = It->second;
2370 NeedsStackCopy = true;
2371 } else {
2372 ByValSrc = Arg;
2373 NeedsStackCopy = !isTailCall;
2374 }
2375
2376 // If part of the argument is in registers, load them.
2377 if (CurByValIdx < ByValArgsCount) {
2378 unsigned RegBegin, RegEnd;
2379 CCInfo.getInRegsParamInfo(CurByValIdx, RegBegin, RegEnd);
2380
2381 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2382 unsigned int i, j;
2383 for (i = 0, j = RegBegin; j < RegEnd; i++, j++) {
2384 SDValue Const = DAG.getConstant(4*i, dl, MVT::i32);
2385 SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, Const);
2386 SDValue Load =
2387 DAG.getLoad(PtrVT, dl, Chain, AddArg, MachinePointerInfo(),
2388 DAG.InferPtrAlign(AddArg));
2389 MemOpChains.push_back(Load.getValue(1));
2390 RegsToPass.push_back(std::make_pair(j, Load));
2391 }
2392
2393 // If parameter size outsides register area, "offset" value
2394 // helps us to calculate stack slot for remained part properly.
2395 offset = RegEnd - RegBegin;
2396
2397 CCInfo.nextInRegsParam();
2398 }
2399
2400 // If the memory part of the argument isn't already in the correct place
2401 // (which can happen with tail calls), copy it into the argument area.
2402 if (NeedsStackCopy && Flags.getByValSize() > 4 * offset) {
2403 auto PtrVT = getPointerTy(DAG.getDataLayout());
2404 SDValue Dst;
2405 MachinePointerInfo DstInfo;
2406 std::tie(Dst, DstInfo) =
2407 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2408 SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
2409 SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
2410 SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
2411 MVT::i32);
2412 SDValue AlignNode =
2413 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2414
2415 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2416 SDValue Ops[] = { Chain, Dst, Src, SizeNode, AlignNode};
2417 MemOpChains.push_back(DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs,
2418 Ops));
2419 }
2420 } else {
2421 assert(VA.isMemLoc());
2422 SDValue DstAddr;
2423 MachinePointerInfo DstInfo;
2424 std::tie(DstAddr, DstInfo) =
2425 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2426
2427 SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
2428 MemOpChains.push_back(Store);
2429 }
2430 }
2431
2432 if (!MemOpChains.empty())
2433 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
2434
2435 // Build a sequence of copy-to-reg nodes chained together with token chain
2436 // and flag operands which copy the outgoing args into the appropriate regs.
2437 SDValue InGlue;
2438 for (const auto &[Reg, N] : RegsToPass) {
2439 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
2440 InGlue = Chain.getValue(1);
2441 }
2442
2443 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2444 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2445 // node so that legalize doesn't hack it.
2446 bool isDirect = false;
2447
2448 const TargetMachine &TM = getTargetMachine();
2449 const Triple &TT = TM.getTargetTriple();
2450 const GlobalValue *GVal = nullptr;
2451 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
2452 GVal = G->getGlobal();
2453 bool isStub = !TM.shouldAssumeDSOLocal(GVal) && TT.isOSBinFormatMachO();
2454
2455 bool isARMFunc = !Subtarget->isThumb() || (isStub && !Subtarget->isMClass());
2456 bool isLocalARMFunc = false;
2457 auto PtrVt = getPointerTy(DAG.getDataLayout());
2458
2459 if (Subtarget->genLongCalls()) {
2460 bool isPIC = isPositionIndependent() && !TT.isOSWindows();
2461 if (isPIC && Subtarget->genExecuteOnly())
2462 reportFatalUsageError("long-calls with execute-only and "
2463 "position-independent code is not supported");
2464 if (Subtarget->isROPI())
2465 reportFatalUsageError("long-calls with ROPI is not currently supported");
2466
2467 // Handle a global address or an external symbol. If it's not one of
2468 // those, the target's already in a register, so we don't need to do
2469 // anything extra.
2470 if (isa<GlobalAddressSDNode>(Callee)) {
2471 if (Subtarget->genExecuteOnly()) {
2472 // Execute-only forbids constant pools in .text, so use movw/movt.
2473 // fPIC is not supported with execute-only.
2474 if (Subtarget->useMovt())
2475 ++NumMovwMovt;
2476 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2477 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2478 } else if (isPIC) {
2479 // PIC without execute-only: use GOT-based addressing.
2480 // DSO-local symbols use a plain PC-relative WrapperPIC;
2481 // non-DSO-local symbols additionally load the address from the GOT.
2482 SDValue G = DAG.getTargetGlobalAddress(
2483 GVal, dl, PtrVt, 0, GVal->isDSOLocal() ? 0 : ARMII::MO_GOT);
2484 Callee = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVt, G);
2485 if (!GVal->isDSOLocal())
2486 Callee =
2487 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2489 } else {
2490 // Neither execute-only nor PIC: load the address from a constant pool.
2491 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2492 ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(
2493 GVal, ARMPCLabelIndex, ARMCP::CPValue, 0);
2494
2495 // Get the address of the callee into a register
2496 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2497 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2498 Callee = DAG.getLoad(
2499 PtrVt, dl, DAG.getEntryNode(), Addr,
2501 }
2502 } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
2503 const char *Sym = S->getSymbol();
2504
2505 if (Subtarget->genExecuteOnly()) {
2506 // Execute-only forbids constant pools in .text, so use movw/movt.
2507 // fPIC is not supported with execute-only.
2508 if (Subtarget->useMovt())
2509 ++NumMovwMovt;
2510 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2511 DAG.getTargetExternalSymbol(Sym, PtrVt, 0));
2512 } else if (isPIC) {
2513 // PIC without execute-only: load the symbol's address from the GOT via
2514 // a GOT_PREL constant pool entry consumed by a PICLDR.
2515 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
2516 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2517 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2518 *DAG.getContext(), Sym, ARMPCLabelIndex, PCAdj, ARMCP::GOT_PREL,
2519 /*AddCurrentAddress=*/true);
2520 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2521 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2522 SDValue GOTOffset = DAG.getLoad(
2523 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2525 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2526 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, GOTOffset, PICLabel);
2527 Callee =
2528 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2530 } else {
2531 // Neither execute-only nor PIC: load the address from a constant pool.
2532 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2533 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2534 *DAG.getContext(), Sym, ARMPCLabelIndex, 0);
2535
2536 // Get the address of the callee into a register
2537 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2538 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2539 Callee = DAG.getLoad(
2540 PtrVt, dl, DAG.getEntryNode(), Addr,
2542 }
2543 }
2544 } else if (isa<GlobalAddressSDNode>(Callee)) {
2545 if (!PreferIndirect) {
2546 isDirect = true;
2547 bool isDef = GVal->isStrongDefinitionForLinker();
2548
2549 // ARM call to a local ARM function is predicable.
2550 isLocalARMFunc = !Subtarget->isThumb() && (isDef || !ARMInterworking);
2551 // tBX takes a register source operand.
2552 if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2553 assert(TT.isOSBinFormatMachO() && "WrapperPIC use on non-MachO?");
2554 Callee = DAG.getNode(
2555 ARMISD::WrapperPIC, dl, PtrVt,
2556 DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, ARMII::MO_NONLAZY));
2557 Callee = DAG.getLoad(
2558 PtrVt, dl, DAG.getEntryNode(), Callee,
2562 } else if (Subtarget->isTargetCOFF()) {
2563 assert(Subtarget->isTargetWindows() &&
2564 "Windows is the only supported COFF target");
2565 unsigned TargetFlags = ARMII::MO_NO_FLAG;
2566 if (GVal->hasDLLImportStorageClass())
2567 TargetFlags = ARMII::MO_DLLIMPORT;
2568 else if (!TM.shouldAssumeDSOLocal(GVal))
2569 TargetFlags = ARMII::MO_COFFSTUB;
2570 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, /*offset=*/0,
2571 TargetFlags);
2572 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
2573 Callee =
2574 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
2575 DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
2577 } else {
2578 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, 0);
2579 }
2580 }
2581 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2582 isDirect = true;
2583 // tBX takes a register source operand.
2584 const char *Sym = S->getSymbol();
2585 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2586 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2587 ARMConstantPoolValue *CPV =
2589 ARMPCLabelIndex, 4);
2590 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2591 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2592 Callee = DAG.getLoad(
2593 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2595 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2596 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, Callee, PICLabel);
2597 } else {
2598 Callee = DAG.getTargetExternalSymbol(Sym, PtrVt, 0);
2599 }
2600 }
2601
2602 if (isCmseNSCall) {
2603 assert(!isARMFunc && !isDirect &&
2604 "Cannot handle call to ARM function or direct call");
2605 if (NumBytes > 0) {
2606 DAG.getContext()->diagnose(
2607 DiagnosticInfoUnsupported(DAG.getMachineFunction().getFunction(),
2608 "call to non-secure function would require "
2609 "passing arguments on stack",
2610 dl.getDebugLoc()));
2611 }
2612 if (isStructRet) {
2613 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2615 "call to non-secure function would return value through pointer",
2616 dl.getDebugLoc()));
2617 }
2618 }
2619
2620 // FIXME: handle tail calls differently.
2621 unsigned CallOpc;
2622 if (Subtarget->isThumb()) {
2623 if (GuardWithBTI)
2624 CallOpc = ARMISD::t2CALL_BTI;
2625 else if (isCmseNSCall)
2626 CallOpc = ARMISD::tSECALL;
2627 else if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
2628 CallOpc = ARMISD::CALL_NOLINK;
2629 else
2630 CallOpc = ARMISD::CALL;
2631 } else {
2632 if (!isDirect && !Subtarget->hasV5TOps())
2633 CallOpc = ARMISD::CALL_NOLINK;
2634 else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
2635 // Emit regular call when code size is the priority
2636 !Subtarget->hasMinSize())
2637 // "mov lr, pc; b _foo" to avoid confusing the RSP
2638 CallOpc = ARMISD::CALL_NOLINK;
2639 else
2640 CallOpc = isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL;
2641 }
2642
2643 // We don't usually want to end the call-sequence here because we would tidy
2644 // the frame up *after* the call, however in the ABI-changing tail-call case
2645 // we've carefully laid out the parameters so that when sp is reset they'll be
2646 // in the correct location.
2647 if (isTailCall && !isSibCall) {
2648 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
2649 InGlue = Chain.getValue(1);
2650 }
2651
2652 std::vector<SDValue> Ops;
2653 Ops.push_back(Chain);
2654 Ops.push_back(Callee);
2655
2656 if (isTailCall) {
2657 Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
2658 }
2659
2660 // Add argument registers to the end of the list so that they are known live
2661 // into the call.
2662 for (const auto &[Reg, N] : RegsToPass)
2663 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2664
2665 // Add a register mask operand representing the call-preserved registers.
2666 const uint32_t *Mask;
2667 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
2668 if (isThisReturn) {
2669 // For 'this' returns, use the R0-preserving mask if applicable
2670 Mask = ARI->getThisReturnPreservedMask(MF, CallConv);
2671 if (!Mask) {
2672 // Set isThisReturn to false if the calling convention is not one that
2673 // allows 'returned' to be modeled in this way, so LowerCallResult does
2674 // not try to pass 'this' straight through
2675 isThisReturn = false;
2676 Mask = ARI->getCallPreservedMask(MF, CallConv);
2677 }
2678 } else
2679 Mask = ARI->getCallPreservedMask(MF, CallConv);
2680
2681 assert(Mask && "Missing call preserved mask for calling convention");
2682 Ops.push_back(DAG.getRegisterMask(Mask));
2683
2684 if (InGlue.getNode())
2685 Ops.push_back(InGlue);
2686
2687 if (isTailCall) {
2689 SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
2690 if (CLI.CFIType)
2691 Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2692 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2693 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2694 return Ret;
2695 }
2696
2697 // Returns a chain and a flag for retval copy to use.
2698 Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
2699 if (CLI.CFIType)
2700 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2701 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2702 InGlue = Chain.getValue(1);
2703 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
2704
2705 // If we're guaranteeing tail-calls will be honoured, the callee must
2706 // pop its own argument stack on return. But this call is *not* a tail call so
2707 // we need to undo that after it returns to restore the status-quo.
2708 bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
2709 uint64_t CalleePopBytes =
2710 canGuaranteeTCO(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : -1U;
2711
2712 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, CalleePopBytes, InGlue, dl);
2713 if (!Ins.empty())
2714 InGlue = Chain.getValue(1);
2715
2716 // Handle result values, copying them out of physregs into vregs that we
2717 // return.
2718 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2719 InVals, isThisReturn,
2720 isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
2721}
2722
2723/// HandleByVal - Every parameter *after* a byval parameter is passed
2724/// on the stack. Remember the next parameter register to allocate,
2725/// and then confiscate the rest of the parameter registers to insure
2726/// this.
2727void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size,
2728 Align Alignment) const {
2729 // Byval (as with any stack) slots are always at least 4 byte aligned.
2730 Alignment = std::max(Alignment, Align(4));
2731
2732 MCRegister Reg = State->AllocateReg(GPRArgRegs);
2733 if (!Reg)
2734 return;
2735
2736 unsigned AlignInRegs = Alignment.value() / 4;
2737 unsigned Waste = (ARM::R4 - Reg) % AlignInRegs;
2738 for (unsigned i = 0; i < Waste; ++i)
2739 Reg = State->AllocateReg(GPRArgRegs);
2740
2741 if (!Reg)
2742 return;
2743
2744 unsigned Excess = 4 * (ARM::R4 - Reg);
2745
2746 // Special case when NSAA != SP and parameter size greater than size of
2747 // all remained GPR regs. In that case we can't split parameter, we must
2748 // send it to stack. We also must set NCRN to R4, so waste all
2749 // remained registers.
2750 const unsigned NSAAOffset = State->getStackSize();
2751 if (NSAAOffset != 0 && Size > Excess) {
2752 while (State->AllocateReg(GPRArgRegs))
2753 ;
2754 return;
2755 }
2756
2757 // First register for byval parameter is the first register that wasn't
2758 // allocated before this method call, so it would be "reg".
2759 // If parameter is small enough to be saved in range [reg, r4), then
2760 // the end (first after last) register would be reg + param-size-in-regs,
2761 // else parameter would be splitted between registers and stack,
2762 // end register would be r4 in this case.
2763 unsigned ByValRegBegin = Reg;
2764 unsigned ByValRegEnd = std::min<unsigned>(Reg + Size / 4, ARM::R4);
2765 State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd);
2766 // Note, first register is allocated in the beginning of function already,
2767 // allocate remained amount of registers we need.
2768 for (unsigned i = Reg + 1; i != ByValRegEnd; ++i)
2769 State->AllocateReg(GPRArgRegs);
2770 // A byval parameter that is split between registers and memory needs its
2771 // size truncated here.
2772 // In the case where the entire structure fits in registers, we set the
2773 // size in memory to zero.
2774 Size = std::max<int>(Size - Excess, 0);
2775}
2776
2777/// IsEligibleForTailCallOptimization - Check whether the call is eligible
2778/// for tail call optimization. Targets which want to do tail call
2779/// optimization should implement this function. Note that this function also
2780/// processes musttail calls, so when this function returns false on a valid
2781/// musttail call, a fatal backend error occurs.
2782bool ARMTargetLowering::IsEligibleForTailCallOptimization(
2784 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
2785 CallingConv::ID CalleeCC = CLI.CallConv;
2786 SDValue Callee = CLI.Callee;
2787 bool isVarArg = CLI.IsVarArg;
2788 const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2789 const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2790 const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2791 const SelectionDAG &DAG = CLI.DAG;
2793 const Function &CallerF = MF.getFunction();
2794 CallingConv::ID CallerCC = CallerF.getCallingConv();
2795
2796 assert(Subtarget->supportsTailCall());
2797
2798 // Indirect tail-calls require a register to hold the target address. That
2799 // register must be:
2800 // * Allocatable (i.e. r0-r7 if the target is Thumb1).
2801 // * Not callee-saved, so must be one of r0-r3 or r12.
2802 // * Not used to hold an argument to the tail-called function, which might be
2803 // in r0-r3.
2804 // * Not used to hold the return address authentication code, which is in r12
2805 // if enabled.
2806 // Sometimes, no register matches all of these conditions, so we can't do a
2807 // tail-call.
2808 if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) {
2809 SmallSet<MCPhysReg, 5> AddressRegisters = {ARM::R0, ARM::R1, ARM::R2,
2810 ARM::R3};
2811 if (!(Subtarget->isThumb1Only() ||
2812 MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)))
2813 AddressRegisters.insert(ARM::R12);
2814 for (const CCValAssign &AL : ArgLocs)
2815 if (AL.isRegLoc())
2816 AddressRegisters.erase(AL.getLocReg());
2817 if (AddressRegisters.empty()) {
2818 LLVM_DEBUG(dbgs() << "false (no reg to hold function pointer)\n");
2819 return false;
2820 }
2821 }
2822
2823 // Look for obvious safe cases to perform tail call optimization that do not
2824 // require ABI changes. This is what gcc calls sibcall.
2825
2826 // Exception-handling functions need a special set of instructions to indicate
2827 // a return to the hardware. Tail-calling another function would probably
2828 // break this.
2829 if (CallerF.hasFnAttribute("interrupt")) {
2830 LLVM_DEBUG(dbgs() << "false (interrupt attribute)\n");
2831 return false;
2832 }
2833
2834 if (canGuaranteeTCO(CalleeCC,
2835 getTargetMachine().Options.GuaranteedTailCallOpt)) {
2836 LLVM_DEBUG(dbgs() << (CalleeCC == CallerCC ? "true" : "false")
2837 << " (guaranteed tail-call CC)\n");
2838 return CalleeCC == CallerCC;
2839 }
2840
2841 // Also avoid sibcall optimization if either caller or callee uses struct
2842 // return semantics.
2843 bool isCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
2844 bool isCallerStructRet = MF.getFunction().hasStructRetAttr();
2845 if (isCalleeStructRet != isCallerStructRet) {
2846 LLVM_DEBUG(dbgs() << "false (struct-ret)\n");
2847 return false;
2848 }
2849
2850 // Externally-defined functions with weak linkage should not be
2851 // tail-called on ARM when the OS does not support dynamic
2852 // pre-emption of symbols, as the AAELF spec requires normal calls
2853 // to undefined weak functions to be replaced with a NOP or jump to the
2854 // next instruction. The behaviour of branch instructions in this
2855 // situation (as used for tail calls) is implementation-defined, so we
2856 // cannot rely on the linker replacing the tail call with a return.
2857 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2858 const GlobalValue *GV = G->getGlobal();
2859 const Triple &TT = GV->getParent()->getTargetTriple();
2860 if (GV->hasExternalWeakLinkage() &&
2861 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
2862 TT.isOSBinFormatMachO())) {
2863 LLVM_DEBUG(dbgs() << "false (external weak linkage)\n");
2864 return false;
2865 }
2866 }
2867
2868 // Check that the call results are passed in the same way.
2869 LLVMContext &C = *DAG.getContext();
2871 getEffectiveCallingConv(CalleeCC, isVarArg),
2872 getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
2873 CCAssignFnForReturn(CalleeCC, isVarArg),
2874 CCAssignFnForReturn(CallerCC, CallerF.isVarArg()))) {
2875 LLVM_DEBUG(dbgs() << "false (incompatible results)\n");
2876 return false;
2877 }
2878 // The callee has to preserve all registers the caller needs to preserve.
2879 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
2880 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
2881 if (CalleeCC != CallerCC) {
2882 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
2883 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) {
2884 LLVM_DEBUG(dbgs() << "false (not all registers preserved)\n");
2885 return false;
2886 }
2887 }
2888
2889 // If Caller's vararg argument has been split between registers and stack, do
2890 // not perform tail call, since part of the argument is in caller's local
2891 // frame.
2892 const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
2893 if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
2894 LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
2895 return false;
2896 }
2897
2898 // If the callee takes no arguments then go on to check the results of the
2899 // call.
2900 const MachineRegisterInfo &MRI = MF.getRegInfo();
2901 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals)) {
2902 LLVM_DEBUG(dbgs() << "false (parameters in CSRs do not match)\n");
2903 return false;
2904 }
2905
2906 // If the stack arguments for this call do not fit into our own save area then
2907 // the call cannot be made tail.
2908 if (CCInfo.getStackSize() > AFI_Caller->getArgumentStackSize())
2909 return false;
2910
2911 LLVM_DEBUG(dbgs() << "true\n");
2912 return true;
2913}
2914
2915bool
2916ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2917 MachineFunction &MF, bool isVarArg,
2919 LLVMContext &Context, const Type *RetTy) const {
2921 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
2922 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2923}
2924
2926 const SDLoc &DL, SelectionDAG &DAG) {
2927 const MachineFunction &MF = DAG.getMachineFunction();
2928 const Function &F = MF.getFunction();
2929
2930 StringRef IntKind = F.getFnAttribute("interrupt").getValueAsString();
2931
2932 // See ARM ARM v7 B1.8.3. On exception entry LR is set to a possibly offset
2933 // version of the "preferred return address". These offsets affect the return
2934 // instruction if this is a return from PL1 without hypervisor extensions.
2935 // IRQ/FIQ: +4 "subs pc, lr, #4"
2936 // SWI: 0 "subs pc, lr, #0"
2937 // ABORT: +4 "subs pc, lr, #4"
2938 // UNDEF: +4/+2 "subs pc, lr, #0"
2939 // UNDEF varies depending on where the exception came from ARM or Thumb
2940 // mode. Alongside GCC, we throw our hands up in disgust and pretend it's 0.
2941
2942 int64_t LROffset;
2943 if (IntKind == "" || IntKind == "IRQ" || IntKind == "FIQ" ||
2944 IntKind == "ABORT")
2945 LROffset = 4;
2946 else if (IntKind == "SWI" || IntKind == "UNDEF")
2947 LROffset = 0;
2948 else
2949 report_fatal_error("Unsupported interrupt attribute. If present, value "
2950 "must be one of: IRQ, FIQ, SWI, ABORT or UNDEF");
2951
2952 RetOps.insert(RetOps.begin() + 1,
2953 DAG.getConstant(LROffset, DL, MVT::i32, false));
2954
2955 return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
2956}
2957
2958SDValue
2959ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2960 bool isVarArg,
2962 const SmallVectorImpl<SDValue> &OutVals,
2963 const SDLoc &dl, SelectionDAG &DAG) const {
2964 // CCValAssign - represent the assignment of the return value to a location.
2966
2967 // CCState - Info about the registers and stack slots.
2968 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
2969 *DAG.getContext());
2970
2971 // Analyze outgoing return values.
2972 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2973
2974 SDValue Glue;
2976 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
2977 bool isLittleEndian = Subtarget->isLittle();
2978
2980 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2981 AFI->setReturnRegsCount(RVLocs.size());
2982
2983 // Report error if cmse entry function returns structure through first ptr arg.
2984 if (AFI->isCmseNSEntryFunction() && MF.getFunction().hasStructRetAttr()) {
2985 // Note: using an empty SDLoc(), as the first line of the function is a
2986 // better place to report than the last line.
2987 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2989 "secure entry function would return value through pointer",
2990 SDLoc().getDebugLoc()));
2991 }
2992
2993 // Copy the result values into the output registers.
2994 for (unsigned i = 0, realRVLocIdx = 0;
2995 i != RVLocs.size();
2996 ++i, ++realRVLocIdx) {
2997 CCValAssign &VA = RVLocs[i];
2998 assert(VA.isRegLoc() && "Can only return in registers!");
2999
3000 SDValue Arg = OutVals[realRVLocIdx];
3001 bool ReturnF16 = false;
3002
3003 if (Subtarget->hasFullFP16() && Subtarget->isTargetHardFloat()) {
3004 // Half-precision return values can be returned like this:
3005 //
3006 // t11 f16 = fadd ...
3007 // t12: i16 = bitcast t11
3008 // t13: i32 = zero_extend t12
3009 // t14: f32 = bitcast t13 <~~~~~~~ Arg
3010 //
3011 // to avoid code generation for bitcasts, we simply set Arg to the node
3012 // that produces the f16 value, t11 in this case.
3013 //
3014 if (Arg.getValueType() == MVT::f32 && Arg.getOpcode() == ISD::BITCAST) {
3015 SDValue ZE = Arg.getOperand(0);
3016 if (ZE.getOpcode() == ISD::ZERO_EXTEND && ZE.getValueType() == MVT::i32) {
3017 SDValue BC = ZE.getOperand(0);
3018 if (BC.getOpcode() == ISD::BITCAST && BC.getValueType() == MVT::i16) {
3019 Arg = BC.getOperand(0);
3020 ReturnF16 = true;
3021 }
3022 }
3023 }
3024 }
3025
3026 switch (VA.getLocInfo()) {
3027 default: llvm_unreachable("Unknown loc info!");
3028 case CCValAssign::Full: break;
3029 case CCValAssign::BCvt:
3030 if (!ReturnF16)
3031 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3032 break;
3033 }
3034
3035 // Mask f16 arguments if this is a CMSE nonsecure entry.
3036 auto RetVT = Outs[realRVLocIdx].ArgVT;
3037 if (AFI->isCmseNSEntryFunction() && (RetVT == MVT::f16)) {
3038 if (VA.needsCustom() && VA.getValVT() == MVT::f16) {
3039 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
3040 } else {
3041 auto LocBits = VA.getLocVT().getSizeInBits();
3042 auto MaskValue = APInt::getLowBitsSet(LocBits, RetVT.getSizeInBits());
3043 SDValue Mask =
3044 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
3045 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
3046 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
3047 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3048 }
3049 }
3050
3051 if (VA.needsCustom() &&
3052 (VA.getLocVT() == MVT::v2f64 || VA.getLocVT() == MVT::f64)) {
3053 if (VA.getLocVT() == MVT::v2f64) {
3054 // Extract the first half and return it in two registers.
3055 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3056 DAG.getConstant(0, dl, MVT::i32));
3057 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
3058 DAG.getVTList(MVT::i32, MVT::i32), Half);
3059
3060 Chain =
3061 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3062 HalfGPRs.getValue(isLittleEndian ? 0 : 1), Glue);
3063 Glue = Chain.getValue(1);
3064 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3065 VA = RVLocs[++i]; // skip ahead to next loc
3066 Chain =
3067 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3068 HalfGPRs.getValue(isLittleEndian ? 1 : 0), Glue);
3069 Glue = Chain.getValue(1);
3070 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3071 VA = RVLocs[++i]; // skip ahead to next loc
3072
3073 // Extract the 2nd half and fall through to handle it as an f64 value.
3074 Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3075 DAG.getConstant(1, dl, MVT::i32));
3076 }
3077 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
3078 // available.
3079 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
3080 DAG.getVTList(MVT::i32, MVT::i32), Arg);
3081 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3082 fmrrd.getValue(isLittleEndian ? 0 : 1), Glue);
3083 Glue = Chain.getValue(1);
3084 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3085 VA = RVLocs[++i]; // skip ahead to next loc
3086 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3087 fmrrd.getValue(isLittleEndian ? 1 : 0), Glue);
3088 } else
3089 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
3090
3091 // Guarantee that all emitted copies are
3092 // stuck together, avoiding something bad.
3093 Glue = Chain.getValue(1);
3094 RetOps.push_back(DAG.getRegister(
3095 VA.getLocReg(), ReturnF16 ? Arg.getValueType() : VA.getLocVT()));
3096 }
3097 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
3098 const MCPhysReg *I =
3099 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3100 if (I) {
3101 for (; *I; ++I) {
3102 if (ARM::GPRRegClass.contains(*I))
3103 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3104 else if (ARM::DPRRegClass.contains(*I))
3106 else
3107 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3108 }
3109 }
3110
3111 // Update chain and glue.
3112 RetOps[0] = Chain;
3113 if (Glue.getNode())
3114 RetOps.push_back(Glue);
3115
3116 // CPUs which aren't M-class use a special sequence to return from
3117 // exceptions (roughly, any instruction setting pc and cpsr simultaneously,
3118 // though we use "subs pc, lr, #N").
3119 //
3120 // M-class CPUs actually use a normal return sequence with a special
3121 // (hardware-provided) value in LR, so the normal code path works.
3122 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt") &&
3123 !Subtarget->isMClass()) {
3124 if (Subtarget->isThumb1Only())
3125 report_fatal_error("interrupt attribute is not supported in Thumb1");
3126 return LowerInterruptReturn(RetOps, dl, DAG);
3127 }
3128
3129 unsigned RetNode =
3130 AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
3131 return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
3132}
3133
3134bool ARMTargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
3135 if (N->getNumValues() != 1)
3136 return false;
3137 if (!N->hasNUsesOfValue(1, 0))
3138 return false;
3139
3140 SDValue TCChain = Chain;
3141 SDNode *Copy = *N->user_begin();
3142 if (Copy->getOpcode() == ISD::CopyToReg) {
3143 // If the copy has a glue operand, we conservatively assume it isn't safe to
3144 // perform a tail call.
3145 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3146 return false;
3147 TCChain = Copy->getOperand(0);
3148 } else if (Copy->getOpcode() == ARMISD::VMOVRRD) {
3149 SDNode *VMov = Copy;
3150 // f64 returned in a pair of GPRs.
3151 SmallPtrSet<SDNode*, 2> Copies;
3152 for (SDNode *U : VMov->users()) {
3153 if (U->getOpcode() != ISD::CopyToReg)
3154 return false;
3155 Copies.insert(U);
3156 }
3157 if (Copies.size() > 2)
3158 return false;
3159
3160 for (SDNode *U : VMov->users()) {
3161 SDValue UseChain = U->getOperand(0);
3162 if (Copies.count(UseChain.getNode()))
3163 // Second CopyToReg
3164 Copy = U;
3165 else {
3166 // We are at the top of this chain.
3167 // If the copy has a glue operand, we conservatively assume it
3168 // isn't safe to perform a tail call.
3169 if (U->getOperand(U->getNumOperands() - 1).getValueType() == MVT::Glue)
3170 return false;
3171 // First CopyToReg
3172 TCChain = UseChain;
3173 }
3174 }
3175 } else if (Copy->getOpcode() == ISD::BITCAST) {
3176 // f32 returned in a single GPR.
3177 if (!Copy->hasOneUse())
3178 return false;
3179 Copy = *Copy->user_begin();
3180 if (Copy->getOpcode() != ISD::CopyToReg || !Copy->hasNUsesOfValue(1, 0))
3181 return false;
3182 // If the copy has a glue operand, we conservatively assume it isn't safe to
3183 // perform a tail call.
3184 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3185 return false;
3186 TCChain = Copy->getOperand(0);
3187 } else {
3188 return false;
3189 }
3190
3191 bool HasRet = false;
3192 for (const SDNode *U : Copy->users()) {
3193 if (U->getOpcode() != ARMISD::RET_GLUE &&
3194 U->getOpcode() != ARMISD::INTRET_GLUE)
3195 return false;
3196 HasRet = true;
3197 }
3198
3199 if (!HasRet)
3200 return false;
3201
3202 Chain = TCChain;
3203 return true;
3204}
3205
3206bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
3207 if (!Subtarget->supportsTailCall())
3208 return false;
3209
3210 if (!CI->isTailCall())
3211 return false;
3212
3213 return true;
3214}
3215
3216// Trying to write a 64 bit value so need to split into two 32 bit values first,
3217// and pass the lower and high parts through.
3219 SDLoc DL(Op);
3220 SDValue WriteValue = Op->getOperand(2);
3221
3222 // This function is only supposed to be called for i64 type argument.
3223 assert(WriteValue.getValueType() == MVT::i64
3224 && "LowerWRITE_REGISTER called for non-i64 type argument.");
3225
3226 SDValue Lo, Hi;
3227 std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32);
3228 SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi };
3229 return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops);
3230}
3231
3232// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3233// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
3234// one of the above mentioned nodes. It has to be wrapped because otherwise
3235// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3236// be used to form addressing mode. These wrapped nodes will be selected
3237// into MOVi.
3238SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
3239 SelectionDAG &DAG) const {
3240 EVT PtrVT = Op.getValueType();
3241 // FIXME there is no actual debug info here
3242 SDLoc dl(Op);
3243 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3244 SDValue Res;
3245
3246 // When generating execute-only code Constant Pools must be promoted to the
3247 // global data section. It's a bit ugly that we can't share them across basic
3248 // blocks, but this way we guarantee that execute-only behaves correct with
3249 // position-independent addressing modes.
3250 if (Subtarget->genExecuteOnly()) {
3251 auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
3252 auto *T = CP->getType();
3253 auto C = const_cast<Constant*>(CP->getConstVal());
3254 auto M = DAG.getMachineFunction().getFunction().getParent();
3255 auto GV = new GlobalVariable(
3256 *M, T, /*isConstant=*/true, GlobalVariable::InternalLinkage, C,
3257 Twine(DAG.getDataLayout().getInternalSymbolPrefix()) + "CP" +
3258 Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
3259 Twine(AFI->createPICLabelUId()));
3260 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3261 return LowerGlobalAddress(GA, DAG);
3262 }
3263
3264 // The 16-bit ADR instruction can only encode offsets that are multiples of 4,
3265 // so we need to align to at least 4 bytes when we don't have 32-bit ADR.
3266 Align CPAlign = CP->getAlign();
3267 if (Subtarget->isThumb1Only())
3268 CPAlign = std::max(CPAlign, Align(4));
3270 Res =
3271 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CPAlign);
3272 else
3273 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CPAlign);
3274 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
3275}
3276
3278 // If we don't have a 32-bit pc-relative branch instruction then the jump
3279 // table consists of block addresses. Usually this is inline, but for
3280 // execute-only it must be placed out-of-line.
3281 if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
3284}
3285
3286SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
3287 SelectionDAG &DAG) const {
3290 unsigned ARMPCLabelIndex = 0;
3291 SDLoc DL(Op);
3292 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3293 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
3294 SDValue CPAddr;
3295 bool IsPositionIndependent = isPositionIndependent() || Subtarget->isROPI();
3296 if (!IsPositionIndependent) {
3297 CPAddr = DAG.getTargetConstantPool(BA, PtrVT, Align(4));
3298 } else {
3299 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3300 ARMPCLabelIndex = AFI->createPICLabelUId();
3302 ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex,
3303 ARMCP::CPBlockAddress, PCAdj);
3304 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3305 }
3306 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
3307 SDValue Result = DAG.getLoad(
3308 PtrVT, DL, DAG.getEntryNode(), CPAddr,
3310 if (!IsPositionIndependent)
3311 return Result;
3312 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, DL, MVT::i32);
3313 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
3314}
3315
3316/// Convert a TLS address reference into the correct sequence of loads
3317/// and calls to compute the variable's address for Darwin, and return an
3318/// SDValue containing the final node.
3319
3320/// Darwin only has one TLS scheme which must be capable of dealing with the
3321/// fully general situation, in the worst case. This means:
3322/// + "extern __thread" declaration.
3323/// + Defined in a possibly unknown dynamic library.
3324///
3325/// The general system is that each __thread variable has a [3 x i32] descriptor
3326/// which contains information used by the runtime to calculate the address. The
3327/// only part of this the compiler needs to know about is the first word, which
3328/// contains a function pointer that must be called with the address of the
3329/// entire descriptor in "r0".
3330///
3331/// Since this descriptor may be in a different unit, in general access must
3332/// proceed along the usual ARM rules. A common sequence to produce is:
3333///
3334/// movw rT1, :lower16:_var$non_lazy_ptr
3335/// movt rT1, :upper16:_var$non_lazy_ptr
3336/// ldr r0, [rT1]
3337/// ldr rT2, [r0]
3338/// blx rT2
3339/// [...address now in r0...]
3340SDValue
3341ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
3342 SelectionDAG &DAG) const {
3343 assert(getTargetMachine().getTargetTriple().isOSDarwin() &&
3344 "This function expects a Darwin target");
3345 SDLoc DL(Op);
3346
3347 // First step is to get the address of the actua global symbol. This is where
3348 // the TLS descriptor lives.
3349 SDValue DescAddr = LowerGlobalAddressDarwin(Op, DAG);
3350
3351 // The first entry in the descriptor is a function pointer that we must call
3352 // to obtain the address of the variable.
3353 SDValue Chain = DAG.getEntryNode();
3354 SDValue FuncTLVGet = DAG.getLoad(
3355 MVT::i32, DL, Chain, DescAddr,
3359 Chain = FuncTLVGet.getValue(1);
3360
3362 MachineFrameInfo &MFI = F.getFrameInfo();
3363 MFI.setAdjustsStack(true);
3364
3365 // TLS calls preserve all registers except those that absolutely must be
3366 // trashed: R0 (it takes an argument), LR (it's a call) and CPSR (let's not be
3367 // silly).
3368 auto TRI =
3370 auto ARI = static_cast<const ARMRegisterInfo *>(TRI);
3371 const uint32_t *Mask = ARI->getTLSCallPreservedMask(DAG.getMachineFunction());
3372
3373 // Finally, we can make the call. This is just a degenerate version of a
3374 // normal AArch64 call node: r0 takes the address of the descriptor, and
3375 // returns the address of the variable in this thread.
3376 Chain = DAG.getCopyToReg(Chain, DL, ARM::R0, DescAddr, SDValue());
3377 Chain =
3378 DAG.getNode(ARMISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
3379 Chain, FuncTLVGet, DAG.getRegister(ARM::R0, MVT::i32),
3380 DAG.getRegisterMask(Mask), Chain.getValue(1));
3381 return DAG.getCopyFromReg(Chain, DL, ARM::R0, MVT::i32, Chain.getValue(1));
3382}
3383
3384SDValue
3385ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
3386 SelectionDAG &DAG) const {
3387 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3388 "Windows specific TLS lowering");
3389
3390 SDValue Chain = DAG.getEntryNode();
3391 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3392 SDLoc DL(Op);
3393
3394 // Load the current TEB (thread environment block)
3395 SDValue Ops[] = {Chain,
3396 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
3397 DAG.getTargetConstant(15, DL, MVT::i32),
3398 DAG.getTargetConstant(0, DL, MVT::i32),
3399 DAG.getTargetConstant(13, DL, MVT::i32),
3400 DAG.getTargetConstant(0, DL, MVT::i32),
3401 DAG.getTargetConstant(2, DL, MVT::i32)};
3402 SDValue CurrentTEB = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
3403 DAG.getVTList(MVT::i32, MVT::Other), Ops);
3404
3405 SDValue TEB = CurrentTEB.getValue(0);
3406 Chain = CurrentTEB.getValue(1);
3407
3408 // Load the ThreadLocalStoragePointer from the TEB
3409 // A pointer to the TLS array is located at offset 0x2c from the TEB.
3410 SDValue TLSArray =
3411 DAG.getNode(ISD::ADD, DL, PtrVT, TEB, DAG.getIntPtrConstant(0x2c, DL));
3412 TLSArray = DAG.getLoad(PtrVT, DL, Chain, TLSArray, MachinePointerInfo());
3413
3414 // The pointer to the thread's TLS data area is at the TLS Index scaled by 4
3415 // offset into the TLSArray.
3416
3417 // Load the TLS index from the C runtime
3418 SDValue TLSIndex =
3419 DAG.getTargetExternalSymbol("_tls_index", PtrVT, ARMII::MO_NO_FLAG);
3420 TLSIndex = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, TLSIndex);
3421 TLSIndex = DAG.getLoad(PtrVT, DL, Chain, TLSIndex, MachinePointerInfo());
3422
3423 SDValue Slot = DAG.getNode(ISD::SHL, DL, PtrVT, TLSIndex,
3424 DAG.getConstant(2, DL, MVT::i32));
3425 SDValue TLS = DAG.getLoad(PtrVT, DL, Chain,
3426 DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
3427 MachinePointerInfo());
3428
3429 // Get the offset of the start of the .tls section (section base)
3430 const auto *GA = cast<GlobalAddressSDNode>(Op);
3431 auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
3432 SDValue Offset = DAG.getLoad(
3433 PtrVT, DL, Chain,
3434 DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
3435 DAG.getTargetConstantPool(CPV, PtrVT, Align(4))),
3437
3438 return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
3439}
3440
3441// Lower ISD::GlobalTLSAddress using the "general dynamic" model
3442SDValue
3443ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
3444 SelectionDAG &DAG) const {
3445 SDLoc dl(GA);
3446 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3447 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3449 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3450 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3451 ARMConstantPoolValue *CPV =
3452 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3453 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
3454 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3455 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
3456 Argument = DAG.getLoad(
3457 PtrVT, dl, DAG.getEntryNode(), Argument,
3459 SDValue Chain = Argument.getValue(1);
3460
3461 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3462 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
3463
3464 // call __tls_get_addr.
3466 Args.emplace_back(Argument, Type::getInt32Ty(*DAG.getContext()));
3467
3468 // FIXME: is there useful debug info available here?
3469 TargetLowering::CallLoweringInfo CLI(DAG);
3470 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3472 DAG.getExternalSymbol("__tls_get_addr", PtrVT), std::move(Args));
3473
3474 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3475 return CallResult.first;
3476}
3477
3478// Lower ISD::GlobalTLSAddress using the "initial exec" or
3479// "local exec" model.
3480SDValue
3481ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
3482 SelectionDAG &DAG,
3483 TLSModel::Model model) const {
3484 const GlobalValue *GV = GA->getGlobal();
3485 SDLoc dl(GA);
3486 SDValue Offset;
3487 SDValue Chain = DAG.getEntryNode();
3488 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3489 // Get the Thread Pointer
3490 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3491
3492 if (model == TLSModel::InitialExec) {
3494 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3495 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3496 // Initial exec model.
3497 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3498 ARMConstantPoolValue *CPV =
3499 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3501 true);
3502 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3503 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3504 Offset = DAG.getLoad(
3505 PtrVT, dl, Chain, Offset,
3507 Chain = Offset.getValue(1);
3508
3509 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3510 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
3511
3512 Offset = DAG.getLoad(
3513 PtrVT, dl, Chain, Offset,
3515 } else {
3516 // local exec model
3517 assert(model == TLSModel::LocalExec);
3518 ARMConstantPoolValue *CPV =
3520 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3521 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3522 Offset = DAG.getLoad(
3523 PtrVT, dl, Chain, Offset,
3525 }
3526
3527 // The address of the thread local variable is the add of the thread
3528 // pointer with the offset of the variable.
3529 return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
3530}
3531
3532SDValue
3533ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
3534 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
3535 if (DAG.getTarget().useEmulatedTLS())
3536 return LowerToTLSEmulatedModel(GA, DAG);
3537
3538 const Triple &TT = getTargetMachine().getTargetTriple();
3539 if (TT.isOSDarwin())
3540 return LowerGlobalTLSAddressDarwin(Op, DAG);
3541
3542 if (TT.isOSWindows())
3543 return LowerGlobalTLSAddressWindows(Op, DAG);
3544
3545 // TODO: implement the "local dynamic" model
3546 assert(TT.isOSBinFormatELF() && "Only ELF implemented here");
3548
3549 switch (model) {
3552 return LowerToTLSGeneralDynamicModel(GA, DAG);
3555 return LowerToTLSExecModels(GA, DAG, model);
3556 }
3557 llvm_unreachable("bogus TLS model");
3558}
3559
3560/// Return true if all users of V are within function F, looking through
3561/// ConstantExprs.
3562static bool allUsersAreInFunction(const Value *V, const Function *F) {
3563 SmallVector<const User*,4> Worklist(V->users());
3564 while (!Worklist.empty()) {
3565 auto *U = Worklist.pop_back_val();
3566 if (isa<ConstantExpr>(U)) {
3567 append_range(Worklist, U->users());
3568 continue;
3569 }
3570
3571 auto *I = dyn_cast<Instruction>(U);
3572 if (!I || I->getParent()->getParent() != F)
3573 return false;
3574 }
3575 return true;
3576}
3577
3579 const GlobalValue *GV, SelectionDAG &DAG,
3580 EVT PtrVT, const SDLoc &dl) {
3581 // If we're creating a pool entry for a constant global with unnamed address,
3582 // and the global is small enough, we can emit it inline into the constant pool
3583 // to save ourselves an indirection.
3584 //
3585 // This is a win if the constant is only used in one function (so it doesn't
3586 // need to be duplicated) or duplicating the constant wouldn't increase code
3587 // size (implying the constant is no larger than 4 bytes).
3588 const Function &F = DAG.getMachineFunction().getFunction();
3589
3590 // We rely on this decision to inline being idempotent and unrelated to the
3591 // use-site. We know that if we inline a variable at one use site, we'll
3592 // inline it elsewhere too (and reuse the constant pool entry). Fast-isel
3593 // doesn't know about this optimization, so bail out if it's enabled else
3594 // we could decide to inline here (and thus never emit the GV) but require
3595 // the GV from fast-isel generated code.
3598 return SDValue();
3599
3600 auto *GVar = dyn_cast<GlobalVariable>(GV);
3601 if (!GVar || !GVar->hasInitializer() ||
3602 !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
3603 !GVar->hasLocalLinkage())
3604 return SDValue();
3605
3606 // If we inline a value that contains relocations, we move the relocations
3607 // from .data to .text. This is not allowed in position-independent code.
3608 auto *Init = GVar->getInitializer();
3609 if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3610 Init->needsDynamicRelocation())
3611 return SDValue();
3612
3613 // The constant islands pass can only really deal with alignment requests
3614 // <= 4 bytes and cannot pad constants itself. Therefore we cannot promote
3615 // any type wanting greater alignment requirements than 4 bytes. We also
3616 // can only promote constants that are multiples of 4 bytes in size or
3617 // are paddable to a multiple of 4. Currently we only try and pad constants
3618 // that are strings for simplicity.
3619 auto *CDAInit = dyn_cast<ConstantDataArray>(Init);
3620 unsigned Size = DAG.getDataLayout().getTypeAllocSize(Init->getType());
3621 Align PrefAlign = DAG.getDataLayout().getPreferredAlign(GVar);
3622 unsigned RequiredPadding = 4 - (Size % 4);
3623 bool PaddingPossible =
3624 RequiredPadding == 4 || (CDAInit && CDAInit->isString());
3625 if (!PaddingPossible || PrefAlign > 4 || Size > ConstpoolPromotionMaxSize ||
3626 Size == 0)
3627 return SDValue();
3628
3629 unsigned PaddedSize = Size + ((RequiredPadding == 4) ? 0 : RequiredPadding);
3631 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3632
3633 // We can't bloat the constant pool too much, else the ConstantIslands pass
3634 // may fail to converge. If we haven't promoted this global yet (it may have
3635 // multiple uses), and promoting it would increase the constant pool size (Sz
3636 // > 4), ensure we have space to do so up to MaxTotal.
3637 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar) && Size > 4)
3638 if (AFI->getPromotedConstpoolIncrease() + PaddedSize - 4 >=
3640 return SDValue();
3641
3642 // This is only valid if all users are in a single function; we can't clone
3643 // the constant in general. The LLVM IR unnamed_addr allows merging
3644 // constants, but not cloning them.
3645 //
3646 // We could potentially allow cloning if we could prove all uses of the
3647 // constant in the current function don't care about the address, like
3648 // printf format strings. But that isn't implemented for now.
3649 if (!allUsersAreInFunction(GVar, &F))
3650 return SDValue();
3651
3652 // We're going to inline this global. Pad it out if needed.
3653 if (RequiredPadding != 4) {
3654 StringRef S = CDAInit->getAsString();
3655
3657 std::copy(S.bytes_begin(), S.bytes_end(), V.begin());
3658 while (RequiredPadding--)
3659 V.push_back(0);
3661 }
3662
3663 auto CPVal = ARMConstantPoolConstant::Create(GVar, Init);
3664 SDValue CPAddr = DAG.getTargetConstantPool(CPVal, PtrVT, Align(4));
3665 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar)) {
3668 PaddedSize - 4);
3669 }
3670 ++NumConstpoolPromoted;
3671 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3672}
3673
3675 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
3676 if (!(GV = GA->getAliaseeObject()))
3677 return false;
3678 if (const auto *V = dyn_cast<GlobalVariable>(GV))
3679 return V->isConstant();
3680 return isa<Function>(GV);
3681}
3682
3683SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3684 SelectionDAG &DAG) const {
3685 switch (Subtarget->getTargetTriple().getObjectFormat()) {
3686 default: llvm_unreachable("unknown object format");
3687 case Triple::COFF:
3688 return LowerGlobalAddressWindows(Op, DAG);
3689 case Triple::ELF:
3690 return LowerGlobalAddressELF(Op, DAG);
3691 case Triple::MachO:
3692 return LowerGlobalAddressDarwin(Op, DAG);
3693 }
3694}
3695
3696SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
3697 SelectionDAG &DAG) const {
3698 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3699 SDLoc dl(Op);
3700 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3701 bool IsRO = isReadOnly(GV);
3702
3703 // promoteToConstantPool only if not generating XO text section
3704 if (GV->isDSOLocal() && !Subtarget->genExecuteOnly())
3705 if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
3706 return V;
3707
3708 if (isPositionIndependent()) {
3709 SDValue G = DAG.getTargetGlobalAddress(
3710 GV, dl, PtrVT, 0, GV->isDSOLocal() ? 0 : ARMII::MO_GOT);
3711 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3712 if (!GV->isDSOLocal())
3713 Result =
3714 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3716 return Result;
3717 } else if (Subtarget->isROPI() && IsRO) {
3718 // PC-relative.
3719 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3720 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3721 return Result;
3722 } else if (Subtarget->isRWPI() && !IsRO) {
3723 // SB-relative.
3724 SDValue RelAddr;
3725 if (Subtarget->useMovt()) {
3726 ++NumMovwMovt;
3727 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_SBREL);
3728 RelAddr = DAG.getNode(ARMISD::Wrapper, dl, PtrVT, G);
3729 } else { // use literal pool for address constant
3730 ARMConstantPoolValue *CPV =
3732 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3733 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3734 RelAddr = DAG.getLoad(
3735 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3737 }
3738 SDValue SB = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::R9, PtrVT);
3739 SDValue Result = DAG.getNode(ISD::ADD, dl, PtrVT, SB, RelAddr);
3740 return Result;
3741 }
3742
3743 // If we have T2 ops, we can materialize the address directly via movt/movw
3744 // pair. This is always cheaper. If need to generate Execute Only code, and we
3745 // only have Thumb1 available, we can't use a constant pool and are forced to
3746 // use immediate relocations.
3747 if (Subtarget->useMovt() || Subtarget->genExecuteOnly()) {
3748 if (Subtarget->useMovt())
3749 ++NumMovwMovt;
3750 // FIXME: Once remat is capable of dealing with instructions with register
3751 // operands, expand this into two nodes.
3752 return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
3753 DAG.getTargetGlobalAddress(GV, dl, PtrVT));
3754 } else {
3755 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
3756 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3757 return DAG.getLoad(
3758 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3760 }
3761}
3762
3763SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3764 SelectionDAG &DAG) const {
3765 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3766 "ROPI/RWPI not currently supported for Darwin");
3767 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3768 SDLoc dl(Op);
3769 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3770
3771 if (Subtarget->useMovt())
3772 ++NumMovwMovt;
3773
3774 // FIXME: Once remat is capable of dealing with instructions with register
3775 // operands, expand this into multiple nodes
3776 unsigned Wrapper =
3777 isPositionIndependent() ? ARMISD::WrapperPIC : ARMISD::Wrapper;
3778
3779 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
3780 SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
3781
3782 if (Subtarget->isGVIndirectSymbol(GV))
3783 Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3785 return Result;
3786}
3787
3788SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op,
3789 SelectionDAG &DAG) const {
3790 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3791 "non-Windows COFF is not supported");
3792 assert(Subtarget->useMovt() &&
3793 "Windows on ARM expects to use movw/movt");
3794 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3795 "ROPI/RWPI not currently supported for Windows");
3796
3797 const TargetMachine &TM = getTargetMachine();
3798 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3799 ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG;
3800 if (GV->hasDLLImportStorageClass())
3801 TargetFlags = ARMII::MO_DLLIMPORT;
3802 else if (!TM.shouldAssumeDSOLocal(GV))
3803 TargetFlags = ARMII::MO_COFFSTUB;
3804 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3805 SDValue Result;
3806 SDLoc DL(Op);
3807
3808 ++NumMovwMovt;
3809
3810 // FIXME: Once remat is capable of dealing with instructions with register
3811 // operands, expand this into two nodes.
3812 Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT,
3813 DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*offset=*/0,
3814 TargetFlags));
3815 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
3816 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
3818 return Result;
3819}
3820
3821SDValue
3822ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const {
3823 SDLoc dl(Op);
3824 SDValue Val = DAG.getConstant(0, dl, MVT::i32);
3825 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl,
3826 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
3827 Op.getOperand(1), Val);
3828}
3829
3830SDValue
3831ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
3832 SDLoc dl(Op);
3833 return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
3834 Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
3835}
3836
3837SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
3838 SelectionDAG &DAG) const {
3839 SDLoc dl(Op);
3840 return DAG.getNode(ARMISD::EH_SJLJ_SETUP_DISPATCH, dl, MVT::Other,
3841 Op.getOperand(0));
3842}
3843
3844SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3845 SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3846 unsigned IntNo =
3847 Op.getConstantOperandVal(Op.getOperand(0).getValueType() == MVT::Other);
3848 switch (IntNo) {
3849 default:
3850 return SDValue(); // Don't custom lower most intrinsics.
3851 case Intrinsic::arm_gnu_eabi_mcount: {
3853 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3854 SDLoc dl(Op);
3855 SDValue Chain = Op.getOperand(0);
3856 // call "\01__gnu_mcount_nc"
3857 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3858 const uint32_t *Mask =
3860 assert(Mask && "Missing call preserved mask for calling convention");
3861 // Mark LR an implicit live-in.
3862 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3863 SDValue ReturnAddress =
3864 DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3865 constexpr EVT ResultTys[] = {MVT::Other, MVT::Glue};
3866 SDValue Callee =
3867 DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3868 SDValue RegisterMask = DAG.getRegisterMask(Mask);
3869 if (Subtarget->isThumb())
3870 return SDValue(
3871 DAG.getMachineNode(
3872 ARM::tBL_PUSHLR, dl, ResultTys,
3873 {ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3874 DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3875 0);
3876 return SDValue(
3877 DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3878 {ReturnAddress, Callee, RegisterMask, Chain}),
3879 0);
3880 }
3881 }
3882}
3883
3884SDValue
3885ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
3886 const ARMSubtarget *Subtarget) const {
3887 unsigned IntNo = Op.getConstantOperandVal(0);
3888 SDLoc dl(Op);
3889 switch (IntNo) {
3890 default: return SDValue(); // Don't custom lower most intrinsics.
3891 case Intrinsic::localaddress: {
3892 const MachineFunction &MF = DAG.getMachineFunction();
3893 const auto *RegInfo = Subtarget->getRegisterInfo();
3894 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
3895 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
3896 Op.getSimpleValueType());
3897 }
3898 case Intrinsic::eh_recoverfp: {
3899 SDValue FnOp = Op.getOperand(1);
3900 GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
3901 auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
3902 if (!Fn)
3904 "llvm.eh.recoverfp must take a function as the first argument");
3905 const auto *RegInfo = Subtarget->getRegisterInfo();
3906 Register BaseReg = RegInfo->getBaseRegister();
3908 MachineBasicBlock &MBB = *MF.begin();
3909 if (!MBB.isLiveIn(BaseReg))
3910 MBB.addLiveIn(BaseReg);
3911 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3912 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, BaseReg, PtrVT);
3913 }
3914 case Intrinsic::thread_pointer: {
3915 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3916 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3917 }
3918 case Intrinsic::arm_cls: {
3919 // Note: arm_cls and arm_cls64 intrinsics are expanded directly here
3920 // in LowerINTRINSIC_WO_CHAIN since there's no native scalar CLS
3921 // instruction.
3922 const SDValue &Operand = Op.getOperand(1);
3923 const EVT VTy = Op.getValueType();
3924 return DAG.getNode(ISD::CTLS, dl, VTy, Operand);
3925 }
3926 case Intrinsic::arm_cls64: {
3927 // arm_cls64 returns i32 but takes i64 input.
3928 // Use ISD::CTLS for i64 and truncate the result.
3929 SDValue CTLS64 = DAG.getNode(ISD::CTLS, dl, MVT::i64, Op.getOperand(1));
3930 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, CTLS64);
3931 }
3932 case Intrinsic::arm_neon_vcls:
3933 case Intrinsic::arm_mve_vcls: {
3934 // Lower vector CLS intrinsics to ISD::CTLS.
3935 // Vector CTLS is Legal when NEON/MVE is available (set elsewhere).
3936 const EVT VTy = Op.getValueType();
3937 return DAG.getNode(ISD::CTLS, dl, VTy, Op.getOperand(1));
3938 }
3939 case Intrinsic::eh_sjlj_lsda: {
3941 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3942 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3943 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3944 SDValue CPAddr;
3945 bool IsPositionIndependent = isPositionIndependent();
3946 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
3947 ARMConstantPoolValue *CPV =
3948 ARMConstantPoolConstant::Create(&MF.getFunction(), ARMPCLabelIndex,
3949 ARMCP::CPLSDA, PCAdj);
3950 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3951 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3952 SDValue Result = DAG.getLoad(
3953 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3955
3956 if (IsPositionIndependent) {
3957 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3958 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
3959 }
3960 return Result;
3961 }
3962 case Intrinsic::arm_neon_vabs:
3963 return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(),
3964 Op.getOperand(1));
3965 case Intrinsic::arm_neon_vabds:
3966 if (Op.getValueType().isInteger())
3967 return DAG.getNode(ISD::ABDS, SDLoc(Op), Op.getValueType(),
3968 Op.getOperand(1), Op.getOperand(2));
3969 return SDValue();
3970 case Intrinsic::arm_neon_vabdu:
3971 return DAG.getNode(ISD::ABDU, SDLoc(Op), Op.getValueType(),
3972 Op.getOperand(1), Op.getOperand(2));
3973 case Intrinsic::arm_neon_vmulls:
3974 case Intrinsic::arm_neon_vmullu: {
3975 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
3976 ? ARMISD::VMULLs : ARMISD::VMULLu;
3977 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3978 Op.getOperand(1), Op.getOperand(2));
3979 }
3980 case Intrinsic::arm_neon_vminnm:
3981 case Intrinsic::arm_neon_vmaxnm: {
3982 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminnm)
3983 ? ISD::FMINNUM : ISD::FMAXNUM;
3984 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3985 Op.getOperand(1), Op.getOperand(2));
3986 }
3987 case Intrinsic::arm_neon_vminu:
3988 case Intrinsic::arm_neon_vmaxu: {
3989 if (Op.getValueType().isFloatingPoint())
3990 return SDValue();
3991 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminu)
3992 ? ISD::UMIN : ISD::UMAX;
3993 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3994 Op.getOperand(1), Op.getOperand(2));
3995 }
3996 case Intrinsic::arm_neon_vmins:
3997 case Intrinsic::arm_neon_vmaxs: {
3998 // v{min,max}s is overloaded between signed integers and floats.
3999 if (!Op.getValueType().isFloatingPoint()) {
4000 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
4001 ? ISD::SMIN : ISD::SMAX;
4002 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
4003 Op.getOperand(1), Op.getOperand(2));
4004 }
4005 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
4006 ? ISD::FMINIMUM : ISD::FMAXIMUM;
4007 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
4008 Op.getOperand(1), Op.getOperand(2));
4009 }
4010 case Intrinsic::arm_neon_vtbl1:
4011 return DAG.getNode(ARMISD::VTBL1, SDLoc(Op), Op.getValueType(),
4012 Op.getOperand(1), Op.getOperand(2));
4013 case Intrinsic::arm_neon_vtbl2:
4014 return DAG.getNode(ARMISD::VTBL2, SDLoc(Op), Op.getValueType(),
4015 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4016 case Intrinsic::arm_mve_pred_i2v:
4017 case Intrinsic::arm_mve_pred_v2i:
4018 return DAG.getNode(ARMISD::PREDICATE_CAST, SDLoc(Op), Op.getValueType(),
4019 Op.getOperand(1));
4020 case Intrinsic::arm_mve_vreinterpretq:
4021 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(Op), Op.getValueType(),
4022 Op.getOperand(1));
4023 case Intrinsic::arm_mve_lsll:
4024 return DAG.getNode(ARMISD::LSLL, SDLoc(Op), Op->getVTList(),
4025 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4026 case Intrinsic::arm_mve_asrl:
4027 return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
4028 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4029 case Intrinsic::arm_mve_vsli:
4030 return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
4031 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4032 case Intrinsic::arm_mve_vsri:
4033 return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
4034 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4035 }
4036}
4037
4039 const ARMSubtarget *Subtarget) {
4040 SDLoc dl(Op);
4041 auto SSID = static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
4042 if (SSID == SyncScope::SingleThread)
4043 return Op;
4044
4045 if (!Subtarget->hasDataBarrier()) {
4046 // Some ARMv6 cpus can support data barriers with an mcr instruction.
4047 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
4048 // here.
4049 assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() &&
4050 "Unexpected ISD::ATOMIC_FENCE encountered. Should be libcall!");
4051 return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0),
4052 DAG.getConstant(0, dl, MVT::i32));
4053 }
4054
4055 AtomicOrdering Ord =
4056 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
4058 if (Subtarget->isMClass()) {
4059 // Only a full system barrier exists in the M-class architectures.
4061 } else if (Subtarget->preferISHSTBarriers() &&
4062 Ord == AtomicOrdering::Release) {
4063 // Swift happens to implement ISHST barriers in a way that's compatible with
4064 // Release semantics but weaker than ISH so we'd be fools not to use
4065 // it. Beware: other processors probably don't!
4067 }
4068
4069 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
4070 DAG.getConstant(Intrinsic::arm_dmb, dl, MVT::i32),
4071 DAG.getConstant(Domain, dl, MVT::i32));
4072}
4073
4075 const ARMSubtarget *Subtarget) {
4076 // ARM pre v5TE and Thumb1 does not have preload instructions.
4077 if (!(Subtarget->isThumb2() ||
4078 (!Subtarget->isThumb1Only() && Subtarget->hasV5TEOps())))
4079 // Just preserve the chain.
4080 return Op.getOperand(0);
4081
4082 SDLoc dl(Op);
4083 unsigned isRead = ~Op.getConstantOperandVal(2) & 1;
4084 if (!isRead &&
4085 (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
4086 // ARMv7 with MP extension has PLDW.
4087 return Op.getOperand(0);
4088
4089 unsigned isData = Op.getConstantOperandVal(4);
4090 if (Subtarget->isThumb()) {
4091 // Invert the bits.
4092 isRead = ~isRead & 1;
4093 isData = ~isData & 1;
4094 }
4095
4096 return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
4097 Op.getOperand(1), DAG.getConstant(isRead, dl, MVT::i32),
4098 DAG.getConstant(isData, dl, MVT::i32));
4099}
4100
4103 ARMFunctionInfo *FuncInfo = MF.getInfo<ARMFunctionInfo>();
4104
4105 // vastart just stores the address of the VarArgsFrameIndex slot into the
4106 // memory location argument.
4107 SDLoc dl(Op);
4109 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4110 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4111 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
4112 MachinePointerInfo(SV));
4113}
4114
4115SDValue ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA,
4116 CCValAssign &NextVA,
4117 SDValue &Root,
4118 SelectionDAG &DAG,
4119 const SDLoc &dl) const {
4121 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4122
4123 const TargetRegisterClass *RC;
4124 if (AFI->isThumb1OnlyFunction())
4125 RC = &ARM::tGPRRegClass;
4126 else
4127 RC = &ARM::GPRRegClass;
4128
4129 // Transform the arguments stored in physical registers into virtual ones.
4130 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4131 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4132
4133 SDValue ArgValue2;
4134 if (NextVA.isMemLoc()) {
4135 MachineFrameInfo &MFI = MF.getFrameInfo();
4136 int FI = MFI.CreateFixedObject(4, NextVA.getLocMemOffset(), true);
4137
4138 // Create load node to retrieve arguments from the stack.
4139 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4140 ArgValue2 = DAG.getLoad(
4141 MVT::i32, dl, Root, FIN,
4143 } else {
4144 Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
4145 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4146 }
4147 if (!Subtarget->isLittle())
4148 std::swap (ArgValue, ArgValue2);
4149 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
4150}
4151
4152// The remaining GPRs hold either the beginning of variable-argument
4153// data, or the beginning of an aggregate passed by value (usually
4154// byval). Either way, we allocate stack slots adjacent to the data
4155// provided by our caller, and store the unallocated registers there.
4156// If this is a variadic function, the va_list pointer will begin with
4157// these values; otherwise, this reassembles a (byval) structure that
4158// was split between registers and memory.
4159// Return: The frame index registers were stored into.
4160int ARMTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG,
4161 const SDLoc &dl, SDValue &Chain,
4162 const Value *OrigArg,
4163 unsigned InRegsParamRecordIdx,
4164 int ArgOffset, unsigned ArgSize) const {
4165 // Currently, two use-cases possible:
4166 // Case #1. Non-var-args function, and we meet first byval parameter.
4167 // Setup first unallocated register as first byval register;
4168 // eat all remained registers
4169 // (these two actions are performed by HandleByVal method).
4170 // Then, here, we initialize stack frame with
4171 // "store-reg" instructions.
4172 // Case #2. Var-args function, that doesn't contain byval parameters.
4173 // The same: eat all remained unallocated registers,
4174 // initialize stack frame.
4175
4177 MachineFrameInfo &MFI = MF.getFrameInfo();
4178 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4179 unsigned RBegin, REnd;
4180 if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) {
4181 CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, RBegin, REnd);
4182 } else {
4183 unsigned RBeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4184 RBegin = RBeginIdx == 4 ? (unsigned)ARM::R4 : GPRArgRegs[RBeginIdx];
4185 REnd = ARM::R4;
4186 }
4187
4188 if (REnd != RBegin)
4189 ArgOffset = -4 * (ARM::R4 - RBegin);
4190
4191 auto PtrVT = getPointerTy(DAG.getDataLayout());
4192 int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, false);
4193 SDValue FIN = DAG.getFrameIndex(FrameIndex, PtrVT);
4194
4196 const TargetRegisterClass *RC =
4197 AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
4198
4199 for (unsigned Reg = RBegin, i = 0; Reg < REnd; ++Reg, ++i) {
4200 Register VReg = MF.addLiveIn(Reg, RC);
4201 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
4202 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
4203 MachinePointerInfo(OrigArg, 4 * i));
4204 MemOps.push_back(Store);
4205 FIN = DAG.getNode(ISD::ADD, dl, PtrVT, FIN, DAG.getConstant(4, dl, PtrVT));
4206 }
4207
4208 if (!MemOps.empty())
4209 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
4210 return FrameIndex;
4211}
4212
4213// Setup stack frame, the va_list pointer will start from.
4214void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
4215 const SDLoc &dl, SDValue &Chain,
4216 unsigned ArgOffset,
4217 unsigned TotalArgRegsSaveSize,
4218 bool ForceMutable) const {
4220 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4221
4222 // Try to store any remaining integer argument regs
4223 // to their spots on the stack so that they may be loaded by dereferencing
4224 // the result of va_next.
4225 // If there is no regs to be stored, just point address after last
4226 // argument passed via stack.
4227 int FrameIndex = StoreByValRegs(
4228 CCInfo, DAG, dl, Chain, nullptr, CCInfo.getInRegsParamsCount(),
4229 CCInfo.getStackSize(), std::max(4U, TotalArgRegsSaveSize));
4230 AFI->setVarArgsFrameIndex(FrameIndex);
4231}
4232
4233bool ARMTargetLowering::splitValueIntoRegisterParts(
4234 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
4235 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
4236 EVT ValueVT = Val.getValueType();
4237 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4238 unsigned ValueBits = ValueVT.getSizeInBits();
4239 unsigned PartBits = PartVT.getSizeInBits();
4240 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(ValueBits), Val);
4241 Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::getIntegerVT(PartBits), Val);
4242 Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
4243 Parts[0] = Val;
4244 return true;
4245 }
4246 return false;
4247}
4248
4249SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
4250 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
4251 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
4252 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4253 unsigned ValueBits = ValueVT.getSizeInBits();
4254 unsigned PartBits = PartVT.getSizeInBits();
4255 SDValue Val = Parts[0];
4256
4257 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(PartBits), Val);
4258 Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::getIntegerVT(ValueBits), Val);
4259 Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
4260 return Val;
4261 }
4262 return SDValue();
4263}
4264
4265SDValue ARMTargetLowering::LowerFormalArguments(
4266 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
4267 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
4268 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
4270 MachineFrameInfo &MFI = MF.getFrameInfo();
4271
4272 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4273
4274 // Assign locations to all of the incoming arguments.
4276 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
4277 *DAG.getContext());
4278 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4279
4281 unsigned CurArgIdx = 0;
4282
4283 // Initially ArgRegsSaveSize is zero.
4284 // Then we increase this value each time we meet byval parameter.
4285 // We also increase this value in case of varargs function.
4286 AFI->setArgRegsSaveSize(0);
4287
4288 // Calculate the amount of stack space that we need to allocate to store
4289 // byval and variadic arguments that are passed in registers.
4290 // We need to know this before we allocate the first byval or variadic
4291 // argument, as they will be allocated a stack slot below the CFA (Canonical
4292 // Frame Address, the stack pointer at entry to the function).
4293 unsigned ArgRegBegin = ARM::R4;
4294 for (const CCValAssign &VA : ArgLocs) {
4295 if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
4296 break;
4297
4298 unsigned Index = VA.getValNo();
4299 ISD::ArgFlagsTy Flags = Ins[Index].Flags;
4300 if (!Flags.isByVal())
4301 continue;
4302
4303 assert(VA.isMemLoc() && "unexpected byval pointer in reg");
4304 unsigned RBegin, REnd;
4305 CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
4306 ArgRegBegin = std::min(ArgRegBegin, RBegin);
4307
4308 CCInfo.nextInRegsParam();
4309 }
4310 CCInfo.rewindByValRegsInfo();
4311
4312 int lastInsIndex = -1;
4313 if (isVarArg && MFI.hasVAStart()) {
4314 unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4315 if (RegIdx != std::size(GPRArgRegs))
4316 ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
4317 }
4318
4319 unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
4320 AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
4321 auto PtrVT = getPointerTy(DAG.getDataLayout());
4322
4323 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4324 CCValAssign &VA = ArgLocs[i];
4325 if (Ins[VA.getValNo()].isOrigArg()) {
4326 std::advance(CurOrigArg,
4327 Ins[VA.getValNo()].getOrigArgIndex() - CurArgIdx);
4328 CurArgIdx = Ins[VA.getValNo()].getOrigArgIndex();
4329 }
4330 // Arguments stored in registers.
4331 if (VA.isRegLoc()) {
4332 EVT RegVT = VA.getLocVT();
4333 SDValue ArgValue;
4334
4335 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4336 // f64 and vector types are split up into multiple registers or
4337 // combinations of registers and stack slots.
4338 SDValue ArgValue1 =
4339 GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4340 VA = ArgLocs[++i]; // skip ahead to next loc
4341 SDValue ArgValue2;
4342 if (VA.isMemLoc()) {
4343 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), true);
4344 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4345 ArgValue2 = DAG.getLoad(
4346 MVT::f64, dl, Chain, FIN,
4348 } else {
4349 ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4350 }
4351 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
4352 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4353 ArgValue1, DAG.getIntPtrConstant(0, dl));
4354 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4355 ArgValue2, DAG.getIntPtrConstant(1, dl));
4356 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
4357 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4358 } else {
4359 const TargetRegisterClass *RC;
4360
4361 if (RegVT == MVT::f16 || RegVT == MVT::bf16)
4362 RC = &ARM::HPRRegClass;
4363 else if (RegVT == MVT::f32)
4364 RC = &ARM::SPRRegClass;
4365 else if (RegVT == MVT::f64 || RegVT == MVT::v4f16 ||
4366 RegVT == MVT::v4bf16)
4367 RC = &ARM::DPRRegClass;
4368 else if (RegVT == MVT::v2f64 || RegVT == MVT::v8f16 ||
4369 RegVT == MVT::v8bf16)
4370 RC = &ARM::QPRRegClass;
4371 else if (RegVT == MVT::i32)
4372 RC = AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass
4373 : &ARM::GPRRegClass;
4374 else
4375 llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
4376
4377 // Transform the arguments in physical registers into virtual ones.
4378 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4379 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
4380
4381 // If this value is passed in r0 and has the returned attribute (e.g.
4382 // C++ 'structors), record this fact for later use.
4383 if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
4384 AFI->setPreservesR0();
4385 }
4386 }
4387
4388 // If this is an 8 or 16-bit value, it is really passed promoted
4389 // to 32 bits. Insert an assert[sz]ext to capture this, then
4390 // truncate to the right size.
4391 switch (VA.getLocInfo()) {
4392 default: llvm_unreachable("Unknown loc info!");
4393 case CCValAssign::Full: break;
4394 case CCValAssign::BCvt:
4395 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4396 break;
4397 }
4398
4399 // f16 arguments have their size extended to 4 bytes and passed as if they
4400 // had been copied to the LSBs of a 32-bit register.
4401 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
4402 if (VA.needsCustom() &&
4403 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4404 ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4405
4406 // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4407 // less than 32 bits must be sign- or zero-extended in the callee for
4408 // security reasons. Although the ABI mandates an extension done by the
4409 // caller, the latter cannot be trusted to follow the rules of the ABI.
4410 const ISD::InputArg &Arg = Ins[VA.getValNo()];
4411 if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4412 RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4413 ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4414
4415 InVals.push_back(ArgValue);
4416 } else { // VA.isRegLoc()
4417 // Only arguments passed on the stack should make it here.
4418 assert(VA.isMemLoc());
4419 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
4420
4421 int index = VA.getValNo();
4422
4423 // Some Ins[] entries become multiple ArgLoc[] entries.
4424 // Process them only once.
4425 if (index != lastInsIndex)
4426 {
4427 ISD::ArgFlagsTy Flags = Ins[index].Flags;
4428 // FIXME: For now, all byval parameter objects are marked mutable.
4429 // This can be changed with more analysis.
4430 // In case of tail call optimization mark all arguments mutable.
4431 // Since they could be overwritten by lowering of arguments in case of
4432 // a tail call.
4433 if (Flags.isByVal()) {
4434 assert(Ins[index].isOrigArg() &&
4435 "Byval arguments cannot be implicit");
4436 unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed();
4437
4438 int FrameIndex = StoreByValRegs(
4439 CCInfo, DAG, dl, Chain, &*CurOrigArg, CurByValIndex,
4440 VA.getLocMemOffset(), Flags.getByValSize());
4441 InVals.push_back(DAG.getFrameIndex(FrameIndex, PtrVT));
4442 CCInfo.nextInRegsParam();
4443 } else if (VA.needsCustom() && (VA.getValVT() == MVT::f16 ||
4444 VA.getValVT() == MVT::bf16)) {
4445 // f16 and bf16 values are passed in the least-significant half of
4446 // a 4 byte stack slot. This is done as-if the extension was done
4447 // in a 32-bit register, so the actual bytes used for the value
4448 // differ between little and big endian.
4449 assert(VA.getLocVT().getSizeInBits() == 32);
4450 unsigned FIOffset = VA.getLocMemOffset();
4451 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits() / 8,
4452 FIOffset, true);
4453
4454 SDValue Addr = DAG.getFrameIndex(FI, PtrVT);
4455 if (DAG.getDataLayout().isBigEndian())
4456 Addr = DAG.getObjectPtrOffset(dl, Addr, TypeSize::getFixed(2));
4457
4458 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, Addr,
4460 DAG.getMachineFunction(), FI)));
4461
4462 } else {
4463 unsigned FIOffset = VA.getLocMemOffset();
4464 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
4465 FIOffset, true);
4466
4467 // Create load nodes to retrieve arguments from the stack.
4468 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4469 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
4471 DAG.getMachineFunction(), FI)));
4472 }
4473 lastInsIndex = index;
4474 }
4475 }
4476 }
4477
4478 // varargs
4479 if (isVarArg && MFI.hasVAStart()) {
4480 VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getStackSize(),
4481 TotalArgRegsSaveSize);
4482 if (AFI->isCmseNSEntryFunction()) {
4483 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4485 "secure entry function must not be variadic", dl.getDebugLoc()));
4486 }
4487 }
4488
4489 // A variadic function that forwards through a musttail call needs its unnamed
4490 // register arguments modelled as live, so the allocator does not use one as
4491 // scratch. This must run after the va_list save area above, which consumes
4492 // the same registers, and is deliberately *not* predicated on hasVAStart():
4493 // a forwarding thunk never calls va_start.
4494 if (isVarArg && MFI.hasMustTailInVarArgFunc()) {
4495 // getRemainingRegParmsForType() walks the assign function until an argument
4496 // lands in memory, so the convention must have a stack fallback. GHC and
4497 // the Windows CFGuard check stub assign to registers only and would run off
4498 // the end of their tables; neither supports variadic arguments anyway.
4499 CallingConv::ID EffCC = getEffectiveCallingConv(CallConv, isVarArg);
4500 if (EffCC != CallingConv::GHC && EffCC != CallingConv::CFGuard_Check) {
4501 // Only the core registers can hold an unnamed argument:
4502 // getEffectiveCallingConv() degrades every VFP convention to ARM_AAPCS
4503 // when isVarArg is set.
4504 SmallVector<MVT, 1> RegParmTypes;
4505 RegParmTypes.push_back(MVT::i32);
4506 SmallVectorImpl<ForwardedRegister> &Forwards =
4509 Forwards, RegParmTypes, CCAssignFnForCall(CallConv, isVarArg));
4510 }
4511 }
4512
4513 unsigned StackArgSize = CCInfo.getStackSize();
4514 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4515 if (canGuaranteeTCO(CallConv, TailCallOpt)) {
4516 // The only way to guarantee a tail call is if the callee restores its
4517 // argument area, but it must also keep the stack aligned when doing so.
4518 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
4519 assert(StackAlign && "data layout string is missing stack alignment");
4520 StackArgSize = alignTo(StackArgSize, *StackAlign);
4521
4522 AFI->setArgumentStackToRestore(StackArgSize);
4523 }
4524 AFI->setArgumentStackSize(StackArgSize);
4525
4526 if (CCInfo.getStackSize() > 0 && AFI->isCmseNSEntryFunction()) {
4527 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4529 "secure entry function requires arguments on stack", dl.getDebugLoc()));
4530 }
4531
4532 return Chain;
4533}
4534
4535/// isFloatingPointZero - Return true if this is +0.0.
4538 return CFP->getValueAPF().isPosZero();
4539 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
4540 // Maybe this has already been legalized into the constant pool?
4541 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
4542 SDValue WrapperOp = Op.getOperand(1).getOperand(0);
4544 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
4545 return CFP->getValueAPF().isPosZero();
4546 }
4547 } else if (Op->getOpcode() == ISD::BITCAST &&
4548 Op->getValueType(0) == MVT::f64) {
4549 // Handle (ISD::BITCAST (ARMISD::VMOVIMM (ISD::TargetConstant 0)) MVT::f64)
4550 // created by LowerConstantFP().
4551 SDValue BitcastOp = Op->getOperand(0);
4552 if (BitcastOp->getOpcode() == ARMISD::VMOVIMM &&
4553 isNullConstant(BitcastOp->getOperand(0)))
4554 return true;
4555 }
4556 return false;
4557}
4558
4560 // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
4561 if (Op->getFlags().hasNoSignedWrap())
4562 return true;
4563
4564 // We can still figure out if the second operand is safe to use
4565 // in a CMN instruction by checking if it is known to be not the minimum
4566 // signed value. If it is not, then we can safely use CMN.
4567 // Note: We can eventually remove this check and simply rely on
4568 // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
4569 // consistently sets them appropriately when making said nodes.
4570
4571 KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
4572 return !KnownSrc.getSignedMinValue().isMinSignedValue();
4573}
4574
4576 return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
4577 (isIntEqualitySetCC(CC) ||
4578 (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
4579 (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
4580}
4581
4582/// Returns how profitable it is to fold a comparison's operand's shift and/or
4583/// extension operations into the comparison instruction's second operand
4584/// (so_reg_imm / so_reg_reg for ARM, t2_so_reg for Thumb-2).
4586 // Thumb-1 CMP does not support shifted second operands.
4587 if (ST.isThumb1Only() || !Op.hasOneUse())
4588 return 0;
4589
4590 unsigned Opc = Op.getOpcode();
4591 if (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) {
4592 if (auto *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
4593 return ShiftAmt->getZExtValue() <= 31 ? 1 : 0;
4594 // Register-controlled shift: only ARM-mode CMP/CMN (so_reg_reg) supports
4595 // this; Thumb-2 t2_so_reg requires an immediate shift amount.
4596 return ST.isThumb() ? 0 : 1;
4597 }
4598
4599 if (Opc == ISD::ROTR) {
4600 // Rotr constants will be normalized via mod 32, or & 31,
4601 // so we do not have to bounds check.
4602 if (isa<ConstantSDNode>(Op.getOperand(1)))
4603 return 1;
4604 return ST.isThumb() ? 0 : 1;
4605 }
4606
4607 return 0;
4608}
4609
4610// Return a cheaper value with the same zero/nonzero result as a low-mask AND.
4612 const SDLoc &DL) {
4613 if (Value.getValueType() != MVT::i32 || Value.getOpcode() != ISD::AND ||
4614 !Value.hasOneUse())
4615 return SDValue();
4616
4617 auto *Mask = dyn_cast<ConstantSDNode>(Value.getOperand(1));
4618 if (!Mask)
4619 return SDValue();
4620 uint32_t MaskValue = Mask->getZExtValue();
4621 // Keep the existing single-bit lowering and UXTB/UXTH for byte/halfword
4622 // masks, and avoid a zero or no-op shift.
4623 if (!isMask_32(MaskValue) || MaskValue == 1 || MaskValue == 0xff ||
4624 MaskValue == 0xffff || MaskValue == ~0U)
4625 return SDValue();
4626
4627 return DAG.getNode(
4628 ISD::SHL, DL, MVT::i32, Value.getOperand(0),
4629 DAG.getConstant(llvm::countl_zero(MaskValue), DL, MVT::i32));
4630}
4631
4632/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4633/// the given operands.
4634SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4635 SDValue &ARMcc, SelectionDAG &DAG,
4636 const SDLoc &dl) const {
4637 // For a zero test, replace a low-mask AND feeding an OR with a shift. ARM
4638 // and Thumb-2 can fold the shift into the OR. Require single uses to avoid
4639 // duplicating live work.
4640 if (!Subtarget->isThumb1Only() && isIntEqualitySetCC(CC) &&
4641 isNullConstant(RHS) && LHS.getValueType() == MVT::i32 &&
4642 LHS.getOpcode() == ISD::OR && LHS.hasOneUse()) {
4643 for (unsigned I = 0; I != 2; ++I) {
4644 if (SDValue Shift =
4645 getShiftedLowMaskZeroTest(LHS.getOperand(I), DAG, dl)) {
4646 LHS = DAG.getNode(ISD::OR, dl, MVT::i32, LHS.getOperand(I ^ 1), Shift);
4647 break;
4648 }
4649 }
4650 }
4651
4652 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4653 unsigned C = RHSC->getZExtValue();
4654 if (!isLegalICmpImmediate((int32_t)C)) {
4655 // Constant does not fit, try adjusting it by one.
4656 switch (CC) {
4657 default: break;
4658 case ISD::SETLT:
4659 case ISD::SETGE:
4660 if (C != 0x80000000 && isLegalICmpImmediate(C-1)) {
4661 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4662 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4663 }
4664 break;
4665 case ISD::SETULT:
4666 case ISD::SETUGE:
4667 if (C != 0 && isLegalICmpImmediate(C-1)) {
4668 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4669 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4670 }
4671 break;
4672 case ISD::SETLE:
4673 case ISD::SETGT:
4674 if (C != 0x7fffffff && isLegalICmpImmediate(C+1)) {
4675 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4676 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4677 }
4678 break;
4679 case ISD::SETULE:
4680 case ISD::SETUGT:
4681 if (C != 0xffffffff && isLegalICmpImmediate(C+1)) {
4682 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4683 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4684 }
4685 break;
4686 }
4687 }
4688 }
4689
4690 // Thumb1 has very limited immediate modes, so turning an "and" into a
4691 // shift can save multiple instructions.
4692 //
4693 // If we have (x & C1), and C1 is an appropriate mask, we can transform it
4694 // into "((x << n) >> n)". But that isn't necessarily profitable on its
4695 // own. If it's the operand to an unsigned comparison with an immediate,
4696 // we can eliminate one of the shifts: we transform
4697 // "((x << n) >> n) == C2" to "(x << n) == (C2 << n)".
4698 //
4699 // We avoid transforming cases which aren't profitable due to encoding
4700 // details:
4701 //
4702 // 1. C2 fits into the immediate field of a cmp, and the transformed version
4703 // would not; in that case, we're essentially trading one immediate load for
4704 // another.
4705 // 2. C1 is 255 or 65535, so we can use uxtb or uxth.
4706 // 3. C2 is zero; we have other code for this special case.
4707 //
4708 // FIXME: Figure out profitability for Thumb2; we usually can't save an
4709 // instruction, since the AND is always one instruction anyway, but we could
4710 // use narrow instructions in some cases.
4711 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::AND &&
4712 LHS->hasOneUse() && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4713 LHS.getValueType() == MVT::i32 && isa<ConstantSDNode>(RHS) &&
4714 !isSignedIntSetCC(CC)) {
4715 unsigned Mask = LHS.getConstantOperandVal(1);
4716 auto *RHSC = cast<ConstantSDNode>(RHS.getNode());
4717 uint64_t RHSV = RHSC->getZExtValue();
4718 if (isMask_32(Mask) && (RHSV & ~Mask) == 0 && Mask != 255 && Mask != 65535) {
4719 unsigned ShiftBits = llvm::countl_zero(Mask);
4720 if (RHSV && (RHSV > 255 || (RHSV << ShiftBits) <= 255)) {
4721 SDValue ShiftAmt = DAG.getConstant(ShiftBits, dl, MVT::i32);
4722 LHS = DAG.getNode(ISD::SHL, dl, MVT::i32, LHS.getOperand(0), ShiftAmt);
4723 RHS = DAG.getConstant(RHSV << ShiftBits, dl, MVT::i32);
4724 }
4725 }
4726 }
4727
4728 // The specific comparison "(x<<c) > 0x80000000U" can be optimized to a
4729 // single "lsls x, c+1". The shift sets the "C" and "Z" flags the same
4730 // way a cmp would.
4731 // FIXME: Add support for ARM/Thumb2; this would need isel patterns, and
4732 // some tweaks to the heuristics for the previous and->shift transform.
4733 // FIXME: Optimize cases where the LHS isn't a shift.
4734 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::SHL &&
4735 isa<ConstantSDNode>(RHS) && RHS->getAsZExtVal() == 0x80000000U &&
4736 CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4737 LHS.getConstantOperandVal(1) < 31) {
4738 unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
4739 SDValue Shift =
4740 DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
4741 LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
4742 ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
4743 return Shift.getValue(1);
4744 }
4745
4747
4748 unsigned CompareType;
4749 switch (CondCode) {
4750 default:
4751 CompareType = ARMISD::CMP;
4752 break;
4753 case ARMCC::EQ:
4754 case ARMCC::NE:
4755 // Uses only Z Flag
4756 CompareType = ARMISD::CMPZ;
4757 break;
4758 }
4759
4760 // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
4761 // the codebase.
4762
4763 // TODO: When we have a solution to the vselect predicate not allowing pl/mi
4764 // all the time, allow those cases to be cmn too no matter what.
4765 if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
4766 CompareType = ARMISD::CMN;
4767 RHS = RHS.getOperand(1);
4768 } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
4769 CompareType = ARMISD::CMN;
4770 LHS = LHS.getOperand(1);
4772 }
4773
4774 // Prefer folding shifts / CMN into the cmp/cmn second operand (so_reg /
4775 // t2_so_reg). When both sides compete, pick the higher
4776 // getCmpOperandFoldingProfit. Only when RHS is not a legal icmp
4777 // immediate: otherwise keep the canonical (reg, imm) form.
4778 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getNode());
4779 if (!C || !isLegalICmpImmediate(C->getSExtValue())) {
4780 if (getCmpOperandFoldingProfit(LHS, *Subtarget) >
4781 getCmpOperandFoldingProfit(RHS, *Subtarget)) {
4782 std::swap(LHS, RHS);
4783 if (CompareType == ARMISD::CMP)
4785 }
4786 }
4787
4788 // If the RHS is a constant zero then the V (overflow) flag will never be
4789 // set. This can allow us to simplify GE to PL or LT to MI, which can be
4790 // simpler for other passes (like the peephole optimiser) to deal with.
4791 if (isNullConstant(RHS)) {
4792 switch (CondCode) {
4793 default:
4794 break;
4795 case ARMCC::GE:
4797 break;
4798 case ARMCC::LT:
4800 break;
4801 }
4802 }
4803
4804 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
4805 return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
4806}
4807
4808/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
4809SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4810 SelectionDAG &DAG, const SDLoc &dl,
4811 bool Signaling) const {
4812 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
4813 SDValue Flags;
4815 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP, dl, FlagsVT,
4816 LHS, RHS);
4817 else
4818 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
4819 FlagsVT, LHS);
4820 return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
4821}
4822
4823// This function returns three things: the arithmetic computation itself
4824// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4825// comparison and the condition code define the case in which the arithmetic
4826// computation *does not* overflow.
4827std::pair<SDValue, SDValue>
4828ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4829 SDValue &ARMcc) const {
4830 assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4831
4832 SDValue Value, OverflowCmp;
4833 SDValue LHS = Op.getOperand(0);
4834 SDValue RHS = Op.getOperand(1);
4835 SDLoc dl(Op);
4836
4837 // FIXME: We are currently always generating CMPs because we don't support
4838 // generating CMN through the backend. This is not as good as the natural
4839 // CMP case because it causes a register dependency and cannot be folded
4840 // later.
4841
4842 switch (Op.getOpcode()) {
4843 default:
4844 llvm_unreachable("Unknown overflow instruction!");
4845 case ISD::SADDO:
4846 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4847 Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4848 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4849 break;
4850 case ISD::UADDO:
4851 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4852 // We use ADDC here to correspond to its use in LowerALUO.
4853 // We do not use it in the USUBO case as Value may not be used.
4854 Value = DAG.getNode(ARMISD::ADDC, dl,
4855 DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4856 .getValue(0);
4857 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4858 break;
4859 case ISD::SSUBO:
4860 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4861 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4862 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4863 break;
4864 case ISD::USUBO:
4865 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4866 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4867 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4868 break;
4869 case ISD::UMULO:
4870 // We generate a UMUL_LOHI and then check if the high word is 0.
4871 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4872 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4873 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4874 LHS, RHS);
4875 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4876 DAG.getConstant(0, dl, MVT::i32));
4877 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4878 break;
4879 case ISD::SMULO:
4880 // We generate a SMUL_LOHI and then check if all the bits of the high word
4881 // are the same as the sign bit of the low word.
4882 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4883 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4884 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4885 LHS, RHS);
4886 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4887 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4888 Value.getValue(0),
4889 DAG.getConstant(31, dl, MVT::i32)));
4890 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4891 break;
4892 } // switch (...)
4893
4894 return std::make_pair(Value, OverflowCmp);
4895}
4896
4898 SDLoc DL(Value);
4899 EVT VT = Value.getValueType();
4900
4901 if (Invert)
4902 Value = DAG.getNode(ISD::SUB, DL, MVT::i32,
4903 DAG.getConstant(1, DL, MVT::i32), Value);
4904
4905 SDValue Cmp = DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(VT, MVT::i32),
4906 Value, DAG.getConstant(1, DL, VT));
4907 return Cmp.getValue(1);
4908}
4909
4911 bool Invert) {
4912 SDLoc DL(Flags);
4913
4914 if (Invert) {
4915 // Convert flags to boolean with ADDE 0,0,Carry then compute 1 - bool.
4916 SDValue BoolCarry = DAG.getNode(
4917 ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4918 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT), Flags);
4919 return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, VT), BoolCarry);
4920 }
4921
4922 // Now convert the carry flag into a boolean carry. We do this
4923 // using ARMISD::ADDE 0, 0, Carry
4924 return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4925 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT),
4926 Flags);
4927}
4928
4929// Value is 1 if 'V' bit is 1, else 0
4931 SDLoc DL(Flags);
4932 SDValue Zero = DAG.getConstant(0, DL, VT);
4933 SDValue One = DAG.getConstant(1, DL, VT);
4934 SDValue ARMcc = DAG.getConstant(ARMCC::VS, DL, MVT::i32);
4935 return DAG.getNode(ARMISD::CMOV, DL, VT, Zero, One, ARMcc, Flags);
4936}
4937
4938SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
4939 // Let legalize expand this if it isn't a legal type yet.
4940 if (!isTypeLegal(Op.getValueType()))
4941 return SDValue();
4942
4943 SDValue LHS = Op.getOperand(0);
4944 SDValue RHS = Op.getOperand(1);
4945 SDLoc dl(Op);
4946
4947 EVT VT = Op.getValueType();
4948 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4949 SDValue Value;
4950 SDValue Overflow;
4951 switch (Op.getOpcode()) {
4952 case ISD::UADDO:
4953 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4954 // Convert the carry flag into a boolean value.
4955 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, false);
4956 break;
4957 case ISD::USUBO:
4958 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4959 // Convert the carry flag into a boolean value.
4960 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, true);
4961 break;
4962 default: {
4963 // Handle other operations with getARMXALUOOp
4964 SDValue OverflowCmp, ARMcc;
4965 std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4966 // We use 0 and 1 as false and true values.
4967 // ARMcc represents the "no overflow" condition (e.g., VC for signed ops).
4968 // CMOV operand order is (FalseVal, TrueVal), so we put 1 in FalseVal
4969 // position to get Overflow=1 when the "no overflow" condition is false.
4970 Overflow =
4971 DAG.getNode(ARMISD::CMOV, dl, MVT::i32,
4972 DAG.getConstant(1, dl, MVT::i32), // FalseVal: overflow
4973 DAG.getConstant(0, dl, MVT::i32), // TrueVal: no overflow
4974 ARMcc, OverflowCmp);
4975 break;
4976 }
4977 }
4978
4979 return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4980}
4981
4983 const ARMSubtarget *Subtarget) {
4984 EVT VT = Op.getValueType();
4985 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || Subtarget->isThumb1Only())
4986 return SDValue();
4987 if (!VT.isSimple())
4988 return SDValue();
4989
4990 unsigned NewOpcode;
4991 switch (VT.getSimpleVT().SimpleTy) {
4992 default:
4993 return SDValue();
4994 case MVT::i8:
4995 switch (Op->getOpcode()) {
4996 case ISD::UADDSAT:
4997 NewOpcode = ARMISD::UQADD8b;
4998 break;
4999 case ISD::SADDSAT:
5000 NewOpcode = ARMISD::QADD8b;
5001 break;
5002 case ISD::USUBSAT:
5003 NewOpcode = ARMISD::UQSUB8b;
5004 break;
5005 case ISD::SSUBSAT:
5006 NewOpcode = ARMISD::QSUB8b;
5007 break;
5008 }
5009 break;
5010 case MVT::i16:
5011 switch (Op->getOpcode()) {
5012 case ISD::UADDSAT:
5013 NewOpcode = ARMISD::UQADD16b;
5014 break;
5015 case ISD::SADDSAT:
5016 NewOpcode = ARMISD::QADD16b;
5017 break;
5018 case ISD::USUBSAT:
5019 NewOpcode = ARMISD::UQSUB16b;
5020 break;
5021 case ISD::SSUBSAT:
5022 NewOpcode = ARMISD::QSUB16b;
5023 break;
5024 }
5025 break;
5026 }
5027
5028 SDLoc dl(Op);
5029 SDValue Add =
5030 DAG.getNode(NewOpcode, dl, MVT::i32,
5031 DAG.getSExtOrTrunc(Op->getOperand(0), dl, MVT::i32),
5032 DAG.getSExtOrTrunc(Op->getOperand(1), dl, MVT::i32));
5033 return DAG.getNode(ISD::TRUNCATE, dl, VT, Add);
5034}
5035
5036SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
5037 SDValue Cond = Op.getOperand(0);
5038 SDValue SelectTrue = Op.getOperand(1);
5039 SDValue SelectFalse = Op.getOperand(2);
5040 SDLoc dl(Op);
5041 unsigned Opc = Cond.getOpcode();
5042
5043 if (Cond.getResNo() == 1 &&
5044 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5045 Opc == ISD::USUBO)) {
5046 if (!isTypeLegal(Cond->getValueType(0)))
5047 return SDValue();
5048
5049 SDValue Value, OverflowCmp;
5050 SDValue ARMcc;
5051 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5052 EVT VT = Op.getValueType();
5053
5054 return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
5055 }
5056
5057 // Convert:
5058 //
5059 // (select (cmov 1, 0, cond), t, f) -> (cmov t, f, cond)
5060 // (select (cmov 0, 1, cond), t, f) -> (cmov f, t, cond)
5061 //
5062 if (Cond.getOpcode() == ARMISD::CMOV && Cond.hasOneUse()) {
5063 const ConstantSDNode *CMOVTrue =
5064 dyn_cast<ConstantSDNode>(Cond.getOperand(0));
5065 const ConstantSDNode *CMOVFalse =
5066 dyn_cast<ConstantSDNode>(Cond.getOperand(1));
5067
5068 if (CMOVTrue && CMOVFalse) {
5069 unsigned CMOVTrueVal = CMOVTrue->getZExtValue();
5070 unsigned CMOVFalseVal = CMOVFalse->getZExtValue();
5071
5072 SDValue True;
5073 SDValue False;
5074 if (CMOVTrueVal == 1 && CMOVFalseVal == 0) {
5075 True = SelectTrue;
5076 False = SelectFalse;
5077 } else if (CMOVTrueVal == 0 && CMOVFalseVal == 1) {
5078 True = SelectFalse;
5079 False = SelectTrue;
5080 }
5081
5082 if (True.getNode() && False.getNode())
5083 return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
5084 Cond.getOperand(3), DAG);
5085 }
5086 }
5087
5088 return DAG.getSelectCC(dl, Cond,
5089 DAG.getConstant(0, dl, Cond.getValueType()),
5090 SelectTrue, SelectFalse, ISD::SETNE);
5091}
5092
5094 bool &swpCmpOps, bool &swpVselOps) {
5095 // Start by selecting the GE condition code for opcodes that return true for
5096 // 'equality'
5097 if (CC == ISD::SETUGE || CC == ISD::SETOGE || CC == ISD::SETOLE ||
5098 CC == ISD::SETULE || CC == ISD::SETGE || CC == ISD::SETLE)
5099 CondCode = ARMCC::GE;
5100
5101 // and GT for opcodes that return false for 'equality'.
5102 else if (CC == ISD::SETUGT || CC == ISD::SETOGT || CC == ISD::SETOLT ||
5103 CC == ISD::SETULT || CC == ISD::SETGT || CC == ISD::SETLT)
5104 CondCode = ARMCC::GT;
5105
5106 // Since we are constrained to GE/GT, if the opcode contains 'less', we need
5107 // to swap the compare operands.
5108 if (CC == ISD::SETOLE || CC == ISD::SETULE || CC == ISD::SETOLT ||
5109 CC == ISD::SETULT || CC == ISD::SETLE || CC == ISD::SETLT)
5110 swpCmpOps = true;
5111
5112 // Both GT and GE are ordered comparisons, and return false for 'unordered'.
5113 // If we have an unordered opcode, we need to swap the operands to the VSEL
5114 // instruction (effectively negating the condition).
5115 //
5116 // This also has the effect of swapping which one of 'less' or 'greater'
5117 // returns true, so we also swap the compare operands. It also switches
5118 // whether we return true for 'equality', so we compensate by picking the
5119 // opposite condition code to our original choice.
5120 if (CC == ISD::SETULE || CC == ISD::SETULT || CC == ISD::SETUGE ||
5121 CC == ISD::SETUGT) {
5122 swpCmpOps = !swpCmpOps;
5123 swpVselOps = !swpVselOps;
5124 CondCode = CondCode == ARMCC::GT ? ARMCC::GE : ARMCC::GT;
5125 }
5126
5127 // 'ordered' is 'anything but unordered', so use the VS condition code and
5128 // swap the VSEL operands.
5129 if (CC == ISD::SETO) {
5130 CondCode = ARMCC::VS;
5131 swpVselOps = true;
5132 }
5133
5134 // 'unordered or not equal' is 'anything but equal', so use the EQ condition
5135 // code and swap the VSEL operands. Also do this if we don't care about the
5136 // unordered case.
5137 if (CC == ISD::SETUNE || CC == ISD::SETNE) {
5138 CondCode = ARMCC::EQ;
5139 swpVselOps = true;
5140 }
5141}
5142
5143SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
5144 SDValue TrueVal, SDValue ARMcc,
5145 SDValue Flags, SelectionDAG &DAG) const {
5146 if (!Subtarget->hasFP64() && VT == MVT::f64) {
5147 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5148 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
5149 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5150 DAG.getVTList(MVT::i32, MVT::i32), TrueVal);
5151
5152 SDValue TrueLow = TrueVal.getValue(0);
5153 SDValue TrueHigh = TrueVal.getValue(1);
5154 SDValue FalseLow = FalseVal.getValue(0);
5155 SDValue FalseHigh = FalseVal.getValue(1);
5156
5157 SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
5158 ARMcc, Flags);
5159 SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
5160 ARMcc, Flags);
5161
5162 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
5163 }
5164 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
5165}
5166
5168 return CC == ISD::SETGT || CC == ISD::SETGE;
5169}
5170
5172 return CC == ISD::SETLT || CC == ISD::SETLE;
5173}
5174
5175// See if a conditional (LHS CC RHS ? TrueVal : FalseVal) is lower-saturating.
5176// All of these conditions (and their <= and >= counterparts) will do:
5177// x < k ? k : x
5178// x > k ? x : k
5179// k < x ? x : k
5180// k > x ? k : x
5181static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
5182 const SDValue TrueVal, const SDValue FalseVal,
5183 const ISD::CondCode CC, const SDValue K) {
5184 return (isGTorGE(CC) &&
5185 ((K == LHS && K == TrueVal) || (K == RHS && K == FalseVal))) ||
5186 (isLTorLE(CC) &&
5187 ((K == RHS && K == TrueVal) || (K == LHS && K == FalseVal)));
5188}
5189
5190// Check if two chained conditionals could be converted into SSAT or USAT.
5191//
5192// SSAT can replace a set of two conditional selectors that bound a number to an
5193// interval of type [k, ~k] when k + 1 is a power of 2. Here are some examples:
5194//
5195// x < -k ? -k : (x > k ? k : x)
5196// x < -k ? -k : (x < k ? x : k)
5197// x > -k ? (x > k ? k : x) : -k
5198// x < k ? (x < -k ? -k : x) : k
5199// etc.
5200//
5201// LLVM canonicalizes these to either a min(max()) or a max(min())
5202// pattern. This function tries to match one of these and will return a SSAT
5203// node if successful.
5204//
5205// USAT works similarly to SSAT but bounds on the interval [0, k] where k + 1
5206// is a power of 2.
5208 EVT VT = Op.getValueType();
5209 SDValue V1 = Op.getOperand(0);
5210 SDValue K1 = Op.getOperand(1);
5211 SDValue TrueVal1 = Op.getOperand(2);
5212 SDValue FalseVal1 = Op.getOperand(3);
5213 ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5214
5215 const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
5216 if (Op2.getOpcode() != ISD::SELECT_CC)
5217 return SDValue();
5218
5219 SDValue V2 = Op2.getOperand(0);
5220 SDValue K2 = Op2.getOperand(1);
5221 SDValue TrueVal2 = Op2.getOperand(2);
5222 SDValue FalseVal2 = Op2.getOperand(3);
5223 ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
5224
5225 SDValue V1Tmp = V1;
5226 SDValue V2Tmp = V2;
5227
5228 // Check that the registers and the constants match a max(min()) or min(max())
5229 // pattern
5230 if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
5231 K2 != FalseVal2 ||
5232 !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
5233 return SDValue();
5234
5235 // Check that the constant in the lower-bound check is
5236 // the opposite of the constant in the upper-bound check
5237 // in 1's complement.
5239 return SDValue();
5240
5241 int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
5242 int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
5243 int64_t PosVal = std::max(Val1, Val2);
5244 int64_t NegVal = std::min(Val1, Val2);
5245
5246 if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
5247 !isPowerOf2_64(PosVal + 1))
5248 return SDValue();
5249
5250 // Handle the difference between USAT (unsigned) and SSAT (signed)
5251 // saturation
5252 // At this point, PosVal is guaranteed to be positive
5253 uint64_t K = PosVal;
5254 SDLoc dl(Op);
5255 if (Val1 == ~Val2)
5256 return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
5257 DAG.getConstant(llvm::countr_one(K), dl, VT));
5258 if (NegVal == 0)
5259 return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
5260 DAG.getConstant(llvm::countr_one(K), dl, VT));
5261
5262 return SDValue();
5263}
5264
5265// Check if a condition of the type x < k ? k : x can be converted into a
5266// bit operation instead of conditional moves.
5267// Currently this is allowed given:
5268// - The conditions and values match up
5269// - k is 0 or -1 (all ones)
5270// This function will not check the last condition, thats up to the caller
5271// It returns true if the transformation can be made, and in such case
5272// returns x in V, and k in SatK.
5274 SDValue &SatK)
5275{
5276 SDValue LHS = Op.getOperand(0);
5277 SDValue RHS = Op.getOperand(1);
5278 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5279 SDValue TrueVal = Op.getOperand(2);
5280 SDValue FalseVal = Op.getOperand(3);
5281
5283 ? &RHS
5284 : nullptr;
5285
5286 // No constant operation in comparison, early out
5287 if (!K)
5288 return false;
5289
5290 SDValue KTmp = isa<ConstantSDNode>(TrueVal) ? TrueVal : FalseVal;
5291 V = (KTmp == TrueVal) ? FalseVal : TrueVal;
5292 SDValue VTmp = (K && *K == LHS) ? RHS : LHS;
5293
5294 // If the constant on left and right side, or variable on left and right,
5295 // does not match, early out
5296 if (*K != KTmp || V != VTmp)
5297 return false;
5298
5299 if (isLowerSaturate(LHS, RHS, TrueVal, FalseVal, CC, *K)) {
5300 SatK = *K;
5301 return true;
5302 }
5303
5304 return false;
5305}
5306
5307bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
5308 if (VT == MVT::f32)
5309 return !Subtarget->hasVFP2Base();
5310 if (VT == MVT::f64)
5311 return !Subtarget->hasFP64();
5312 if (VT == MVT::f16)
5313 return !Subtarget->hasFullFP16();
5314 return false;
5315}
5316
5317static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
5318 SDValue FalseVal, const ARMSubtarget *Subtarget) {
5319 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5320 ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
5321 if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
5322 return SDValue();
5323
5324 unsigned TVal = CTVal->getZExtValue();
5325 unsigned FVal = CFVal->getZExtValue();
5326
5327 Opcode = 0;
5328 InvertCond = false;
5329 if (TVal == ~FVal) {
5330 Opcode = ARMISD::CSINV;
5331 } else if (TVal == ~FVal + 1) {
5332 Opcode = ARMISD::CSNEG;
5333 } else if (TVal + 1 == FVal) {
5334 Opcode = ARMISD::CSINC;
5335 } else if (TVal == FVal + 1) {
5336 Opcode = ARMISD::CSINC;
5337 std::swap(TrueVal, FalseVal);
5338 std::swap(TVal, FVal);
5339 InvertCond = !InvertCond;
5340 } else {
5341 return SDValue();
5342 }
5343
5344 // If one of the constants is cheaper than another, materialise the
5345 // cheaper one and let the csel generate the other.
5346 if (Opcode != ARMISD::CSINC &&
5347 HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
5348 std::swap(TrueVal, FalseVal);
5349 std::swap(TVal, FVal);
5350 InvertCond = !InvertCond;
5351 }
5352
5353 // Attempt to use ZR checking TVal is 0, possibly inverting the condition
5354 // to get there. CSINC not is invertable like the other two (~(~a) == a,
5355 // -(-a) == a, but (a+1)+1 != a).
5356 if (FVal == 0 && Opcode != ARMISD::CSINC) {
5357 std::swap(TrueVal, FalseVal);
5358 std::swap(TVal, FVal);
5359 InvertCond = !InvertCond;
5360 }
5361
5362 return TrueVal;
5363}
5364
5365SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
5366 EVT VT = Op.getValueType();
5367 SDLoc dl(Op);
5368
5369 // Try to convert two saturating conditional selects into a single SSAT
5370 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
5371 if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
5372 return SatValue;
5373
5374 // Try to convert expressions of the form x < k ? k : x (and similar forms)
5375 // into more efficient bit operations, which is possible when k is 0 or -1
5376 // On ARM and Thumb-2 which have flexible operand 2 this will result in
5377 // single instructions. On Thumb the shift and the bit operation will be two
5378 // instructions.
5379 // Only allow this transformation on full-width (32-bit) operations
5380 SDValue LowerSatConstant;
5381 SDValue SatValue;
5382 if (VT == MVT::i32 &&
5383 isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
5384 SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
5385 DAG.getConstant(31, dl, VT));
5386 if (isNullConstant(LowerSatConstant)) {
5387 SDValue NotShiftV = DAG.getNode(ISD::XOR, dl, VT, ShiftV,
5388 DAG.getAllOnesConstant(dl, VT));
5389 return DAG.getNode(ISD::AND, dl, VT, SatValue, NotShiftV);
5390 } else if (isAllOnesConstant(LowerSatConstant))
5391 return DAG.getNode(ISD::OR, dl, VT, SatValue, ShiftV);
5392 }
5393
5394 SDValue LHS = Op.getOperand(0);
5395 SDValue RHS = Op.getOperand(1);
5396 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5397 SDValue TrueVal = Op.getOperand(2);
5398 SDValue FalseVal = Op.getOperand(3);
5399 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5400 ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
5401 if (Op.getValueType().isInteger()) {
5402
5403 // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
5404 // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
5405 // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
5406 // Both require less instructions than compare and conditional select.
5407 if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
5408 RHSC->isZero() && CFVal && CFVal->isZero() &&
5409 LHS.getValueType() == RHS.getValueType()) {
5410 EVT VT = LHS.getValueType();
5411 SDValue Shift =
5412 DAG.getNode(ISD::SRA, dl, VT, LHS,
5413 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5414
5415 if (CC == ISD::SETGT)
5416 Shift = DAG.getNOT(dl, Shift, VT);
5417
5418 return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
5419 }
5420
5421 // (SELECT_CC setlt, x, 0, 1, 0) -> SRL(x, bw-1)
5422 if (CC == ISD::SETLT && isNullConstant(RHS) && isOneConstant(TrueVal) &&
5423 isNullConstant(FalseVal) && LHS.getValueType() == VT)
5424 return DAG.getNode(ISD::SRL, dl, VT, LHS,
5425 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5426 }
5427
5428 if (LHS.getValueType() == MVT::i32) {
5429 unsigned Opcode;
5430 bool InvertCond;
5431 if (SDValue Op =
5432 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
5433 if (InvertCond)
5434 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5435
5436 SDValue ARMcc;
5437 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5438 EVT VT = Op.getValueType();
5439 return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
5440 }
5441 }
5442
5443 if (isUnsupportedFloatingType(LHS.getValueType())) {
5444 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5445
5446 // If softenSetCCOperands only returned one value, we should compare it to
5447 // zero.
5448 if (!RHS.getNode()) {
5449 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5450 CC = ISD::SETNE;
5451 }
5452 }
5453
5454 if (LHS.getValueType() == MVT::i32) {
5455 // Try to generate VSEL on ARMv8.
5456 // The VSEL instruction can't use all the usual ARM condition
5457 // codes: it only has two bits to select the condition code, so it's
5458 // constrained to use only GE, GT, VS and EQ.
5459 //
5460 // To implement all the various ISD::SETXXX opcodes, we sometimes need to
5461 // swap the operands of the previous compare instruction (effectively
5462 // inverting the compare condition, swapping 'less' and 'greater') and
5463 // sometimes need to swap the operands to the VSEL (which inverts the
5464 // condition in the sense of firing whenever the previous condition didn't)
5465 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
5466 TrueVal.getValueType() == MVT::f32 ||
5467 TrueVal.getValueType() == MVT::f64)) {
5469 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
5470 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
5471 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5472 std::swap(TrueVal, FalseVal);
5473 }
5474 }
5475
5476 SDValue ARMcc;
5477 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5478 // Choose GE over PL, which vsel does now support
5479 if (ARMcc->getAsZExtVal() == ARMCC::PL)
5480 ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
5481 return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5482 }
5483
5484 ARMCC::CondCodes CondCode, CondCode2;
5485 FPCCToARMCC(CC, CondCode, CondCode2);
5486
5487 // Normalize the fp compare. If RHS is zero we prefer to keep it there so we
5488 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
5489 // must use VSEL (limited condition codes), due to not having conditional f16
5490 // moves.
5491 if (Subtarget->hasFPARMv8Base() &&
5492 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
5493 (TrueVal.getValueType() == MVT::f16 ||
5494 TrueVal.getValueType() == MVT::f32 ||
5495 TrueVal.getValueType() == MVT::f64)) {
5496 bool swpCmpOps = false;
5497 bool swpVselOps = false;
5498 checkVSELConstraints(CC, CondCode, swpCmpOps, swpVselOps);
5499
5500 if (CondCode == ARMCC::GT || CondCode == ARMCC::GE ||
5501 CondCode == ARMCC::VS || CondCode == ARMCC::EQ) {
5502 if (swpCmpOps)
5503 std::swap(LHS, RHS);
5504 if (swpVselOps)
5505 std::swap(TrueVal, FalseVal);
5506 }
5507 }
5508
5509 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5510 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5511 SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5512 if (CondCode2 != ARMCC::AL) {
5513 SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
5514 Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
5515 }
5516 return Result;
5517}
5518
5519/// canChangeToInt - Given the fp compare operand, return true if it is suitable
5520/// to morph to an integer compare sequence.
5521static bool canChangeToInt(SDValue Op, bool &SeenZero,
5522 const ARMSubtarget *Subtarget) {
5523 SDNode *N = Op.getNode();
5524 if (!N->hasOneUse())
5525 // Otherwise it requires moving the value from fp to integer registers.
5526 return false;
5527 if (!N->getNumValues())
5528 return false;
5529 EVT VT = Op.getValueType();
5530 if (VT != MVT::f32 && !Subtarget->isFPBrccSlow())
5531 // f32 case is generally profitable. f64 case only makes sense when vcmpe +
5532 // vmrs are very slow, e.g. cortex-a8.
5533 return false;
5534
5535 if (isFloatingPointZero(Op)) {
5536 SeenZero = true;
5537 return true;
5538 }
5539 return ISD::isNormalLoad(N);
5540}
5541
5544 return DAG.getConstant(0, SDLoc(Op), MVT::i32);
5545
5547 return DAG.getLoad(MVT::i32, SDLoc(Op), Ld->getChain(), Ld->getBasePtr(),
5548 Ld->getPointerInfo(), Ld->getAlign(),
5549 Ld->getMemOperand()->getFlags());
5550
5551 llvm_unreachable("Unknown VFP cmp argument!");
5552}
5553
5555 SDValue &RetVal1, SDValue &RetVal2) {
5556 SDLoc dl(Op);
5557
5558 if (isFloatingPointZero(Op)) {
5559 RetVal1 = DAG.getConstant(0, dl, MVT::i32);
5560 RetVal2 = DAG.getConstant(0, dl, MVT::i32);
5561 return;
5562 }
5563
5564 if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Op)) {
5565 SDValue Ptr = Ld->getBasePtr();
5566 RetVal1 =
5567 DAG.getLoad(MVT::i32, dl, Ld->getChain(), Ptr, Ld->getPointerInfo(),
5568 Ld->getAlign(), Ld->getMemOperand()->getFlags());
5569
5570 EVT PtrType = Ptr.getValueType();
5571 SDValue NewPtr = DAG.getNode(ISD::ADD, dl,
5572 PtrType, Ptr, DAG.getConstant(4, dl, PtrType));
5573 RetVal2 = DAG.getLoad(MVT::i32, dl, Ld->getChain(), NewPtr,
5574 Ld->getPointerInfo().getWithOffset(4),
5575 commonAlignment(Ld->getAlign(), 4),
5576 Ld->getMemOperand()->getFlags());
5577 return;
5578 }
5579
5580 llvm_unreachable("Unknown VFP cmp argument!");
5581}
5582
5583/// OptimizeVFPBrcond - With nnan and without daz, it's legal to optimize some
5584/// f32 and even f64 comparisons to integer ones.
5585SDValue
5586ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
5587 SDValue Chain = Op.getOperand(0);
5588 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5589 SDValue LHS = Op.getOperand(2);
5590 SDValue RHS = Op.getOperand(3);
5591 SDValue Dest = Op.getOperand(4);
5592 SDLoc dl(Op);
5593
5594 bool LHSSeenZero = false;
5595 bool LHSOk = canChangeToInt(LHS, LHSSeenZero, Subtarget);
5596 bool RHSSeenZero = false;
5597 bool RHSOk = canChangeToInt(RHS, RHSSeenZero, Subtarget);
5598 if (LHSOk && RHSOk && (LHSSeenZero || RHSSeenZero)) {
5599 // If unsafe fp math optimization is enabled and there are no other uses of
5600 // the CMP operands, and the condition code is EQ or NE, we can optimize it
5601 // to an integer comparison.
5602 if (CC == ISD::SETOEQ)
5603 CC = ISD::SETEQ;
5604 else if (CC == ISD::SETUNE)
5605 CC = ISD::SETNE;
5606
5607 SDValue Mask = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5608 SDValue ARMcc;
5609 if (LHS.getValueType() == MVT::f32) {
5610 LHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5611 bitcastf32Toi32(LHS, DAG), Mask);
5612 RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5613 bitcastf32Toi32(RHS, DAG), Mask);
5614 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5615 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5616 Cmp);
5617 }
5618
5619 SDValue LHS1, LHS2;
5620 SDValue RHS1, RHS2;
5621 expandf64Toi32(LHS, DAG, LHS1, LHS2);
5622 expandf64Toi32(RHS, DAG, RHS1, RHS2);
5623 LHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, LHS2, Mask);
5624 RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
5626 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5627 SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
5628 return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
5629 }
5630
5631 return SDValue();
5632}
5633
5634// Generate CMP + CMOV for integer abs.
5635SDValue ARMTargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
5636 SDLoc DL(Op);
5637
5638 SDValue Neg = DAG.getNegative(Op.getOperand(0), DL, MVT::i32);
5639
5640 // Generate CMP & CMOV.
5641 SDValue Cmp = DAG.getNode(ARMISD::CMP, DL, FlagsVT, Op.getOperand(0),
5642 DAG.getConstant(0, DL, MVT::i32));
5643 return DAG.getNode(ARMISD::CMOV, DL, MVT::i32, Op.getOperand(0), Neg,
5644 DAG.getConstant(ARMCC::MI, DL, MVT::i32), Cmp);
5645}
5646
5648 ARMCC::CondCodes CondCode =
5649 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();
5650 CondCode = ARMCC::getOppositeCondition(CondCode);
5651 return DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5652}
5653
5654SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5655 SDValue Chain = Op.getOperand(0);
5656 SDValue Cond = Op.getOperand(1);
5657 SDValue Dest = Op.getOperand(2);
5658 SDLoc dl(Op);
5659
5660 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5661 // instruction.
5662 unsigned Opc = Cond.getOpcode();
5663 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5664 !Subtarget->isThumb1Only();
5665 if (Cond.getResNo() == 1 &&
5666 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5667 Opc == ISD::USUBO || OptimizeMul)) {
5668 // Only lower legal XALUO ops.
5669 if (!isTypeLegal(Cond->getValueType(0)))
5670 return SDValue();
5671
5672 // The actual operation with overflow check.
5673 SDValue Value, OverflowCmp;
5674 SDValue ARMcc;
5675 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5676
5677 // Reverse the condition code.
5678 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5679
5680 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5681 OverflowCmp);
5682 }
5683
5684 return SDValue();
5685}
5686
5687SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5688 SDValue Chain = Op.getOperand(0);
5689 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5690 SDValue LHS = Op.getOperand(2);
5691 SDValue RHS = Op.getOperand(3);
5692 SDValue Dest = Op.getOperand(4);
5693 SDLoc dl(Op);
5694
5695 if (isUnsupportedFloatingType(LHS.getValueType())) {
5696 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5697
5698 // If softenSetCCOperands only returned one value, we should compare it to
5699 // zero.
5700 if (!RHS.getNode()) {
5701 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5702 CC = ISD::SETNE;
5703 }
5704 }
5705
5706 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5707 // instruction.
5708 unsigned Opc = LHS.getOpcode();
5709 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5710 !Subtarget->isThumb1Only();
5711 if (LHS.getResNo() == 1 && (isOneConstant(RHS) || isNullConstant(RHS)) &&
5712 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5713 Opc == ISD::USUBO || OptimizeMul) &&
5714 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5715 // Only lower legal XALUO ops.
5716 if (!isTypeLegal(LHS->getValueType(0)))
5717 return SDValue();
5718
5719 // The actual operation with overflow check.
5720 SDValue Value, OverflowCmp;
5721 SDValue ARMcc;
5722 std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5723
5724 if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5725 // Reverse the condition code.
5726 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5727 }
5728
5729 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5730 OverflowCmp);
5731 }
5732
5733 if (LHS.getValueType() == MVT::i32) {
5734 SDValue ARMcc;
5735 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5736 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
5737 }
5738
5739 SDNodeFlags Flags = Op->getFlags();
5740 if (Flags.hasNoNaNs() &&
5741 DAG.getDenormalMode(MVT::f32) == DenormalMode::getIEEE() &&
5742 DAG.getDenormalMode(MVT::f64) == DenormalMode::getIEEE() &&
5743 (CC == ISD::SETEQ || CC == ISD::SETOEQ || CC == ISD::SETNE ||
5744 CC == ISD::SETUNE)) {
5745 if (SDValue Result = OptimizeVFPBrcond(Op, DAG))
5746 return Result;
5747 }
5748
5749 ARMCC::CondCodes CondCode, CondCode2;
5750 FPCCToARMCC(CC, CondCode, CondCode2);
5751
5752 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5753 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5754 SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
5755 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5756 if (CondCode2 != ARMCC::AL) {
5757 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
5758 SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
5759 Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5760 }
5761 return Res;
5762}
5763
5764SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
5765 SDValue Chain = Op.getOperand(0);
5766 SDValue Table = Op.getOperand(1);
5767 SDValue Index = Op.getOperand(2);
5768 SDLoc dl(Op);
5769
5770 EVT PTy = getPointerTy(DAG.getDataLayout());
5771 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
5772 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
5773 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
5774 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
5775 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
5776 if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
5777 // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
5778 // which does another jump to the destination. This also makes it easier
5779 // to translate it to TBB / TBH later (Thumb2 only).
5780 // FIXME: This might not work if the function is extremely large.
5781 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,
5782 Addr, Op.getOperand(2), JTI);
5783 }
5784 if (isPositionIndependent() || Subtarget->isROPI()) {
5785 Addr =
5786 DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
5788 Chain = Addr.getValue(1);
5789 Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
5790 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5791 } else {
5792 Addr =
5793 DAG.getLoad(PTy, dl, Chain, Addr,
5795 Chain = Addr.getValue(1);
5796 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5797 }
5798}
5799
5801 EVT VT = Op.getValueType();
5802 SDLoc dl(Op);
5803
5804 if (Op.getValueType().getVectorElementType() == MVT::i32) {
5805 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::f32)
5806 return Op;
5807 return DAG.UnrollVectorOp(Op.getNode());
5808 }
5809
5810 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5811
5812 EVT NewTy;
5813 const EVT OpTy = Op.getOperand(0).getValueType();
5814 if (OpTy == MVT::v4f32)
5815 NewTy = MVT::v4i32;
5816 else if (OpTy == MVT::v4f16 && HasFullFP16)
5817 NewTy = MVT::v4i16;
5818 else if (OpTy == MVT::v8f16 && HasFullFP16)
5819 NewTy = MVT::v8i16;
5820 else
5821 llvm_unreachable("Invalid type for custom lowering!");
5822
5823 if (VT != MVT::v4i16 && VT != MVT::v8i16)
5824 return DAG.UnrollVectorOp(Op.getNode());
5825
5826 Op = DAG.getNode(Op.getOpcode(), dl, NewTy, Op.getOperand(0));
5827 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
5828}
5829
5830SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
5831 EVT VT = Op.getValueType();
5832 if (VT.isVector())
5833 return LowerVectorFP_TO_INT(Op, DAG);
5834
5835 bool IsStrict = Op->isStrictFPOpcode();
5836 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5837
5838 if (isUnsupportedFloatingType(SrcVal.getValueType())) {
5839 RTLIB::Libcall LC;
5840 if (Op.getOpcode() == ISD::FP_TO_SINT ||
5841 Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
5842 LC = RTLIB::getFPTOSINT(SrcVal.getValueType(),
5843 Op.getValueType());
5844 else
5845 LC = RTLIB::getFPTOUINT(SrcVal.getValueType(),
5846 Op.getValueType());
5847 SDLoc Loc(Op);
5848 MakeLibCallOptions CallOptions;
5849 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5850 SDValue Result;
5851 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5852 CallOptions, Loc, Chain);
5853 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5854 }
5855
5856 return Op;
5857}
5858
5860 const ARMSubtarget *Subtarget) {
5861 EVT VT = Op.getValueType();
5862 EVT ToVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
5863 EVT FromVT = Op.getOperand(0).getValueType();
5864
5865 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f32)
5866 return Op;
5867 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f64 &&
5868 Subtarget->hasFP64())
5869 return Op;
5870 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f16 &&
5871 Subtarget->hasFullFP16())
5872 return Op;
5873 if (VT == MVT::v4i32 && ToVT == MVT::i32 && FromVT == MVT::v4f32 &&
5874 Subtarget->hasMVEFloatOps())
5875 return Op;
5876 if (VT == MVT::v8i16 && ToVT == MVT::i16 && FromVT == MVT::v8f16 &&
5877 Subtarget->hasMVEFloatOps())
5878 return Op;
5879
5880 if (FromVT != MVT::v4f32 && FromVT != MVT::v8f16)
5881 return SDValue();
5882
5883 SDLoc DL(Op);
5884 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
5885 unsigned BW = ToVT.getScalarSizeInBits() - IsSigned;
5886 SDValue CVT = DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
5887 DAG.getValueType(VT.getScalarType()));
5888 SDValue Max = DAG.getNode(IsSigned ? ISD::SMIN : ISD::UMIN, DL, VT, CVT,
5889 DAG.getConstant((1 << BW) - 1, DL, VT));
5890 if (IsSigned)
5891 Max = DAG.getNode(ISD::SMAX, DL, VT, Max,
5892 DAG.getSignedConstant(-(1 << BW), DL, VT));
5893 return Max;
5894}
5895
5897 EVT VT = Op.getValueType();
5898 SDLoc dl(Op);
5899
5900 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::i32) {
5901 if (VT.getVectorElementType() == MVT::f32)
5902 return Op;
5903 return DAG.UnrollVectorOp(Op.getNode());
5904 }
5905
5906 assert((Op.getOperand(0).getValueType() == MVT::v4i16 ||
5907 Op.getOperand(0).getValueType() == MVT::v8i16) &&
5908 "Invalid type for custom lowering!");
5909
5910 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5911
5912 EVT DestVecType;
5913 if (VT == MVT::v4f32)
5914 DestVecType = MVT::v4i32;
5915 else if (VT == MVT::v4f16 && HasFullFP16)
5916 DestVecType = MVT::v4i16;
5917 else if (VT == MVT::v8f16 && HasFullFP16)
5918 DestVecType = MVT::v8i16;
5919 else
5920 return DAG.UnrollVectorOp(Op.getNode());
5921
5922 unsigned CastOpc;
5923 unsigned Opc;
5924 switch (Op.getOpcode()) {
5925 default: llvm_unreachable("Invalid opcode!");
5926 case ISD::SINT_TO_FP:
5927 CastOpc = ISD::SIGN_EXTEND;
5929 break;
5930 case ISD::UINT_TO_FP:
5931 CastOpc = ISD::ZERO_EXTEND;
5933 break;
5934 }
5935
5936 Op = DAG.getNode(CastOpc, dl, DestVecType, Op.getOperand(0));
5937 return DAG.getNode(Opc, dl, VT, Op);
5938}
5939
5940SDValue ARMTargetLowering::LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const {
5941 EVT VT = Op.getValueType();
5942 if (VT.isVector())
5943 return LowerVectorINT_TO_FP(Op, DAG);
5944
5945 bool IsStrict = Op->isStrictFPOpcode();
5946 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5947
5948 if (isUnsupportedFloatingType(VT)) {
5949 RTLIB::Libcall LC;
5950 if (Op.getOpcode() == ISD::SINT_TO_FP ||
5951 Op.getOpcode() == ISD::STRICT_SINT_TO_FP)
5952 LC = RTLIB::getSINTTOFP(SrcVal.getValueType(), Op.getValueType());
5953 else
5954 LC = RTLIB::getUINTTOFP(SrcVal.getValueType(), Op.getValueType());
5955 SDLoc Loc(Op);
5956 MakeLibCallOptions CallOptions;
5957 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5958 SDValue Result;
5959 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5960 CallOptions, Loc, Chain);
5961 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5962 }
5963
5964 return Op;
5965}
5966
5967SDValue ARMTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
5968 // Implement fcopysign with a fabs and a conditional fneg.
5969 SDValue Tmp0 = Op.getOperand(0);
5970 SDValue Tmp1 = Op.getOperand(1);
5971 SDLoc dl(Op);
5972 EVT VT = Op.getValueType();
5973 EVT SrcVT = Tmp1.getValueType();
5974 bool InGPR = Tmp0.getOpcode() == ISD::BITCAST ||
5975 Tmp0.getOpcode() == ARMISD::VMOVDRR;
5976 bool UseNEON = !InGPR && Subtarget->hasNEON();
5977
5978 if (UseNEON) {
5979 // Use VBSL to copy the sign bit.
5980 unsigned EncodedVal = ARM_AM::createVMOVModImm(0x6, 0x80);
5981 SDValue Mask = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v2i32,
5982 DAG.getTargetConstant(EncodedVal, dl, MVT::i32));
5983 EVT OpVT = (VT == MVT::f32) ? MVT::v2i32 : MVT::v1i64;
5984 if (VT == MVT::f64)
5985 Mask = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5986 DAG.getNode(ISD::BITCAST, dl, OpVT, Mask),
5987 DAG.getConstant(32, dl, MVT::i32));
5988 else /*if (VT == MVT::f32)*/
5989 Tmp0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp0);
5990 if (SrcVT == MVT::f32) {
5991 Tmp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp1);
5992 if (VT == MVT::f64)
5993 Tmp1 = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5994 DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1),
5995 DAG.getConstant(32, dl, MVT::i32));
5996 } else if (VT == MVT::f32)
5997 Tmp1 = DAG.getNode(ARMISD::VSHRuIMM, dl, MVT::v1i64,
5998 DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, Tmp1),
5999 DAG.getConstant(32, dl, MVT::i32));
6000 Tmp0 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp0);
6001 Tmp1 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1);
6002
6003 SDValue AllOnes = DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff),
6004 dl, MVT::i32);
6005 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v8i8, AllOnes);
6006 SDValue MaskNot = DAG.getNode(ISD::XOR, dl, OpVT, Mask,
6007 DAG.getNode(ISD::BITCAST, dl, OpVT, AllOnes));
6008
6009 SDValue Res = DAG.getNode(ISD::OR, dl, OpVT,
6010 DAG.getNode(ISD::AND, dl, OpVT, Tmp1, Mask),
6011 DAG.getNode(ISD::AND, dl, OpVT, Tmp0, MaskNot));
6012 if (VT == MVT::f32) {
6013 Res = DAG.getNode(ISD::BITCAST, dl, MVT::v2f32, Res);
6014 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
6015 DAG.getConstant(0, dl, MVT::i32));
6016 } else {
6017 Res = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Res);
6018 }
6019
6020 return Res;
6021 }
6022
6023 // Bitcast operand 1 to i32.
6024 if (SrcVT == MVT::f64)
6025 Tmp1 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
6026 Tmp1).getValue(1);
6027 Tmp1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp1);
6028
6029 // Or in the signbit with integer operations.
6030 SDValue Mask1 = DAG.getConstant(0x80000000, dl, MVT::i32);
6031 SDValue Mask2 = DAG.getConstant(0x7fffffff, dl, MVT::i32);
6032 Tmp1 = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp1, Mask1);
6033 if (VT == MVT::f32) {
6034 Tmp0 = DAG.getNode(ISD::AND, dl, MVT::i32,
6035 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp0), Mask2);
6036 return DAG.getNode(ISD::BITCAST, dl, MVT::f32,
6037 DAG.getNode(ISD::OR, dl, MVT::i32, Tmp0, Tmp1));
6038 }
6039
6040 // f64: Or the high part with signbit and then combine two parts.
6041 Tmp0 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
6042 Tmp0);
6043 SDValue Lo = Tmp0.getValue(0);
6044 SDValue Hi = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp0.getValue(1), Mask2);
6045 Hi = DAG.getNode(ISD::OR, dl, MVT::i32, Hi, Tmp1);
6046 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
6047}
6048
6049SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
6051 MachineFrameInfo &MFI = MF.getFrameInfo();
6052 MFI.setReturnAddressIsTaken(true);
6053
6054 EVT VT = Op.getValueType();
6055 SDLoc dl(Op);
6056 unsigned Depth = Op.getConstantOperandVal(0);
6057 if (Depth) {
6058 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
6059 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
6060 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
6061 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
6062 MachinePointerInfo());
6063 }
6064
6065 // Return LR, which contains the return address. Mark it an implicit live-in.
6066 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
6067 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
6068}
6069
6070SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
6071 const ARMBaseRegisterInfo &ARI =
6072 *static_cast<const ARMBaseRegisterInfo*>(RegInfo);
6074 MachineFrameInfo &MFI = MF.getFrameInfo();
6075 MFI.setFrameAddressIsTaken(true);
6076
6077 EVT VT = Op.getValueType();
6078 SDLoc dl(Op); // FIXME probably not meaningful
6079 unsigned Depth = Op.getConstantOperandVal(0);
6080 Register FrameReg = ARI.getFrameRegister(MF);
6081 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
6082 while (Depth--)
6083 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
6084 MachinePointerInfo());
6085 return FrameAddr;
6086}
6087
6088// FIXME? Maybe this could be a TableGen attribute on some registers and
6089// this table could be generated automatically from RegInfo.
6090Register ARMTargetLowering::getRegisterByName(const char* RegName, LLT VT,
6091 const MachineFunction &MF) const {
6092 return StringSwitch<Register>(RegName)
6093 .Case("sp", ARM::SP)
6094 .Default(Register());
6095}
6096
6097// Result is 64 bit value so split into two 32 bit values and return as a
6098// pair of values.
6100 SelectionDAG &DAG) {
6101 SDLoc DL(N);
6102
6103 // This function is only supposed to be called for i64 type destination.
6104 assert(N->getValueType(0) == MVT::i64
6105 && "ExpandREAD_REGISTER called for non-i64 type result.");
6106
6108 DAG.getVTList(MVT::i32, MVT::i32, MVT::Other),
6109 N->getOperand(0),
6110 N->getOperand(1));
6111
6112 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0),
6113 Read.getValue(1)));
6114 Results.push_back(Read.getValue(2)); // Chain
6115}
6116
6117/// \p BC is a bitcast that is about to be turned into a VMOVDRR.
6118/// When \p DstVT, the destination type of \p BC, is on the vector
6119/// register bank and the source of bitcast, \p Op, operates on the same bank,
6120/// it might be possible to combine them, such that everything stays on the
6121/// vector register bank.
6122/// \p return The node that would replace \p BT, if the combine
6123/// is possible.
6125 SelectionDAG &DAG) {
6126 SDValue Op = BC->getOperand(0);
6127 EVT DstVT = BC->getValueType(0);
6128
6129 // The only vector instruction that can produce a scalar (remember,
6130 // since the bitcast was about to be turned into VMOVDRR, the source
6131 // type is i64) from a vector is EXTRACT_VECTOR_ELT.
6132 // Moreover, we can do this combine only if there is one use.
6133 // Finally, if the destination type is not a vector, there is not
6134 // much point on forcing everything on the vector bank.
6135 if (!DstVT.isVector() || Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
6136 !Op.hasOneUse())
6137 return SDValue();
6138
6139 // If the index is not constant, we will introduce an additional
6140 // multiply that will stick.
6141 // Give up in that case.
6142 ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Op.getOperand(1));
6143 if (!Index)
6144 return SDValue();
6145 unsigned DstNumElt = DstVT.getVectorNumElements();
6146
6147 // Compute the new index.
6148 const APInt &APIntIndex = Index->getAPIntValue();
6149 APInt NewIndex(APIntIndex.getBitWidth(), DstNumElt);
6150 NewIndex *= APIntIndex;
6151 // Check if the new constant index fits into i32.
6152 if (NewIndex.getBitWidth() > 32)
6153 return SDValue();
6154
6155 // vMTy bitcast(i64 extractelt vNi64 src, i32 index) ->
6156 // vMTy extractsubvector vNxMTy (bitcast vNi64 src), i32 index*M)
6157 SDLoc dl(Op);
6158 SDValue ExtractSrc = Op.getOperand(0);
6159 EVT VecVT = EVT::getVectorVT(
6160 *DAG.getContext(), DstVT.getScalarType(),
6161 ExtractSrc.getValueType().getVectorNumElements() * DstNumElt);
6162 SDValue BitCast = DAG.getNode(ISD::BITCAST, dl, VecVT, ExtractSrc);
6163 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, BitCast,
6164 DAG.getConstant(NewIndex.getZExtValue(), dl, MVT::i32));
6165}
6166
6167/// ExpandBITCAST - If the target supports VFP, this function is called to
6168/// expand a bit convert where either the source or destination type is i64 to
6169/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
6170/// operand type is illegal (e.g., v2f32 for a target that doesn't support
6171/// vectors), since the legalizer won't know what to do with that.
6172SDValue ARMTargetLowering::ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
6173 const ARMSubtarget *Subtarget) const {
6174 SDLoc dl(N);
6175 SDValue Op = N->getOperand(0);
6176
6177 // This function is only supposed to be called for i16 and i64 types, either
6178 // as the source or destination of the bit convert.
6179 EVT SrcVT = Op.getValueType();
6180 EVT DstVT = N->getValueType(0);
6181
6182 if ((SrcVT == MVT::i16 || SrcVT == MVT::i32) &&
6183 (DstVT == MVT::f16 || DstVT == MVT::bf16))
6184 return MoveToHPR(SDLoc(N), DAG, MVT::i32, DstVT.getSimpleVT(),
6185 DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i32, Op));
6186
6187 if ((DstVT == MVT::i16 || DstVT == MVT::i32) &&
6188 (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
6189 if (Subtarget->hasFullFP16() && !Subtarget->hasBF16())
6190 Op = DAG.getBitcast(MVT::f16, Op);
6191 return DAG.getNode(
6192 ISD::TRUNCATE, SDLoc(N), DstVT,
6193 MoveFromHPR(SDLoc(N), DAG, MVT::i32, SrcVT.getSimpleVT(), Op));
6194 }
6195
6196 if (!(SrcVT == MVT::i64 || DstVT == MVT::i64))
6197 return SDValue();
6198
6199 // Turn i64->f64 into VMOVDRR.
6200 if (SrcVT == MVT::i64 && isTypeLegal(DstVT)) {
6201 // Do not force values to GPRs (this is what VMOVDRR does for the inputs)
6202 // if we can combine the bitcast with its source.
6203 if (SDValue Val = CombineVMOVDRRCandidateWithVecOp(N, DAG))
6204 return Val;
6205 SDValue Lo, Hi;
6206 std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32);
6207 return DAG.getNode(ISD::BITCAST, dl, DstVT,
6208 DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi));
6209 }
6210
6211 // Turn f64->i64 into VMOVRRD.
6212 if (DstVT == MVT::i64 && isTypeLegal(SrcVT)) {
6213 SDValue Cvt;
6214 if (DAG.getDataLayout().isBigEndian() && SrcVT.isVector() &&
6215 SrcVT.getVectorNumElements() > 1)
6216 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6217 DAG.getVTList(MVT::i32, MVT::i32),
6218 DAG.getNode(ARMISD::VREV64, dl, SrcVT, Op));
6219 else
6220 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6221 DAG.getVTList(MVT::i32, MVT::i32), Op);
6222 // Merge the pieces into a single i64 value.
6223 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1));
6224 }
6225
6226 return SDValue();
6227}
6228
6229/// getZeroVector - Returns a vector of specified type with all zero elements.
6230/// Zero vectors are used to represent vector negation and in those cases
6231/// will be implemented with the NEON VNEG instruction. However, VNEG does
6232/// not support i64 elements, so sometimes the zero vectors will need to be
6233/// explicitly constructed. Regardless, use a canonical VMOV to create the
6234/// zero vector.
6235static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
6236 assert(VT.isVector() && "Expected a vector type");
6237 // The canonical modified immediate encoding of a zero vector is....0!
6238 SDValue EncodedVal = DAG.getTargetConstant(0, dl, MVT::i32);
6239 EVT VmovVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
6240 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, EncodedVal);
6241 return DAG.getNode(ISD::BITCAST, dl, VT, Vmov);
6242}
6243
6244/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
6245/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6246SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
6247 SelectionDAG &DAG) const {
6248 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6249 EVT VT = Op.getValueType();
6250 unsigned VTBits = VT.getSizeInBits();
6251 SDLoc dl(Op);
6252 SDValue ShOpLo = Op.getOperand(0);
6253 SDValue ShOpHi = Op.getOperand(1);
6254 SDValue ShAmt = Op.getOperand(2);
6255 SDValue ARMcc;
6256 unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
6257
6258 assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
6259
6260 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6261 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6262 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt);
6263 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6264 DAG.getConstant(VTBits, dl, MVT::i32));
6265 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt);
6266 SDValue LoSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6267 SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
6268 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6269 ISD::SETGE, ARMcc, DAG, dl);
6270 SDValue Lo =
6271 DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
6272
6273 SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
6274 SDValue HiBigShift = Opc == ISD::SRA
6275 ? DAG.getNode(Opc, dl, VT, ShOpHi,
6276 DAG.getConstant(VTBits - 1, dl, VT))
6277 : DAG.getConstant(0, dl, VT);
6278 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6279 ISD::SETGE, ARMcc, DAG, dl);
6280 SDValue Hi =
6281 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6282
6283 SDValue Ops[2] = { Lo, Hi };
6284 return DAG.getMergeValues(Ops, dl);
6285}
6286
6287/// LowerShiftLeftParts - Lower SHL_PARTS, which returns two
6288/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6289SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op,
6290 SelectionDAG &DAG) const {
6291 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6292 EVT VT = Op.getValueType();
6293 unsigned VTBits = VT.getSizeInBits();
6294 SDLoc dl(Op);
6295 SDValue ShOpLo = Op.getOperand(0);
6296 SDValue ShOpHi = Op.getOperand(1);
6297 SDValue ShAmt = Op.getOperand(2);
6298 SDValue ARMcc;
6299
6300 assert(Op.getOpcode() == ISD::SHL_PARTS);
6301 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6302 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6303 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
6304 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
6305 SDValue HiSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6306
6307 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6308 DAG.getConstant(VTBits, dl, MVT::i32));
6309 SDValue HiBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
6310 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6311 ISD::SETGE, ARMcc, DAG, dl);
6312 SDValue Hi =
6313 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6314
6315 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6316 ISD::SETGE, ARMcc, DAG, dl);
6317 SDValue LoSmallShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
6318 SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift,
6319 DAG.getConstant(0, dl, VT), ARMcc, CmpLo);
6320
6321 SDValue Ops[2] = { Lo, Hi };
6322 return DAG.getMergeValues(Ops, dl);
6323}
6324
6325SDValue ARMTargetLowering::LowerGET_ROUNDING(SDValue Op,
6326 SelectionDAG &DAG) const {
6327 // The rounding mode is in bits 23:22 of the FPSCR.
6328 // The ARM rounding mode value to FLT_ROUNDS mapping is 0->1, 1->2, 2->3, 3->0
6329 // The formula we use to implement this is (((FPSCR + 1 << 22) >> 22) & 3)
6330 // so that the shift + and get folded into a bitfield extract.
6331 SDLoc dl(Op);
6332 SDValue Chain = Op.getOperand(0);
6333 SDValue Ops[] = {Chain,
6334 DAG.getConstant(Intrinsic::arm_get_fpscr, dl, MVT::i32)};
6335
6336 SDValue FPSCR =
6337 DAG.getNode(ISD::INTRINSIC_W_CHAIN, dl, {MVT::i32, MVT::Other}, Ops);
6338 Chain = FPSCR.getValue(1);
6339 SDValue FltRounds = DAG.getNode(ISD::ADD, dl, MVT::i32, FPSCR,
6340 DAG.getConstant(1U << 22, dl, MVT::i32));
6341 SDValue RMODE = DAG.getNode(ISD::SRL, dl, MVT::i32, FltRounds,
6342 DAG.getConstant(22, dl, MVT::i32));
6343 SDValue And = DAG.getNode(ISD::AND, dl, MVT::i32, RMODE,
6344 DAG.getConstant(3, dl, MVT::i32));
6345 return DAG.getMergeValues({And, Chain}, dl);
6346}
6347
6348SDValue ARMTargetLowering::LowerSET_ROUNDING(SDValue Op,
6349 SelectionDAG &DAG) const {
6350 SDLoc DL(Op);
6351 SDValue Chain = Op->getOperand(0);
6352 SDValue RMValue = Op->getOperand(1);
6353
6354 // The rounding mode is in bits 23:22 of the FPSCR.
6355 // The llvm.set.rounding argument value to ARM rounding mode value mapping
6356 // is 0->3, 1->0, 2->1, 3->2. The formula we use to implement this is
6357 // ((arg - 1) & 3) << 22).
6358 //
6359 // It is expected that the argument of llvm.set.rounding is within the
6360 // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
6361 // responsibility of the code generated llvm.set.rounding to ensure this
6362 // condition.
6363
6364 // Calculate new value of FPSCR[23:22].
6365 RMValue = DAG.getNode(ISD::SUB, DL, MVT::i32, RMValue,
6366 DAG.getConstant(1, DL, MVT::i32));
6367 RMValue = DAG.getNode(ISD::AND, DL, MVT::i32, RMValue,
6368 DAG.getConstant(0x3, DL, MVT::i32));
6369 RMValue = DAG.getNode(ISD::SHL, DL, MVT::i32, RMValue,
6370 DAG.getConstant(ARM::RoundingBitsPos, DL, MVT::i32));
6371
6372 // Get current value of FPSCR.
6373 SDValue Ops[] = {Chain,
6374 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6375 SDValue FPSCR =
6376 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6377 Chain = FPSCR.getValue(1);
6378 FPSCR = FPSCR.getValue(0);
6379
6380 // Put new rounding mode into FPSCR[23:22].
6381 const unsigned RMMask = ~(ARM::Rounding::rmMask << ARM::RoundingBitsPos);
6382 FPSCR = DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6383 DAG.getConstant(RMMask, DL, MVT::i32));
6384 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCR, RMValue);
6385 SDValue Ops2[] = {
6386 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6387 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6388}
6389
6390SDValue ARMTargetLowering::LowerSET_FPMODE(SDValue Op,
6391 SelectionDAG &DAG) const {
6392 SDLoc DL(Op);
6393 SDValue Chain = Op->getOperand(0);
6394 SDValue Mode = Op->getOperand(1);
6395
6396 // Generate nodes to build:
6397 // FPSCR = (FPSCR & FPStatusBits) | (Mode & ~FPStatusBits)
6398 SDValue Ops[] = {Chain,
6399 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6400 SDValue FPSCR =
6401 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6402 Chain = FPSCR.getValue(1);
6403 FPSCR = FPSCR.getValue(0);
6404
6405 SDValue FPSCRMasked =
6406 DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6407 DAG.getConstant(ARM::FPStatusBits, DL, MVT::i32));
6408 SDValue InputMasked =
6409 DAG.getNode(ISD::AND, DL, MVT::i32, Mode,
6410 DAG.getConstant(~ARM::FPStatusBits, DL, MVT::i32));
6411 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCRMasked, InputMasked);
6412
6413 SDValue Ops2[] = {
6414 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6415 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6416}
6417
6418SDValue ARMTargetLowering::LowerRESET_FPMODE(SDValue Op,
6419 SelectionDAG &DAG) const {
6420 SDLoc DL(Op);
6421 SDValue Chain = Op->getOperand(0);
6422
6423 // To get the default FP mode all control bits are cleared:
6424 // FPSCR = FPSCR & (FPStatusBits | FPReservedBits)
6425 SDValue Ops[] = {Chain,
6426 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6427 SDValue FPSCR =
6428 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6429 Chain = FPSCR.getValue(1);
6430 FPSCR = FPSCR.getValue(0);
6431
6432 SDValue FPSCRMasked = DAG.getNode(
6433 ISD::AND, DL, MVT::i32, FPSCR,
6435 SDValue Ops2[] = {Chain,
6436 DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32),
6437 FPSCRMasked};
6438 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6439}
6440
6442 const ARMSubtarget *ST) {
6443 SDLoc dl(N);
6444 EVT VT = N->getValueType(0);
6445 if (VT.isVector() && ST->hasNEON()) {
6446
6447 // Compute the least significant set bit: LSB = X & -X
6448 SDValue X = N->getOperand(0);
6449 SDValue NX = DAG.getNode(ISD::SUB, dl, VT, getZeroVector(VT, DAG, dl), X);
6450 SDValue LSB = DAG.getNode(ISD::AND, dl, VT, X, NX);
6451
6453
6454 if (ElemTy == MVT::i8) {
6455 // Compute with: cttz(x) = ctpop(lsb - 1)
6456 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6457 DAG.getTargetConstant(1, dl, ElemTy));
6458 SDValue Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6459 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6460 }
6461
6462 if ((ElemTy == MVT::i16 || ElemTy == MVT::i32) &&
6463 (N->getOpcode() == ISD::CTTZ_ZERO_POISON)) {
6464 // Compute with: cttz(x) = (width - 1) - ctlz(lsb), if x != 0
6465 unsigned NumBits = ElemTy.getSizeInBits();
6466 SDValue WidthMinus1 =
6467 DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6468 DAG.getTargetConstant(NumBits - 1, dl, ElemTy));
6469 SDValue CTLZ = DAG.getNode(ISD::CTLZ, dl, VT, LSB);
6470 return DAG.getNode(ISD::SUB, dl, VT, WidthMinus1, CTLZ);
6471 }
6472
6473 // Compute with: cttz(x) = ctpop(lsb - 1)
6474
6475 // Compute LSB - 1.
6476 SDValue Bits;
6477 if (ElemTy == MVT::i64) {
6478 // Load constant 0xffff'ffff'ffff'ffff to register.
6479 SDValue FF = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6480 DAG.getTargetConstant(0x1eff, dl, MVT::i32));
6481 Bits = DAG.getNode(ISD::ADD, dl, VT, LSB, FF);
6482 } else {
6483 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6484 DAG.getTargetConstant(1, dl, ElemTy));
6485 Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6486 }
6487 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6488 }
6489
6490 if (!ST->hasV6T2Ops())
6491 return SDValue();
6492
6493 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, VT, N->getOperand(0));
6494 return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
6495}
6496
6498 const ARMSubtarget *ST) {
6499 EVT VT = N->getValueType(0);
6500 SDLoc DL(N);
6501
6502 assert(ST->hasNEON() && "Custom ctpop lowering requires NEON.");
6503 assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
6504 VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
6505 "Unexpected type for custom ctpop lowering");
6506
6507 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6508 EVT VT8Bit = VT.is64BitVector() ? MVT::v8i8 : MVT::v16i8;
6509 SDValue Res = DAG.getBitcast(VT8Bit, N->getOperand(0));
6510 Res = DAG.getNode(ISD::CTPOP, DL, VT8Bit, Res);
6511
6512 // Widen v8i8/v16i8 CTPOP result to VT by repeatedly widening pairwise adds.
6513 unsigned EltSize = 8;
6514 unsigned NumElts = VT.is64BitVector() ? 8 : 16;
6515 while (EltSize != VT.getScalarSizeInBits()) {
6517 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddlu, DL,
6518 TLI.getPointerTy(DAG.getDataLayout())));
6519 Ops.push_back(Res);
6520
6521 EltSize *= 2;
6522 NumElts /= 2;
6523 MVT WidenVT = MVT::getVectorVT(MVT::getIntegerVT(EltSize), NumElts);
6524 Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, WidenVT, Ops);
6525 }
6526
6527 return Res;
6528}
6529
6530/// Getvshiftimm - Check if this is a valid build_vector for the immediate
6531/// operand of a vector shift operation, where all the elements of the
6532/// build_vector must have the same constant integer value.
6533static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) {
6534 // Ignore bit_converts.
6535 while (Op.getOpcode() == ISD::BITCAST)
6536 Op = Op.getOperand(0);
6538 APInt SplatBits, SplatUndef;
6539 unsigned SplatBitSize;
6540 bool HasAnyUndefs;
6541 if (!BVN ||
6542 !BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6543 ElementBits) ||
6544 SplatBitSize > ElementBits)
6545 return false;
6546 Cnt = SplatBits.getSExtValue();
6547 return true;
6548}
6549
6550/// isVShiftLImm - Check if this is a valid build_vector for the immediate
6551/// operand of a vector shift left operation. That value must be in the range:
6552/// 0 <= Value < ElementBits for a left shift; or
6553/// 0 <= Value <= ElementBits for a long left shift.
6554static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) {
6555 assert(VT.isVector() && "vector shift count is not a vector type");
6556 int64_t ElementBits = VT.getScalarSizeInBits();
6557 if (!getVShiftImm(Op, ElementBits, Cnt))
6558 return false;
6559 return (Cnt >= 0 && (isLong ? Cnt - 1 : Cnt) < ElementBits);
6560}
6561
6562/// isVShiftRImm - Check if this is a valid build_vector for the immediate
6563/// operand of a vector shift right operation. For a shift opcode, the value
6564/// is positive, but for an intrinsic the value count must be negative. The
6565/// absolute value must be in the range:
6566/// 1 <= |Value| <= ElementBits for a right shift; or
6567/// 1 <= |Value| <= ElementBits/2 for a narrow right shift.
6568static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic,
6569 int64_t &Cnt) {
6570 assert(VT.isVector() && "vector shift count is not a vector type");
6571 int64_t ElementBits = VT.getScalarSizeInBits();
6572 if (!getVShiftImm(Op, ElementBits, Cnt))
6573 return false;
6574 if (!isIntrinsic)
6575 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits / 2 : ElementBits));
6576 if (Cnt >= -(isNarrow ? ElementBits / 2 : ElementBits) && Cnt <= -1) {
6577 Cnt = -Cnt;
6578 return true;
6579 }
6580 return false;
6581}
6582
6584 const ARMSubtarget *ST) {
6585 EVT VT = N->getValueType(0);
6586 SDLoc dl(N);
6587 int64_t Cnt;
6588
6589 if (!VT.isVector())
6590 return SDValue();
6591
6592 // We essentially have two forms here. Shift by an immediate and shift by a
6593 // vector register (there are also shift by a gpr, but that is just handled
6594 // with a tablegen pattern). We cannot easily match shift by an immediate in
6595 // tablegen so we do that here and generate a VSHLIMM/VSHRsIMM/VSHRuIMM.
6596 // For shifting by a vector, we don't have VSHR, only VSHL (which can be
6597 // signed or unsigned, and a negative shift indicates a shift right).
6598 if (N->getOpcode() == ISD::SHL) {
6599 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt))
6600 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
6601 DAG.getConstant(Cnt, dl, MVT::i32));
6602 return DAG.getNode(ARMISD::VSHLu, dl, VT, N->getOperand(0),
6603 N->getOperand(1));
6604 }
6605
6606 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
6607 "unexpected vector shift opcode");
6608
6609 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
6610 unsigned VShiftOpc =
6611 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
6612 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
6613 DAG.getConstant(Cnt, dl, MVT::i32));
6614 }
6615
6616 // Other right shifts we don't have operations for (we use a shift left by a
6617 // negative number).
6618 EVT ShiftVT = N->getOperand(1).getValueType();
6619 SDValue NegatedCount = DAG.getNode(
6620 ISD::SUB, dl, ShiftVT, getZeroVector(ShiftVT, DAG, dl), N->getOperand(1));
6621 unsigned VShiftOpc =
6622 (N->getOpcode() == ISD::SRA ? ARMISD::VSHLs : ARMISD::VSHLu);
6623 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0), NegatedCount);
6624}
6625
6627 const ARMSubtarget *ST) {
6628 EVT VT = N->getValueType(0);
6629 SDLoc dl(N);
6630
6631 // We can get here for a node like i32 = ISD::SHL i32, i64
6632 if (VT != MVT::i64)
6633 return SDValue();
6634
6635 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA ||
6636 N->getOpcode() == ISD::SHL) &&
6637 "Unknown shift to lower!");
6638
6639 unsigned ShOpc = N->getOpcode();
6640 if (ST->hasMVEIntegerOps()) {
6641 SDValue ShAmt = N->getOperand(1);
6642 unsigned ShPartsOpc = ARMISD::LSLL;
6644
6645 // If the shift amount is greater than 32 or has a greater bitwidth than 64
6646 // then do the default optimisation
6647 if ((!Con && ShAmt->getValueType(0).getSizeInBits() > 64) ||
6648 (Con && (Con->getAPIntValue() == 0 || Con->getAPIntValue().uge(32))))
6649 return SDValue();
6650
6651 // Extract the lower 32 bits of the shift amount if it's not an i32
6652 if (ShAmt->getValueType(0) != MVT::i32)
6653 ShAmt = DAG.getZExtOrTrunc(ShAmt, dl, MVT::i32);
6654
6655 if (ShOpc == ISD::SRL) {
6656 if (!Con)
6657 // There is no t2LSRLr instruction so negate and perform an lsll if the
6658 // shift amount is in a register, emulating a right shift.
6659 ShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6660 DAG.getConstant(0, dl, MVT::i32), ShAmt);
6661 else
6662 // Else generate an lsrl on the immediate shift amount
6663 ShPartsOpc = ARMISD::LSRL;
6664 } else if (ShOpc == ISD::SRA)
6665 ShPartsOpc = ARMISD::ASRL;
6666
6667 // Split Lower/Upper 32 bits of the destination/source
6668 SDValue Lo, Hi;
6669 std::tie(Lo, Hi) =
6670 DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6671 // Generate the shift operation as computed above
6672 Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi,
6673 ShAmt);
6674 // The upper 32 bits come from the second return value of lsll
6675 Hi = SDValue(Lo.getNode(), 1);
6676 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6677 }
6678
6679 // We only lower SRA, SRL of 1 here, all others use generic lowering.
6680 if (!isOneConstant(N->getOperand(1)) || N->getOpcode() == ISD::SHL)
6681 return SDValue();
6682
6683 // If we are in thumb mode, we don't have RRX.
6684 if (ST->isThumb1Only())
6685 return SDValue();
6686
6687 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr.
6688 SDValue Lo, Hi;
6689 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6690
6691 // First, build a LSRS1/ASRS1 op, which shifts the top part by one and
6692 // captures the shifted out bit into a carry flag.
6693 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::LSRS1 : ARMISD::ASRS1;
6694 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, FlagsVT), Hi);
6695
6696 // The low part is an ARMISD::RRX operand, which shifts the carry in.
6697 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1));
6698
6699 // Merge the pieces into a single i64 value.
6700 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6701}
6702
6704 const ARMSubtarget *ST) {
6705 bool Invert = false;
6706 bool Swap = false;
6707 unsigned Opc = ARMCC::AL;
6708
6709 SDValue Op0 = Op.getOperand(0);
6710 SDValue Op1 = Op.getOperand(1);
6711 SDValue CC = Op.getOperand(2);
6712 EVT VT = Op.getValueType();
6713 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
6714 SDLoc dl(Op);
6715
6716 EVT CmpVT;
6717 if (ST->hasNEON())
6719 else {
6720 assert(ST->hasMVEIntegerOps() &&
6721 "No hardware support for integer vector comparison!");
6722
6723 if (Op.getValueType().getVectorElementType() != MVT::i1)
6724 return SDValue();
6725
6726 // Make sure we expand floating point setcc to scalar if we do not have
6727 // mve.fp, so that we can handle them from there.
6728 if (Op0.getValueType().isFloatingPoint() && !ST->hasMVEFloatOps())
6729 return SDValue();
6730
6731 CmpVT = VT;
6732 }
6733
6734 if (Op0.getValueType().getVectorElementType() == MVT::i64 &&
6735 (SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE)) {
6736 // Special-case integer 64-bit equality comparisons. They aren't legal,
6737 // but they can be lowered with a few vector instructions.
6738 unsigned CmpElements = CmpVT.getVectorNumElements() * 2;
6739 EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, CmpElements);
6740 SDValue CastOp0 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op0);
6741 SDValue CastOp1 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op1);
6742 SDValue Cmp = DAG.getNode(ISD::SETCC, dl, SplitVT, CastOp0, CastOp1,
6743 DAG.getCondCode(ISD::SETEQ));
6744 SDValue Reversed = DAG.getNode(ARMISD::VREV64, dl, SplitVT, Cmp);
6745 SDValue Merged = DAG.getNode(ISD::AND, dl, SplitVT, Cmp, Reversed);
6746 Merged = DAG.getNode(ISD::BITCAST, dl, CmpVT, Merged);
6747 if (SetCCOpcode == ISD::SETNE)
6748 Merged = DAG.getNOT(dl, Merged, CmpVT);
6749 Merged = DAG.getSExtOrTrunc(Merged, dl, VT);
6750 return Merged;
6751 }
6752
6753 if (CmpVT.getVectorElementType() == MVT::i64)
6754 // 64-bit comparisons are not legal in general.
6755 return SDValue();
6756
6757 if (Op1.getValueType().isFloatingPoint()) {
6758 switch (SetCCOpcode) {
6759 default: llvm_unreachable("Illegal FP comparison");
6760 case ISD::SETUNE:
6761 case ISD::SETNE:
6762 if (ST->hasMVEFloatOps()) {
6763 Opc = ARMCC::NE; break;
6764 } else {
6765 Invert = true; [[fallthrough]];
6766 }
6767 case ISD::SETOEQ:
6768 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6769 case ISD::SETOLT:
6770 case ISD::SETLT: Swap = true; [[fallthrough]];
6771 case ISD::SETOGT:
6772 case ISD::SETGT: Opc = ARMCC::GT; break;
6773 case ISD::SETOLE:
6774 case ISD::SETLE: Swap = true; [[fallthrough]];
6775 case ISD::SETOGE:
6776 case ISD::SETGE: Opc = ARMCC::GE; break;
6777 case ISD::SETUGE: Swap = true; [[fallthrough]];
6778 case ISD::SETULE: Invert = true; Opc = ARMCC::GT; break;
6779 case ISD::SETUGT: Swap = true; [[fallthrough]];
6780 case ISD::SETULT: Invert = true; Opc = ARMCC::GE; break;
6781 case ISD::SETUEQ: Invert = true; [[fallthrough]];
6782 case ISD::SETONE: {
6783 // Expand this to (OLT | OGT).
6784 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6785 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6786 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6787 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6788 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6789 if (Invert)
6790 Result = DAG.getNOT(dl, Result, VT);
6791 return Result;
6792 }
6793 case ISD::SETUO: Invert = true; [[fallthrough]];
6794 case ISD::SETO: {
6795 // Expand this to (OLT | OGE).
6796 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6797 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6798 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6799 DAG.getConstant(ARMCC::GE, dl, MVT::i32));
6800 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6801 if (Invert)
6802 Result = DAG.getNOT(dl, Result, VT);
6803 return Result;
6804 }
6805 }
6806 } else {
6807 // Integer comparisons.
6808 switch (SetCCOpcode) {
6809 default: llvm_unreachable("Illegal integer comparison");
6810 case ISD::SETNE:
6811 if (ST->hasMVEIntegerOps()) {
6812 Opc = ARMCC::NE; break;
6813 } else {
6814 Invert = true; [[fallthrough]];
6815 }
6816 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6817 case ISD::SETLT: Swap = true; [[fallthrough]];
6818 case ISD::SETGT: Opc = ARMCC::GT; break;
6819 case ISD::SETLE: Swap = true; [[fallthrough]];
6820 case ISD::SETGE: Opc = ARMCC::GE; break;
6821 case ISD::SETULT: Swap = true; [[fallthrough]];
6822 case ISD::SETUGT: Opc = ARMCC::HI; break;
6823 case ISD::SETULE: Swap = true; [[fallthrough]];
6824 case ISD::SETUGE: Opc = ARMCC::HS; break;
6825 }
6826
6827 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero).
6828 if (ST->hasNEON() && Opc == ARMCC::EQ) {
6829 SDValue AndOp;
6831 AndOp = Op0;
6832 else if (ISD::isBuildVectorAllZeros(Op0.getNode()))
6833 AndOp = Op1;
6834
6835 // Ignore bitconvert.
6836 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BITCAST)
6837 AndOp = AndOp.getOperand(0);
6838
6839 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
6840 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
6841 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
6842 SDValue Result = DAG.getNode(ARMISD::VTST, dl, CmpVT, Op0, Op1);
6843 if (!Invert)
6844 Result = DAG.getNOT(dl, Result, VT);
6845 return Result;
6846 }
6847 }
6848 }
6849
6850 if (Swap)
6851 std::swap(Op0, Op1);
6852
6853 // If one of the operands is a constant vector zero, attempt to fold the
6854 // comparison to a specialized compare-against-zero form.
6856 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::EQ ||
6857 Opc == ARMCC::NE)) {
6858 if (Opc == ARMCC::GE)
6859 Opc = ARMCC::LE;
6860 else if (Opc == ARMCC::GT)
6861 Opc = ARMCC::LT;
6862 std::swap(Op0, Op1);
6863 }
6864
6865 SDValue Result;
6867 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::LE ||
6868 Opc == ARMCC::LT || Opc == ARMCC::NE || Opc == ARMCC::EQ))
6869 Result = DAG.getNode(ARMISD::VCMPZ, dl, CmpVT, Op0,
6870 DAG.getConstant(Opc, dl, MVT::i32));
6871 else
6872 Result = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6873 DAG.getConstant(Opc, dl, MVT::i32));
6874
6875 Result = DAG.getSExtOrTrunc(Result, dl, VT);
6876
6877 if (Invert)
6878 Result = DAG.getNOT(dl, Result, VT);
6879
6880 return Result;
6881}
6882
6884 SDValue LHS = Op.getOperand(0);
6885 SDValue RHS = Op.getOperand(1);
6886
6887 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
6888
6889 SDValue Carry = Op.getOperand(2);
6890 SDValue Cond = Op.getOperand(3);
6891 SDLoc DL(Op);
6892
6893 // ARMISD::SUBE expects a carry not a borrow like ISD::USUBO_CARRY so we
6894 // have to invert the carry first.
6895 SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
6896
6897 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
6898 SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, InvCarry);
6899
6900 SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
6901 SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
6902 SDValue ARMcc = DAG.getConstant(
6903 IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
6904 return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
6905 Cmp.getValue(1));
6906}
6907
6908/// isVMOVModifiedImm - Check if the specified splat value corresponds to a
6909/// valid vector constant for a NEON or MVE instruction with a "modified
6910/// immediate" operand (e.g., VMOV). If so, return the encoded value.
6911static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
6912 unsigned SplatBitSize, SelectionDAG &DAG,
6913 const SDLoc &dl, EVT &VT, EVT VectorVT,
6914 VMOVModImmType type) {
6915 unsigned OpCmode, Imm;
6916 bool is128Bits = VectorVT.is128BitVector();
6917
6918 // SplatBitSize is set to the smallest size that splats the vector, so a
6919 // zero vector will always have SplatBitSize == 8. However, NEON modified
6920 // immediate instructions others than VMOV do not support the 8-bit encoding
6921 // of a zero vector, and the default encoding of zero is supposed to be the
6922 // 32-bit version.
6923 if (SplatBits == 0)
6924 SplatBitSize = 32;
6925
6926 switch (SplatBitSize) {
6927 case 8:
6928 if (type != VMOVModImm)
6929 return SDValue();
6930 // Any 1-byte value is OK. Op=0, Cmode=1110.
6931 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
6932 OpCmode = 0xe;
6933 Imm = SplatBits;
6934 VT = is128Bits ? MVT::v16i8 : MVT::v8i8;
6935 break;
6936
6937 case 16:
6938 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero.
6939 VT = is128Bits ? MVT::v8i16 : MVT::v4i16;
6940 if ((SplatBits & ~0xff) == 0) {
6941 // Value = 0x00nn: Op=x, Cmode=100x.
6942 OpCmode = 0x8;
6943 Imm = SplatBits;
6944 break;
6945 }
6946 if ((SplatBits & ~0xff00) == 0) {
6947 // Value = 0xnn00: Op=x, Cmode=101x.
6948 OpCmode = 0xa;
6949 Imm = SplatBits >> 8;
6950 break;
6951 }
6952 return SDValue();
6953
6954 case 32:
6955 // NEON's 32-bit VMOV supports splat values where:
6956 // * only one byte is nonzero, or
6957 // * the least significant byte is 0xff and the second byte is nonzero, or
6958 // * the least significant 2 bytes are 0xff and the third is nonzero.
6959 VT = is128Bits ? MVT::v4i32 : MVT::v2i32;
6960 if ((SplatBits & ~0xff) == 0) {
6961 // Value = 0x000000nn: Op=x, Cmode=000x.
6962 OpCmode = 0;
6963 Imm = SplatBits;
6964 break;
6965 }
6966 if ((SplatBits & ~0xff00) == 0) {
6967 // Value = 0x0000nn00: Op=x, Cmode=001x.
6968 OpCmode = 0x2;
6969 Imm = SplatBits >> 8;
6970 break;
6971 }
6972 if ((SplatBits & ~0xff0000) == 0) {
6973 // Value = 0x00nn0000: Op=x, Cmode=010x.
6974 OpCmode = 0x4;
6975 Imm = SplatBits >> 16;
6976 break;
6977 }
6978 if ((SplatBits & ~0xff000000) == 0) {
6979 // Value = 0xnn000000: Op=x, Cmode=011x.
6980 OpCmode = 0x6;
6981 Imm = SplatBits >> 24;
6982 break;
6983 }
6984
6985 // cmode == 0b1100 and cmode == 0b1101 are not supported for VORR or VBIC
6986 if (type == OtherModImm) return SDValue();
6987
6988 if ((SplatBits & ~0xffff) == 0 &&
6989 ((SplatBits | SplatUndef) & 0xff) == 0xff) {
6990 // Value = 0x0000nnff: Op=x, Cmode=1100.
6991 OpCmode = 0xc;
6992 Imm = SplatBits >> 8;
6993 break;
6994 }
6995
6996 // cmode == 0b1101 is not supported for MVE VMVN
6997 if (type == MVEVMVNModImm)
6998 return SDValue();
6999
7000 if ((SplatBits & ~0xffffff) == 0 &&
7001 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
7002 // Value = 0x00nnffff: Op=x, Cmode=1101.
7003 OpCmode = 0xd;
7004 Imm = SplatBits >> 16;
7005 break;
7006 }
7007
7008 // Note: there are a few 32-bit splat values (specifically: 00ffff00,
7009 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not
7010 // VMOV.I32. A (very) minor optimization would be to replicate the value
7011 // and fall through here to test for a valid 64-bit splat. But, then the
7012 // caller would also need to check and handle the change in size.
7013 return SDValue();
7014
7015 case 64: {
7016 if (type != VMOVModImm)
7017 return SDValue();
7018 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
7019 uint64_t BitMask = 0xff;
7020 unsigned ImmMask = 1;
7021 Imm = 0;
7022 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) {
7023 if (((SplatBits | SplatUndef) & BitMask) == BitMask) {
7024 Imm |= ImmMask;
7025 } else if ((SplatBits & BitMask) != 0) {
7026 return SDValue();
7027 }
7028 BitMask <<= 8;
7029 ImmMask <<= 1;
7030 }
7031
7032 // Op=1, Cmode=1110.
7033 OpCmode = 0x1e;
7034 VT = is128Bits ? MVT::v2i64 : MVT::v1i64;
7035 break;
7036 }
7037
7038 default:
7039 llvm_unreachable("unexpected size for isVMOVModifiedImm");
7040 }
7041
7042 unsigned EncodedVal = ARM_AM::createVMOVModImm(OpCmode, Imm);
7043 return DAG.getTargetConstant(EncodedVal, dl, MVT::i32);
7044}
7045
7046SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
7047 const ARMSubtarget *ST) const {
7048 EVT VT = Op.getValueType();
7049 bool IsDouble = (VT == MVT::f64);
7050 ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
7051 const APFloat &FPVal = CFP->getValueAPF();
7052
7053 // Prevent floating-point constants from using literal loads
7054 // when execute-only is enabled.
7055 if (ST->genExecuteOnly()) {
7056 // We shouldn't trigger this for v6m execute-only
7057 assert((!ST->isThumb1Only() || ST->hasV8MBaselineOps()) &&
7058 "Unexpected architecture");
7059
7060 // If we can represent the constant as an immediate, don't lower it
7061 if (isFPImmLegal(FPVal, VT))
7062 return Op;
7063 // Otherwise, construct as integer, and move to float register
7064 APInt INTVal = FPVal.bitcastToAPInt();
7065 SDLoc DL(CFP);
7066 switch (VT.getSimpleVT().SimpleTy) {
7067 default:
7068 llvm_unreachable("Unknown floating point type!");
7069 break;
7070 case MVT::f64: {
7071 SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);
7072 SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);
7073 return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);
7074 }
7075 case MVT::f32:
7076 return DAG.getNode(ARMISD::VMOVSR, DL, VT,
7077 DAG.getConstant(INTVal, DL, MVT::i32));
7078 }
7079 }
7080
7081 if (!ST->hasVFP3Base())
7082 return SDValue();
7083
7084 // Use the default (constant pool) lowering for double constants when we have
7085 // an SP-only FPU
7086 if (IsDouble && !Subtarget->hasFP64())
7087 return SDValue();
7088
7089 // Try splatting with a VMOV.f32...
7090 int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);
7091
7092 if (ImmVal != -1) {
7093 if (IsDouble || !ST->useNEONForSinglePrecisionFP()) {
7094 // We have code in place to select a valid ConstantFP already, no need to
7095 // do any mangling.
7096 return Op;
7097 }
7098
7099 // It's a float and we are trying to use NEON operations where
7100 // possible. Lower it to a splat followed by an extract.
7101 SDLoc DL(Op);
7102 SDValue NewVal = DAG.getTargetConstant(ImmVal, DL, MVT::i32);
7103 SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
7104 NewVal);
7105 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
7106 DAG.getConstant(0, DL, MVT::i32));
7107 }
7108
7109 // The rest of our options are NEON only, make sure that's allowed before
7110 // proceeding..
7111 if (!ST->hasNEON() || (!IsDouble && !ST->useNEONForSinglePrecisionFP()))
7112 return SDValue();
7113
7114 EVT VMovVT;
7115 uint64_t iVal = FPVal.bitcastToAPInt().getZExtValue();
7116
7117 // It wouldn't really be worth bothering for doubles except for one very
7118 // important value, which does happen to match: 0.0. So make sure we don't do
7119 // anything stupid.
7120 if (IsDouble && (iVal & 0xffffffff) != (iVal >> 32))
7121 return SDValue();
7122
7123 // Try a VMOV.i32 (FIXME: i8, i16, or i64 could work too).
7124 SDValue NewVal = isVMOVModifiedImm(iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op),
7125 VMovVT, VT, VMOVModImm);
7126 if (NewVal != SDValue()) {
7127 SDLoc DL(Op);
7128 SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
7129 NewVal);
7130 if (IsDouble)
7131 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7132
7133 // It's a float: cast and extract a vector element.
7134 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7135 VecConstant);
7136 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7137 DAG.getConstant(0, DL, MVT::i32));
7138 }
7139
7140 // Finally, try a VMVN.i32
7141 NewVal = isVMOVModifiedImm(~iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op), VMovVT,
7142 VT, VMVNModImm);
7143 if (NewVal != SDValue()) {
7144 SDLoc DL(Op);
7145 SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
7146
7147 if (IsDouble)
7148 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7149
7150 // It's a float: cast and extract a vector element.
7151 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7152 VecConstant);
7153 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7154 DAG.getConstant(0, DL, MVT::i32));
7155 }
7156
7157 return SDValue();
7158}
7159
7160// check if an VEXT instruction can handle the shuffle mask when the
7161// vector sources of the shuffle are the same.
7162static bool isSingletonVEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
7163 unsigned NumElts = VT.getVectorNumElements();
7164
7165 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7166 if (M[0] < 0)
7167 return false;
7168
7169 Imm = M[0];
7170
7171 // If this is a VEXT shuffle, the immediate value is the index of the first
7172 // element. The other shuffle indices must be the successive elements after
7173 // the first one.
7174 unsigned ExpectedElt = Imm;
7175 for (unsigned i = 1; i < NumElts; ++i) {
7176 // Increment the expected index. If it wraps around, just follow it
7177 // back to index zero and keep going.
7178 ++ExpectedElt;
7179 if (ExpectedElt == NumElts)
7180 ExpectedElt = 0;
7181
7182 if (M[i] < 0) continue; // ignore UNDEF indices
7183 if (ExpectedElt != static_cast<unsigned>(M[i]))
7184 return false;
7185 }
7186
7187 return true;
7188}
7189
7190static bool isVEXTMask(ArrayRef<int> M, EVT VT,
7191 bool &ReverseVEXT, unsigned &Imm) {
7192 unsigned NumElts = VT.getVectorNumElements();
7193 ReverseVEXT = false;
7194
7195 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7196 if (M[0] < 0)
7197 return false;
7198
7199 Imm = M[0];
7200
7201 // If this is a VEXT shuffle, the immediate value is the index of the first
7202 // element. The other shuffle indices must be the successive elements after
7203 // the first one.
7204 unsigned ExpectedElt = Imm;
7205 for (unsigned i = 1; i < NumElts; ++i) {
7206 // Increment the expected index. If it wraps around, it may still be
7207 // a VEXT but the source vectors must be swapped.
7208 ExpectedElt += 1;
7209 if (ExpectedElt == NumElts * 2) {
7210 ExpectedElt = 0;
7211 ReverseVEXT = true;
7212 }
7213
7214 if (M[i] < 0) continue; // ignore UNDEF indices
7215 if (ExpectedElt != static_cast<unsigned>(M[i]))
7216 return false;
7217 }
7218
7219 // Adjust the index value if the source operands will be swapped.
7220 if (ReverseVEXT)
7221 Imm -= NumElts;
7222
7223 return true;
7224}
7225
7226static bool isVTBLMask(ArrayRef<int> M, EVT VT) {
7227 // We can handle <8 x i8> vector shuffles. If the index in the mask is out of
7228 // range, then 0 is placed into the resulting vector. So pretty much any mask
7229 // of 8 elements can work here.
7230 return VT == MVT::v8i8 && M.size() == 8;
7231}
7232
7233/// Check if \p ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN),
7234/// and return the corresponding ARMISD opcode if it is, or 0 if it isn't.
7235static unsigned isNEONTwoResultShuffleMask(ArrayRef<int> ShuffleMask, EVT VT,
7236 unsigned &WhichResult,
7237 bool &isV_UNDEF) {
7238 isV_UNDEF = false;
7239 if (isVTRNMask(ShuffleMask, VT, WhichResult))
7240 return ARMISD::VTRN;
7241 if (isVUZPMask(ShuffleMask, VT, WhichResult))
7242 return ARMISD::VUZP;
7243 if (isVZIPMask(ShuffleMask, VT, WhichResult))
7244 return ARMISD::VZIP;
7245
7246 isV_UNDEF = true;
7247 if (isVTRN_v_undef_Mask(ShuffleMask, VT, WhichResult))
7248 return ARMISD::VTRN;
7249 if (isVUZP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7250 return ARMISD::VUZP;
7251 if (isVZIP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7252 return ARMISD::VZIP;
7253
7254 return 0;
7255}
7256
7257/// \return true if this is a reverse operation on an vector.
7258static bool isReverseMask(ArrayRef<int> M, EVT VT) {
7259 unsigned NumElts = VT.getVectorNumElements();
7260 // Make sure the mask has the right size.
7261 if (NumElts != M.size())
7262 return false;
7263
7264 // Look for <15, ..., 3, -1, 1, 0>.
7265 for (unsigned i = 0; i != NumElts; ++i)
7266 if (M[i] >= 0 && M[i] != (int) (NumElts - 1 - i))
7267 return false;
7268
7269 return true;
7270}
7271
7272static bool isTruncMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7273 unsigned NumElts = VT.getVectorNumElements();
7274 // Make sure the mask has the right size.
7275 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7276 return false;
7277
7278 // Half-width truncation patterns (e.g. v4i32 -> v8i16):
7279 // !Top && SingleSource: <0, 2, 4, 6, 0, 2, 4, 6>
7280 // !Top && !SingleSource: <0, 2, 4, 6, 8, 10, 12, 14>
7281 // Top && SingleSource: <1, 3, 5, 7, 1, 3, 5, 7>
7282 // Top && !SingleSource: <1, 3, 5, 7, 9, 11, 13, 15>
7283 int Ofs = Top ? 1 : 0;
7284 int Upper = SingleSource ? 0 : NumElts;
7285 for (int i = 0, e = NumElts / 2; i != e; ++i) {
7286 if (M[i] >= 0 && M[i] != (i * 2) + Ofs)
7287 return false;
7288 if (M[i + e] >= 0 && M[i + e] != (i * 2) + Ofs + Upper)
7289 return false;
7290 }
7291 return true;
7292}
7293
7294static bool isVMOVNMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7295 unsigned NumElts = VT.getVectorNumElements();
7296 // Make sure the mask has the right size.
7297 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7298 return false;
7299
7300 // If Top
7301 // Look for <0, N, 2, N+2, 4, N+4, ..>.
7302 // This inserts Input2 into Input1
7303 // else if not Top
7304 // Look for <0, N+1, 2, N+3, 4, N+5, ..>
7305 // This inserts Input1 into Input2
7306 unsigned Offset = Top ? 0 : 1;
7307 unsigned N = SingleSource ? 0 : NumElts;
7308 for (unsigned i = 0; i < NumElts; i += 2) {
7309 if (M[i] >= 0 && M[i] != (int)i)
7310 return false;
7311 if (M[i + 1] >= 0 && M[i + 1] != (int)(N + i + Offset))
7312 return false;
7313 }
7314
7315 return true;
7316}
7317
7318static bool isVMOVNTruncMask(ArrayRef<int> M, EVT ToVT, bool rev) {
7319 unsigned NumElts = ToVT.getVectorNumElements();
7320 if (NumElts != M.size())
7321 return false;
7322
7323 // Test if the Trunc can be convertible to a VMOVN with this shuffle. We are
7324 // looking for patterns of:
7325 // !rev: 0 N/2 1 N/2+1 2 N/2+2 ...
7326 // rev: N/2 0 N/2+1 1 N/2+2 2 ...
7327
7328 unsigned Off0 = rev ? NumElts / 2 : 0;
7329 unsigned Off1 = rev ? 0 : NumElts / 2;
7330 for (unsigned i = 0; i < NumElts; i += 2) {
7331 if (M[i] >= 0 && M[i] != (int)(Off0 + i / 2))
7332 return false;
7333 if (M[i + 1] >= 0 && M[i + 1] != (int)(Off1 + i / 2))
7334 return false;
7335 }
7336
7337 return true;
7338}
7339
7340// Reconstruct an MVE VCVT from a BuildVector of scalar fptrunc, all extracted
7341// from a pair of inputs. For example:
7342// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7343// FP_ROUND(EXTRACT_ELT(Y, 0),
7344// FP_ROUND(EXTRACT_ELT(X, 1),
7345// FP_ROUND(EXTRACT_ELT(Y, 1), ...)
7347 const ARMSubtarget *ST) {
7348 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7349 if (!ST->hasMVEFloatOps())
7350 return SDValue();
7351
7352 SDLoc dl(BV);
7353 EVT VT = BV.getValueType();
7354 if (VT != MVT::v8f16)
7355 return SDValue();
7356
7357 // We are looking for a buildvector of fptrunc elements, where all the
7358 // elements are interleavingly extracted from two sources. Check the first two
7359 // items are valid enough and extract some info from them (they are checked
7360 // properly in the loop below).
7361 if (BV.getOperand(0).getOpcode() != ISD::FP_ROUND ||
7364 return SDValue();
7365 if (BV.getOperand(1).getOpcode() != ISD::FP_ROUND ||
7368 return SDValue();
7369 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7370 SDValue Op1 = BV.getOperand(1).getOperand(0).getOperand(0);
7371 if (Op0.getValueType() != MVT::v4f32 || Op1.getValueType() != MVT::v4f32)
7372 return SDValue();
7373
7374 // Check all the values in the BuildVector line up with our expectations.
7375 for (unsigned i = 1; i < 4; i++) {
7376 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7377 return Trunc.getOpcode() == ISD::FP_ROUND &&
7379 Trunc.getOperand(0).getOperand(0) == Op &&
7380 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7381 };
7382 if (!Check(BV.getOperand(i * 2 + 0), Op0, i))
7383 return SDValue();
7384 if (!Check(BV.getOperand(i * 2 + 1), Op1, i))
7385 return SDValue();
7386 }
7387
7388 SDValue N1 = DAG.getNode(ARMISD::VCVTN, dl, VT, DAG.getUNDEF(VT), Op0,
7389 DAG.getConstant(0, dl, MVT::i32));
7390 return DAG.getNode(ARMISD::VCVTN, dl, VT, N1, Op1,
7391 DAG.getConstant(1, dl, MVT::i32));
7392}
7393
7394// Reconstruct an MVE VCVT from a BuildVector of scalar fpext, all extracted
7395// from a single input on alternating lanes. For example:
7396// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7397// FP_ROUND(EXTRACT_ELT(X, 2),
7398// FP_ROUND(EXTRACT_ELT(X, 4), ...)
7400 const ARMSubtarget *ST) {
7401 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7402 if (!ST->hasMVEFloatOps())
7403 return SDValue();
7404
7405 SDLoc dl(BV);
7406 EVT VT = BV.getValueType();
7407 if (VT != MVT::v4f32)
7408 return SDValue();
7409
7410 // We are looking for a buildvector of fptext elements, where all the
7411 // elements are alternating lanes from a single source. For example <0,2,4,6>
7412 // or <1,3,5,7>. Check the first two items are valid enough and extract some
7413 // info from them (they are checked properly in the loop below).
7414 if (BV.getOperand(0).getOpcode() != ISD::FP_EXTEND ||
7416 return SDValue();
7417 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7419 if (Op0.getValueType() != MVT::v8f16 || (Offset != 0 && Offset != 1))
7420 return SDValue();
7421
7422 // Check all the values in the BuildVector line up with our expectations.
7423 for (unsigned i = 1; i < 4; i++) {
7424 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7425 return Trunc.getOpcode() == ISD::FP_EXTEND &&
7427 Trunc.getOperand(0).getOperand(0) == Op &&
7428 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7429 };
7430 if (!Check(BV.getOperand(i), Op0, 2 * i + Offset))
7431 return SDValue();
7432 }
7433
7434 return DAG.getNode(ARMISD::VCVTL, dl, VT, Op0,
7435 DAG.getConstant(Offset, dl, MVT::i32));
7436}
7437
7438// If N is an integer constant that can be moved into a register in one
7439// instruction, return an SDValue of such a constant (will become a MOV
7440// instruction). Otherwise return null.
7442 const ARMSubtarget *ST, const SDLoc &dl) {
7443 uint64_t Val;
7444 if (!isa<ConstantSDNode>(N))
7445 return SDValue();
7446 Val = N->getAsZExtVal();
7447
7448 if (ST->isThumb1Only()) {
7449 if (Val <= 255 || ~Val <= 255)
7450 return DAG.getConstant(Val, dl, MVT::i32);
7451 } else {
7452 if (ARM_AM::getSOImmVal(Val) != -1 || ARM_AM::getSOImmVal(~Val) != -1)
7453 return DAG.getConstant(Val, dl, MVT::i32);
7454 }
7455 return SDValue();
7456}
7457
7459 const ARMSubtarget *ST) {
7460 SDLoc dl(Op);
7461 EVT VT = Op.getValueType();
7462
7463 assert(ST->hasMVEIntegerOps() && "LowerBUILD_VECTOR_i1 called without MVE!");
7464
7465 unsigned NumElts = VT.getVectorNumElements();
7466 unsigned BoolMask;
7467 unsigned BitsPerBool;
7468 if (NumElts == 2) {
7469 BitsPerBool = 8;
7470 BoolMask = 0xff;
7471 } else if (NumElts == 4) {
7472 BitsPerBool = 4;
7473 BoolMask = 0xf;
7474 } else if (NumElts == 8) {
7475 BitsPerBool = 2;
7476 BoolMask = 0x3;
7477 } else if (NumElts == 16) {
7478 BitsPerBool = 1;
7479 BoolMask = 0x1;
7480 } else
7481 return SDValue();
7482
7483 // If this is a single value copied into all lanes (a splat), we can just sign
7484 // extend that single value
7485 SDValue FirstOp = Op.getOperand(0);
7486 if (!isa<ConstantSDNode>(FirstOp) &&
7487 llvm::all_of(llvm::drop_begin(Op->ops()), [&FirstOp](const SDUse &U) {
7488 return U.get().isUndef() || U.get() == FirstOp;
7489 })) {
7490 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
7491 DAG.getValueType(MVT::i1));
7492 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
7493 }
7494
7495 // First create base with bits set where known
7496 unsigned Bits32 = 0;
7497 for (unsigned i = 0; i < NumElts; ++i) {
7498 SDValue V = Op.getOperand(i);
7499 if (!isa<ConstantSDNode>(V) && !V.isUndef())
7500 continue;
7501 bool BitSet = V.isUndef() ? false : V->getAsZExtVal();
7502 if (BitSet)
7503 Bits32 |= BoolMask << (i * BitsPerBool);
7504 }
7505
7506 // Add in unknown nodes
7507 SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
7508 DAG.getConstant(Bits32, dl, MVT::i32));
7509 for (unsigned i = 0; i < NumElts; ++i) {
7510 SDValue V = Op.getOperand(i);
7511 if (isa<ConstantSDNode>(V) || V.isUndef())
7512 continue;
7513 Base = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Base, V,
7514 DAG.getConstant(i, dl, MVT::i32));
7515 }
7516
7517 return Base;
7518}
7519
7521 const ARMSubtarget *ST) {
7522 if (!ST->hasMVEIntegerOps())
7523 return SDValue();
7524
7525 // We are looking for a buildvector where each element is Op[0] + i*N
7526 EVT VT = Op.getValueType();
7527 SDValue Op0 = Op.getOperand(0);
7528 unsigned NumElts = VT.getVectorNumElements();
7529
7530 // Get the increment value from operand 1
7531 SDValue Op1 = Op.getOperand(1);
7532 if (Op1.getOpcode() != ISD::ADD || Op1.getOperand(0) != Op0 ||
7534 return SDValue();
7535 unsigned N = Op1.getConstantOperandVal(1);
7536 if (N != 1 && N != 2 && N != 4 && N != 8)
7537 return SDValue();
7538
7539 // Check that each other operand matches
7540 for (unsigned I = 2; I < NumElts; I++) {
7541 SDValue OpI = Op.getOperand(I);
7542 if (OpI.getOpcode() != ISD::ADD || OpI.getOperand(0) != Op0 ||
7544 OpI.getConstantOperandVal(1) != I * N)
7545 return SDValue();
7546 }
7547
7548 SDLoc DL(Op);
7549 return DAG.getNode(ARMISD::VIDUP, DL, DAG.getVTList(VT, MVT::i32), Op0,
7550 DAG.getConstant(N, DL, MVT::i32));
7551}
7552
7553// Returns true if the operation N can be treated as qr instruction variant at
7554// operand Op.
7555static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op) {
7556 switch (N->getOpcode()) {
7557 case ISD::ADD:
7558 case ISD::MUL:
7559 case ISD::SADDSAT:
7560 case ISD::UADDSAT:
7561 case ISD::AVGFLOORS:
7562 case ISD::AVGFLOORU:
7563 return true;
7564 case ISD::SUB:
7565 case ISD::SSUBSAT:
7566 case ISD::USUBSAT:
7567 return N->getOperand(1).getNode() == Op;
7569 switch (N->getConstantOperandVal(0)) {
7570 case Intrinsic::arm_mve_add_predicated:
7571 case Intrinsic::arm_mve_mul_predicated:
7572 case Intrinsic::arm_mve_qadd_predicated:
7573 case Intrinsic::arm_mve_vhadd:
7574 case Intrinsic::arm_mve_hadd_predicated:
7575 case Intrinsic::arm_mve_vqdmulh:
7576 case Intrinsic::arm_mve_qdmulh_predicated:
7577 case Intrinsic::arm_mve_vqrdmulh:
7578 case Intrinsic::arm_mve_qrdmulh_predicated:
7579 case Intrinsic::arm_mve_vqdmull:
7580 case Intrinsic::arm_mve_vqdmull_predicated:
7581 return true;
7582 case Intrinsic::arm_mve_sub_predicated:
7583 case Intrinsic::arm_mve_qsub_predicated:
7584 case Intrinsic::arm_mve_vhsub:
7585 case Intrinsic::arm_mve_hsub_predicated:
7586 return N->getOperand(2).getNode() == Op;
7587 default:
7588 return false;
7589 }
7590 default:
7591 return false;
7592 }
7593}
7594
7595// If this is a case we can't handle, return null and let the default
7596// expansion code take care of it.
7597SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
7598 const ARMSubtarget *ST) const {
7599 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode());
7600 SDLoc dl(Op);
7601 EVT VT = Op.getValueType();
7602
7603 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
7604 return LowerBUILD_VECTOR_i1(Op, DAG, ST);
7605
7606 if (SDValue R = LowerBUILD_VECTORToVIDUP(Op, DAG, ST))
7607 return R;
7608
7609 APInt SplatBits, SplatUndef;
7610 unsigned SplatBitSize;
7611 bool HasAnyUndefs;
7612 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
7613 if (SplatUndef.isAllOnes())
7614 return DAG.getUNDEF(VT);
7615
7616 // If all the users of this constant splat are qr instruction variants,
7617 // generate a vdup of the constant.
7618 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == SplatBitSize &&
7619 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32) &&
7620 all_of(BVN->users(),
7621 [BVN](const SDNode *U) { return IsQRMVEInstruction(U, BVN); })) {
7622 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7623 : SplatBitSize == 16 ? MVT::v8i16
7624 : MVT::v16i8;
7625 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7626 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7627 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7628 }
7629
7630 if ((ST->hasNEON() && SplatBitSize <= 64) ||
7631 (ST->hasMVEIntegerOps() && SplatBitSize <= 64)) {
7632 // Check if an immediate VMOV works.
7633 EVT VmovVT;
7634 SDValue Val =
7635 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
7636 SplatBitSize, DAG, dl, VmovVT, VT, VMOVModImm);
7637
7638 if (Val.getNode()) {
7639 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, Val);
7640 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7641 }
7642
7643 // Try an immediate VMVN.
7644 uint64_t NegatedImm = (~SplatBits).getZExtValue();
7645 Val = isVMOVModifiedImm(
7646 NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, dl, VmovVT,
7647 VT, ST->hasMVEIntegerOps() ? MVEVMVNModImm : VMVNModImm);
7648 if (Val.getNode()) {
7649 SDValue Vmov = DAG.getNode(ARMISD::VMVNIMM, dl, VmovVT, Val);
7650 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7651 }
7652
7653 // Use vmov.f32 to materialize other v2f32 and v4f32 splats.
7654 if ((VT == MVT::v2f32 || VT == MVT::v4f32) && SplatBitSize == 32) {
7655 int ImmVal = ARM_AM::getFP32Imm(SplatBits);
7656 if (ImmVal != -1) {
7657 SDValue Val = DAG.getTargetConstant(ImmVal, dl, MVT::i32);
7658 return DAG.getNode(ARMISD::VMOVFPIMM, dl, VT, Val);
7659 }
7660 }
7661
7662 // If we are under MVE, generate a VDUP(constant), bitcast to the original
7663 // type.
7664 if (ST->hasMVEIntegerOps() &&
7665 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32)) {
7666 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7667 : SplatBitSize == 16 ? MVT::v8i16
7668 : MVT::v16i8;
7669 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7670 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7671 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7672 }
7673 }
7674 }
7675
7676 // Scan through the operands to see if only one value is used.
7677 //
7678 // As an optimisation, even if more than one value is used it may be more
7679 // profitable to splat with one value then change some lanes.
7680 //
7681 // Heuristically we decide to do this if the vector has a "dominant" value,
7682 // defined as splatted to more than half of the lanes.
7683 unsigned NumElts = VT.getVectorNumElements();
7684 bool isOnlyLowElement = true;
7685 bool usesOnlyOneValue = true;
7686 bool hasDominantValue = false;
7687 bool isConstant = true;
7688
7689 // Map of the number of times a particular SDValue appears in the
7690 // element list.
7691 DenseMap<SDValue, unsigned> ValueCounts;
7692 SDValue Value;
7693 for (unsigned i = 0; i < NumElts; ++i) {
7694 SDValue V = Op.getOperand(i);
7695 if (V.isUndef())
7696 continue;
7697 if (i > 0)
7698 isOnlyLowElement = false;
7700 isConstant = false;
7701
7702 unsigned &Count = ValueCounts[V];
7703
7704 // Is this value dominant? (takes up more than half of the lanes)
7705 if (++Count > (NumElts / 2)) {
7706 hasDominantValue = true;
7707 Value = V;
7708 }
7709 }
7710 if (ValueCounts.size() != 1)
7711 usesOnlyOneValue = false;
7712 if (!Value.getNode() && !ValueCounts.empty())
7713 Value = ValueCounts.begin()->first;
7714
7715 if (ValueCounts.empty())
7716 return DAG.getUNDEF(VT);
7717
7718 // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
7719 // Keep going if we are hitting this case.
7720 if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()) &&
7721 (VT != MVT::v8f16 || ST->hasFullFP16()))
7722 return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
7723
7724 unsigned EltSize = VT.getScalarSizeInBits();
7725
7726 // Use VDUP for non-constant splats. For f32 constant splats, reduce to
7727 // i32 and try again.
7728 if (hasDominantValue && EltSize <= 32) {
7729 if (!isConstant) {
7730 SDValue N;
7731
7732 // If we are VDUPing a value that comes directly from a vector, that will
7733 // cause an unnecessary move to and from a GPR, where instead we could
7734 // just use VDUPLANE. We can only do this if the lane being extracted
7735 // is at a constant index, as the VDUP from lane instructions only have
7736 // constant-index forms.
7737 ConstantSDNode *constIndex;
7738 if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7739 (constIndex = dyn_cast<ConstantSDNode>(Value->getOperand(1)))) {
7740 // We need to create a new undef vector to use for the VDUPLANE if the
7741 // size of the vector from which we get the value is different than the
7742 // size of the vector that we need to create. We will insert the element
7743 // such that the register coalescer will remove unnecessary copies.
7744 if (VT != Value->getOperand(0).getValueType()) {
7745 unsigned index = constIndex->getAPIntValue().getLimitedValue() %
7747 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7748 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DAG.getUNDEF(VT),
7749 Value, DAG.getConstant(index, dl, MVT::i32)),
7750 DAG.getConstant(index, dl, MVT::i32));
7751 } else
7752 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7753 Value->getOperand(0), Value->getOperand(1));
7754 } else
7755 N = DAG.getNode(ARMISD::VDUP, dl, VT, Value);
7756
7757 if (!usesOnlyOneValue) {
7758 // The dominant value was splatted as 'N', but we now have to insert
7759 // all differing elements.
7760 for (unsigned I = 0; I < NumElts; ++I) {
7761 if (Op.getOperand(I) == Value)
7762 continue;
7764 Ops.push_back(N);
7765 Ops.push_back(Op.getOperand(I));
7766 Ops.push_back(DAG.getConstant(I, dl, MVT::i32));
7767 N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ops);
7768 }
7769 }
7770 return N;
7771 }
7774 MVT FVT = VT.getVectorElementType().getSimpleVT();
7775 assert(FVT == MVT::f32 || FVT == MVT::f16);
7776 MVT IVT = (FVT == MVT::f32) ? MVT::i32 : MVT::i16;
7777 for (unsigned i = 0; i < NumElts; ++i)
7778 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, IVT,
7779 Op.getOperand(i)));
7780 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), IVT, NumElts);
7781 SDValue Val = DAG.getBuildVector(VecVT, dl, Ops);
7782 Val = LowerBUILD_VECTOR(Val, DAG, ST);
7783 if (Val.getNode())
7784 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7785 }
7786 if (usesOnlyOneValue) {
7787 SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl);
7788 if (isConstant && Val.getNode())
7789 return DAG.getNode(ARMISD::VDUP, dl, VT, Val);
7790 }
7791 }
7792
7793 // If all elements are constants and the case above didn't get hit, fall back
7794 // to the default expansion, which will generate a load from the constant
7795 // pool.
7796 if (isConstant)
7797 return SDValue();
7798
7799 // Reconstruct the BUILDVECTOR to one of the legal shuffles (such as vext and
7800 // vmovn). Empirical tests suggest this is rarely worth it for vectors of
7801 // length <= 2.
7802 if (NumElts >= 4)
7803 if (SDValue shuffle = ReconstructShuffle(Op, DAG))
7804 return shuffle;
7805
7806 // Attempt to turn a buildvector of scalar fptrunc's or fpext's back into
7807 // VCVT's
7808 if (SDValue VCVT = LowerBuildVectorOfFPTrunc(Op, DAG, Subtarget))
7809 return VCVT;
7810 if (SDValue VCVT = LowerBuildVectorOfFPExt(Op, DAG, Subtarget))
7811 return VCVT;
7812
7813 if (ST->hasNEON() && VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
7814 // If we haven't found an efficient lowering, try splitting a 128-bit vector
7815 // into two 64-bit vectors; we might discover a better way to lower it.
7816 SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
7817 EVT ExtVT = VT.getVectorElementType();
7818 EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
7819 SDValue Lower = DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[0], NumElts / 2));
7820 if (Lower.getOpcode() == ISD::BUILD_VECTOR)
7821 Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
7822 SDValue Upper =
7823 DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[NumElts / 2], NumElts / 2));
7824 if (Upper.getOpcode() == ISD::BUILD_VECTOR)
7825 Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
7826 if (Lower && Upper)
7827 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
7828 }
7829
7830 // Vectors with 32- or 64-bit elements can be built by directly assigning
7831 // the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
7832 // will be legalized.
7833 if (EltSize >= 32) {
7834 // Do the expansion with floating-point types, since that is what the VFP
7835 // registers are defined to use, and since i64 is not legal.
7836 EVT EltVT = EVT::getFloatingPointVT(EltSize);
7837 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
7839 for (unsigned i = 0; i < NumElts; ++i)
7840 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, EltVT, Op.getOperand(i)));
7841 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
7842 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7843 }
7844
7845 // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
7846 // know the default expansion would otherwise fall back on something even
7847 // worse. For a vector with one or two non-undef values, that's
7848 // scalar_to_vector for the elements followed by a shuffle (provided the
7849 // shuffle is valid for the target) and materialization element by element
7850 // on the stack followed by a load for everything else.
7851 if ((!isConstant && !usesOnlyOneValue) ||
7852 (VT == MVT::v8f16 && !ST->hasFullFP16())) {
7853 SDValue Vec = DAG.getUNDEF(VT);
7854 for (unsigned i = 0 ; i < NumElts; ++i) {
7855 SDValue V = Op.getOperand(i);
7856 if (V.isUndef())
7857 continue;
7858 SDValue LaneIdx = DAG.getConstant(i, dl, MVT::i32);
7859 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
7860 }
7861 return Vec;
7862 }
7863
7864 return SDValue();
7865}
7866
7867// Gather data to see if the operation can be modelled as a
7868// shuffle in combination with VEXTs.
7869SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
7870 SelectionDAG &DAG) const {
7871 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7872 SDLoc dl(Op);
7873 EVT VT = Op.getValueType();
7874 unsigned NumElts = VT.getVectorNumElements();
7875
7876 struct ShuffleSourceInfo {
7877 SDValue Vec;
7878 unsigned MinElt = std::numeric_limits<unsigned>::max();
7879 unsigned MaxElt = 0;
7880
7881 // We may insert some combination of BITCASTs and VEXT nodes to force Vec to
7882 // be compatible with the shuffle we intend to construct. As a result
7883 // ShuffleVec will be some sliding window into the original Vec.
7884 SDValue ShuffleVec;
7885
7886 // Code should guarantee that element i in Vec starts at element "WindowBase
7887 // + i * WindowScale in ShuffleVec".
7888 int WindowBase = 0;
7889 int WindowScale = 1;
7890
7891 ShuffleSourceInfo(SDValue Vec) : Vec(Vec), ShuffleVec(Vec) {}
7892
7893 bool operator ==(SDValue OtherVec) { return Vec == OtherVec; }
7894 };
7895
7896 // First gather all vectors used as an immediate source for this BUILD_VECTOR
7897 // node.
7899 for (unsigned i = 0; i < NumElts; ++i) {
7900 SDValue V = Op.getOperand(i);
7901 if (V.isUndef())
7902 continue;
7903 else if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
7904 // A shuffle can only come from building a vector from various
7905 // elements of other vectors.
7906 return SDValue();
7907 } else if (!isa<ConstantSDNode>(V.getOperand(1))) {
7908 // Furthermore, shuffles require a constant mask, whereas extractelts
7909 // accept variable indices.
7910 return SDValue();
7911 }
7912
7913 // Add this element source to the list if it's not already there.
7914 SDValue SourceVec = V.getOperand(0);
7915 auto Source = llvm::find(Sources, SourceVec);
7916 if (Source == Sources.end())
7917 Source = Sources.insert(Sources.end(), ShuffleSourceInfo(SourceVec));
7918
7919 // Update the minimum and maximum lane number seen.
7920 unsigned EltNo = V.getConstantOperandVal(1);
7921 Source->MinElt = std::min(Source->MinElt, EltNo);
7922 Source->MaxElt = std::max(Source->MaxElt, EltNo);
7923 }
7924
7925 // Currently only do something sane when at most two source vectors
7926 // are involved.
7927 if (Sources.size() > 2)
7928 return SDValue();
7929
7930 // Find out the smallest element size among result and two sources, and use
7931 // it as element size to build the shuffle_vector.
7932 EVT SmallestEltTy = VT.getVectorElementType();
7933 for (auto &Source : Sources) {
7934 EVT SrcEltTy = Source.Vec.getValueType().getVectorElementType();
7935 if (SrcEltTy.bitsLT(SmallestEltTy))
7936 SmallestEltTy = SrcEltTy;
7937 }
7938 unsigned ResMultiplier =
7939 VT.getScalarSizeInBits() / SmallestEltTy.getSizeInBits();
7940 NumElts = VT.getSizeInBits() / SmallestEltTy.getSizeInBits();
7941 EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
7942
7943 // If the source vector is too wide or too narrow, we may nevertheless be able
7944 // to construct a compatible shuffle either by concatenating it with UNDEF or
7945 // extracting a suitable range of elements.
7946 for (auto &Src : Sources) {
7947 EVT SrcVT = Src.ShuffleVec.getValueType();
7948
7949 uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
7950 uint64_t VTSize = VT.getFixedSizeInBits();
7951 if (SrcVTSize == VTSize)
7952 continue;
7953
7954 // This stage of the search produces a source with the same element type as
7955 // the original, but with a total width matching the BUILD_VECTOR output.
7956 EVT EltVT = SrcVT.getVectorElementType();
7957 unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
7958 EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
7959
7960 if (SrcVTSize < VTSize) {
7961 if (2 * SrcVTSize != VTSize)
7962 return SDValue();
7963 // We can pad out the smaller vector for free, so if it's part of a
7964 // shuffle...
7965 Src.ShuffleVec =
7966 DAG.getNode(ISD::CONCAT_VECTORS, dl, DestVT, Src.ShuffleVec,
7967 DAG.getUNDEF(Src.ShuffleVec.getValueType()));
7968 continue;
7969 }
7970
7971 if (SrcVTSize != 2 * VTSize)
7972 return SDValue();
7973
7974 if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
7975 // Span too large for a VEXT to cope
7976 return SDValue();
7977 }
7978
7979 if (Src.MinElt >= NumSrcElts) {
7980 // The extraction can just take the second half
7981 Src.ShuffleVec =
7982 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
7983 DAG.getConstant(NumSrcElts, dl, MVT::i32));
7984 Src.WindowBase = -NumSrcElts;
7985 } else if (Src.MaxElt < NumSrcElts) {
7986 // The extraction can just take the first half
7987 Src.ShuffleVec =
7988 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
7989 DAG.getConstant(0, dl, MVT::i32));
7990 } else {
7991 // An actual VEXT is needed
7992 SDValue VEXTSrc1 =
7993 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
7994 DAG.getConstant(0, dl, MVT::i32));
7995 SDValue VEXTSrc2 =
7996 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
7997 DAG.getConstant(NumSrcElts, dl, MVT::i32));
7998
7999 Src.ShuffleVec = DAG.getNode(ARMISD::VEXT, dl, DestVT, VEXTSrc1,
8000 VEXTSrc2,
8001 DAG.getConstant(Src.MinElt, dl, MVT::i32));
8002 Src.WindowBase = -Src.MinElt;
8003 }
8004 }
8005
8006 // Another possible incompatibility occurs from the vector element types. We
8007 // can fix this by bitcasting the source vectors to the same type we intend
8008 // for the shuffle.
8009 for (auto &Src : Sources) {
8010 EVT SrcEltTy = Src.ShuffleVec.getValueType().getVectorElementType();
8011 if (SrcEltTy == SmallestEltTy)
8012 continue;
8013 assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
8014 Src.ShuffleVec = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, ShuffleVT, Src.ShuffleVec);
8015 Src.WindowScale = SrcEltTy.getSizeInBits() / SmallestEltTy.getSizeInBits();
8016 Src.WindowBase *= Src.WindowScale;
8017 }
8018
8019 // Final check before we try to actually produce a shuffle.
8020 LLVM_DEBUG({
8021 for (auto Src : Sources)
8022 assert(Src.ShuffleVec.getValueType() == ShuffleVT);
8023 });
8024
8025 // The stars all align, our next step is to produce the mask for the shuffle.
8026 SmallVector<int, 8> Mask(ShuffleVT.getVectorNumElements(), -1);
8027 int BitsPerShuffleLane = ShuffleVT.getScalarSizeInBits();
8028 for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
8029 SDValue Entry = Op.getOperand(i);
8030 if (Entry.isUndef())
8031 continue;
8032
8033 auto Src = llvm::find(Sources, Entry.getOperand(0));
8034 int EltNo = cast<ConstantSDNode>(Entry.getOperand(1))->getSExtValue();
8035
8036 // EXTRACT_VECTOR_ELT performs an implicit any_ext; BUILD_VECTOR an implicit
8037 // trunc. So only std::min(SrcBits, DestBits) actually get defined in this
8038 // segment.
8039 EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
8040 int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
8041 VT.getScalarSizeInBits());
8042 int LanesDefined = BitsDefined / BitsPerShuffleLane;
8043
8044 // This source is expected to fill ResMultiplier lanes of the final shuffle,
8045 // starting at the appropriate offset.
8046 int *LaneMask = &Mask[i * ResMultiplier];
8047
8048 int ExtractBase = EltNo * Src->WindowScale + Src->WindowBase;
8049 ExtractBase += NumElts * (Src - Sources.begin());
8050 for (int j = 0; j < LanesDefined; ++j)
8051 LaneMask[j] = ExtractBase + j;
8052 }
8053
8054
8055 // We can't handle more than two sources. This should have already
8056 // been checked before this point.
8057 assert(Sources.size() <= 2 && "Too many sources!");
8058
8059 SDValue ShuffleOps[] = { DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT) };
8060 for (unsigned i = 0; i < Sources.size(); ++i)
8061 ShuffleOps[i] = Sources[i].ShuffleVec;
8062
8063 SDValue Shuffle = buildLegalVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
8064 ShuffleOps[1], Mask, DAG);
8065 if (!Shuffle)
8066 return SDValue();
8067 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuffle);
8068}
8069
8071 OP_COPY = 0, // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
8080 OP_VUZPL, // VUZP, left result
8081 OP_VUZPR, // VUZP, right result
8082 OP_VZIPL, // VZIP, left result
8083 OP_VZIPR, // VZIP, right result
8084 OP_VTRNL, // VTRN, left result
8085 OP_VTRNR // VTRN, right result
8086};
8087
8088static bool isLegalMVEShuffleOp(unsigned PFEntry) {
8089 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8090 switch (OpNum) {
8091 case OP_COPY:
8092 case OP_VREV:
8093 case OP_VDUP0:
8094 case OP_VDUP1:
8095 case OP_VDUP2:
8096 case OP_VDUP3:
8097 return true;
8098 }
8099 return false;
8100}
8101
8102/// isShuffleMaskLegal - Targets can use this to indicate that they only
8103/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
8104/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
8105/// are assumed to be legal.
8107 if (VT.getVectorNumElements() == 4 &&
8108 (VT.is128BitVector() || VT.is64BitVector())) {
8109 unsigned PFIndexes[4];
8110 for (unsigned i = 0; i != 4; ++i) {
8111 if (M[i] < 0)
8112 PFIndexes[i] = 8;
8113 else
8114 PFIndexes[i] = M[i];
8115 }
8116
8117 // Compute the index in the perfect shuffle table.
8118 unsigned PFTableIndex =
8119 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8120 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8121 unsigned Cost = (PFEntry >> 30);
8122
8123 if (Cost <= 4 && (Subtarget->hasNEON() || isLegalMVEShuffleOp(PFEntry)))
8124 return true;
8125 }
8126
8127 bool ReverseVEXT, isV_UNDEF;
8128 unsigned Imm, WhichResult;
8129
8130 unsigned EltSize = VT.getScalarSizeInBits();
8131 if (EltSize >= 32 ||
8133 ShuffleVectorInst::isIdentityMask(M, M.size()) ||
8134 isVREVMask(M, VT, 64) ||
8135 isVREVMask(M, VT, 32) ||
8136 isVREVMask(M, VT, 16))
8137 return true;
8138 else if (Subtarget->hasNEON() &&
8139 (isVEXTMask(M, VT, ReverseVEXT, Imm) ||
8140 isVTBLMask(M, VT) ||
8141 isNEONTwoResultShuffleMask(M, VT, WhichResult, isV_UNDEF)))
8142 return true;
8143 else if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8144 isReverseMask(M, VT))
8145 return true;
8146 else if (Subtarget->hasMVEIntegerOps() &&
8147 (isVMOVNMask(M, VT, true, false) ||
8148 isVMOVNMask(M, VT, false, false) || isVMOVNMask(M, VT, true, true)))
8149 return true;
8150 else if (Subtarget->hasMVEIntegerOps() &&
8151 (isTruncMask(M, VT, false, false) ||
8152 isTruncMask(M, VT, false, true) ||
8153 isTruncMask(M, VT, true, false) || isTruncMask(M, VT, true, true)))
8154 return true;
8155 else
8156 return false;
8157}
8158
8159/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
8160/// the specified operations to build the shuffle.
8162 SDValue RHS, SelectionDAG &DAG,
8163 const SDLoc &dl) {
8164 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8165 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8166 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8167
8168 if (OpNum == OP_COPY) {
8169 if (LHSID == (1*9+2)*9+3) return LHS;
8170 assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
8171 return RHS;
8172 }
8173
8174 SDValue OpLHS, OpRHS;
8175 OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
8176 OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);
8177 EVT VT = OpLHS.getValueType();
8178
8179 switch (OpNum) {
8180 default: llvm_unreachable("Unknown shuffle opcode!");
8181 case OP_VREV:
8182 // VREV divides the vector in half and swaps within the half.
8183 if (VT.getScalarSizeInBits() == 32)
8184 return DAG.getNode(ARMISD::VREV64, dl, VT, OpLHS);
8185 // vrev <4 x i16> -> VREV32
8186 if (VT.getScalarSizeInBits() == 16)
8187 return DAG.getNode(ARMISD::VREV32, dl, VT, OpLHS);
8188 // vrev <4 x i8> -> VREV16
8189 assert(VT.getScalarSizeInBits() == 8);
8190 return DAG.getNode(ARMISD::VREV16, dl, VT, OpLHS);
8191 case OP_VDUP0:
8192 case OP_VDUP1:
8193 case OP_VDUP2:
8194 case OP_VDUP3:
8195 return DAG.getNode(ARMISD::VDUPLANE, dl, VT,
8196 OpLHS, DAG.getConstant(OpNum-OP_VDUP0, dl, MVT::i32));
8197 case OP_VEXT1:
8198 case OP_VEXT2:
8199 case OP_VEXT3:
8200 return DAG.getNode(ARMISD::VEXT, dl, VT,
8201 OpLHS, OpRHS,
8202 DAG.getConstant(OpNum - OP_VEXT1 + 1, dl, MVT::i32));
8203 case OP_VUZPL:
8204 case OP_VUZPR:
8205 return DAG.getNode(ARMISD::VUZP, dl, DAG.getVTList(VT, VT),
8206 OpLHS, OpRHS).getValue(OpNum-OP_VUZPL);
8207 case OP_VZIPL:
8208 case OP_VZIPR:
8209 return DAG.getNode(ARMISD::VZIP, dl, DAG.getVTList(VT, VT),
8210 OpLHS, OpRHS).getValue(OpNum-OP_VZIPL);
8211 case OP_VTRNL:
8212 case OP_VTRNR:
8213 return DAG.getNode(ARMISD::VTRN, dl, DAG.getVTList(VT, VT),
8214 OpLHS, OpRHS).getValue(OpNum-OP_VTRNL);
8215 }
8216}
8217
8219 ArrayRef<int> ShuffleMask,
8220 SelectionDAG &DAG) {
8221 // Check to see if we can use the VTBL instruction.
8222 SDValue V1 = Op.getOperand(0);
8223 SDValue V2 = Op.getOperand(1);
8224 SDLoc DL(Op);
8225
8226 SmallVector<SDValue, 8> VTBLMask;
8227 for (int I : ShuffleMask)
8228 VTBLMask.push_back(DAG.getSignedConstant(I, DL, MVT::i32));
8229
8230 if (V2.getNode()->isUndef())
8231 return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1,
8232 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8233
8234 return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2,
8235 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8236}
8237
8239 SDLoc DL(Op);
8240 EVT VT = Op.getValueType();
8241
8242 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8243 "Expect an v8i16/v16i8 type");
8244 SDValue OpLHS = DAG.getNode(ARMISD::VREV64, DL, VT, Op.getOperand(0));
8245 // For a v16i8 type: After the VREV, we have got <7, ..., 0, 15, ..., 8>. Now,
8246 // extract the first 8 bytes into the top double word and the last 8 bytes
8247 // into the bottom double word, through a new vector shuffle that will be
8248 // turned into a VEXT on Neon, or a couple of VMOVDs on MVE.
8249 std::vector<int> NewMask;
8250 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8251 NewMask.push_back(VT.getVectorNumElements() / 2 + i);
8252 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8253 NewMask.push_back(i);
8254 return DAG.getVectorShuffle(VT, DL, OpLHS, OpLHS, NewMask);
8255}
8256
8258 switch (VT.getSimpleVT().SimpleTy) {
8259 case MVT::v2i1:
8260 return MVT::v2f64;
8261 case MVT::v4i1:
8262 return MVT::v4i32;
8263 case MVT::v8i1:
8264 return MVT::v8i16;
8265 case MVT::v16i1:
8266 return MVT::v16i8;
8267 default:
8268 llvm_unreachable("Unexpected vector predicate type");
8269 }
8270}
8271
8273 SelectionDAG &DAG) {
8274 // Converting from boolean predicates to integers involves creating a vector
8275 // of all ones or all zeroes and selecting the lanes based upon the real
8276 // predicate.
8278 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff), dl, MVT::i32);
8279 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllOnes);
8280
8281 SDValue AllZeroes =
8282 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0x0), dl, MVT::i32);
8283 AllZeroes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllZeroes);
8284
8285 // Get full vector type from predicate type
8287
8288 SDValue RecastV1;
8289 // If the real predicate is an v8i1 or v4i1 (not v16i1) then we need to recast
8290 // this to a v16i1. This cannot be done with an ordinary bitcast because the
8291 // sizes are not the same. We have to use a MVE specific PREDICATE_CAST node,
8292 // since we know in hardware the sizes are really the same.
8293 if (VT != MVT::v16i1)
8294 RecastV1 = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Pred);
8295 else
8296 RecastV1 = Pred;
8297
8298 // Select either all ones or zeroes depending upon the real predicate bits.
8299 SDValue PredAsVector =
8300 DAG.getNode(ISD::VSELECT, dl, MVT::v16i8, RecastV1, AllOnes, AllZeroes);
8301
8302 // Recast our new predicate-as-integer v16i8 vector into something
8303 // appropriate for the shuffle, i.e. v4i32 for a real v4i1 predicate.
8304 return DAG.getNode(ISD::BITCAST, dl, NewVT, PredAsVector);
8305}
8306
8308 const ARMSubtarget *ST) {
8309 EVT VT = Op.getValueType();
8311 ArrayRef<int> ShuffleMask = SVN->getMask();
8312
8313 assert(ST->hasMVEIntegerOps() &&
8314 "No support for vector shuffle of boolean predicates");
8315
8316 SDValue V1 = Op.getOperand(0);
8317 SDValue V2 = Op.getOperand(1);
8318 SDLoc dl(Op);
8319 if (isReverseMask(ShuffleMask, VT)) {
8320 SDValue cast = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, V1);
8321 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, cast);
8322 SDValue srl = DAG.getNode(ISD::SRL, dl, MVT::i32, rbit,
8323 DAG.getConstant(16, dl, MVT::i32));
8324 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, srl);
8325 }
8326
8327 // Until we can come up with optimised cases for every single vector
8328 // shuffle in existence we have chosen the least painful strategy. This is
8329 // to essentially promote the boolean predicate to a 8-bit integer, where
8330 // each predicate represents a byte. Then we fall back on a normal integer
8331 // vector shuffle and convert the result back into a predicate vector. In
8332 // many cases the generated code might be even better than scalar code
8333 // operating on bits. Just imagine trying to shuffle 8 arbitrary 2-bit
8334 // fields in a register into 8 other arbitrary 2-bit fields!
8335 SDValue PredAsVector1 = PromoteMVEPredVector(dl, V1, VT, DAG);
8336 EVT NewVT = PredAsVector1.getValueType();
8337 SDValue PredAsVector2 = V2.isUndef() ? DAG.getUNDEF(NewVT)
8338 : PromoteMVEPredVector(dl, V2, VT, DAG);
8339 assert(PredAsVector2.getValueType() == NewVT &&
8340 "Expected identical vector type in expanded i1 shuffle!");
8341
8342 // Do the shuffle!
8343 SDValue Shuffled = DAG.getVectorShuffle(NewVT, dl, PredAsVector1,
8344 PredAsVector2, ShuffleMask);
8345
8346 // Now return the result of comparing the shuffled vector with zero,
8347 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1. For a v2i1
8348 // we convert to a v4i1 compare to fill in the two halves of the i64 as i32s.
8349 if (VT == MVT::v2i1) {
8350 SDValue BC = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Shuffled);
8351 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, BC,
8352 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8353 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8354 }
8355 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Shuffled,
8356 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8357}
8358
8360 ArrayRef<int> ShuffleMask,
8361 SelectionDAG &DAG) {
8362 // Attempt to lower the vector shuffle using as many whole register movs as
8363 // possible. This is useful for types smaller than 32bits, which would
8364 // often otherwise become a series for grp movs.
8365 SDLoc dl(Op);
8366 EVT VT = Op.getValueType();
8367 if (VT.getScalarSizeInBits() >= 32)
8368 return SDValue();
8369
8370 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8371 "Unexpected vector type");
8372 int NumElts = VT.getVectorNumElements();
8373 int QuarterSize = NumElts / 4;
8374 // The four final parts of the vector, as i32's
8375 SDValue Parts[4];
8376
8377 // Look for full lane vmovs like <0,1,2,3> or <u,5,6,7> etc, (but not
8378 // <u,u,u,u>), returning the vmov lane index
8379 auto getMovIdx = [](ArrayRef<int> ShuffleMask, int Start, int Length) {
8380 // Detect which mov lane this would be from the first non-undef element.
8381 int MovIdx = -1;
8382 for (int i = 0; i < Length; i++) {
8383 if (ShuffleMask[Start + i] >= 0) {
8384 if (ShuffleMask[Start + i] % Length != i)
8385 return -1;
8386 MovIdx = ShuffleMask[Start + i] / Length;
8387 break;
8388 }
8389 }
8390 // If all items are undef, leave this for other combines
8391 if (MovIdx == -1)
8392 return -1;
8393 // Check the remaining values are the correct part of the same mov
8394 for (int i = 1; i < Length; i++) {
8395 if (ShuffleMask[Start + i] >= 0 &&
8396 (ShuffleMask[Start + i] / Length != MovIdx ||
8397 ShuffleMask[Start + i] % Length != i))
8398 return -1;
8399 }
8400 return MovIdx;
8401 };
8402
8403 for (int Part = 0; Part < 4; ++Part) {
8404 // Does this part look like a mov
8405 int Elt = getMovIdx(ShuffleMask, Part * QuarterSize, QuarterSize);
8406 if (Elt != -1) {
8407 SDValue Input = Op->getOperand(0);
8408 if (Elt >= 4) {
8409 Input = Op->getOperand(1);
8410 Elt -= 4;
8411 }
8412 SDValue BitCast = DAG.getBitcast(MVT::v4f32, Input);
8413 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, BitCast,
8414 DAG.getConstant(Elt, dl, MVT::i32));
8415 }
8416 }
8417
8418 // Nothing interesting found, just return
8419 if (!Parts[0] && !Parts[1] && !Parts[2] && !Parts[3])
8420 return SDValue();
8421
8422 // The other parts need to be built with the old shuffle vector, cast to a
8423 // v4i32 and extract_vector_elts
8424 if (!Parts[0] || !Parts[1] || !Parts[2] || !Parts[3]) {
8425 SmallVector<int, 16> NewShuffleMask;
8426 for (int Part = 0; Part < 4; ++Part)
8427 for (int i = 0; i < QuarterSize; i++)
8428 NewShuffleMask.push_back(
8429 Parts[Part] ? -1 : ShuffleMask[Part * QuarterSize + i]);
8430 SDValue NewShuffle = DAG.getVectorShuffle(
8431 VT, dl, Op->getOperand(0), Op->getOperand(1), NewShuffleMask);
8432 SDValue BitCast = DAG.getBitcast(MVT::v4f32, NewShuffle);
8433
8434 for (int Part = 0; Part < 4; ++Part)
8435 if (!Parts[Part])
8436 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32,
8437 BitCast, DAG.getConstant(Part, dl, MVT::i32));
8438 }
8439 // Build a vector out of the various parts and bitcast it back to the original
8440 // type.
8441 SDValue NewVec = DAG.getNode(ARMISD::BUILD_VECTOR, dl, MVT::v4f32, Parts);
8442 return DAG.getBitcast(VT, NewVec);
8443}
8444
8446 ArrayRef<int> ShuffleMask,
8447 SelectionDAG &DAG) {
8448 SDValue V1 = Op.getOperand(0);
8449 SDValue V2 = Op.getOperand(1);
8450 EVT VT = Op.getValueType();
8451 unsigned NumElts = VT.getVectorNumElements();
8452
8453 // An One-Off Identity mask is one that is mostly an identity mask from as
8454 // single source but contains a single element out-of-place, either from a
8455 // different vector or from another position in the same vector. As opposed to
8456 // lowering this via a ARMISD::BUILD_VECTOR we can generate an extract/insert
8457 // pair directly.
8458 auto isOneOffIdentityMask = [](ArrayRef<int> Mask, EVT VT, int BaseOffset,
8459 int &OffElement) {
8460 OffElement = -1;
8461 int NonUndef = 0;
8462 for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
8463 if (Mask[i] == -1)
8464 continue;
8465 NonUndef++;
8466 if (Mask[i] != i + BaseOffset) {
8467 if (OffElement == -1)
8468 OffElement = i;
8469 else
8470 return false;
8471 }
8472 }
8473 return NonUndef > 2 && OffElement != -1;
8474 };
8475 int OffElement;
8476 SDValue VInput;
8477 if (isOneOffIdentityMask(ShuffleMask, VT, 0, OffElement))
8478 VInput = V1;
8479 else if (isOneOffIdentityMask(ShuffleMask, VT, NumElts, OffElement))
8480 VInput = V2;
8481 else
8482 return SDValue();
8483
8484 SDLoc dl(Op);
8485 EVT SVT = VT.getScalarType() == MVT::i8 || VT.getScalarType() == MVT::i16
8486 ? MVT::i32
8487 : VT.getScalarType();
8488 SDValue Elt = DAG.getNode(
8489 ISD::EXTRACT_VECTOR_ELT, dl, SVT,
8490 ShuffleMask[OffElement] < (int)NumElts ? V1 : V2,
8491 DAG.getVectorIdxConstant(ShuffleMask[OffElement] % NumElts, dl));
8492 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, VInput, Elt,
8493 DAG.getVectorIdxConstant(OffElement % NumElts, dl));
8494}
8495
8497 const ARMSubtarget *ST) {
8498 SDValue V1 = Op.getOperand(0);
8499 SDValue V2 = Op.getOperand(1);
8500 SDLoc dl(Op);
8501 EVT VT = Op.getValueType();
8503 unsigned EltSize = VT.getScalarSizeInBits();
8504
8505 if (ST->hasMVEIntegerOps() && EltSize == 1)
8506 return LowerVECTOR_SHUFFLE_i1(Op, DAG, ST);
8507
8508 // Convert shuffles that are directly supported on NEON to target-specific
8509 // DAG nodes, instead of keeping them as shuffles and matching them again
8510 // during code selection. This is more efficient and avoids the possibility
8511 // of inconsistencies between legalization and selection.
8512 // FIXME: floating-point vectors should be canonicalized to integer vectors
8513 // of the same time so that they get CSEd properly.
8514 ArrayRef<int> ShuffleMask = SVN->getMask();
8515
8516 if (EltSize <= 32) {
8517 if (SVN->isSplat()) {
8518 int Lane = SVN->getSplatIndex();
8519 // If this is undef splat, generate it via "just" vdup, if possible.
8520 if (Lane == -1) Lane = 0;
8521
8522 // Test if V1 is a SCALAR_TO_VECTOR.
8523 if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR) {
8524 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8525 }
8526 // Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
8527 // (and probably will turn into a SCALAR_TO_VECTOR once legalization
8528 // reaches it).
8529 if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
8530 !isa<ConstantSDNode>(V1.getOperand(0))) {
8531 bool IsScalarToVector = true;
8532 for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
8533 if (!V1.getOperand(i).isUndef()) {
8534 IsScalarToVector = false;
8535 break;
8536 }
8537 if (IsScalarToVector)
8538 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8539 }
8540 return DAG.getNode(ARMISD::VDUPLANE, dl, VT, V1,
8541 DAG.getConstant(Lane, dl, MVT::i32));
8542 }
8543
8544 bool ReverseVEXT = false;
8545 unsigned Imm = 0;
8546 if (ST->hasNEON() && isVEXTMask(ShuffleMask, VT, ReverseVEXT, Imm)) {
8547 if (ReverseVEXT)
8548 std::swap(V1, V2);
8549 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V2,
8550 DAG.getConstant(Imm, dl, MVT::i32));
8551 }
8552
8553 if (isVREVMask(ShuffleMask, VT, 64))
8554 return DAG.getNode(ARMISD::VREV64, dl, VT, V1);
8555 if (isVREVMask(ShuffleMask, VT, 32))
8556 return DAG.getNode(ARMISD::VREV32, dl, VT, V1);
8557 if (isVREVMask(ShuffleMask, VT, 16))
8558 return DAG.getNode(ARMISD::VREV16, dl, VT, V1);
8559
8560 if (ST->hasNEON() && V2->isUndef() && isSingletonVEXTMask(ShuffleMask, VT, Imm)) {
8561 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V1,
8562 DAG.getConstant(Imm, dl, MVT::i32));
8563 }
8564
8565 // Check for Neon shuffles that modify both input vectors in place.
8566 // If both results are used, i.e., if there are two shuffles with the same
8567 // source operands and with masks corresponding to both results of one of
8568 // these operations, DAG memoization will ensure that a single node is
8569 // used for both shuffles.
8570 unsigned WhichResult = 0;
8571 bool isV_UNDEF = false;
8572 if (ST->hasNEON()) {
8573 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8574 ShuffleMask, VT, WhichResult, isV_UNDEF)) {
8575 if (isV_UNDEF)
8576 V2 = V1;
8577 return DAG.getNode(ShuffleOpc, dl, DAG.getVTList(VT, VT), V1, V2)
8578 .getValue(WhichResult);
8579 }
8580 }
8581 if (ST->hasMVEIntegerOps()) {
8582 if (isVMOVNMask(ShuffleMask, VT, false, false))
8583 return DAG.getNode(ARMISD::VMOVN, dl, VT, V2, V1,
8584 DAG.getConstant(0, dl, MVT::i32));
8585 if (isVMOVNMask(ShuffleMask, VT, true, false))
8586 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V2,
8587 DAG.getConstant(1, dl, MVT::i32));
8588 if (isVMOVNMask(ShuffleMask, VT, true, true))
8589 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V1,
8590 DAG.getConstant(1, dl, MVT::i32));
8591 }
8592
8593 // Also check for these shuffles through CONCAT_VECTORS: we canonicalize
8594 // shuffles that produce a result larger than their operands with:
8595 // shuffle(concat(v1, undef), concat(v2, undef))
8596 // ->
8597 // shuffle(concat(v1, v2), undef)
8598 // because we can access quad vectors (see PerformVECTOR_SHUFFLECombine).
8599 //
8600 // This is useful in the general case, but there are special cases where
8601 // native shuffles produce larger results: the two-result ops.
8602 //
8603 // Look through the concat when lowering them:
8604 // shuffle(concat(v1, v2), undef)
8605 // ->
8606 // concat(VZIP(v1, v2):0, :1)
8607 //
8608 if (ST->hasNEON() && V1->getOpcode() == ISD::CONCAT_VECTORS && V2->isUndef()) {
8609 SDValue SubV1 = V1->getOperand(0);
8610 SDValue SubV2 = V1->getOperand(1);
8611 EVT SubVT = SubV1.getValueType();
8612
8613 // We expect these to have been canonicalized to -1.
8614 assert(llvm::all_of(ShuffleMask, [&](int i) {
8615 return i < (int)VT.getVectorNumElements();
8616 }) && "Unexpected shuffle index into UNDEF operand!");
8617
8618 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8619 ShuffleMask, SubVT, WhichResult, isV_UNDEF)) {
8620 if (isV_UNDEF)
8621 SubV2 = SubV1;
8622 assert((WhichResult == 0) &&
8623 "In-place shuffle of concat can only have one result!");
8624 SDValue Res = DAG.getNode(ShuffleOpc, dl, DAG.getVTList(SubVT, SubVT),
8625 SubV1, SubV2);
8626 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Res.getValue(0),
8627 Res.getValue(1));
8628 }
8629 }
8630 }
8631
8632 if (ST->hasMVEIntegerOps() && EltSize <= 32 &&
8633 (ST->hasFullFP16() || VT != MVT::v8f16)) {
8634 if (SDValue V = LowerVECTOR_SHUFFLEUsingOneOff(Op, ShuffleMask, DAG))
8635 return V;
8636
8637 for (bool Top : {false, true}) {
8638 for (bool SingleSource : {false, true}) {
8639 if (isTruncMask(ShuffleMask, VT, Top, SingleSource)) {
8640 MVT FromSVT = MVT::getIntegerVT(EltSize * 2);
8641 MVT FromVT = MVT::getVectorVT(FromSVT, ShuffleMask.size() / 2);
8642 SDValue Lo = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT, V1);
8643 SDValue Hi = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT,
8644 SingleSource ? V1 : V2);
8645 if (Top) {
8646 SDValue Amt = DAG.getConstant(EltSize, dl, FromVT);
8647 Lo = DAG.getNode(ISD::SRL, dl, FromVT, Lo, Amt);
8648 Hi = DAG.getNode(ISD::SRL, dl, FromVT, Hi, Amt);
8649 }
8650 return DAG.getNode(ARMISD::MVETRUNC, dl, VT, Lo, Hi);
8651 }
8652 }
8653 }
8654 }
8655
8656 // If the shuffle is not directly supported and it has 4 elements, use
8657 // the PerfectShuffle-generated table to synthesize it from other shuffles.
8658 unsigned NumElts = VT.getVectorNumElements();
8659 if (NumElts == 4) {
8660 unsigned PFIndexes[4];
8661 for (unsigned i = 0; i != 4; ++i) {
8662 if (ShuffleMask[i] < 0)
8663 PFIndexes[i] = 8;
8664 else
8665 PFIndexes[i] = ShuffleMask[i];
8666 }
8667
8668 // Compute the index in the perfect shuffle table.
8669 unsigned PFTableIndex =
8670 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8671 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8672 unsigned Cost = (PFEntry >> 30);
8673
8674 if (Cost <= 4) {
8675 if (ST->hasNEON())
8676 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8677 else if (isLegalMVEShuffleOp(PFEntry)) {
8678 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8679 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8680 unsigned PFEntryLHS = PerfectShuffleTable[LHSID];
8681 unsigned PFEntryRHS = PerfectShuffleTable[RHSID];
8682 if (isLegalMVEShuffleOp(PFEntryLHS) && isLegalMVEShuffleOp(PFEntryRHS))
8683 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8684 }
8685 }
8686 }
8687
8688 // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
8689 if (EltSize >= 32) {
8690 // Do the expansion with floating-point types, since that is what the VFP
8691 // registers are defined to use, and since i64 is not legal.
8692 EVT EltVT = EVT::getFloatingPointVT(EltSize);
8693 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
8694 V1 = DAG.getNode(ISD::BITCAST, dl, VecVT, V1);
8695 V2 = DAG.getNode(ISD::BITCAST, dl, VecVT, V2);
8697 for (unsigned i = 0; i < NumElts; ++i) {
8698 if (ShuffleMask[i] < 0)
8699 Ops.push_back(DAG.getUNDEF(EltVT));
8700 else
8701 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
8702 ShuffleMask[i] < (int)NumElts ? V1 : V2,
8703 DAG.getConstant(ShuffleMask[i] & (NumElts-1),
8704 dl, MVT::i32)));
8705 }
8706 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
8707 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
8708 }
8709
8710 if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8711 isReverseMask(ShuffleMask, VT))
8712 return LowerReverse_VECTOR_SHUFFLE(Op, DAG);
8713
8714 if (ST->hasNEON() && VT == MVT::v8i8)
8715 if (SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG))
8716 return NewOp;
8717
8718 if (ST->hasMVEIntegerOps())
8719 if (SDValue NewOp = LowerVECTOR_SHUFFLEUsingMovs(Op, ShuffleMask, DAG))
8720 return NewOp;
8721
8722 // Lower v8f16 via v8i16 to avoid invalid f16 nodes.
8723 if (VT == MVT::v8f16 && !ST->hasFullFP16()) {
8724 SDValue BC0 =
8725 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(0));
8726 SDValue BC1 =
8727 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(1));
8728 SDValue Shuf = DAG.getVectorShuffle(MVT::v8i16, dl, BC0, BC1, ShuffleMask);
8729 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuf);
8730 }
8731
8732 return SDValue();
8733}
8734
8736 const ARMSubtarget *ST) {
8737 EVT VecVT = Op.getOperand(0).getValueType();
8738 SDLoc dl(Op);
8739
8740 assert(ST->hasMVEIntegerOps() &&
8741 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8742
8743 SDValue Conv =
8744 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8745 unsigned Lane = Op.getConstantOperandVal(2);
8746 unsigned LaneWidth =
8748 unsigned Mask = ((1 << LaneWidth) - 1) << Lane * LaneWidth;
8749 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32,
8750 Op.getOperand(1), DAG.getValueType(MVT::i1));
8751 SDValue BFI = DAG.getNode(ARMISD::BFI, dl, MVT::i32, Conv, Ext,
8752 DAG.getConstant(~Mask, dl, MVT::i32));
8753 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), BFI);
8754}
8755
8756SDValue ARMTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
8757 SelectionDAG &DAG) const {
8758 // INSERT_VECTOR_ELT is legal only for immediate indexes.
8759 SDValue Lane = Op.getOperand(2);
8760 if (!isa<ConstantSDNode>(Lane))
8761 return SDValue();
8762
8763 SDValue Elt = Op.getOperand(1);
8764 EVT EltVT = Elt.getValueType();
8765
8766 if (Subtarget->hasMVEIntegerOps() &&
8767 Op.getValueType().getScalarSizeInBits() == 1)
8768 return LowerINSERT_VECTOR_ELT_i1(Op, DAG, Subtarget);
8769
8770 if (getTypeAction(*DAG.getContext(), EltVT) ==
8772 // INSERT_VECTOR_ELT doesn't want f16 operands promoting to f32,
8773 // but the type system will try to do that if we don't intervene.
8774 // Reinterpret any such vector-element insertion as one with the
8775 // corresponding integer types.
8776
8777 SDLoc dl(Op);
8778
8779 EVT IEltVT = MVT::getIntegerVT(EltVT.getScalarSizeInBits());
8780 assert(getTypeAction(*DAG.getContext(), IEltVT) !=
8782
8783 SDValue VecIn = Op.getOperand(0);
8784 EVT VecVT = VecIn.getValueType();
8785 EVT IVecVT = EVT::getVectorVT(*DAG.getContext(), IEltVT,
8786 VecVT.getVectorNumElements());
8787
8788 SDValue IElt = DAG.getNode(ISD::BITCAST, dl, IEltVT, Elt);
8789 SDValue IVecIn = DAG.getNode(ISD::BITCAST, dl, IVecVT, VecIn);
8790 SDValue IVecOut = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, IVecVT,
8791 IVecIn, IElt, Lane);
8792 return DAG.getNode(ISD::BITCAST, dl, VecVT, IVecOut);
8793 }
8794
8795 return Op;
8796}
8797
8799 const ARMSubtarget *ST) {
8800 EVT VecVT = Op.getOperand(0).getValueType();
8801 SDLoc dl(Op);
8802
8803 assert(ST->hasMVEIntegerOps() &&
8804 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8805
8806 SDValue Conv =
8807 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8808 unsigned Lane = Op.getConstantOperandVal(1);
8809 unsigned LaneWidth =
8811 SDValue Shift = DAG.getNode(ISD::SRL, dl, MVT::i32, Conv,
8812 DAG.getConstant(Lane * LaneWidth, dl, MVT::i32));
8813 return Shift;
8814}
8815
8817 const ARMSubtarget *ST) {
8818 // EXTRACT_VECTOR_ELT is legal only for immediate indexes.
8819 SDValue Lane = Op.getOperand(1);
8820 if (!isa<ConstantSDNode>(Lane))
8821 return SDValue();
8822
8823 SDValue Vec = Op.getOperand(0);
8824 EVT VT = Vec.getValueType();
8825
8826 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8827 return LowerEXTRACT_VECTOR_ELT_i1(Op, DAG, ST);
8828
8829 if (Op.getValueType() == MVT::i32 && Vec.getScalarValueSizeInBits() < 32) {
8830 SDLoc dl(Op);
8831 return DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane);
8832 }
8833
8834 return Op;
8835}
8836
8838 const ARMSubtarget *ST) {
8839 SDLoc dl(Op);
8840 assert(Op.getValueType().getScalarSizeInBits() == 1 &&
8841 "Unexpected custom CONCAT_VECTORS lowering");
8842 assert(isPowerOf2_32(Op.getNumOperands()) &&
8843 "Unexpected custom CONCAT_VECTORS lowering");
8844 assert(ST->hasMVEIntegerOps() &&
8845 "CONCAT_VECTORS lowering only supported for MVE");
8846
8847 auto ConcatPair = [&](SDValue V1, SDValue V2) {
8848 EVT Op1VT = V1.getValueType();
8849 EVT Op2VT = V2.getValueType();
8850 assert(Op1VT == Op2VT && "Operand types don't match!");
8851 assert((Op1VT == MVT::v2i1 || Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) &&
8852 "Unexpected i1 concat operations!");
8853 EVT VT = Op1VT.getDoubleNumVectorElementsVT(*DAG.getContext());
8854
8855 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
8856 SDValue NewV2 = PromoteMVEPredVector(dl, V2, Op2VT, DAG);
8857
8858 // We now have Op1 + Op2 promoted to vectors of integers, where v8i1 gets
8859 // promoted to v8i16, etc.
8860 MVT ElType =
8862 unsigned NumElts = 2 * Op1VT.getVectorNumElements();
8863
8864 EVT ConcatVT = MVT::getVectorVT(ElType, NumElts);
8865 if (Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) {
8866 // Use MVETRUNC to truncate the combined NewV1::NewV2 into the smaller
8867 // ConcatVT.
8868 SDValue ConVec =
8869 DAG.getNode(ARMISD::MVETRUNC, dl, ConcatVT, NewV1, NewV2);
8870 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
8871 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8872 }
8873
8874 // Extract the vector elements from Op1 and Op2 one by one and truncate them
8875 // to be the right size for the destination. For example, if Op1 is v4i1
8876 // then the promoted vector is v4i32. The result of concatenation gives a
8877 // v8i1, which when promoted is v8i16. That means each i32 element from Op1
8878 // needs truncating to i16 and inserting in the result.
8879 auto ExtractInto = [&DAG, &dl](SDValue NewV, SDValue ConVec, unsigned &j) {
8880 EVT NewVT = NewV.getValueType();
8881 EVT ConcatVT = ConVec.getValueType();
8882 unsigned ExtScale = 1;
8883 if (NewVT == MVT::v2f64) {
8884 NewV = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, NewV);
8885 ExtScale = 2;
8886 }
8887 for (unsigned i = 0, e = NewVT.getVectorNumElements(); i < e; i++, j++) {
8888 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV,
8889 DAG.getIntPtrConstant(i * ExtScale, dl));
8890 ConVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ConcatVT, ConVec, Elt,
8891 DAG.getConstant(j, dl, MVT::i32));
8892 }
8893 return ConVec;
8894 };
8895 unsigned j = 0;
8896 SDValue ConVec = DAG.getNode(ISD::UNDEF, dl, ConcatVT);
8897 ConVec = ExtractInto(NewV1, ConVec, j);
8898 ConVec = ExtractInto(NewV2, ConVec, j);
8899
8900 // Now return the result of comparing the subvector with zero, which will
8901 // generate a real predicate, i.e. v4i1, v8i1 or v16i1.
8902 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
8903 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8904 };
8905
8906 // Concat each pair of subvectors and pack into the lower half of the array.
8907 SmallVector<SDValue> ConcatOps(Op->ops());
8908 while (ConcatOps.size() > 1) {
8909 for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) {
8910 SDValue V1 = ConcatOps[I];
8911 SDValue V2 = ConcatOps[I + 1];
8912 ConcatOps[I / 2] = ConcatPair(V1, V2);
8913 }
8914 ConcatOps.resize(ConcatOps.size() / 2);
8915 }
8916 return ConcatOps[0];
8917}
8918
8920 const ARMSubtarget *ST) {
8921 EVT VT = Op->getValueType(0);
8922 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8923 return LowerCONCAT_VECTORS_i1(Op, DAG, ST);
8924
8925 // The only time a CONCAT_VECTORS operation can have legal types is when
8926 // two 64-bit vectors are concatenated to a 128-bit vector.
8927 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
8928 "unexpected CONCAT_VECTORS");
8929 SDLoc dl(Op);
8930 SDValue Val = DAG.getUNDEF(MVT::v2f64);
8931 SDValue Op0 = Op.getOperand(0);
8932 SDValue Op1 = Op.getOperand(1);
8933 if (!Op0.isUndef())
8934 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
8935 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op0),
8936 DAG.getIntPtrConstant(0, dl));
8937 if (!Op1.isUndef())
8938 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
8939 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op1),
8940 DAG.getIntPtrConstant(1, dl));
8941 return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Val);
8942}
8943
8945 const ARMSubtarget *ST) {
8946 SDValue V1 = Op.getOperand(0);
8947 SDValue V2 = Op.getOperand(1);
8948 SDLoc dl(Op);
8949 EVT VT = Op.getValueType();
8950 EVT Op1VT = V1.getValueType();
8951 unsigned NumElts = VT.getVectorNumElements();
8952 unsigned Index = V2->getAsZExtVal();
8953
8954 assert(VT.getScalarSizeInBits() == 1 &&
8955 "Unexpected custom EXTRACT_SUBVECTOR lowering");
8956 assert(ST->hasMVEIntegerOps() &&
8957 "EXTRACT_SUBVECTOR lowering only supported for MVE");
8958
8959 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
8960
8961 // We now have Op1 promoted to a vector of integers, where v8i1 gets
8962 // promoted to v8i16, etc.
8963
8965
8966 if (NumElts == 2) {
8967 EVT SubVT = MVT::v4i32;
8968 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
8969 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j += 2) {
8970 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
8971 DAG.getIntPtrConstant(i, dl));
8972 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
8973 DAG.getConstant(j, dl, MVT::i32));
8974 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
8975 DAG.getConstant(j + 1, dl, MVT::i32));
8976 }
8977 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, SubVec,
8978 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8979 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8980 }
8981
8982 EVT SubVT = MVT::getVectorVT(ElType, NumElts);
8983 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
8984 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j++) {
8985 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
8986 DAG.getIntPtrConstant(i, dl));
8987 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
8988 DAG.getConstant(j, dl, MVT::i32));
8989 }
8990
8991 // Now return the result of comparing the subvector with zero,
8992 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1.
8993 return DAG.getNode(ARMISD::VCMPZ, dl, VT, SubVec,
8994 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8995}
8996
8997// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
8999 const ARMSubtarget *ST) {
9000 assert(ST->hasMVEIntegerOps() && "Expected MVE!");
9001 EVT VT = N->getValueType(0);
9002 assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
9003 "Expected a vector i1 type!");
9004 SDValue Op = N->getOperand(0);
9005 EVT FromVT = Op.getValueType();
9006 SDLoc DL(N);
9007
9008 SDValue And =
9009 DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
9010 return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
9011 DAG.getCondCode(ISD::SETNE));
9012}
9013
9015 const ARMSubtarget *Subtarget) {
9016 if (!Subtarget->hasMVEIntegerOps())
9017 return SDValue();
9018
9019 EVT ToVT = N->getValueType(0);
9020 if (ToVT.getScalarType() == MVT::i1)
9021 return LowerTruncatei1(N, DAG, Subtarget);
9022
9023 // MVE does not have a single instruction to perform the truncation of a v4i32
9024 // into the lower half of a v8i16, in the same way that a NEON vmovn would.
9025 // Most of the instructions in MVE follow the 'Beats' system, where moving
9026 // values from different lanes is usually something that the instructions
9027 // avoid.
9028 //
9029 // Instead it has top/bottom instructions such as VMOVLT/B and VMOVNT/B,
9030 // which take a the top/bottom half of a larger lane and extend it (or do the
9031 // opposite, truncating into the top/bottom lane from a larger lane). Note
9032 // that because of the way we widen lanes, a v4i16 is really a v4i32 using the
9033 // bottom 16bits from each vector lane. This works really well with T/B
9034 // instructions, but that doesn't extend to v8i32->v8i16 where the lanes need
9035 // to move order.
9036 //
9037 // But truncates and sext/zext are always going to be fairly common from llvm.
9038 // We have several options for how to deal with them:
9039 // - Wherever possible combine them into an instruction that makes them
9040 // "free". This includes loads/stores, which can perform the trunc as part
9041 // of the memory operation. Or certain shuffles that can be turned into
9042 // VMOVN/VMOVL.
9043 // - Lane Interleaving to transform blocks surrounded by ext/trunc. So
9044 // trunc(mul(sext(a), sext(b))) may become
9045 // VMOVNT(VMUL(VMOVLB(a), VMOVLB(b)), VMUL(VMOVLT(a), VMOVLT(b))). (Which in
9046 // this case can use VMULL). This is performed in the
9047 // MVELaneInterleavingPass.
9048 // - Otherwise we have an option. By default we would expand the
9049 // zext/sext/trunc into a series of lane extract/inserts going via GPR
9050 // registers. One for each vector lane in the vector. This can obviously be
9051 // very expensive.
9052 // - The other option is to use the fact that loads/store can extend/truncate
9053 // to turn a trunc into two truncating stack stores and a stack reload. This
9054 // becomes 3 back-to-back memory operations, but at least that is less than
9055 // all the insert/extracts.
9056 //
9057 // In order to do the last, we convert certain trunc's into MVETRUNC, which
9058 // are either optimized where they can be, or eventually lowered into stack
9059 // stores/loads. This prevents us from splitting a v8i16 trunc into two stores
9060 // two early, where other instructions would be better, and stops us from
9061 // having to reconstruct multiple buildvector shuffles into loads/stores.
9062 if (ToVT != MVT::v8i16 && ToVT != MVT::v16i8)
9063 return SDValue();
9064 EVT FromVT = N->getOperand(0).getValueType();
9065 if (FromVT != MVT::v8i32 && FromVT != MVT::v16i16)
9066 return SDValue();
9067
9068 SDValue Lo, Hi;
9069 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
9070 SDLoc DL(N);
9071 return DAG.getNode(ARMISD::MVETRUNC, DL, ToVT, Lo, Hi);
9072}
9073
9075 const ARMSubtarget *Subtarget) {
9076 if (!Subtarget->hasMVEIntegerOps())
9077 return SDValue();
9078
9079 // See LowerTruncate above for an explanation of MVEEXT/MVETRUNC.
9080
9081 EVT ToVT = N->getValueType(0);
9082 if (ToVT != MVT::v16i32 && ToVT != MVT::v8i32 && ToVT != MVT::v16i16)
9083 return SDValue();
9084 SDValue Op = N->getOperand(0);
9085 EVT FromVT = Op.getValueType();
9086 if (FromVT != MVT::v8i16 && FromVT != MVT::v16i8)
9087 return SDValue();
9088
9089 SDLoc DL(N);
9090 EVT ExtVT = ToVT.getHalfNumVectorElementsVT(*DAG.getContext());
9091 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8)
9092 ExtVT = MVT::v8i16;
9093
9094 unsigned Opcode =
9096 SDValue Ext = DAG.getNode(Opcode, DL, DAG.getVTList(ExtVT, ExtVT), Op);
9097 SDValue Ext1 = Ext.getValue(1);
9098
9099 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8) {
9100 Ext = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext);
9101 Ext1 = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext1);
9102 }
9103
9104 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Ext, Ext1);
9105}
9106
9107/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
9108/// element has been zero/sign-extended, depending on the isSigned parameter,
9109/// from an integer type half its size.
9111 bool isSigned) {
9112 // A v2i64 BUILD_VECTOR will have been legalized to a BITCAST from v4i32.
9113 EVT VT = N->getValueType(0);
9114 if (VT == MVT::v2i64 && N->getOpcode() == ISD::BITCAST) {
9115 SDNode *BVN = N->getOperand(0).getNode();
9116 if (BVN->getValueType(0) != MVT::v4i32 ||
9117 BVN->getOpcode() != ISD::BUILD_VECTOR)
9118 return false;
9119 unsigned LoElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9120 unsigned HiElt = 1 - LoElt;
9125 if (!Lo0 || !Hi0 || !Lo1 || !Hi1)
9126 return false;
9127 if (isSigned) {
9128 if (Hi0->getSExtValue() == Lo0->getSExtValue() >> 32 &&
9129 Hi1->getSExtValue() == Lo1->getSExtValue() >> 32)
9130 return true;
9131 } else {
9132 if (Hi0->isZero() && Hi1->isZero())
9133 return true;
9134 }
9135 return false;
9136 }
9137
9138 if (N->getOpcode() != ISD::BUILD_VECTOR)
9139 return false;
9140
9141 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
9142 SDNode *Elt = N->getOperand(i).getNode();
9144 unsigned EltSize = VT.getScalarSizeInBits();
9145 unsigned HalfSize = EltSize / 2;
9146 if (isSigned) {
9147 if (!isIntN(HalfSize, C->getSExtValue()))
9148 return false;
9149 } else {
9150 if (!isUIntN(HalfSize, C->getZExtValue()))
9151 return false;
9152 }
9153 continue;
9154 }
9155 return false;
9156 }
9157
9158 return true;
9159}
9160
9161/// isSignExtended - Check if a node is a vector value that is sign-extended
9162/// or a constant BUILD_VECTOR with sign-extended elements.
9164 if (N->getOpcode() == ISD::SIGN_EXTEND || ISD::isSEXTLoad(N))
9165 return true;
9166 if (isExtendedBUILD_VECTOR(N, DAG, true))
9167 return true;
9168 return false;
9169}
9170
9171/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
9172/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
9174 if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
9176 return true;
9177 if (isExtendedBUILD_VECTOR(N, DAG, false))
9178 return true;
9179 return false;
9180}
9181
9182static EVT getExtensionTo64Bits(const EVT &OrigVT) {
9183 if (OrigVT.getSizeInBits() >= 64)
9184 return OrigVT;
9185
9186 assert(OrigVT.isSimple() && "Expecting a simple value type");
9187
9188 MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
9189 switch (OrigSimpleTy) {
9190 default: llvm_unreachable("Unexpected Vector Type");
9191 case MVT::v2i8:
9192 case MVT::v2i16:
9193 return MVT::v2i32;
9194 case MVT::v4i8:
9195 return MVT::v4i16;
9196 }
9197}
9198
9199/// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
9200/// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
9201/// We insert the required extension here to get the vector to fill a D register.
9203 const EVT &OrigTy,
9204 const EVT &ExtTy,
9205 unsigned ExtOpcode) {
9206 // The vector originally had a size of OrigTy. It was then extended to ExtTy.
9207 // We expect the ExtTy to be 128-bits total. If the OrigTy is less than
9208 // 64-bits we need to insert a new extension so that it will be 64-bits.
9209 assert(ExtTy.is128BitVector() && "Unexpected extension size");
9210 if (OrigTy.getSizeInBits() >= 64)
9211 return N;
9212
9213 // Must extend size to at least 64 bits to be used as an operand for VMULL.
9214 EVT NewVT = getExtensionTo64Bits(OrigTy);
9215
9216 return DAG.getNode(ExtOpcode, SDLoc(N), NewVT, N);
9217}
9218
9219/// SkipLoadExtensionForVMULL - return a load of the original vector size that
9220/// does not do any sign/zero extension. If the original vector is less
9221/// than 64 bits, an appropriate extension will be added after the load to
9222/// reach a total size of 64 bits. We have to add the extension separately
9223/// because ARM does not have a sign/zero extending load for vectors.
9225 EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
9226
9227 // The load already has the right type.
9228 if (ExtendedTy == LD->getMemoryVT())
9229 return DAG.getLoad(LD->getMemoryVT(), SDLoc(LD), LD->getChain(),
9230 LD->getBasePtr(), LD->getPointerInfo(), LD->getAlign(),
9231 LD->getMemOperand()->getFlags());
9232
9233 // We need to create a zextload/sextload. We cannot just create a load
9234 // followed by a zext/zext node because LowerMUL is also run during normal
9235 // operation legalization where we can't create illegal types.
9236 return DAG.getExtLoad(LD->getExtensionType(), SDLoc(LD), ExtendedTy,
9237 LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
9238 LD->getMemoryVT(), LD->getAlign(),
9239 LD->getMemOperand()->getFlags());
9240}
9241
9242/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
9243/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
9244/// the unextended value. The unextended vector should be 64 bits so that it can
9245/// be used as an operand to a VMULL instruction. If the original vector size
9246/// before extension is less than 64 bits we add a an extension to resize
9247/// the vector to 64 bits.
9249 if (N->getOpcode() == ISD::SIGN_EXTEND ||
9250 N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
9251 return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
9252 N->getOperand(0)->getValueType(0),
9253 N->getValueType(0),
9254 N->getOpcode());
9255
9256 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
9257 assert((ISD::isSEXTLoad(LD) || ISD::isZEXTLoad(LD)) &&
9258 "Expected extending load");
9259
9260 SDValue newLoad = SkipLoadExtensionForVMULL(LD, DAG);
9261 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), newLoad.getValue(1));
9262 unsigned Opcode = ISD::isSEXTLoad(LD) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
9263 SDValue extLoad =
9264 DAG.getNode(Opcode, SDLoc(newLoad), LD->getValueType(0), newLoad);
9265 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 0), extLoad);
9266
9267 return newLoad;
9268 }
9269
9270 // Otherwise, the value must be a BUILD_VECTOR. For v2i64, it will
9271 // have been legalized as a BITCAST from v4i32.
9272 if (N->getOpcode() == ISD::BITCAST) {
9273 SDNode *BVN = N->getOperand(0).getNode();
9275 BVN->getValueType(0) == MVT::v4i32 && "expected v4i32 BUILD_VECTOR");
9276 unsigned LowElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9277 return DAG.getBuildVector(
9278 MVT::v2i32, SDLoc(N),
9279 {BVN->getOperand(LowElt), BVN->getOperand(LowElt + 2)});
9280 }
9281 // Construct a new BUILD_VECTOR with elements truncated to half the size.
9282 assert(N->getOpcode() == ISD::BUILD_VECTOR && "expected BUILD_VECTOR");
9283 EVT VT = N->getValueType(0);
9284 unsigned EltSize = VT.getScalarSizeInBits() / 2;
9285 unsigned NumElts = VT.getVectorNumElements();
9286 MVT TruncVT = MVT::getIntegerVT(EltSize);
9288 SDLoc dl(N);
9289 for (unsigned i = 0; i != NumElts; ++i) {
9290 const APInt &CInt = N->getConstantOperandAPInt(i);
9291 // Element types smaller than 32 bits are not legal, so use i32 elements.
9292 // The values are implicitly truncated so sext vs. zext doesn't matter.
9293 Ops.push_back(DAG.getConstant(CInt.zextOrTrunc(32), dl, MVT::i32));
9294 }
9295 return DAG.getBuildVector(MVT::getVectorVT(TruncVT, NumElts), dl, Ops);
9296}
9297
9298static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
9299 unsigned Opcode = N->getOpcode();
9300 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9301 SDNode *N0 = N->getOperand(0).getNode();
9302 SDNode *N1 = N->getOperand(1).getNode();
9303 return N0->hasOneUse() && N1->hasOneUse() &&
9304 isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
9305 }
9306 return false;
9307}
9308
9309static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
9310 unsigned Opcode = N->getOpcode();
9311 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9312 SDNode *N0 = N->getOperand(0).getNode();
9313 SDNode *N1 = N->getOperand(1).getNode();
9314 return N0->hasOneUse() && N1->hasOneUse() &&
9315 isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
9316 }
9317 return false;
9318}
9319
9321 // Multiplications are only custom-lowered for 128-bit vectors so that
9322 // VMULL can be detected. Otherwise v2i64 multiplications are not legal.
9323 EVT VT = Op.getValueType();
9324 assert(VT.is128BitVector() && VT.isInteger() &&
9325 "unexpected type for custom-lowering ISD::MUL");
9326 SDNode *N0 = Op.getOperand(0).getNode();
9327 SDNode *N1 = Op.getOperand(1).getNode();
9328 unsigned NewOpc = 0;
9329 bool isMLA = false;
9330 bool isN0SExt = isSignExtended(N0, DAG);
9331 bool isN1SExt = isSignExtended(N1, DAG);
9332 if (isN0SExt && isN1SExt)
9333 NewOpc = ARMISD::VMULLs;
9334 else {
9335 bool isN0ZExt = isZeroExtended(N0, DAG);
9336 bool isN1ZExt = isZeroExtended(N1, DAG);
9337 if (isN0ZExt && isN1ZExt)
9338 NewOpc = ARMISD::VMULLu;
9339 else if (isN1SExt || isN1ZExt) {
9340 // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
9341 // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
9342 if (isN1SExt && isAddSubSExt(N0, DAG)) {
9343 NewOpc = ARMISD::VMULLs;
9344 isMLA = true;
9345 } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
9346 NewOpc = ARMISD::VMULLu;
9347 isMLA = true;
9348 } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
9349 std::swap(N0, N1);
9350 NewOpc = ARMISD::VMULLu;
9351 isMLA = true;
9352 }
9353 }
9354
9355 if (!NewOpc) {
9356 if (VT == MVT::v2i64)
9357 // Fall through to expand this. It is not legal.
9358 return SDValue();
9359 else
9360 // Other vector multiplications are legal.
9361 return Op;
9362 }
9363 }
9364
9365 // Legalize to a VMULL instruction.
9366 SDLoc DL(Op);
9367 SDValue Op0;
9368 SDValue Op1 = SkipExtensionForVMULL(N1, DAG);
9369 if (!isMLA) {
9370 Op0 = SkipExtensionForVMULL(N0, DAG);
9372 Op1.getValueType().is64BitVector() &&
9373 "unexpected types for extended operands to VMULL");
9374 return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
9375 }
9376
9377 // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
9378 // isel lowering to take advantage of no-stall back to back vmul + vmla.
9379 // vmull q0, d4, d6
9380 // vmlal q0, d5, d6
9381 // is faster than
9382 // vaddl q0, d4, d5
9383 // vmovl q1, d6
9384 // vmul q0, q0, q1
9385 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG);
9386 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG);
9387 EVT Op1VT = Op1.getValueType();
9388 return DAG.getNode(N0->getOpcode(), DL, VT,
9389 DAG.getNode(NewOpc, DL, VT,
9390 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
9391 DAG.getNode(NewOpc, DL, VT,
9392 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
9393}
9394
9396 SelectionDAG &DAG) {
9397 // TODO: Should this propagate fast-math-flags?
9398
9399 // Convert to float
9400 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo));
9401 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo));
9402 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X);
9403 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y);
9404 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X);
9405 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y);
9406 // Get reciprocal estimate.
9407 // float4 recip = vrecpeq_f32(yf);
9408 Y = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9409 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9410 Y);
9411 // Because char has a smaller range than uchar, we can actually get away
9412 // without any newton steps. This requires that we use a weird bias
9413 // of 0xb000, however (again, this has been exhaustively tested).
9414 // float4 result = as_float4(as_int4(xf*recip) + 0xb000);
9415 X = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, X, Y);
9416 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, X);
9417 Y = DAG.getConstant(0xb000, dl, MVT::v4i32);
9418 X = DAG.getNode(ISD::ADD, dl, MVT::v4i32, X, Y);
9419 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, X);
9420 // Convert back to short.
9421 X = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, X);
9422 X = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, X);
9423 return X;
9424}
9425
9427 SelectionDAG &DAG) {
9428 // TODO: Should this propagate fast-math-flags?
9429
9430 SDValue N2;
9431 // Convert to float.
9432 // float4 yf = vcvt_f32_s32(vmovl_s16(y));
9433 // float4 xf = vcvt_f32_s32(vmovl_s16(x));
9434 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N0);
9435 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N1);
9436 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9437 N1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9438
9439 // Use reciprocal estimate and one refinement step.
9440 // float4 recip = vrecpeq_f32(yf);
9441 // recip *= vrecpsq_f32(yf, recip);
9442 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9443 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9444 N1);
9445 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9446 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9447 N1, N2);
9448 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9449 // Because short has a smaller range than ushort, we can actually get away
9450 // with only a single newton step. This requires that we use a weird bias
9451 // of 89, however (again, this has been exhaustively tested).
9452 // float4 result = as_float4(as_int4(xf*recip) + 0x89);
9453 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9454 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9455 N1 = DAG.getConstant(0x89, dl, MVT::v4i32);
9456 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9457 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9458 // Convert back to integer and return.
9459 // return vmovn_s32(vcvt_s32_f32(result));
9460 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9461 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9462 return N0;
9463}
9464
9466 const ARMSubtarget *ST) {
9467 EVT VT = Op.getValueType();
9468 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9469 "unexpected type for custom-lowering ISD::SDIV");
9470
9471 SDLoc dl(Op);
9472 SDValue N0 = Op.getOperand(0);
9473 SDValue N1 = Op.getOperand(1);
9474 SDValue N2, N3;
9475
9476 if (VT == MVT::v8i8) {
9477 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N0);
9478 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N1);
9479
9480 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9481 DAG.getIntPtrConstant(4, dl));
9482 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9483 DAG.getIntPtrConstant(4, dl));
9484 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9485 DAG.getIntPtrConstant(0, dl));
9486 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9487 DAG.getIntPtrConstant(0, dl));
9488
9489 N0 = LowerSDIV_v4i8(N0, N1, dl, DAG); // v4i16
9490 N2 = LowerSDIV_v4i8(N2, N3, dl, DAG); // v4i16
9491
9492 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9493 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9494
9495 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v8i8, N0);
9496 return N0;
9497 }
9498 return LowerSDIV_v4i16(N0, N1, dl, DAG);
9499}
9500
9502 const ARMSubtarget *ST) {
9503 // TODO: Should this propagate fast-math-flags?
9504 EVT VT = Op.getValueType();
9505 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9506 "unexpected type for custom-lowering ISD::UDIV");
9507
9508 SDLoc dl(Op);
9509 SDValue N0 = Op.getOperand(0);
9510 SDValue N1 = Op.getOperand(1);
9511 SDValue N2, N3;
9512
9513 if (VT == MVT::v8i8) {
9514 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N0);
9515 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N1);
9516
9517 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9518 DAG.getIntPtrConstant(4, dl));
9519 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9520 DAG.getIntPtrConstant(4, dl));
9521 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9522 DAG.getIntPtrConstant(0, dl));
9523 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9524 DAG.getIntPtrConstant(0, dl));
9525
9526 N0 = LowerSDIV_v4i16(N0, N1, dl, DAG); // v4i16
9527 N2 = LowerSDIV_v4i16(N2, N3, dl, DAG); // v4i16
9528
9529 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9530 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9531
9532 N0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v8i8,
9533 DAG.getConstant(Intrinsic::arm_neon_vqmovnsu, dl,
9534 MVT::i32),
9535 N0);
9536 return N0;
9537 }
9538
9539 // v4i16 sdiv ... Convert to float.
9540 // float4 yf = vcvt_f32_s32(vmovl_u16(y));
9541 // float4 xf = vcvt_f32_s32(vmovl_u16(x));
9542 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N0);
9543 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N1);
9544 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9545 SDValue BN1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9546
9547 // Use reciprocal estimate and two refinement steps.
9548 // float4 recip = vrecpeq_f32(yf);
9549 // recip *= vrecpsq_f32(yf, recip);
9550 // recip *= vrecpsq_f32(yf, recip);
9551 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9552 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9553 BN1);
9554 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9555 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9556 BN1, N2);
9557 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9558 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9559 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9560 BN1, N2);
9561 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9562 // Simply multiplying by the reciprocal estimate can leave us a few ulps
9563 // too low, so we add 2 ulps (exhaustive testing shows that this is enough,
9564 // and that it will never cause us to return an answer too large).
9565 // float4 result = as_float4(as_int4(xf*recip) + 2);
9566 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9567 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9568 N1 = DAG.getConstant(2, dl, MVT::v4i32);
9569 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9570 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9571 // Convert back to integer and return.
9572 // return vmovn_u32(vcvt_s32_f32(result));
9573 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9574 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9575 return N0;
9576}
9577
9579 unsigned Opcode, bool IsSigned) {
9580 EVT VT0 = Op.getValue(0).getValueType();
9581 EVT VT1 = Op.getValue(1).getValueType();
9582
9583 bool InvertCarry = Opcode == ARMISD::SUBE;
9584 SDValue OpLHS = Op.getOperand(0);
9585 SDValue OpRHS = Op.getOperand(1);
9586 SDValue OpCarryIn = valueToCarryFlag(Op.getOperand(2), DAG, InvertCarry);
9587
9588 SDLoc DL(Op);
9589
9590 SDValue Result = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::i32), OpLHS,
9591 OpRHS, OpCarryIn);
9592
9593 SDValue OutFlag =
9594 IsSigned ? overflowFlagToValue(Result.getValue(1), VT1, DAG)
9595 : carryFlagToValue(Result.getValue(1), VT1, DAG, InvertCarry);
9596
9597 return DAG.getMergeValues({Result, OutFlag}, DL);
9598}
9599
9600SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
9601 bool Signed,
9602 SDValue &Chain) const {
9603 EVT VT = Op.getValueType();
9604 assert((VT == MVT::i32 || VT == MVT::i64) &&
9605 "unexpected type for custom lowering DIV");
9606 SDLoc dl(Op);
9607
9608 const auto &DL = DAG.getDataLayout();
9609 RTLIB::Libcall LC;
9610 if (Signed)
9611 LC = VT == MVT::i32 ? RTLIB::SDIVREM_I32 : RTLIB::SDIVREM_I64;
9612 else
9613 LC = VT == MVT::i32 ? RTLIB::UDIVREM_I32 : RTLIB::UDIVREM_I64;
9614
9615 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
9616 SDValue ES = DAG.getExternalSymbol(LCImpl, getPointerTy(DL));
9617
9619
9620 for (auto AI : {1, 0}) {
9621 SDValue Operand = Op.getOperand(AI);
9622 Args.emplace_back(Operand,
9623 Operand.getValueType().getTypeForEVT(*DAG.getContext()));
9624 }
9625
9626 CallLoweringInfo CLI(DAG);
9627 CLI.setDebugLoc(dl).setChain(Chain).setCallee(
9629 VT.getTypeForEVT(*DAG.getContext()), ES, std::move(Args));
9630
9631 return LowerCallTo(CLI).first;
9632}
9633
9634// This is a code size optimisation: return the original SDIV node to
9635// DAGCombiner when we don't want to expand SDIV into a sequence of
9636// instructions, and an empty node otherwise which will cause the
9637// SDIV to be expanded in DAGCombine.
9638SDValue
9639ARMTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
9640 SelectionDAG &DAG,
9641 SmallVectorImpl<SDNode *> &Created) const {
9642 // TODO: Support SREM
9643 if (N->getOpcode() != ISD::SDIV)
9644 return SDValue();
9645
9646 const auto &ST = DAG.getSubtarget<ARMSubtarget>();
9647 const bool MinSize = ST.hasMinSize();
9648 const bool HasDivide = ST.isThumb() ? ST.hasDivideInThumbMode()
9649 : ST.hasDivideInARMMode();
9650
9651 // Don't touch vector types; rewriting this may lead to scalarizing
9652 // the int divs.
9653 if (N->getOperand(0).getValueType().isVector())
9654 return SDValue();
9655
9656 // Bail if MinSize is not set, and also for both ARM and Thumb mode we need
9657 // hwdiv support for this to be really profitable.
9658 if (!(MinSize && HasDivide))
9659 return SDValue();
9660
9661 // ARM mode is a bit simpler than Thumb: we can handle large power
9662 // of 2 immediates with 1 mov instruction; no further checks required,
9663 // just return the sdiv node.
9664 if (!ST.isThumb())
9665 return SDValue(N, 0);
9666
9667 // In Thumb mode, immediates larger than 128 need a wide 4-byte MOV,
9668 // and thus lose the code size benefits of a MOVS that requires only 2.
9669 // TargetTransformInfo and 'getIntImmCodeSizeCost' could be helpful here,
9670 // but as it's doing exactly this, it's not worth the trouble to get TTI.
9671 if (Divisor.sgt(128))
9672 return SDValue();
9673
9674 return SDValue(N, 0);
9675}
9676
9677SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
9678 bool Signed) const {
9679 assert(Op.getValueType() == MVT::i32 &&
9680 "unexpected type for custom lowering DIV");
9681 SDLoc dl(Op);
9682
9683 SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
9684 DAG.getEntryNode(), Op.getOperand(1));
9685
9686 return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9687}
9688
9690 SDLoc DL(N);
9691 SDValue Op = N->getOperand(1);
9692 if (N->getValueType(0) == MVT::i32)
9693 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
9694 SDValue Lo, Hi;
9695 std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32);
9696 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
9697 DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
9698}
9699
9700void ARMTargetLowering::ExpandDIV_Windows(
9701 SDValue Op, SelectionDAG &DAG, bool Signed,
9703 const auto &DL = DAG.getDataLayout();
9704
9705 assert(Op.getValueType() == MVT::i64 &&
9706 "unexpected type for custom lowering DIV");
9707 SDLoc dl(Op);
9708
9709 SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
9710
9711 SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9712
9713 SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
9714 SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
9715 DAG.getConstant(32, dl, getPointerTy(DL)));
9716 Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper);
9717
9718 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lower, Upper));
9719}
9720
9721std::pair<SDValue, SDValue>
9722ARMTargetLowering::LowerAEABIUnalignedLoad(SDValue Op,
9723 SelectionDAG &DAG) const {
9724 // If we have an unaligned load from a i32 or i64 that would normally be
9725 // split into separate ldrb's, we can use the __aeabi_uread4/__aeabi_uread8
9726 // functions instead.
9727 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9728 EVT MemVT = LD->getMemoryVT();
9729 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9730 return std::make_pair(SDValue(), SDValue());
9731
9732 const auto &MF = DAG.getMachineFunction();
9733 unsigned AS = LD->getAddressSpace();
9734 Align Alignment = LD->getAlign();
9735 const DataLayout &DL = DAG.getDataLayout();
9736 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9737 RTLIB::Libcall LC =
9738 (MemVT == MVT::i32) ? RTLIB::AEABI_UREAD4 : RTLIB::AEABI_UREAD8;
9739
9740 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9741 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9742 MakeLibCallOptions Opts;
9743 SDLoc dl(Op);
9744
9745 auto Pair = makeLibCall(DAG, LC, MemVT.getSimpleVT(), LD->getBasePtr(),
9746 Opts, dl, LD->getChain());
9747
9748 // If necessary, extend the node to 64bit
9749 if (LD->getExtensionType() != ISD::NON_EXTLOAD) {
9750 unsigned ExtType = LD->getExtensionType() == ISD::SEXTLOAD
9753 SDValue EN = DAG.getNode(ExtType, dl, LD->getValueType(0), Pair.first);
9754 Pair.first = EN;
9755 }
9756 return Pair;
9757 }
9758
9759 // Default expand to individual loads
9760 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9761 return expandUnalignedLoad(LD, DAG);
9762 return std::make_pair(SDValue(), SDValue());
9763}
9764
9765SDValue ARMTargetLowering::LowerAEABIUnalignedStore(SDValue Op,
9766 SelectionDAG &DAG) const {
9767 // If we have an unaligned store to a i32 or i64 that would normally be
9768 // split into separate ldrb's, we can use the __aeabi_uwrite4/__aeabi_uwrite8
9769 // functions instead.
9770 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9771 EVT MemVT = ST->getMemoryVT();
9772 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9773 return SDValue();
9774
9775 const auto &MF = DAG.getMachineFunction();
9776 unsigned AS = ST->getAddressSpace();
9777 Align Alignment = ST->getAlign();
9778 const DataLayout &DL = DAG.getDataLayout();
9779 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9780 RTLIB::Libcall LC =
9781 (MemVT == MVT::i32) ? RTLIB::AEABI_UWRITE4 : RTLIB::AEABI_UWRITE8;
9782
9783 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9784 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9785
9786 SDLoc dl(Op);
9787
9788 // If necessary, trunc the value to 32bit
9789 SDValue StoreVal = ST->getOperand(1);
9790 if (ST->isTruncatingStore())
9791 StoreVal = DAG.getNode(ISD::TRUNCATE, dl, MemVT, ST->getOperand(1));
9792
9793 MakeLibCallOptions Opts;
9794 auto CallResult =
9795 makeLibCall(DAG, LC, MVT::isVoid, {StoreVal, ST->getBasePtr()}, Opts,
9796 dl, ST->getChain());
9797
9798 return CallResult.second;
9799 }
9800
9801 // Default expand to individual stores
9802 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9803 return expandUnalignedStore(ST, DAG);
9804 return SDValue();
9805}
9806
9808 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9809 EVT MemVT = LD->getMemoryVT();
9810 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9811 MemVT == MVT::v16i1) &&
9812 "Expected a predicate type!");
9813 assert(MemVT == Op.getValueType());
9814 assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
9815 "Expected a non-extending load");
9816 assert(LD->isUnindexed() && "Expected a unindexed load");
9817
9818 // The basic MVE VLDR on a v2i1/v4i1/v8i1 actually loads the entire 16bit
9819 // predicate, with the "v4i1" bits spread out over the 16 bits loaded. We
9820 // need to make sure that 8/4/2 bits are actually loaded into the correct
9821 // place, which means loading the value and then shuffling the values into
9822 // the bottom bits of the predicate.
9823 // Equally, VLDR for an v16i1 will actually load 32bits (so will be incorrect
9824 // for BE).
9825 // Speaking of BE, apparently the rest of llvm will assume a reverse order to
9826 // a natural VMSR(load), so needs to be reversed.
9827
9828 SDLoc dl(Op);
9829 SDValue Load = DAG.getExtLoad(
9830 ISD::EXTLOAD, dl, MVT::i32, LD->getChain(), LD->getBasePtr(),
9832 LD->getMemOperand());
9833 SDValue Val = Load;
9834 if (DAG.getDataLayout().isBigEndian())
9835 Val = DAG.getNode(ISD::SRL, dl, MVT::i32,
9836 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Load),
9837 DAG.getConstant(32 - MemVT.getSizeInBits(), dl, MVT::i32));
9838 SDValue Pred = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Val);
9839 if (MemVT != MVT::v16i1)
9840 Pred = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MemVT, Pred,
9841 DAG.getConstant(0, dl, MVT::i32));
9842 return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
9843}
9844
9845void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9846 SelectionDAG &DAG) const {
9847 LoadSDNode *LD = cast<LoadSDNode>(N);
9848 EVT MemVT = LD->getMemoryVT();
9849
9850 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
9851 !Subtarget->isThumb1Only() && LD->isVolatile() &&
9852 LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
9853 assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
9854 SDLoc dl(N);
9855 SDValue Result = DAG.getMemIntrinsicNode(
9856 ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
9857 {LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
9858 SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
9859 SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
9860 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
9861 Results.append({Pair, Result.getValue(2)});
9862 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
9863 auto Pair = LowerAEABIUnalignedLoad(SDValue(N, 0), DAG);
9864 if (Pair.first) {
9865 Results.push_back(Pair.first);
9866 Results.push_back(Pair.second);
9867 }
9868 }
9869}
9870
9872 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9873 EVT MemVT = ST->getMemoryVT();
9874 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9875 MemVT == MVT::v16i1) &&
9876 "Expected a predicate type!");
9877 assert(MemVT == ST->getValue().getValueType());
9878 assert(!ST->isTruncatingStore() && "Expected a non-extending store");
9879 assert(ST->isUnindexed() && "Expected a unindexed store");
9880
9881 // Only store the v2i1 or v4i1 or v8i1 worth of bits, via a buildvector with
9882 // top bits unset and a scalar store.
9883 SDLoc dl(Op);
9884 SDValue Build = ST->getValue();
9885 if (MemVT != MVT::v16i1) {
9887 for (unsigned I = 0; I < MemVT.getVectorNumElements(); I++) {
9888 unsigned Elt = DAG.getDataLayout().isBigEndian()
9889 ? MemVT.getVectorNumElements() - I - 1
9890 : I;
9891 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Build,
9892 DAG.getConstant(Elt, dl, MVT::i32)));
9893 }
9894 for (unsigned I = MemVT.getVectorNumElements(); I < 16; I++)
9895 Ops.push_back(DAG.getUNDEF(MVT::i32));
9896 Build = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i1, Ops);
9897 }
9898 SDValue GRP = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Build);
9899 if (MemVT == MVT::v16i1 && DAG.getDataLayout().isBigEndian())
9900 GRP = DAG.getNode(ISD::SRL, dl, MVT::i32,
9901 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, GRP),
9902 DAG.getConstant(16, dl, MVT::i32));
9903 return DAG.getTruncStore(
9904 ST->getChain(), dl, GRP, ST->getBasePtr(),
9906 ST->getMemOperand());
9907}
9908
9909SDValue ARMTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG,
9910 const ARMSubtarget *Subtarget) const {
9911 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9912 EVT MemVT = ST->getMemoryVT();
9913
9914 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
9915 !Subtarget->isThumb1Only() && ST->isVolatile() &&
9916 ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
9917 assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
9918 SDNode *N = Op.getNode();
9919 SDLoc dl(N);
9920
9921 SDValue Lo = DAG.getNode(
9922 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
9923 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
9924 MVT::i32));
9925 SDValue Hi = DAG.getNode(
9926 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
9927 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
9928 MVT::i32));
9929
9930 return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
9931 {ST->getChain(), Lo, Hi, ST->getBasePtr()},
9932 MemVT, ST->getMemOperand());
9933 } else if (Subtarget->hasMVEIntegerOps() &&
9934 ((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9935 MemVT == MVT::v16i1))) {
9936 return LowerPredicateStore(Op, DAG);
9937 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
9938 return LowerAEABIUnalignedStore(Op, DAG);
9939 }
9940 return SDValue();
9941}
9942
9943static bool isZeroVector(SDValue N) {
9944 return (ISD::isBuildVectorAllZeros(N.getNode()) ||
9945 (N->getOpcode() == ARMISD::VMOVIMM &&
9946 isNullConstant(N->getOperand(0))));
9947}
9948
9951 MVT VT = Op.getSimpleValueType();
9952 SDValue Mask = N->getMask();
9953 SDValue PassThru = N->getPassThru();
9954 SDLoc dl(Op);
9955
9956 if (isZeroVector(PassThru))
9957 return Op;
9958
9959 // MVE Masked loads use zero as the passthru value. Here we convert undef to
9960 // zero too, and other values are lowered to a select.
9961 SDValue ZeroVec = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
9962 DAG.getTargetConstant(0, dl, MVT::i32));
9963 SDValue NewLoad = DAG.getMaskedLoad(
9964 VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask, ZeroVec,
9965 N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
9966 N->getExtensionType(), N->isExpandingLoad());
9967 SDValue Combo = NewLoad;
9968 bool PassThruIsCastZero = (PassThru.getOpcode() == ISD::BITCAST ||
9969 PassThru.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
9970 isZeroVector(PassThru->getOperand(0));
9971 if (!PassThru.isUndef() && !PassThruIsCastZero)
9972 Combo = DAG.getNode(ISD::VSELECT, dl, VT, Mask, NewLoad, PassThru);
9973 return DAG.getMergeValues({Combo, NewLoad.getValue(1)}, dl);
9974}
9975
9977 const ARMSubtarget *ST) {
9978 if (!ST->hasMVEIntegerOps())
9979 return SDValue();
9980
9981 SDLoc dl(Op);
9982 unsigned BaseOpcode = 0;
9983 switch (Op->getOpcode()) {
9984 default: llvm_unreachable("Expected VECREDUCE opcode");
9985 case ISD::VECREDUCE_FADD: BaseOpcode = ISD::FADD; break;
9986 case ISD::VECREDUCE_FMUL: BaseOpcode = ISD::FMUL; break;
9987 case ISD::VECREDUCE_MUL: BaseOpcode = ISD::MUL; break;
9988 case ISD::VECREDUCE_AND: BaseOpcode = ISD::AND; break;
9989 case ISD::VECREDUCE_OR: BaseOpcode = ISD::OR; break;
9990 case ISD::VECREDUCE_XOR: BaseOpcode = ISD::XOR; break;
9991 case ISD::VECREDUCE_FMAX: BaseOpcode = ISD::FMAXNUM; break;
9992 case ISD::VECREDUCE_FMIN: BaseOpcode = ISD::FMINNUM; break;
9993 }
9994
9995 SDValue Op0 = Op->getOperand(0);
9996 EVT VT = Op0.getValueType();
9997 EVT EltVT = VT.getVectorElementType();
9998 unsigned NumElts = VT.getVectorNumElements();
9999 unsigned NumActiveLanes = NumElts;
10000
10001 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10002 NumActiveLanes == 2) &&
10003 "Only expected a power 2 vector size");
10004
10005 // Use Mul(X, Rev(X)) until 4 items remain. Going down to 4 vector elements
10006 // allows us to easily extract vector elements from the lanes.
10007 while (NumActiveLanes > 4) {
10008 unsigned RevOpcode = NumActiveLanes == 16 ? ARMISD::VREV16 : ARMISD::VREV32;
10009 SDValue Rev = DAG.getNode(RevOpcode, dl, VT, Op0);
10010 Op0 = DAG.getNode(BaseOpcode, dl, VT, Op0, Rev);
10011 NumActiveLanes /= 2;
10012 }
10013
10014 SDValue Res;
10015 if (NumActiveLanes == 4) {
10016 // The remaining 4 elements are summed sequentially
10017 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10018 DAG.getConstant(0 * NumElts / 4, dl, MVT::i32));
10019 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10020 DAG.getConstant(1 * NumElts / 4, dl, MVT::i32));
10021 SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10022 DAG.getConstant(2 * NumElts / 4, dl, MVT::i32));
10023 SDValue Ext3 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10024 DAG.getConstant(3 * NumElts / 4, dl, MVT::i32));
10025 SDValue Res0 = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10026 SDValue Res1 = DAG.getNode(BaseOpcode, dl, EltVT, Ext2, Ext3, Op->getFlags());
10027 Res = DAG.getNode(BaseOpcode, dl, EltVT, Res0, Res1, Op->getFlags());
10028 } else {
10029 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10030 DAG.getConstant(0, dl, MVT::i32));
10031 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10032 DAG.getConstant(1, dl, MVT::i32));
10033 Res = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10034 }
10035
10036 // Result type may be wider than element type.
10037 if (EltVT != Op->getValueType(0))
10038 Res = DAG.getNode(ISD::ANY_EXTEND, dl, Op->getValueType(0), Res);
10039 return Res;
10040}
10041
10043 const ARMSubtarget *ST) {
10044 if (!ST->hasMVEFloatOps())
10045 return SDValue();
10046 return LowerVecReduce(Op, DAG, ST);
10047}
10048
10050 const ARMSubtarget *ST) {
10051 if (!ST->hasNEON())
10052 return SDValue();
10053
10054 SDLoc dl(Op);
10055 SDValue Op0 = Op->getOperand(0);
10056 EVT VT = Op0.getValueType();
10057 EVT EltVT = VT.getVectorElementType();
10058
10059 unsigned PairwiseIntrinsic = 0;
10060 switch (Op->getOpcode()) {
10061 default:
10062 llvm_unreachable("Expected VECREDUCE opcode");
10064 PairwiseIntrinsic = Intrinsic::arm_neon_vpminu;
10065 break;
10067 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxu;
10068 break;
10070 PairwiseIntrinsic = Intrinsic::arm_neon_vpmins;
10071 break;
10073 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxs;
10074 break;
10075 }
10076 SDValue PairwiseOp = DAG.getConstant(PairwiseIntrinsic, dl, MVT::i32);
10077
10078 unsigned NumElts = VT.getVectorNumElements();
10079 unsigned NumActiveLanes = NumElts;
10080
10081 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10082 NumActiveLanes == 2) &&
10083 "Only expected a power 2 vector size");
10084
10085 // Split 128-bit vectors, since vpmin/max takes 2 64-bit vectors.
10086 if (VT.is128BitVector()) {
10087 SDValue Lo, Hi;
10088 std::tie(Lo, Hi) = DAG.SplitVector(Op0, dl);
10089 VT = Lo.getValueType();
10090 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Lo, Hi});
10091 NumActiveLanes /= 2;
10092 }
10093
10094 // Use pairwise reductions until one lane remains
10095 while (NumActiveLanes > 1) {
10096 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Op0, Op0});
10097 NumActiveLanes /= 2;
10098 }
10099
10100 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10101 DAG.getConstant(0, dl, MVT::i32));
10102
10103 // Result type may be wider than element type.
10104 if (EltVT != Op.getValueType()) {
10105 unsigned Extend = 0;
10106 switch (Op->getOpcode()) {
10107 default:
10108 llvm_unreachable("Expected VECREDUCE opcode");
10111 Extend = ISD::ZERO_EXTEND;
10112 break;
10115 Extend = ISD::SIGN_EXTEND;
10116 break;
10117 }
10118 Res = DAG.getNode(Extend, dl, Op.getValueType(), Res);
10119 }
10120 return Res;
10121}
10122
10124 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering()))
10125 // Acquire/Release load/store is not legal for targets without a dmb or
10126 // equivalent available.
10127 return SDValue();
10128
10129 // Monotonic load/store is legal for all targets.
10130 return Op;
10131}
10132
10135 SelectionDAG &DAG,
10136 const ARMSubtarget *Subtarget) {
10137 SDLoc DL(N);
10138 // Under Power Management extensions, the cycle-count is:
10139 // mrc p15, #0, <Rt>, c9, c13, #0
10140 SDValue Ops[] = { N->getOperand(0), // Chain
10141 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
10142 DAG.getTargetConstant(15, DL, MVT::i32),
10143 DAG.getTargetConstant(0, DL, MVT::i32),
10144 DAG.getTargetConstant(9, DL, MVT::i32),
10145 DAG.getTargetConstant(13, DL, MVT::i32),
10146 DAG.getTargetConstant(0, DL, MVT::i32)
10147 };
10148
10149 SDValue Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
10150 DAG.getVTList(MVT::i32, MVT::Other), Ops);
10151 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Cycles32,
10152 DAG.getConstant(0, DL, MVT::i32)));
10153 Results.push_back(Cycles32.getValue(1));
10154}
10155
10157 SDValue V1) {
10158 SDLoc dl(V0.getNode());
10159 SDValue RegClass =
10160 DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
10161 SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
10162 SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
10163 const SDValue Ops[] = {RegClass, V0, SubReg0, V1, SubReg1};
10164 return SDValue(
10165 DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
10166}
10167
10169 SDLoc dl(V.getNode());
10170 auto [VLo, VHi] = DAG.SplitScalar(V, dl, MVT::i32, MVT::i32);
10171 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10172 if (isBigEndian)
10173 std::swap(VLo, VHi);
10174 return createGPRPairNode2xi32(DAG, VLo, VHi);
10175}
10176
10179 SelectionDAG &DAG) {
10180 assert(N->getValueType(0) == MVT::i64 &&
10181 "AtomicCmpSwap on types less than 64 should be legal");
10182 SDValue Ops[] = {
10183 createGPRPairNode2xi32(DAG, N->getOperand(1),
10184 DAG.getUNDEF(MVT::i32)), // pointer, temp
10185 createGPRPairNodei64(DAG, N->getOperand(2)), // expected
10186 createGPRPairNodei64(DAG, N->getOperand(3)), // new
10187 N->getOperand(0), // chain in
10188 };
10189 SDNode *CmpSwap = DAG.getMachineNode(
10190 ARM::CMP_SWAP_64, SDLoc(N),
10191 DAG.getVTList(MVT::Untyped, MVT::Untyped, MVT::Other), Ops);
10192
10193 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
10194 DAG.setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
10195
10196 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10197
10198 SDValue Lo =
10199 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0,
10200 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10201 SDValue Hi =
10202 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1,
10203 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10204 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i64, Lo, Hi));
10205 Results.push_back(SDValue(CmpSwap, 2));
10206}
10207
10208SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
10209 SDLoc dl(Op);
10210 EVT VT = Op.getValueType();
10211 SDValue Chain = Op.getOperand(0);
10212 SDValue LHS = Op.getOperand(1);
10213 SDValue RHS = Op.getOperand(2);
10214 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
10215 bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
10216
10217 // If we don't have instructions of this float type then soften to a libcall
10218 // and use SETCC instead.
10219 if (isUnsupportedFloatingType(LHS.getValueType())) {
10220 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS,
10221 Chain, IsSignaling);
10222 if (!RHS.getNode()) {
10223 RHS = DAG.getConstant(0, dl, LHS.getValueType());
10224 CC = ISD::SETNE;
10225 }
10226 SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
10227 DAG.getCondCode(CC));
10228 return DAG.getMergeValues({Result, Chain}, dl);
10229 }
10230
10231 ARMCC::CondCodes CondCode, CondCode2;
10232 FPCCToARMCC(CC, CondCode, CondCode2);
10233
10234 SDValue True = DAG.getConstant(1, dl, VT);
10235 SDValue False = DAG.getConstant(0, dl, VT);
10236 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
10237 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
10238 SDValue Result = getCMOV(dl, VT, False, True, ARMcc, Cmp, DAG);
10239 if (CondCode2 != ARMCC::AL) {
10240 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
10241 Result = getCMOV(dl, VT, Result, True, ARMcc, Cmp, DAG);
10242 }
10243 return DAG.getMergeValues({Result, Chain}, dl);
10244}
10245
10246SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
10247 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
10248
10249 EVT VT = getPointerTy(DAG.getDataLayout());
10250 int FI = MFI.CreateFixedObject(4, 0, false);
10251 return DAG.getFrameIndex(FI, VT);
10252}
10253
10254SDValue ARMTargetLowering::LowerFP_TO_BF16(SDValue Op,
10255 SelectionDAG &DAG) const {
10256 SDLoc DL(Op);
10257 MakeLibCallOptions CallOptions;
10258 MVT SVT = Op.getOperand(0).getSimpleValueType();
10259 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, MVT::bf16);
10260 SDValue Res =
10261 makeLibCall(DAG, LC, MVT::f32, Op.getOperand(0), CallOptions, DL).first;
10262 return DAG.getBitcast(MVT::i32, Res);
10263}
10264
10265SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
10266 SDLoc dl(Op);
10267 SDValue LHS = Op.getOperand(0);
10268 SDValue RHS = Op.getOperand(1);
10269
10270 // Determine if this is signed or unsigned comparison
10271 bool IsSigned = (Op.getOpcode() == ISD::SCMP);
10272
10273 // Special case for Thumb1 UCMP only
10274 if (!IsSigned && Subtarget->isThumb1Only()) {
10275 // For Thumb unsigned comparison, use this sequence:
10276 // subs r2, r0, r1 ; r2 = LHS - RHS, sets flags
10277 // sbc r2, r2 ; r2 = r2 - r2 - !carry
10278 // cmp r1, r0 ; compare RHS with LHS
10279 // sbc r1, r1 ; r1 = r1 - r1 - !carry
10280 // subs r0, r2, r1 ; r0 = r2 - r1 (final result)
10281
10282 // First subtraction: LHS - RHS
10283 SDValue Sub1WithFlags = DAG.getNode(
10284 ARMISD::SUBC, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10285 SDValue Sub1Result = Sub1WithFlags.getValue(0);
10286 SDValue Flags1 = Sub1WithFlags.getValue(1);
10287
10288 // SUBE: Sub1Result - Sub1Result - !carry
10289 // This gives 0 if LHS >= RHS (unsigned), -1 if LHS < RHS (unsigned)
10290 SDValue Sbc1 =
10291 DAG.getNode(ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT),
10292 Sub1Result, Sub1Result, Flags1);
10293 SDValue Sbc1Result = Sbc1.getValue(0);
10294
10295 // Second comparison: RHS vs LHS (reverse comparison)
10296 SDValue CmpFlags = DAG.getNode(ARMISD::CMP, dl, FlagsVT, RHS, LHS);
10297
10298 // SUBE: RHS - RHS - !carry
10299 // This gives 0 if RHS <= LHS (unsigned), -1 if RHS > LHS (unsigned)
10300 SDValue Sbc2 = DAG.getNode(
10301 ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT), RHS, RHS, CmpFlags);
10302 SDValue Sbc2Result = Sbc2.getValue(0);
10303
10304 // Final subtraction: Sbc1Result - Sbc2Result (no flags needed)
10305 SDValue Result =
10306 DAG.getNode(ISD::SUB, dl, MVT::i32, Sbc1Result, Sbc2Result);
10307 if (Op.getValueType() != MVT::i32)
10308 Result = DAG.getSExtOrTrunc(Result, dl, Op.getValueType());
10309
10310 return Result;
10311 }
10312
10313 // For the ARM assembly pattern:
10314 // subs r0, r0, r1 ; subtract RHS from LHS and set flags
10315 // movgt r0, #1 ; if LHS > RHS, set result to 1 (GT for signed, HI for
10316 // unsigned) mvnlt r0, #0 ; if LHS < RHS, set result to -1 (LT for
10317 // signed, LO for unsigned)
10318 // ; if LHS == RHS, result remains 0 from the subs
10319
10320 // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
10321 unsigned Opcode = ARMISD::SUBC;
10322
10323 // Check if RHS is a subtraction against 0: (0 - X)
10324 if (RHS.getOpcode() == ISD::SUB) {
10325 SDValue SubLHS = RHS.getOperand(0);
10326 SDValue SubRHS = RHS.getOperand(1);
10327
10328 // Check if it's 0 - X
10329 if (isNullConstant(SubLHS)) {
10330 bool CanUseAdd = false;
10331 if (IsSigned) {
10332 // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
10333 if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
10335 .isMinSignedValue()) {
10336 CanUseAdd = true;
10337 }
10338 } else {
10339 // For UCMP: only if X is known to never be zero
10340 if (DAG.isKnownNeverZero(SubRHS)) {
10341 CanUseAdd = true;
10342 }
10343 }
10344
10345 if (CanUseAdd) {
10346 Opcode = ARMISD::ADDC;
10347 RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
10348 // LHS - (0 - X)
10349 }
10350 }
10351 }
10352
10353 // Generate the operation with flags
10354 SDValue OpWithFlags =
10355 DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10356
10357 SDValue OpResult = OpWithFlags.getValue(0);
10358 SDValue Flags = OpWithFlags.getValue(1);
10359
10360 // Constants for conditional moves
10361 SDValue One = DAG.getConstant(1, dl, MVT::i32);
10362 SDValue MinusOne = DAG.getAllOnesConstant(dl, MVT::i32);
10363
10364 // Select condition codes based on signed vs unsigned
10365 ARMCC::CondCodes GTCond = IsSigned ? ARMCC::GT : ARMCC::HI;
10366 ARMCC::CondCodes LTCond = IsSigned ? ARMCC::LT : ARMCC::LO;
10367
10368 // First conditional move: if greater than, set to 1
10369 SDValue GTCondValue = DAG.getConstant(GTCond, dl, MVT::i32);
10370 SDValue Result1 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, OpResult, One,
10371 GTCondValue, Flags);
10372
10373 // Second conditional move: if less than, set to -1
10374 SDValue LTCondValue = DAG.getConstant(LTCond, dl, MVT::i32);
10375 SDValue Result2 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, Result1, MinusOne,
10376 LTCondValue, Flags);
10377
10378 if (Op.getValueType() != MVT::i32)
10379 Result2 = DAG.getSExtOrTrunc(Result2, dl, Op.getValueType());
10380
10381 return Result2;
10382}
10383
10385 LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
10386 switch (Op.getOpcode()) {
10387 default: llvm_unreachable("Don't know how to custom lower this!");
10388 case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
10389 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
10390 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
10391 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
10392 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
10393 case ISD::SELECT: return LowerSELECT(Op, DAG);
10394 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10395 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
10396 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
10397 case ISD::BR_JT: return LowerBR_JT(Op, DAG);
10398 case ISD::VASTART: return LowerVASTART(Op, DAG);
10399 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget);
10400 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget);
10403 case ISD::SINT_TO_FP:
10404 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
10407 case ISD::FP_TO_SINT:
10408 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
10410 case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG, Subtarget);
10411 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
10412 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
10413 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
10414 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
10415 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
10416 case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
10417 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
10418 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
10419 Subtarget);
10420 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);
10421 case ISD::SHL:
10422 case ISD::SRL:
10423 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget);
10424 case ISD::SREM: return LowerREM(Op.getNode(), DAG);
10425 case ISD::UREM: return LowerREM(Op.getNode(), DAG);
10426 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
10427 case ISD::SRL_PARTS:
10428 case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
10429 case ISD::CTTZ:
10430 case ISD::CTTZ_ZERO_POISON: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
10431 case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
10432 case ISD::SETCC: return LowerVSETCC(Op, DAG, Subtarget);
10433 case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
10434 case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
10435 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
10436 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
10437 case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG, Subtarget);
10438 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
10439 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
10440 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
10441 case ISD::TRUNCATE: return LowerTruncate(Op.getNode(), DAG, Subtarget);
10442 case ISD::SIGN_EXTEND:
10443 case ISD::ZERO_EXTEND: return LowerVectorExtend(Op.getNode(), DAG, Subtarget);
10444 case ISD::GET_ROUNDING: return LowerGET_ROUNDING(Op, DAG);
10445 case ISD::SET_ROUNDING: return LowerSET_ROUNDING(Op, DAG);
10446 case ISD::SET_FPMODE:
10447 return LowerSET_FPMODE(Op, DAG);
10448 case ISD::RESET_FPMODE:
10449 return LowerRESET_FPMODE(Op, DAG);
10450 case ISD::MUL: return LowerMUL(Op, DAG);
10451 case ISD::SDIV:
10452 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10453 !Op.getValueType().isVector())
10454 return LowerDIV_Windows(Op, DAG, /* Signed */ true);
10455 return LowerSDIV(Op, DAG, Subtarget);
10456 case ISD::UDIV:
10457 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10458 !Op.getValueType().isVector())
10459 return LowerDIV_Windows(Op, DAG, /* Signed */ false);
10460 return LowerUDIV(Op, DAG, Subtarget);
10461 case ISD::UADDO_CARRY:
10462 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, false /*unsigned*/);
10463 case ISD::USUBO_CARRY:
10464 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, false /*unsigned*/);
10465 case ISD::SADDO_CARRY:
10466 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, true /*signed*/);
10467 case ISD::SSUBO_CARRY:
10468 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, true /*signed*/);
10469 case ISD::UADDO:
10470 case ISD::USUBO:
10471 case ISD::UMULO:
10472 case ISD::SADDO:
10473 case ISD::SSUBO:
10474 case ISD::SMULO:
10475 return LowerALUO(Op, DAG);
10476 case ISD::SADDSAT:
10477 case ISD::SSUBSAT:
10478 case ISD::UADDSAT:
10479 case ISD::USUBSAT:
10480 return LowerADDSUBSAT(Op, DAG, Subtarget);
10481 case ISD::LOAD: {
10482 auto *LD = cast<LoadSDNode>(Op);
10483 EVT MemVT = LD->getMemoryVT();
10484 if (Subtarget->hasMVEIntegerOps() &&
10485 (MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10486 MemVT == MVT::v16i1))
10487 return LowerPredicateLoad(Op, DAG);
10488
10489 auto Pair = LowerAEABIUnalignedLoad(Op, DAG);
10490 if (Pair.first)
10491 return DAG.getMergeValues({Pair.first, Pair.second}, SDLoc(Pair.first));
10492 return SDValue();
10493 }
10494 case ISD::STORE:
10495 return LowerSTORE(Op, DAG, Subtarget);
10496 case ISD::MLOAD:
10497 return LowerMLOAD(Op, DAG);
10498 case ISD::VECREDUCE_MUL:
10499 case ISD::VECREDUCE_AND:
10500 case ISD::VECREDUCE_OR:
10501 case ISD::VECREDUCE_XOR:
10502 return LowerVecReduce(Op, DAG, Subtarget);
10507 return LowerVecReduceF(Op, DAG, Subtarget);
10512 return LowerVecReduceMinMax(Op, DAG, Subtarget);
10513 case ISD::ATOMIC_LOAD:
10514 case ISD::ATOMIC_STORE:
10515 return LowerAtomicLoadStore(Op, DAG);
10516 case ISD::SDIVREM:
10517 case ISD::UDIVREM: return LowerDivRem(Op, DAG);
10519 if (getTargetMachine().getTargetTriple().isOSWindows())
10520 return LowerDYNAMIC_STACKALLOC(Op, DAG);
10521 llvm_unreachable("Don't know how to custom lower this!");
10523 case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
10525 case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
10526 case ISD::STRICT_FSETCC:
10527 case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
10528 case ISD::SPONENTRY:
10529 return LowerSPONENTRY(Op, DAG);
10530 case ISD::FP_TO_BF16:
10531 return LowerFP_TO_BF16(Op, DAG);
10532 case ARMISD::WIN__DBZCHK: return SDValue();
10533 case ISD::UCMP:
10534 case ISD::SCMP:
10535 return LowerCMP(Op, DAG);
10536 case ISD::ABS:
10537 return LowerABS(Op, DAG);
10538 case ISD::STRICT_LROUND:
10540 case ISD::STRICT_LRINT:
10541 case ISD::STRICT_LLRINT: {
10542 assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10543 Op.getOperand(1).getValueType() == MVT::bf16) &&
10544 "Expected custom lowering of rounding operations only for f16");
10545 SDLoc DL(Op);
10546 SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10547 {Op.getOperand(0), Op.getOperand(1)});
10548 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10549 {Ext.getValue(1), Ext.getValue(0)});
10550 }
10551 }
10552}
10553
10555 SelectionDAG &DAG) {
10556 unsigned IntNo = N->getConstantOperandVal(0);
10557 unsigned Opc = 0;
10558 if (IntNo == Intrinsic::arm_smlald)
10559 Opc = ARMISD::SMLALD;
10560 else if (IntNo == Intrinsic::arm_smlaldx)
10561 Opc = ARMISD::SMLALDX;
10562 else if (IntNo == Intrinsic::arm_smlsld)
10563 Opc = ARMISD::SMLSLD;
10564 else if (IntNo == Intrinsic::arm_smlsldx)
10565 Opc = ARMISD::SMLSLDX;
10566 else
10567 return;
10568
10569 SDLoc dl(N);
10570 SDValue Lo, Hi;
10571 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32);
10572
10573 SDValue LongMul = DAG.getNode(Opc, dl,
10574 DAG.getVTList(MVT::i32, MVT::i32),
10575 N->getOperand(1), N->getOperand(2),
10576 Lo, Hi);
10577 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
10578 LongMul.getValue(0), LongMul.getValue(1)));
10579}
10580
10581/// ReplaceNodeResults - Replace the results of node with an illegal result
10582/// type with new values built out of custom code.
10585 SelectionDAG &DAG) const {
10586 SDValue Res;
10587 switch (N->getOpcode()) {
10588 default:
10589 llvm_unreachable("Don't know how to custom expand this!");
10590 case ISD::READ_REGISTER:
10592 break;
10593 case ISD::BITCAST:
10594 Res = ExpandBITCAST(N, DAG, Subtarget);
10595 break;
10596 case ISD::SRL:
10597 case ISD::SRA:
10598 case ISD::SHL:
10599 Res = Expand64BitShift(N, DAG, Subtarget);
10600 break;
10601 case ISD::SREM:
10602 case ISD::UREM:
10603 Res = LowerREM(N, DAG);
10604 break;
10605 case ISD::SDIVREM:
10606 case ISD::UDIVREM:
10607 Res = LowerDivRem(SDValue(N, 0), DAG);
10608 assert(Res.getNumOperands() == 2 && "DivRem needs two values");
10609 Results.push_back(Res.getValue(0));
10610 Results.push_back(Res.getValue(1));
10611 return;
10612 case ISD::SADDSAT:
10613 case ISD::SSUBSAT:
10614 case ISD::UADDSAT:
10615 case ISD::USUBSAT:
10616 Res = LowerADDSUBSAT(SDValue(N, 0), DAG, Subtarget);
10617 break;
10619 ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
10620 return;
10621 case ISD::UDIV:
10622 case ISD::SDIV:
10623 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
10624 "can only expand DIV on Windows");
10625 return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
10626 Results);
10629 return;
10631 return ReplaceLongIntrinsic(N, Results, DAG);
10632 case ISD::LOAD:
10633 LowerLOAD(N, Results, DAG);
10634 break;
10635 case ISD::STORE:
10636 Res = LowerAEABIUnalignedStore(SDValue(N, 0), DAG);
10637 break;
10638 case ISD::TRUNCATE:
10639 Res = LowerTruncate(N, DAG, Subtarget);
10640 break;
10641 case ISD::SIGN_EXTEND:
10642 case ISD::ZERO_EXTEND:
10643 Res = LowerVectorExtend(N, DAG, Subtarget);
10644 break;
10647 Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
10648 break;
10649 }
10650 if (Res.getNode())
10651 Results.push_back(Res);
10652}
10653
10654//===----------------------------------------------------------------------===//
10655// ARM Scheduler Hooks
10656//===----------------------------------------------------------------------===//
10657
10658/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and
10659/// registers the function context.
10660void ARMTargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
10662 MachineBasicBlock *DispatchBB,
10663 int FI) const {
10664 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
10665 "ROPI/RWPI not currently supported with SjLj");
10666 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10667 DebugLoc dl = MI.getDebugLoc();
10668 MachineFunction *MF = MBB->getParent();
10672 const Function &F = MF->getFunction();
10673
10674 bool isThumb = Subtarget->isThumb();
10675 bool isThumb2 = Subtarget->isThumb2();
10676
10677 unsigned PCLabelId = AFI->createPICLabelUId();
10678 unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8;
10680 ARMConstantPoolMBB::Create(F.getContext(), DispatchBB, PCLabelId, PCAdj);
10681 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
10682
10683 const TargetRegisterClass *TRC = isThumb ? &ARM::tGPRRegClass
10684 : &ARM::GPRRegClass;
10685
10686 // Grab constant pool and fixed stack memory operands.
10687 MachineMemOperand *CPMMO =
10690
10691 MachineMemOperand *FIMMOSt =
10694
10695 // Load the address of the dispatch MBB into the jump buffer.
10696 if (isThumb2) {
10697 // Incoming value: jbuf
10698 // ldr.n r5, LCPI1_1
10699 // orr r5, r5, #1
10700 // add r5, pc
10701 // str r5, [$jbuf, #+4] ; &jbuf[1]
10702 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10703 BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1)
10705 .addMemOperand(CPMMO)
10707 // Set the low bit because of thumb mode.
10708 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10709 BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2)
10710 .addReg(NewVReg1)
10711 .addImm(0x01)
10713 .add(condCodeOp());
10714 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10715 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3)
10716 .addReg(NewVReg2)
10717 .addImm(PCLabelId);
10718 BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12))
10719 .addReg(NewVReg3)
10720 .addFrameIndex(FI)
10721 .addImm(36) // &jbuf[1] :: pc
10722 .addMemOperand(FIMMOSt)
10724 } else if (isThumb) {
10725 // Incoming value: jbuf
10726 // ldr.n r1, LCPI1_4
10727 // add r1, pc
10728 // mov r2, #1
10729 // orrs r1, r2
10730 // add r2, $jbuf, #+4 ; &jbuf[1]
10731 // str r1, [r2]
10732 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10733 BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1)
10735 .addMemOperand(CPMMO)
10737 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10738 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2)
10739 .addReg(NewVReg1)
10740 .addImm(PCLabelId);
10741 // Set the low bit because of thumb mode.
10742 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10743 BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3)
10744 .addReg(ARM::CPSR, RegState::Define)
10745 .addImm(1)
10747 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10748 BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4)
10749 .addReg(ARM::CPSR, RegState::Define)
10750 .addReg(NewVReg2)
10751 .addReg(NewVReg3)
10753 Register NewVReg5 = MRI->createVirtualRegister(TRC);
10754 BuildMI(*MBB, MI, dl, TII->get(ARM::tADDframe), NewVReg5)
10755 .addFrameIndex(FI)
10756 .addImm(36); // &jbuf[1] :: pc
10757 BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi))
10758 .addReg(NewVReg4)
10759 .addReg(NewVReg5)
10760 .addImm(0)
10761 .addMemOperand(FIMMOSt)
10763 } else {
10764 // Incoming value: jbuf
10765 // ldr r1, LCPI1_1
10766 // add r1, pc, r1
10767 // str r1, [$jbuf, #+4] ; &jbuf[1]
10768 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10769 BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1)
10771 .addImm(0)
10772 .addMemOperand(CPMMO)
10774 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10775 BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
10776 .addReg(NewVReg1)
10777 .addImm(PCLabelId)
10779 BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
10780 .addReg(NewVReg2)
10781 .addFrameIndex(FI)
10782 .addImm(36) // &jbuf[1] :: pc
10783 .addMemOperand(FIMMOSt)
10785 }
10786}
10787
10788void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
10789 MachineBasicBlock *MBB) const {
10790 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10791 DebugLoc dl = MI.getDebugLoc();
10792 MachineFunction *MF = MBB->getParent();
10793 MachineRegisterInfo *MRI = &MF->getRegInfo();
10794 MachineFrameInfo &MFI = MF->getFrameInfo();
10795 int FI = MFI.getFunctionContextIndex();
10796
10797 const TargetRegisterClass *TRC = Subtarget->isThumb() ? &ARM::tGPRRegClass
10798 : &ARM::GPRnopcRegClass;
10799
10800 // Get a mapping of the call site numbers to all of the landing pads they're
10801 // associated with.
10802 DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2>> CallSiteNumToLPad;
10803 unsigned MaxCSNum = 0;
10804 for (MachineBasicBlock &BB : *MF) {
10805 if (!BB.isEHPad())
10806 continue;
10807
10808 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
10809 // pad.
10810 for (MachineInstr &II : BB) {
10811 if (!II.isEHLabel())
10812 continue;
10813
10814 MCSymbol *Sym = II.getOperand(0).getMCSymbol();
10815 if (!MF->hasCallSiteLandingPad(Sym)) continue;
10816
10817 SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
10818 for (unsigned Idx : CallSiteIdxs) {
10819 CallSiteNumToLPad[Idx].push_back(&BB);
10820 MaxCSNum = std::max(MaxCSNum, Idx);
10821 }
10822 break;
10823 }
10824 }
10825
10826 // Get an ordered list of the machine basic blocks for the jump table.
10827 std::vector<MachineBasicBlock*> LPadList;
10828 SmallPtrSet<MachineBasicBlock*, 32> InvokeBBs;
10829 LPadList.reserve(CallSiteNumToLPad.size());
10830 for (unsigned I = 1; I <= MaxCSNum; ++I) {
10831 SmallVectorImpl<MachineBasicBlock*> &MBBList = CallSiteNumToLPad[I];
10832 for (MachineBasicBlock *MBB : MBBList) {
10833 LPadList.push_back(MBB);
10834 InvokeBBs.insert_range(MBB->predecessors());
10835 }
10836 }
10837
10838 assert(!LPadList.empty() &&
10839 "No landing pad destinations for the dispatch jump table!");
10840
10841 // Create the jump table and associated information.
10842 MachineJumpTableInfo *JTI =
10843 MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline);
10844 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
10845
10846 // Create the MBBs for the dispatch code.
10847
10848 // Shove the dispatch's address into the return slot in the function context.
10849 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
10850 DispatchBB->setIsEHPad();
10851
10852 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
10853
10854 BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
10855 DispatchBB->addSuccessor(TrapBB);
10856
10857 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
10858 DispatchBB->addSuccessor(DispContBB);
10859
10860 // Insert and MBBs.
10861 MF->insert(MF->end(), DispatchBB);
10862 MF->insert(MF->end(), DispContBB);
10863 MF->insert(MF->end(), TrapBB);
10864
10865 // Insert code into the entry block that creates and registers the function
10866 // context.
10867 SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI);
10868
10869 MachineMemOperand *FIMMOLd = MF->getMachineMemOperand(
10872
10873 MachineInstrBuilder MIB;
10874 MIB = BuildMI(DispatchBB, dl, TII->get(ARM::Int_eh_sjlj_dispatchsetup));
10875
10876 const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
10877 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
10878
10879 // Add a register mask with no preserved registers. This results in all
10880 // registers being marked as clobbered. This can't work if the dispatch block
10881 // is in a Thumb1 function and is linked with ARM code which uses the FP
10882 // registers, as there is no way to preserve the FP registers in Thumb1 mode.
10884
10885 bool IsPositionIndependent = isPositionIndependent();
10886 unsigned NumLPads = LPadList.size();
10887 if (Subtarget->isThumb2()) {
10888 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10889 BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1)
10890 .addFrameIndex(FI)
10891 .addImm(4)
10892 .addMemOperand(FIMMOLd)
10894
10895 if (NumLPads < 256) {
10896 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri))
10897 .addReg(NewVReg1)
10898 .addImm(LPadList.size())
10900 } else {
10901 Register VReg1 = MRI->createVirtualRegister(TRC);
10902 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVi16), VReg1)
10903 .addImm(NumLPads & 0xFFFF)
10905
10906 unsigned VReg2 = VReg1;
10907 if ((NumLPads & 0xFFFF0000) != 0) {
10908 VReg2 = MRI->createVirtualRegister(TRC);
10909 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVTi16), VReg2)
10910 .addReg(VReg1)
10911 .addImm(NumLPads >> 16)
10913 }
10914
10915 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPrr))
10916 .addReg(NewVReg1)
10917 .addReg(VReg2)
10919 }
10920
10921 BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc))
10922 .addMBB(TrapBB)
10924 .addReg(ARM::CPSR);
10925
10926 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10927 BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT), NewVReg3)
10928 .addJumpTableIndex(MJTI)
10930
10931 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10932 BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg4)
10933 .addReg(NewVReg3)
10934 .addReg(NewVReg1)
10937 .add(condCodeOp());
10938
10939 BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT))
10940 .addReg(NewVReg4)
10941 .addReg(NewVReg1)
10942 .addJumpTableIndex(MJTI);
10943 } else if (Subtarget->isThumb()) {
10944 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10945 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1)
10946 .addFrameIndex(FI)
10947 .addImm(1)
10948 .addMemOperand(FIMMOLd)
10950
10951 if (NumLPads < 256) {
10952 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8))
10953 .addReg(NewVReg1)
10954 .addImm(NumLPads)
10956 } else {
10957 MachineConstantPool *ConstantPool = MF->getConstantPool();
10958 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
10959 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
10960
10961 // MachineConstantPool wants an explicit alignment.
10962 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
10963 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
10964
10965 Register VReg1 = MRI->createVirtualRegister(TRC);
10966 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRpci))
10967 .addReg(VReg1, RegState::Define)
10970 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPr))
10971 .addReg(NewVReg1)
10972 .addReg(VReg1)
10974 }
10975
10976 BuildMI(DispatchBB, dl, TII->get(ARM::tBcc))
10977 .addMBB(TrapBB)
10979 .addReg(ARM::CPSR);
10980
10981 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10982 BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2)
10983 .addReg(ARM::CPSR, RegState::Define)
10984 .addReg(NewVReg1)
10985 .addImm(2)
10987
10988 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10989 BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3)
10990 .addJumpTableIndex(MJTI)
10992
10993 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10994 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4)
10995 .addReg(ARM::CPSR, RegState::Define)
10996 .addReg(NewVReg2)
10997 .addReg(NewVReg3)
10999
11000 MachineMemOperand *JTMMOLd =
11001 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11003
11004 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11005 BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5)
11006 .addReg(NewVReg4)
11007 .addImm(0)
11008 .addMemOperand(JTMMOLd)
11010
11011 unsigned NewVReg6 = NewVReg5;
11012 if (IsPositionIndependent) {
11013 NewVReg6 = MRI->createVirtualRegister(TRC);
11014 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6)
11015 .addReg(ARM::CPSR, RegState::Define)
11016 .addReg(NewVReg5)
11017 .addReg(NewVReg3)
11019 }
11020
11021 BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr))
11022 .addReg(NewVReg6)
11023 .addJumpTableIndex(MJTI);
11024 } else {
11025 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11026 BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1)
11027 .addFrameIndex(FI)
11028 .addImm(4)
11029 .addMemOperand(FIMMOLd)
11031
11032 if (NumLPads < 256) {
11033 BuildMI(DispatchBB, dl, TII->get(ARM::CMPri))
11034 .addReg(NewVReg1)
11035 .addImm(NumLPads)
11037 } else if (Subtarget->hasV6T2Ops() && isUInt<16>(NumLPads)) {
11038 Register VReg1 = MRI->createVirtualRegister(TRC);
11039 BuildMI(DispatchBB, dl, TII->get(ARM::MOVi16), VReg1)
11040 .addImm(NumLPads & 0xFFFF)
11042
11043 unsigned VReg2 = VReg1;
11044 if ((NumLPads & 0xFFFF0000) != 0) {
11045 VReg2 = MRI->createVirtualRegister(TRC);
11046 BuildMI(DispatchBB, dl, TII->get(ARM::MOVTi16), VReg2)
11047 .addReg(VReg1)
11048 .addImm(NumLPads >> 16)
11050 }
11051
11052 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11053 .addReg(NewVReg1)
11054 .addReg(VReg2)
11056 } else {
11057 MachineConstantPool *ConstantPool = MF->getConstantPool();
11058 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11059 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11060
11061 // MachineConstantPool wants an explicit alignment.
11062 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11063 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11064
11065 Register VReg1 = MRI->createVirtualRegister(TRC);
11066 BuildMI(DispatchBB, dl, TII->get(ARM::LDRcp))
11067 .addReg(VReg1, RegState::Define)
11069 .addImm(0)
11071 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11072 .addReg(NewVReg1)
11073 .addReg(VReg1)
11075 }
11076
11077 BuildMI(DispatchBB, dl, TII->get(ARM::Bcc))
11078 .addMBB(TrapBB)
11080 .addReg(ARM::CPSR);
11081
11082 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11083 BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg3)
11084 .addReg(NewVReg1)
11087 .add(condCodeOp());
11088 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11089 BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg4)
11090 .addJumpTableIndex(MJTI)
11092
11093 MachineMemOperand *JTMMOLd =
11094 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11096 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11097 BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg5)
11098 .addReg(NewVReg3)
11099 .addReg(NewVReg4)
11100 .addImm(0)
11101 .addMemOperand(JTMMOLd)
11103
11104 if (IsPositionIndependent) {
11105 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd))
11106 .addReg(NewVReg5)
11107 .addReg(NewVReg4)
11108 .addJumpTableIndex(MJTI);
11109 } else {
11110 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTr))
11111 .addReg(NewVReg5)
11112 .addJumpTableIndex(MJTI);
11113 }
11114 }
11115
11116 // Add the jump table entries as successors to the MBB.
11117 SmallPtrSet<MachineBasicBlock*, 8> SeenMBBs;
11118 for (MachineBasicBlock *CurMBB : LPadList) {
11119 if (SeenMBBs.insert(CurMBB).second)
11120 DispContBB->addSuccessor(CurMBB);
11121 }
11122
11123 // N.B. the order the invoke BBs are processed in doesn't matter here.
11124 const MCPhysReg *SavedRegs = RI.getCalleeSavedRegs(MF);
11126 for (MachineBasicBlock *BB : InvokeBBs) {
11127
11128 // Remove the landing pad successor from the invoke block and replace it
11129 // with the new dispatch block.
11130 SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
11131 while (!Successors.empty()) {
11132 MachineBasicBlock *SMBB = Successors.pop_back_val();
11133 if (SMBB->isEHPad()) {
11134 BB->removeSuccessor(SMBB);
11135 MBBLPads.push_back(SMBB);
11136 }
11137 }
11138
11139 BB->addSuccessor(DispatchBB, BranchProbability::getZero());
11140 BB->normalizeSuccProbs();
11141
11142 // Find the invoke call and mark all of the callee-saved registers as
11143 // 'implicit defined' so that they're spilled. This prevents code from
11144 // moving instructions to before the EH block, where they will never be
11145 // executed.
11147 II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
11148 if (!II->isCall()) continue;
11149
11150 DenseSet<unsigned> DefRegs;
11152 OI = II->operands_begin(), OE = II->operands_end();
11153 OI != OE; ++OI) {
11154 if (!OI->isReg()) continue;
11155 DefRegs.insert(OI->getReg());
11156 }
11157
11158 MachineInstrBuilder MIB(*MF, &*II);
11159
11160 for (unsigned i = 0; SavedRegs[i] != 0; ++i) {
11161 unsigned Reg = SavedRegs[i];
11162 if (Subtarget->isThumb2() &&
11163 !ARM::tGPRRegClass.contains(Reg) &&
11164 !ARM::hGPRRegClass.contains(Reg))
11165 continue;
11166 if (Subtarget->isThumb1Only() && !ARM::tGPRRegClass.contains(Reg))
11167 continue;
11168 if (!Subtarget->isThumb() && !ARM::GPRRegClass.contains(Reg))
11169 continue;
11170 if (!DefRegs.contains(Reg))
11172 }
11173
11174 break;
11175 }
11176 }
11177
11178 // Mark all former landing pads as non-landing pads. The dispatch is the only
11179 // landing pad now.
11180 for (MachineBasicBlock *MBBLPad : MBBLPads)
11181 MBBLPad->setIsEHPad(false);
11182
11183 // The instruction is gone now.
11184 MI.eraseFromParent();
11185}
11186
11187static
11189 for (MachineBasicBlock *S : MBB->successors())
11190 if (S != Succ)
11191 return S;
11192 llvm_unreachable("Expecting a BB with two successors!");
11193}
11194
11195/// Return the load opcode for a given load size. If load size >= 8,
11196/// neon opcode will be returned.
11197static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2) {
11198 if (LdSize >= 8)
11199 return LdSize == 16 ? ARM::VLD1q32wb_fixed
11200 : LdSize == 8 ? ARM::VLD1d32wb_fixed : 0;
11201 if (IsThumb1)
11202 return LdSize == 4 ? ARM::tLDRi
11203 : LdSize == 2 ? ARM::tLDRHi
11204 : LdSize == 1 ? ARM::tLDRBi : 0;
11205 if (IsThumb2)
11206 return LdSize == 4 ? ARM::t2LDR_POST
11207 : LdSize == 2 ? ARM::t2LDRH_POST
11208 : LdSize == 1 ? ARM::t2LDRB_POST : 0;
11209 return LdSize == 4 ? ARM::LDR_POST_IMM
11210 : LdSize == 2 ? ARM::LDRH_POST
11211 : LdSize == 1 ? ARM::LDRB_POST_IMM : 0;
11212}
11213
11214/// Return the store opcode for a given store size. If store size >= 8,
11215/// neon opcode will be returned.
11216static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2) {
11217 if (StSize >= 8)
11218 return StSize == 16 ? ARM::VST1q32wb_fixed
11219 : StSize == 8 ? ARM::VST1d32wb_fixed : 0;
11220 if (IsThumb1)
11221 return StSize == 4 ? ARM::tSTRi
11222 : StSize == 2 ? ARM::tSTRHi
11223 : StSize == 1 ? ARM::tSTRBi : 0;
11224 if (IsThumb2)
11225 return StSize == 4 ? ARM::t2STR_POST
11226 : StSize == 2 ? ARM::t2STRH_POST
11227 : StSize == 1 ? ARM::t2STRB_POST : 0;
11228 return StSize == 4 ? ARM::STR_POST_IMM
11229 : StSize == 2 ? ARM::STRH_POST
11230 : StSize == 1 ? ARM::STRB_POST_IMM : 0;
11231}
11232
11233/// Emit a post-increment load operation with given size. The instructions
11234/// will be added to BB at Pos.
11236 const TargetInstrInfo *TII, const DebugLoc &dl,
11237 unsigned LdSize, unsigned Data, unsigned AddrIn,
11238 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11239 unsigned LdOpc = getLdOpcode(LdSize, IsThumb1, IsThumb2);
11240 assert(LdOpc != 0 && "Should have a load opcode");
11241 if (LdSize >= 8) {
11242 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11243 .addReg(AddrOut, RegState::Define)
11244 .addReg(AddrIn)
11245 .addImm(0)
11247 } else if (IsThumb1) {
11248 // load + update AddrIn
11249 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11250 .addReg(AddrIn)
11251 .addImm(0)
11253 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11254 .add(t1CondCodeOp())
11255 .addReg(AddrIn)
11256 .addImm(LdSize)
11258 } else if (IsThumb2) {
11259 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11260 .addReg(AddrOut, RegState::Define)
11261 .addReg(AddrIn)
11262 .addImm(LdSize)
11264 } else { // arm
11265 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11266 .addReg(AddrOut, RegState::Define)
11267 .addReg(AddrIn)
11268 .addReg(0)
11269 .addImm(LdSize)
11271 }
11272}
11273
11274/// Emit a post-increment store operation with given size. The instructions
11275/// will be added to BB at Pos.
11277 const TargetInstrInfo *TII, const DebugLoc &dl,
11278 unsigned StSize, unsigned Data, unsigned AddrIn,
11279 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11280 unsigned StOpc = getStOpcode(StSize, IsThumb1, IsThumb2);
11281 assert(StOpc != 0 && "Should have a store opcode");
11282 if (StSize >= 8) {
11283 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11284 .addReg(AddrIn)
11285 .addImm(0)
11286 .addReg(Data)
11288 } else if (IsThumb1) {
11289 // store + update AddrIn
11290 BuildMI(*BB, Pos, dl, TII->get(StOpc))
11291 .addReg(Data)
11292 .addReg(AddrIn)
11293 .addImm(0)
11295 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11296 .add(t1CondCodeOp())
11297 .addReg(AddrIn)
11298 .addImm(StSize)
11300 } else if (IsThumb2) {
11301 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11302 .addReg(Data)
11303 .addReg(AddrIn)
11304 .addImm(StSize)
11306 } else { // arm
11307 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11308 .addReg(Data)
11309 .addReg(AddrIn)
11310 .addReg(0)
11311 .addImm(StSize)
11313 }
11314}
11315
11317ARMTargetLowering::EmitStructByval(MachineInstr &MI,
11318 MachineBasicBlock *BB) const {
11319 // This pseudo instruction has 3 operands: dst, src, size
11320 // We expand it to a loop if size > Subtarget->getMaxInlineSizeThreshold().
11321 // Otherwise, we will generate unrolled scalar copies.
11322 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11323 const BasicBlock *LLVM_BB = BB->getBasicBlock();
11325
11326 Register dest = MI.getOperand(0).getReg();
11327 Register src = MI.getOperand(1).getReg();
11328 unsigned SizeVal = MI.getOperand(2).getImm();
11329 unsigned Alignment = MI.getOperand(3).getImm();
11330 DebugLoc dl = MI.getDebugLoc();
11331
11332 MachineFunction *MF = BB->getParent();
11333 MachineRegisterInfo &MRI = MF->getRegInfo();
11334 unsigned UnitSize = 0;
11335 const TargetRegisterClass *TRC = nullptr;
11336 const TargetRegisterClass *VecTRC = nullptr;
11337
11338 bool IsThumb1 = Subtarget->isThumb1Only();
11339 bool IsThumb2 = Subtarget->isThumb2();
11340 bool IsThumb = Subtarget->isThumb();
11341
11342 if (Alignment & 1) {
11343 UnitSize = 1;
11344 } else if (Alignment & 2) {
11345 UnitSize = 2;
11346 } else {
11347 // Check whether we can use NEON instructions.
11348 if (!MF->getFunction().hasFnAttribute(Attribute::NoImplicitFloat) &&
11349 Subtarget->hasNEON()) {
11350 if ((Alignment % 16 == 0) && SizeVal >= 16)
11351 UnitSize = 16;
11352 else if ((Alignment % 8 == 0) && SizeVal >= 8)
11353 UnitSize = 8;
11354 }
11355 // Can't use NEON instructions.
11356 if (UnitSize == 0)
11357 UnitSize = 4;
11358 }
11359
11360 // Select the correct opcode and register class for unit size load/store
11361 bool IsNeon = UnitSize >= 8;
11362 TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
11363 if (IsNeon)
11364 VecTRC = UnitSize == 16 ? &ARM::DPairRegClass
11365 : UnitSize == 8 ? &ARM::DPRRegClass
11366 : nullptr;
11367
11368 unsigned BytesLeft = SizeVal % UnitSize;
11369 unsigned LoopSize = SizeVal - BytesLeft;
11370
11371 if (SizeVal <= Subtarget->getMaxInlineSizeThreshold()) {
11372 // Use LDR and STR to copy.
11373 // [scratch, srcOut] = LDR_POST(srcIn, UnitSize)
11374 // [destOut] = STR_POST(scratch, destIn, UnitSize)
11375 unsigned srcIn = src;
11376 unsigned destIn = dest;
11377 for (unsigned i = 0; i < LoopSize; i+=UnitSize) {
11378 Register srcOut = MRI.createVirtualRegister(TRC);
11379 Register destOut = MRI.createVirtualRegister(TRC);
11380 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11381 emitPostLd(BB, MI, TII, dl, UnitSize, scratch, srcIn, srcOut,
11382 IsThumb1, IsThumb2);
11383 emitPostSt(BB, MI, TII, dl, UnitSize, scratch, destIn, destOut,
11384 IsThumb1, IsThumb2);
11385 srcIn = srcOut;
11386 destIn = destOut;
11387 }
11388
11389 // Handle the leftover bytes with LDRB and STRB.
11390 // [scratch, srcOut] = LDRB_POST(srcIn, 1)
11391 // [destOut] = STRB_POST(scratch, destIn, 1)
11392 for (unsigned i = 0; i < BytesLeft; i++) {
11393 Register srcOut = MRI.createVirtualRegister(TRC);
11394 Register destOut = MRI.createVirtualRegister(TRC);
11395 Register scratch = MRI.createVirtualRegister(TRC);
11396 emitPostLd(BB, MI, TII, dl, 1, scratch, srcIn, srcOut,
11397 IsThumb1, IsThumb2);
11398 emitPostSt(BB, MI, TII, dl, 1, scratch, destIn, destOut,
11399 IsThumb1, IsThumb2);
11400 srcIn = srcOut;
11401 destIn = destOut;
11402 }
11403 MI.eraseFromParent(); // The instruction is gone now.
11404 return BB;
11405 }
11406
11407 // Expand the pseudo op to a loop.
11408 // thisMBB:
11409 // ...
11410 // movw varEnd, # --> with thumb2
11411 // movt varEnd, #
11412 // ldrcp varEnd, idx --> without thumb2
11413 // fallthrough --> loopMBB
11414 // loopMBB:
11415 // PHI varPhi, varEnd, varLoop
11416 // PHI srcPhi, src, srcLoop
11417 // PHI destPhi, dst, destLoop
11418 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11419 // [destLoop] = STR_POST(scratch, destPhi, UnitSize)
11420 // subs varLoop, varPhi, #UnitSize
11421 // bne loopMBB
11422 // fallthrough --> exitMBB
11423 // exitMBB:
11424 // epilogue to handle left-over bytes
11425 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11426 // [destOut] = STRB_POST(scratch, destLoop, 1)
11427 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11428 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11429 MF->insert(It, loopMBB);
11430 MF->insert(It, exitMBB);
11431
11432 // Set the call frame size on entry to the new basic blocks.
11433 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11434 loopMBB->setCallFrameSize(CallFrameSize);
11435 exitMBB->setCallFrameSize(CallFrameSize);
11436
11437 // Transfer the remainder of BB and its successor edges to exitMBB.
11438 exitMBB->splice(exitMBB->begin(), BB,
11439 std::next(MachineBasicBlock::iterator(MI)), BB->end());
11441
11442 // Load an immediate to varEnd.
11443 Register varEnd = MRI.createVirtualRegister(TRC);
11444 if (Subtarget->useMovt()) {
11445 BuildMI(BB, dl, TII->get(IsThumb ? ARM::t2MOVi32imm : ARM::MOVi32imm),
11446 varEnd)
11447 .addImm(LoopSize);
11448 } else if (Subtarget->genExecuteOnly()) {
11449 assert(IsThumb && "Non-thumb expected to have used movt");
11450 BuildMI(BB, dl, TII->get(ARM::tMOVi32imm), varEnd).addImm(LoopSize);
11451 } else {
11452 MachineConstantPool *ConstantPool = MF->getConstantPool();
11453 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11454 const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
11455
11456 // MachineConstantPool wants an explicit alignment.
11458 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11459 MachineMemOperand *CPMMO =
11462
11463 if (IsThumb)
11464 BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci))
11465 .addReg(varEnd, RegState::Define)
11468 .addMemOperand(CPMMO);
11469 else
11470 BuildMI(*BB, MI, dl, TII->get(ARM::LDRcp))
11471 .addReg(varEnd, RegState::Define)
11473 .addImm(0)
11475 .addMemOperand(CPMMO);
11476 }
11477 BB->addSuccessor(loopMBB);
11478
11479 // Generate the loop body:
11480 // varPhi = PHI(varLoop, varEnd)
11481 // srcPhi = PHI(srcLoop, src)
11482 // destPhi = PHI(destLoop, dst)
11483 MachineBasicBlock *entryBB = BB;
11484 BB = loopMBB;
11485 Register varLoop = MRI.createVirtualRegister(TRC);
11486 Register varPhi = MRI.createVirtualRegister(TRC);
11487 Register srcLoop = MRI.createVirtualRegister(TRC);
11488 Register srcPhi = MRI.createVirtualRegister(TRC);
11489 Register destLoop = MRI.createVirtualRegister(TRC);
11490 Register destPhi = MRI.createVirtualRegister(TRC);
11491
11492 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), varPhi)
11493 .addReg(varLoop).addMBB(loopMBB)
11494 .addReg(varEnd).addMBB(entryBB);
11495 BuildMI(BB, dl, TII->get(ARM::PHI), srcPhi)
11496 .addReg(srcLoop).addMBB(loopMBB)
11497 .addReg(src).addMBB(entryBB);
11498 BuildMI(BB, dl, TII->get(ARM::PHI), destPhi)
11499 .addReg(destLoop).addMBB(loopMBB)
11500 .addReg(dest).addMBB(entryBB);
11501
11502 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11503 // [destLoop] = STR_POST(scratch, destPhi, UnitSiz)
11504 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11505 emitPostLd(BB, BB->end(), TII, dl, UnitSize, scratch, srcPhi, srcLoop,
11506 IsThumb1, IsThumb2);
11507 emitPostSt(BB, BB->end(), TII, dl, UnitSize, scratch, destPhi, destLoop,
11508 IsThumb1, IsThumb2);
11509
11510 // Decrement loop variable by UnitSize.
11511 if (IsThumb1) {
11512 BuildMI(*BB, BB->end(), dl, TII->get(ARM::tSUBi8), varLoop)
11513 .add(t1CondCodeOp())
11514 .addReg(varPhi)
11515 .addImm(UnitSize)
11517 } else {
11518 MachineInstrBuilder MIB =
11519 BuildMI(*BB, BB->end(), dl,
11520 TII->get(IsThumb2 ? ARM::t2SUBri : ARM::SUBri), varLoop);
11521 MIB.addReg(varPhi)
11522 .addImm(UnitSize)
11524 .add(condCodeOp());
11525 MIB->getOperand(5).setReg(ARM::CPSR);
11526 MIB->getOperand(5).setIsDef(true);
11527 }
11528 BuildMI(*BB, BB->end(), dl,
11529 TII->get(IsThumb1 ? ARM::tBcc : IsThumb2 ? ARM::t2Bcc : ARM::Bcc))
11530 .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
11531
11532 // loopMBB can loop back to loopMBB or fall through to exitMBB.
11533 BB->addSuccessor(loopMBB);
11534 BB->addSuccessor(exitMBB);
11535
11536 // Add epilogue to handle BytesLeft.
11537 BB = exitMBB;
11538 auto StartOfExit = exitMBB->begin();
11539
11540 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11541 // [destOut] = STRB_POST(scratch, destLoop, 1)
11542 unsigned srcIn = srcLoop;
11543 unsigned destIn = destLoop;
11544 for (unsigned i = 0; i < BytesLeft; i++) {
11545 Register srcOut = MRI.createVirtualRegister(TRC);
11546 Register destOut = MRI.createVirtualRegister(TRC);
11547 Register scratch = MRI.createVirtualRegister(TRC);
11548 emitPostLd(BB, StartOfExit, TII, dl, 1, scratch, srcIn, srcOut,
11549 IsThumb1, IsThumb2);
11550 emitPostSt(BB, StartOfExit, TII, dl, 1, scratch, destIn, destOut,
11551 IsThumb1, IsThumb2);
11552 srcIn = srcOut;
11553 destIn = destOut;
11554 }
11555
11556 MI.eraseFromParent(); // The instruction is gone now.
11557 return BB;
11558}
11559
11561ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
11562 MachineBasicBlock *MBB) const {
11563 const TargetMachine &TM = getTargetMachine();
11564 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
11565 DebugLoc DL = MI.getDebugLoc();
11566
11567 assert(TM.getTargetTriple().isOSWindows() &&
11568 "__chkstk is only supported on Windows");
11569 assert(Subtarget->isThumb2() && "Windows on ARM requires Thumb-2 mode");
11570
11571 // __chkstk takes the number of words to allocate on the stack in R4, and
11572 // returns the stack adjustment in number of bytes in R4. This will not
11573 // clober any other registers (other than the obvious lr).
11574 //
11575 // Although, technically, IP should be considered a register which may be
11576 // clobbered, the call itself will not touch it. Windows on ARM is a pure
11577 // thumb-2 environment, so there is no interworking required. As a result, we
11578 // do not expect a veneer to be emitted by the linker, clobbering IP.
11579 //
11580 // Each module receives its own copy of __chkstk, so no import thunk is
11581 // required, again, ensuring that IP is not clobbered.
11582 //
11583 // Finally, although some linkers may theoretically provide a trampoline for
11584 // out of range calls (which is quite common due to a 32M range limitation of
11585 // branches for Thumb), we can generate the long-call version via
11586 // -mcmodel=large, alleviating the need for the trampoline which may clobber
11587 // IP.
11588
11589 RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE);
11590 if (ChkStkLibcall == RTLIB::Unsupported)
11591 reportFatalUsageError("no available implementation of __chkstk");
11592
11593 const char *ChkStk = getLibcallImplName(ChkStkLibcall).data();
11594 switch (TM.getCodeModel()) {
11595 case CodeModel::Tiny:
11596 llvm_unreachable("Tiny code model not available on ARM.");
11597 case CodeModel::Small:
11598 case CodeModel::Medium:
11599 case CodeModel::Kernel:
11600 BuildMI(*MBB, MI, DL, TII.get(ARM::tBL))
11602 .addExternalSymbol(ChkStk)
11603 .setOperandDead(3) // implicit-def $lr
11606 .addReg(ARM::R12,
11608 .addReg(ARM::CPSR,
11610 break;
11611 case CodeModel::Large: {
11612 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
11613 Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11614
11615 BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
11616 .addExternalSymbol(ChkStk);
11619 .addReg(Reg)
11620 .setOperandDead(3) // implicit-def $lr
11623 .addReg(ARM::R12,
11625 .addReg(ARM::CPSR,
11627 break;
11628 }
11629 }
11630
11631 BuildMI(*MBB, MI, DL, TII.get(ARM::t2SUBrr), ARM::SP)
11632 .addReg(ARM::SP, RegState::Kill)
11633 .addReg(ARM::R4, RegState::Kill)
11636 .add(condCodeOp());
11637
11638 MI.eraseFromParent();
11639 return MBB;
11640}
11641
11643ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
11644 MachineBasicBlock *MBB) const {
11645 DebugLoc DL = MI.getDebugLoc();
11646 MachineFunction *MF = MBB->getParent();
11647 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11648
11649 MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
11650 MF->insert(++MBB->getIterator(), ContBB);
11651 ContBB->splice(ContBB->begin(), MBB,
11652 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
11654 MBB->addSuccessor(ContBB);
11655
11656 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11657 BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
11658 MF->push_back(TrapBB);
11659 MBB->addSuccessor(TrapBB);
11660
11661 BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
11662 .addReg(MI.getOperand(0).getReg())
11663 .addImm(0)
11665 BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
11666 .addMBB(TrapBB)
11668 .addReg(ARM::CPSR);
11669
11670 MI.eraseFromParent();
11671 return ContBB;
11672}
11673
11674// The CPSR operand of SelectItr might be missing a kill marker
11675// because there were multiple uses of CPSR, and ISel didn't know
11676// which to mark. Figure out whether SelectItr should have had a
11677// kill marker, and set it if it should. Returns the correct kill
11678// marker value.
11681 const TargetRegisterInfo* TRI) {
11682 // Scan forward through BB for a use/def of CPSR.
11683 MachineBasicBlock::iterator miI(std::next(SelectItr));
11684 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
11685 const MachineInstr& mi = *miI;
11686 if (mi.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
11687 return false;
11688 if (mi.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
11689 break; // Should have kill-flag - update below.
11690 }
11691
11692 // If we hit the end of the block, check whether CPSR is live into a
11693 // successor.
11694 if (miI == BB->end()) {
11695 for (MachineBasicBlock *Succ : BB->successors())
11696 if (Succ->isLiveIn(ARM::CPSR))
11697 return false;
11698 }
11699
11700 // We found a def, or hit the end of the basic block and CPSR wasn't live
11701 // out. SelectMI should have a kill flag on CPSR.
11702 SelectItr->addRegisterKilled(ARM::CPSR, TRI);
11703 return true;
11704}
11705
11706/// Adds logic in loop entry MBB to calculate loop iteration count and adds
11707/// t2WhileLoopSetup and t2WhileLoopStart to generate WLS loop
11709 MachineBasicBlock *TpLoopBody,
11710 MachineBasicBlock *TpExit, Register OpSizeReg,
11711 const TargetInstrInfo *TII, DebugLoc Dl,
11713 // Calculates loop iteration count = ceil(n/16) = (n + 15) >> 4.
11714 Register AddDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11715 BuildMI(TpEntry, Dl, TII->get(ARM::t2ADDri), AddDestReg)
11716 .addUse(OpSizeReg)
11717 .addImm(15)
11719 .addReg(0);
11720
11721 Register LsrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11722 BuildMI(TpEntry, Dl, TII->get(ARM::t2LSRri), LsrDestReg)
11723 .addUse(AddDestReg)
11724 .addImm(4)
11726 .addReg(0);
11727
11728 Register TotalIterationsReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11729 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopSetup), TotalIterationsReg)
11730 .addUse(LsrDestReg);
11731
11732 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopStart))
11733 .addUse(TotalIterationsReg)
11734 .addMBB(TpExit);
11735
11736 BuildMI(TpEntry, Dl, TII->get(ARM::t2B))
11737 .addMBB(TpLoopBody)
11739
11740 return TotalIterationsReg;
11741}
11742
11743/// Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and
11744/// t2DoLoopEnd. These are used by later passes to generate tail predicated
11745/// loops.
11746static void genTPLoopBody(MachineBasicBlock *TpLoopBody,
11747 MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit,
11748 const TargetInstrInfo *TII, DebugLoc Dl,
11749 MachineRegisterInfo &MRI, Register OpSrcReg,
11750 Register OpDestReg, Register ElementCountReg,
11751 Register TotalIterationsReg, bool IsMemcpy) {
11752 // First insert 4 PHI nodes for: Current pointer to Src (if memcpy), Dest
11753 // array, loop iteration counter, predication counter.
11754
11755 Register SrcPhiReg, CurrSrcReg;
11756 if (IsMemcpy) {
11757 // Current position in the src array
11758 SrcPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11759 CurrSrcReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11760 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), SrcPhiReg)
11761 .addUse(OpSrcReg)
11762 .addMBB(TpEntry)
11763 .addUse(CurrSrcReg)
11764 .addMBB(TpLoopBody);
11765 }
11766
11767 // Current position in the dest array
11768 Register DestPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11769 Register CurrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11770 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), DestPhiReg)
11771 .addUse(OpDestReg)
11772 .addMBB(TpEntry)
11773 .addUse(CurrDestReg)
11774 .addMBB(TpLoopBody);
11775
11776 // Current loop counter
11777 Register LoopCounterPhiReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11778 Register RemainingLoopIterationsReg =
11779 MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11780 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), LoopCounterPhiReg)
11781 .addUse(TotalIterationsReg)
11782 .addMBB(TpEntry)
11783 .addUse(RemainingLoopIterationsReg)
11784 .addMBB(TpLoopBody);
11785
11786 // Predication counter
11787 Register PredCounterPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11788 Register RemainingElementsReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11789 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), PredCounterPhiReg)
11790 .addUse(ElementCountReg)
11791 .addMBB(TpEntry)
11792 .addUse(RemainingElementsReg)
11793 .addMBB(TpLoopBody);
11794
11795 // Pass predication counter to VCTP
11796 Register VccrReg = MRI.createVirtualRegister(&ARM::VCCRRegClass);
11797 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VCTP8), VccrReg)
11798 .addUse(PredCounterPhiReg)
11800 .addReg(0)
11801 .addReg(0);
11802
11803 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2SUBri), RemainingElementsReg)
11804 .addUse(PredCounterPhiReg)
11805 .addImm(16)
11807 .addReg(0);
11808
11809 // VLDRB (only if memcpy) and VSTRB instructions, predicated using VPR
11810 Register SrcValueReg;
11811 if (IsMemcpy) {
11812 SrcValueReg = MRI.createVirtualRegister(&ARM::MQPRRegClass);
11813 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VLDRBU8_post))
11814 .addDef(CurrSrcReg)
11815 .addDef(SrcValueReg)
11816 .addReg(SrcPhiReg)
11817 .addImm(16)
11819 .addUse(VccrReg)
11820 .addReg(0);
11821 } else
11822 SrcValueReg = OpSrcReg;
11823
11824 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VSTRBU8_post))
11825 .addDef(CurrDestReg)
11826 .addUse(SrcValueReg)
11827 .addReg(DestPhiReg)
11828 .addImm(16)
11830 .addUse(VccrReg)
11831 .addReg(0);
11832
11833 // Add the pseudoInstrs for decrementing the loop counter and marking the
11834 // end:t2DoLoopDec and t2DoLoopEnd
11835 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopDec), RemainingLoopIterationsReg)
11836 .addUse(LoopCounterPhiReg)
11837 .addImm(1);
11838
11839 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopEnd))
11840 .addUse(RemainingLoopIterationsReg)
11841 .addMBB(TpLoopBody);
11842
11843 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2B))
11844 .addMBB(TpExit)
11846}
11847
11849 // KCFI is supported in all ARM/Thumb modes
11850 return true;
11851}
11852
11856 const TargetInstrInfo *TII) const {
11857 assert(MBBI->isCall() && MBBI->getCFIType() &&
11858 "Invalid call instruction for a KCFI check");
11859
11860 MachineOperand *TargetOp = nullptr;
11861 switch (MBBI->getOpcode()) {
11862 // ARM mode opcodes
11863 case ARM::BLX:
11864 case ARM::BLX_pred:
11865 case ARM::BLX_noip:
11866 case ARM::BLX_pred_noip:
11867 case ARM::BX_CALL:
11868 TargetOp = &MBBI->getOperand(0);
11869 break;
11870 case ARM::TCRETURNri:
11871 case ARM::TCRETURNrinotr12:
11872 case ARM::TAILJMPr:
11873 case ARM::TAILJMPr4:
11874 TargetOp = &MBBI->getOperand(0);
11875 break;
11876 // Thumb mode opcodes (Thumb1 and Thumb2)
11877 // Note: Most Thumb call instructions have predicate operands before the
11878 // target register Format: tBLXr pred, predreg, target_register, ...
11879 case ARM::tBLXr: // Thumb1/Thumb2: BLX register (requires V5T)
11880 case ARM::tBLXr_noip: // Thumb1/Thumb2: BLX register, no IP clobber
11881 case ARM::tBX_CALL: // Thumb1 only: BX call (push LR, BX)
11882 TargetOp = &MBBI->getOperand(2);
11883 break;
11884 // Tail call instructions don't have predicates, target is operand 0
11885 case ARM::tTAILJMPr: // Thumb1/Thumb2: Tail call via register
11886 TargetOp = &MBBI->getOperand(0);
11887 break;
11888 default:
11889 llvm_unreachable("Unexpected CFI call opcode");
11890 }
11891
11892 assert(TargetOp && TargetOp->isReg() && "Invalid target operand");
11893 TargetOp->setIsRenamable(false);
11894
11895 // Select the appropriate KCFI_CHECK variant based on the instruction set
11896 unsigned KCFICheckOpcode;
11897 if (Subtarget->isThumb()) {
11898 if (Subtarget->isThumb2()) {
11899 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb2;
11900 } else {
11901 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb1;
11902 }
11903 } else {
11904 KCFICheckOpcode = ARM::KCFI_CHECK_ARM;
11905 }
11906
11907 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(KCFICheckOpcode))
11908 .addReg(TargetOp->getReg())
11909 .addImm(MBBI->getCFIType())
11910 .getInstr();
11911}
11912
11915 MachineBasicBlock *BB) const {
11916 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11917 DebugLoc dl = MI.getDebugLoc();
11918 bool isThumb2 = Subtarget->isThumb2();
11919 switch (MI.getOpcode()) {
11920 default: {
11921 MI.print(errs());
11922 llvm_unreachable("Unexpected instr type to insert");
11923 }
11924
11925 // Thumb1 post-indexed loads are really just single-register LDMs.
11926 case ARM::tLDR_postidx: {
11927 MachineOperand Def(MI.getOperand(1));
11928 BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD))
11929 .add(Def) // Rn_wb
11930 .add(MI.getOperand(2)) // Rn
11931 .add(MI.getOperand(3)) // PredImm
11932 .add(MI.getOperand(4)) // PredReg
11933 .add(MI.getOperand(0)) // Rt
11934 .cloneMemRefs(MI);
11935 MI.eraseFromParent();
11936 return BB;
11937 }
11938
11939 case ARM::MVE_MEMCPYLOOPINST:
11940 case ARM::MVE_MEMSETLOOPINST: {
11941
11942 // Transformation below expands MVE_MEMCPYLOOPINST/MVE_MEMSETLOOPINST Pseudo
11943 // into a Tail Predicated (TP) Loop. It adds the instructions to calculate
11944 // the iteration count =ceil(size_in_bytes/16)) in the TP entry block and
11945 // adds the relevant instructions in the TP loop Body for generation of a
11946 // WLSTP loop.
11947
11948 // Below is relevant portion of the CFG after the transformation.
11949 // The Machine Basic Blocks are shown along with branch conditions (in
11950 // brackets). Note that TP entry/exit MBBs depict the entry/exit of this
11951 // portion of the CFG and may not necessarily be the entry/exit of the
11952 // function.
11953
11954 // (Relevant) CFG after transformation:
11955 // TP entry MBB
11956 // |
11957 // |-----------------|
11958 // (n <= 0) (n > 0)
11959 // | |
11960 // | TP loop Body MBB<--|
11961 // | | |
11962 // \ |___________|
11963 // \ /
11964 // TP exit MBB
11965
11966 MachineFunction *MF = BB->getParent();
11967 MachineFunctionProperties &Properties = MF->getProperties();
11969
11970 Register OpDestReg = MI.getOperand(0).getReg();
11971 Register OpSrcReg = MI.getOperand(1).getReg();
11972 Register OpSizeReg = MI.getOperand(2).getReg();
11973
11974 // Allocate the required MBBs and add to parent function.
11975 MachineBasicBlock *TpEntry = BB;
11976 MachineBasicBlock *TpLoopBody = MF->CreateMachineBasicBlock();
11977 MachineBasicBlock *TpExit;
11978
11979 MF->push_back(TpLoopBody);
11980
11981 // If any instructions are present in the current block after
11982 // MVE_MEMCPYLOOPINST or MVE_MEMSETLOOPINST, split the current block and
11983 // move the instructions into the newly created exit block. If there are no
11984 // instructions add an explicit branch to the FallThrough block and then
11985 // split.
11986 //
11987 // The split is required for two reasons:
11988 // 1) A terminator(t2WhileLoopStart) will be placed at that site.
11989 // 2) Since a TPLoopBody will be added later, any phis in successive blocks
11990 // need to be updated. splitAt() already handles this.
11991 TpExit = BB->splitAt(MI, false);
11992 if (TpExit == BB) {
11993 assert(BB->canFallThrough() && "Exit Block must be Fallthrough of the "
11994 "block containing memcpy/memset Pseudo");
11995 TpExit = BB->getFallThrough();
11996 BuildMI(BB, dl, TII->get(ARM::t2B))
11997 .addMBB(TpExit)
11999 TpExit = BB->splitAt(MI, false);
12000 }
12001
12002 // Add logic for iteration count
12003 Register TotalIterationsReg =
12004 genTPEntry(TpEntry, TpLoopBody, TpExit, OpSizeReg, TII, dl, MRI);
12005
12006 // Add the vectorized (and predicated) loads/store instructions
12007 bool IsMemcpy = MI.getOpcode() == ARM::MVE_MEMCPYLOOPINST;
12008 genTPLoopBody(TpLoopBody, TpEntry, TpExit, TII, dl, MRI, OpSrcReg,
12009 OpDestReg, OpSizeReg, TotalIterationsReg, IsMemcpy);
12010
12011 // Required to avoid conflict with the MachineVerifier during testing.
12012 Properties.resetNoPHIs();
12013
12014 // Connect the blocks
12015 TpEntry->addSuccessor(TpLoopBody);
12016 TpLoopBody->addSuccessor(TpLoopBody);
12017 TpLoopBody->addSuccessor(TpExit);
12018
12019 // Reorder for a more natural layout
12020 TpLoopBody->moveAfter(TpEntry);
12021 TpExit->moveAfter(TpLoopBody);
12022
12023 // Finally, remove the memcpy Pseudo Instruction
12024 MI.eraseFromParent();
12025
12026 // Return the exit block as it may contain other instructions requiring a
12027 // custom inserter
12028 return TpExit;
12029 }
12030
12031 // The Thumb2 pre-indexed stores have the same MI operands, they just
12032 // define them differently in the .td files from the isel patterns, so
12033 // they need pseudos.
12034 case ARM::t2STR_preidx:
12035 MI.setDesc(TII->get(ARM::t2STR_PRE));
12036 return BB;
12037 case ARM::t2STRB_preidx:
12038 MI.setDesc(TII->get(ARM::t2STRB_PRE));
12039 return BB;
12040 case ARM::t2STRH_preidx:
12041 MI.setDesc(TII->get(ARM::t2STRH_PRE));
12042 return BB;
12043
12044 case ARM::STRi_preidx:
12045 case ARM::STRBi_preidx: {
12046 unsigned NewOpc = MI.getOpcode() == ARM::STRi_preidx ? ARM::STR_PRE_IMM
12047 : ARM::STRB_PRE_IMM;
12048 // Decode the offset.
12049 unsigned Offset = MI.getOperand(4).getImm();
12050 bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub;
12052 if (isSub)
12053 Offset = -Offset;
12054
12055 MachineMemOperand *MMO = *MI.memoperands_begin();
12056 BuildMI(*BB, MI, dl, TII->get(NewOpc))
12057 .add(MI.getOperand(0)) // Rn_wb
12058 .add(MI.getOperand(1)) // Rt
12059 .add(MI.getOperand(2)) // Rn
12060 .addImm(Offset) // offset (skip GPR==zero_reg)
12061 .add(MI.getOperand(5)) // pred
12062 .add(MI.getOperand(6))
12063 .addMemOperand(MMO);
12064 MI.eraseFromParent();
12065 return BB;
12066 }
12067 case ARM::STRr_preidx:
12068 case ARM::STRBr_preidx:
12069 case ARM::STRH_preidx: {
12070 unsigned NewOpc;
12071 switch (MI.getOpcode()) {
12072 default: llvm_unreachable("unexpected opcode!");
12073 case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break;
12074 case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break;
12075 case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break;
12076 }
12077 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc));
12078 for (const MachineOperand &MO : MI.operands())
12079 MIB.add(MO);
12080 MI.eraseFromParent();
12081 return BB;
12082 }
12083
12084 case ARM::tMOVCCr_pseudo: {
12085 // To "insert" a SELECT_CC instruction, we actually have to insert the
12086 // diamond control-flow pattern. The incoming instruction knows the
12087 // destination vreg to set, the condition code register to branch on, the
12088 // true/false values to select between, and a branch opcode to use.
12089 const BasicBlock *LLVM_BB = BB->getBasicBlock();
12091
12092 // thisMBB:
12093 // ...
12094 // TrueVal = ...
12095 // cmpTY ccX, r1, r2
12096 // bCC copy1MBB
12097 // fallthrough --> copy0MBB
12098 MachineBasicBlock *thisMBB = BB;
12099 MachineFunction *F = BB->getParent();
12100 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12101 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
12102 F->insert(It, copy0MBB);
12103 F->insert(It, sinkMBB);
12104
12105 // Set the call frame size on entry to the new basic blocks.
12106 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12107 copy0MBB->setCallFrameSize(CallFrameSize);
12108 sinkMBB->setCallFrameSize(CallFrameSize);
12109
12110 // Check whether CPSR is live past the tMOVCCr_pseudo.
12111 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
12112 if (!MI.killsRegister(ARM::CPSR, /*TRI=*/nullptr) &&
12113 !checkAndUpdateCPSRKill(MI, thisMBB, TRI)) {
12114 copy0MBB->addLiveIn(ARM::CPSR);
12115 sinkMBB->addLiveIn(ARM::CPSR);
12116 }
12117
12118 // Transfer the remainder of BB and its successor edges to sinkMBB.
12119 sinkMBB->splice(sinkMBB->begin(), BB,
12120 std::next(MachineBasicBlock::iterator(MI)), BB->end());
12122
12123 BB->addSuccessor(copy0MBB);
12124 BB->addSuccessor(sinkMBB);
12125
12126 BuildMI(BB, dl, TII->get(ARM::tBcc))
12127 .addMBB(sinkMBB)
12128 .addImm(MI.getOperand(3).getImm())
12129 .addReg(MI.getOperand(4).getReg());
12130
12131 // copy0MBB:
12132 // %FalseValue = ...
12133 // # fallthrough to sinkMBB
12134 BB = copy0MBB;
12135
12136 // Update machine-CFG edges
12137 BB->addSuccessor(sinkMBB);
12138
12139 // sinkMBB:
12140 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12141 // ...
12142 BB = sinkMBB;
12143 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), MI.getOperand(0).getReg())
12144 .addReg(MI.getOperand(1).getReg())
12145 .addMBB(copy0MBB)
12146 .addReg(MI.getOperand(2).getReg())
12147 .addMBB(thisMBB);
12148
12149 MI.eraseFromParent(); // The pseudo instruction is gone now.
12150 return BB;
12151 }
12152
12153 case ARM::BCCi64:
12154 case ARM::BCCZi64: {
12155 // If there is an unconditional branch to the other successor, remove it.
12156 BB->erase(std::next(MachineBasicBlock::iterator(MI)), BB->end());
12157
12158 // Compare both parts that make up the double comparison separately for
12159 // equality.
12160 bool RHSisZero = MI.getOpcode() == ARM::BCCZi64;
12161
12162 Register LHS1 = MI.getOperand(1).getReg();
12163 Register LHS2 = MI.getOperand(2).getReg();
12164 if (RHSisZero) {
12165 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12166 .addReg(LHS1)
12167 .addImm(0)
12169 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12170 .addReg(LHS2).addImm(0)
12171 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12172 } else {
12173 Register RHS1 = MI.getOperand(3).getReg();
12174 Register RHS2 = MI.getOperand(4).getReg();
12175 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12176 .addReg(LHS1)
12177 .addReg(RHS1)
12179 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12180 .addReg(LHS2).addReg(RHS2)
12181 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12182 }
12183
12184 MachineBasicBlock *destMBB = MI.getOperand(RHSisZero ? 3 : 5).getMBB();
12185 MachineBasicBlock *exitMBB = OtherSucc(BB, destMBB);
12186 if (MI.getOperand(0).getImm() == ARMCC::NE)
12187 std::swap(destMBB, exitMBB);
12188
12189 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))
12190 .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
12191 if (isThumb2)
12192 BuildMI(BB, dl, TII->get(ARM::t2B))
12193 .addMBB(exitMBB)
12195 else
12196 BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);
12197
12198 MI.eraseFromParent(); // The pseudo instruction is gone now.
12199 return BB;
12200 }
12201
12202 case ARM::Int_eh_sjlj_setjmp:
12203 case ARM::Int_eh_sjlj_setjmp_nofp:
12204 case ARM::tInt_eh_sjlj_setjmp:
12205 case ARM::t2Int_eh_sjlj_setjmp:
12206 case ARM::t2Int_eh_sjlj_setjmp_nofp:
12207 return BB;
12208
12209 case ARM::Int_eh_sjlj_setup_dispatch:
12210 EmitSjLjDispatchBlock(MI, BB);
12211 return BB;
12212 case ARM::COPY_STRUCT_BYVAL_I32:
12213 ++NumLoopByVals;
12214 return EmitStructByval(MI, BB);
12215 case ARM::WIN__CHKSTK:
12216 return EmitLowered__chkstk(MI, BB);
12217 case ARM::WIN__DBZCHK:
12218 return EmitLowered__dbzchk(MI, BB);
12219 }
12220}
12221
12222/// Attaches vregs to MEMCPY that it will use as scratch registers
12223/// when it is expanded into LDM/STM. This is done as a post-isel lowering
12224/// instead of as a custom inserter because we need the use list from the SDNode.
12225static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget,
12226 MachineInstr &MI, const SDNode *Node) {
12227 bool isThumb1 = Subtarget->isThumb1Only();
12228
12229 MachineFunction *MF = MI.getParent()->getParent();
12231 MachineInstrBuilder MIB(*MF, MI);
12232
12233 // If the new dst/src is unused mark it as dead.
12234 if (!Node->hasAnyUseOfValue(0)) {
12235 MI.getOperand(0).setIsDead(true);
12236 }
12237 if (!Node->hasAnyUseOfValue(1)) {
12238 MI.getOperand(1).setIsDead(true);
12239 }
12240
12241 // The MEMCPY both defines and kills the scratch registers.
12242 for (unsigned I = 0; I != MI.getOperand(4).getImm(); ++I) {
12243 Register TmpReg = MRI.createVirtualRegister(isThumb1 ? &ARM::tGPRRegClass
12244 : &ARM::GPRRegClass);
12246 }
12247}
12248
12250 SDNode *Node) const {
12251 if (MI.getOpcode() == ARM::MEMCPY) {
12252 attachMEMCPYScratchRegs(Subtarget, MI, Node);
12253 return;
12254 }
12255
12256 const MCInstrDesc *MCID = &MI.getDesc();
12257 // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB,
12258 // RSC. Coming out of isel, they have an implicit CPSR def, but the optional
12259 // operand is still set to noreg. If needed, set the optional operand's
12260 // register to CPSR, and remove the redundant implicit def.
12261 //
12262 // e.g. ADCS (..., implicit-def CPSR) -> ADC (... opt:def CPSR).
12263
12264 // Rename pseudo opcodes.
12265 unsigned NewOpc = convertAddSubFlagsOpcode(MI.getOpcode());
12266 unsigned ccOutIdx;
12267 if (NewOpc) {
12268 const ARMBaseInstrInfo *TII = Subtarget->getInstrInfo();
12269 MCID = &TII->get(NewOpc);
12270
12271 assert(MCID->getNumOperands() ==
12272 MI.getDesc().getNumOperands() + 5 - MI.getDesc().getSize()
12273 && "converted opcode should be the same except for cc_out"
12274 " (and, on Thumb1, pred)");
12275
12276 MI.setDesc(*MCID);
12277
12278 // Add the optional cc_out operand
12279 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
12280
12281 // On Thumb1, move all input operands to the end, then add the predicate
12282 if (Subtarget->isThumb1Only()) {
12283 for (unsigned c = MCID->getNumOperands() - 4; c--;) {
12284 MI.addOperand(MI.getOperand(1));
12285 MI.removeOperand(1);
12286 }
12287
12288 // Restore the ties
12289 for (unsigned i = MI.getNumOperands(); i--;) {
12290 const MachineOperand& op = MI.getOperand(i);
12291 if (op.isReg() && op.isUse()) {
12292 int DefIdx = MCID->getOperandConstraint(i, MCOI::TIED_TO);
12293 if (DefIdx != -1)
12294 MI.tieOperands(DefIdx, i);
12295 }
12296 }
12297
12299 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/false));
12300 ccOutIdx = 1;
12301 } else
12302 ccOutIdx = MCID->getNumOperands() - 1;
12303 } else
12304 ccOutIdx = MCID->getNumOperands() - 1;
12305
12306 // Any ARM instruction that sets the 's' bit should specify an optional
12307 // "cc_out" operand in the last operand position.
12308 if (!MI.hasOptionalDef() || !MCID->operands()[ccOutIdx].isOptionalDef()) {
12309 assert(!NewOpc && "Optional cc_out operand required");
12310 return;
12311 }
12312 // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it
12313 // since we already have an optional CPSR def.
12314 bool definesCPSR = false;
12315 bool deadCPSR = false;
12316 for (unsigned i = MCID->getNumOperands(), e = MI.getNumOperands(); i != e;
12317 ++i) {
12318 const MachineOperand &MO = MI.getOperand(i);
12319 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
12320 definesCPSR = true;
12321 if (MO.isDead())
12322 deadCPSR = true;
12323 MI.removeOperand(i);
12324 break;
12325 }
12326 }
12327 if (!definesCPSR) {
12328 assert(!NewOpc && "Optional cc_out operand required");
12329 return;
12330 }
12331 assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag");
12332 if (deadCPSR) {
12333 assert(!MI.getOperand(ccOutIdx).getReg() &&
12334 "expect uninitialized optional cc_out operand");
12335 // Thumb1 instructions must have the S bit even if the CPSR is dead.
12336 if (!Subtarget->isThumb1Only())
12337 return;
12338 }
12339
12340 // If this instruction was defined with an optional CPSR def and its dag node
12341 // had a live implicit CPSR def, then activate the optional CPSR def.
12342 MachineOperand &MO = MI.getOperand(ccOutIdx);
12343 MO.setReg(ARM::CPSR);
12344 MO.setIsDef(true);
12345 MO.setIsDead(deadCPSR);
12346}
12347
12348//===----------------------------------------------------------------------===//
12349// ARM Optimization Hooks
12350//===----------------------------------------------------------------------===//
12351
12352// Helper function that checks if N is a null or all ones constant.
12353static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
12355}
12356
12357// Return true if N is conditionally 0 or all ones.
12358// Detects these expressions where cc is an i1 value:
12359//
12360// (select cc 0, y) [AllOnes=0]
12361// (select cc y, 0) [AllOnes=0]
12362// (zext cc) [AllOnes=0]
12363// (sext cc) [AllOnes=0/1]
12364// (select cc -1, y) [AllOnes=1]
12365// (select cc y, -1) [AllOnes=1]
12366//
12367// Invert is set when N is the null/all ones constant when CC is false.
12368// OtherOp is set to the alternative value of N.
12370 SDValue &CC, bool &Invert,
12371 SDValue &OtherOp,
12372 SelectionDAG &DAG) {
12373 switch (N->getOpcode()) {
12374 default: return false;
12375 case ISD::SELECT: {
12376 CC = N->getOperand(0);
12377 SDValue N1 = N->getOperand(1);
12378 SDValue N2 = N->getOperand(2);
12379 if (isZeroOrAllOnes(N1, AllOnes)) {
12380 Invert = false;
12381 OtherOp = N2;
12382 return true;
12383 }
12384 if (isZeroOrAllOnes(N2, AllOnes)) {
12385 Invert = true;
12386 OtherOp = N1;
12387 return true;
12388 }
12389 return false;
12390 }
12391 case ISD::ZERO_EXTEND:
12392 // (zext cc) can never be the all ones value.
12393 if (AllOnes)
12394 return false;
12395 [[fallthrough]];
12396 case ISD::SIGN_EXTEND: {
12397 SDLoc dl(N);
12398 EVT VT = N->getValueType(0);
12399 CC = N->getOperand(0);
12400 if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC)
12401 return false;
12402 Invert = !AllOnes;
12403 if (AllOnes)
12404 // When looking for an AllOnes constant, N is an sext, and the 'other'
12405 // value is 0.
12406 OtherOp = DAG.getConstant(0, dl, VT);
12407 else if (N->getOpcode() == ISD::ZERO_EXTEND)
12408 // When looking for a 0 constant, N can be zext or sext.
12409 OtherOp = DAG.getConstant(1, dl, VT);
12410 else
12411 OtherOp = DAG.getAllOnesConstant(dl, VT);
12412 return true;
12413 }
12414 }
12415}
12416
12417// Combine a constant select operand into its use:
12418//
12419// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
12420// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
12421// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
12422// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
12423// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
12424//
12425// The transform is rejected if the select doesn't have a constant operand that
12426// is null, or all ones when AllOnes is set.
12427//
12428// Also recognize sext/zext from i1:
12429//
12430// (add (zext cc), x) -> (select cc (add x, 1), x)
12431// (add (sext cc), x) -> (select cc (add x, -1), x)
12432//
12433// These transformations eventually create predicated instructions.
12434//
12435// @param N The node to transform.
12436// @param Slct The N operand that is a select.
12437// @param OtherOp The other N operand (x above).
12438// @param DCI Context.
12439// @param AllOnes Require the select constant to be all ones instead of null.
12440// @returns The new node, or SDValue() on failure.
12441static
12444 bool AllOnes = false) {
12445 SelectionDAG &DAG = DCI.DAG;
12446 EVT VT = N->getValueType(0);
12447 SDValue NonConstantVal;
12448 SDValue CCOp;
12449 bool SwapSelectOps;
12450 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
12451 NonConstantVal, DAG))
12452 return SDValue();
12453
12454 // Slct is now know to be the desired identity constant when CC is true.
12455 SDValue TrueVal = OtherOp;
12456 SDValue FalseVal = DAG.getNode(N->getOpcode(), SDLoc(N), VT,
12457 OtherOp, NonConstantVal);
12458 // Unless SwapSelectOps says CC should be false.
12459 if (SwapSelectOps)
12460 std::swap(TrueVal, FalseVal);
12461
12462 return DAG.getNode(ISD::SELECT, SDLoc(N), VT,
12463 CCOp, TrueVal, FalseVal);
12464}
12465
12466// Attempt combineSelectAndUse on each operand of a commutative operator N.
12467static
12470 SDValue N0 = N->getOperand(0);
12471 SDValue N1 = N->getOperand(1);
12472 if (N0.getNode()->hasOneUse())
12473 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
12474 return Result;
12475 if (N1.getNode()->hasOneUse())
12476 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
12477 return Result;
12478 return SDValue();
12479}
12480
12482 // VUZP shuffle node.
12483 if (N->getOpcode() == ARMISD::VUZP)
12484 return true;
12485
12486 // "VUZP" on i32 is an alias for VTRN.
12487 if (N->getOpcode() == ARMISD::VTRN && N->getValueType(0) == MVT::v2i32)
12488 return true;
12489
12490 return false;
12491}
12492
12495 const ARMSubtarget *Subtarget) {
12496 // Look for ADD(VUZP.0, VUZP.1).
12497 if (!IsVUZPShuffleNode(N0.getNode()) || N0.getNode() != N1.getNode() ||
12498 N0 == N1)
12499 return SDValue();
12500
12501 // Make sure the ADD is a 64-bit add; there is no 128-bit VPADD.
12502 if (!N->getValueType(0).is64BitVector())
12503 return SDValue();
12504
12505 // Generate vpadd.
12506 SelectionDAG &DAG = DCI.DAG;
12507 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12508 SDLoc dl(N);
12509 SDNode *Unzip = N0.getNode();
12510 EVT VT = N->getValueType(0);
12511
12513 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpadd, dl,
12514 TLI.getPointerTy(DAG.getDataLayout())));
12515 Ops.push_back(Unzip->getOperand(0));
12516 Ops.push_back(Unzip->getOperand(1));
12517
12518 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12519}
12520
12523 const ARMSubtarget *Subtarget) {
12524 // Check for two extended operands.
12525 if (!(N0.getOpcode() == ISD::SIGN_EXTEND &&
12526 N1.getOpcode() == ISD::SIGN_EXTEND) &&
12527 !(N0.getOpcode() == ISD::ZERO_EXTEND &&
12528 N1.getOpcode() == ISD::ZERO_EXTEND))
12529 return SDValue();
12530
12531 SDValue N00 = N0.getOperand(0);
12532 SDValue N10 = N1.getOperand(0);
12533
12534 // Look for ADD(SEXT(VUZP.0), SEXT(VUZP.1))
12535 if (!IsVUZPShuffleNode(N00.getNode()) || N00.getNode() != N10.getNode() ||
12536 N00 == N10)
12537 return SDValue();
12538
12539 // We only recognize Q register paddl here; this can't be reached until
12540 // after type legalization.
12541 if (!N00.getValueType().is64BitVector() ||
12543 return SDValue();
12544
12545 // Generate vpaddl.
12546 SelectionDAG &DAG = DCI.DAG;
12547 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12548 SDLoc dl(N);
12549 EVT VT = N->getValueType(0);
12550
12552 // Form vpaddl.sN or vpaddl.uN depending on the kind of extension.
12553 unsigned Opcode;
12554 if (N0.getOpcode() == ISD::SIGN_EXTEND)
12555 Opcode = Intrinsic::arm_neon_vpaddls;
12556 else
12557 Opcode = Intrinsic::arm_neon_vpaddlu;
12558 Ops.push_back(DAG.getConstant(Opcode, dl,
12559 TLI.getPointerTy(DAG.getDataLayout())));
12561 unsigned NumElts = VT.getVectorNumElements();
12562 EVT ConcatVT = EVT::getVectorVT(*DAG.getContext(), ElemTy, NumElts * 2);
12563 SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), ConcatVT,
12564 N00.getOperand(0), N00.getOperand(1));
12565 Ops.push_back(Concat);
12566
12567 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12568}
12569
12570// FIXME: This function shouldn't be necessary; if we lower BUILD_VECTOR in
12571// an appropriate manner, we end up with ADD(VUZP(ZEXT(N))), which is
12572// much easier to match.
12573static SDValue
12576 const ARMSubtarget *Subtarget) {
12577 // Only perform optimization if after legalize, and if NEON is available. We
12578 // also expected both operands to be BUILD_VECTORs.
12579 if (DCI.isBeforeLegalize() || !Subtarget->hasNEON()
12580 || N0.getOpcode() != ISD::BUILD_VECTOR
12581 || N1.getOpcode() != ISD::BUILD_VECTOR)
12582 return SDValue();
12583
12584 // Check output type since VPADDL operand elements can only be 8, 16, or 32.
12585 EVT VT = N->getValueType(0);
12586 if (!VT.isInteger() || VT.getVectorElementType() == MVT::i64)
12587 return SDValue();
12588
12589 // Check that the vector operands are of the right form.
12590 // N0 and N1 are BUILD_VECTOR nodes with N number of EXTRACT_VECTOR
12591 // operands, where N is the size of the formed vector.
12592 // Each EXTRACT_VECTOR should have the same input vector and odd or even
12593 // index such that we have a pair wise add pattern.
12594
12595 // Grab the vector that all EXTRACT_VECTOR nodes should be referencing.
12597 return SDValue();
12598 SDValue Vec = N0->getOperand(0)->getOperand(0);
12599 SDNode *V = Vec.getNode();
12600 unsigned nextIndex = 0;
12601
12602 // For each operands to the ADD which are BUILD_VECTORs,
12603 // check to see if each of their operands are an EXTRACT_VECTOR with
12604 // the same vector and appropriate index.
12605 for (unsigned i = 0, e = N0->getNumOperands(); i != e; ++i) {
12608
12609 SDValue ExtVec0 = N0->getOperand(i);
12610 SDValue ExtVec1 = N1->getOperand(i);
12611
12612 // First operand is the vector, verify its the same.
12613 if (V != ExtVec0->getOperand(0).getNode() ||
12614 V != ExtVec1->getOperand(0).getNode())
12615 return SDValue();
12616
12617 // Second is the constant, verify its correct.
12620
12621 // For the constant, we want to see all the even or all the odd.
12622 if (!C0 || !C1 || C0->getZExtValue() != nextIndex
12623 || C1->getZExtValue() != nextIndex+1)
12624 return SDValue();
12625
12626 // Increment index.
12627 nextIndex+=2;
12628 } else
12629 return SDValue();
12630 }
12631
12632 // Don't generate vpaddl+vmovn; we'll match it to vpadd later. Also make sure
12633 // we're using the entire input vector, otherwise there's a size/legality
12634 // mismatch somewhere.
12635 if (nextIndex != Vec.getValueType().getVectorNumElements() ||
12637 return SDValue();
12638
12639 // Create VPADDL node.
12640 SelectionDAG &DAG = DCI.DAG;
12641 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12642
12643 SDLoc dl(N);
12644
12645 // Build operand list.
12647 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddls, dl,
12648 TLI.getPointerTy(DAG.getDataLayout())));
12649
12650 // Input is the vector.
12651 Ops.push_back(Vec);
12652
12653 // Get widened type and narrowed type.
12654 MVT widenType;
12655 unsigned numElem = VT.getVectorNumElements();
12656
12657 EVT inputLaneType = Vec.getValueType().getVectorElementType();
12658 switch (inputLaneType.getSimpleVT().SimpleTy) {
12659 case MVT::i8: widenType = MVT::getVectorVT(MVT::i16, numElem); break;
12660 case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break;
12661 case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break;
12662 default:
12663 llvm_unreachable("Invalid vector element type for padd optimization.");
12664 }
12665
12666 SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, widenType, Ops);
12667 unsigned ExtOp = VT.bitsGT(tmp.getValueType()) ? ISD::ANY_EXTEND : ISD::TRUNCATE;
12668 return DAG.getNode(ExtOp, dl, VT, tmp);
12669}
12670
12672 if (V->getOpcode() == ISD::UMUL_LOHI ||
12673 V->getOpcode() == ISD::SMUL_LOHI)
12674 return V;
12675 return SDValue();
12676}
12677
12678static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode,
12680 const ARMSubtarget *Subtarget) {
12681 if (!Subtarget->hasBaseDSP())
12682 return SDValue();
12683
12684 // SMLALBB, SMLALBT, SMLALTB, SMLALTT multiply two 16-bit values and
12685 // accumulates the product into a 64-bit value. The 16-bit values will
12686 // be sign extended somehow or SRA'd into 32-bit values
12687 // (addc (adde (mul 16bit, 16bit), lo), hi)
12688 SDValue Mul = AddcNode->getOperand(0);
12689 SDValue Lo = AddcNode->getOperand(1);
12690 if (Mul.getOpcode() != ISD::MUL) {
12691 Lo = AddcNode->getOperand(0);
12692 Mul = AddcNode->getOperand(1);
12693 if (Mul.getOpcode() != ISD::MUL)
12694 return SDValue();
12695 }
12696
12697 SDValue SRA = AddeNode->getOperand(0);
12698 SDValue Hi = AddeNode->getOperand(1);
12699 if (SRA.getOpcode() != ISD::SRA) {
12700 SRA = AddeNode->getOperand(1);
12701 Hi = AddeNode->getOperand(0);
12702 if (SRA.getOpcode() != ISD::SRA)
12703 return SDValue();
12704 }
12705 if (auto Const = dyn_cast<ConstantSDNode>(SRA.getOperand(1))) {
12706 if (Const->getZExtValue() != 31)
12707 return SDValue();
12708 } else
12709 return SDValue();
12710
12711 if (SRA.getOperand(0) != Mul)
12712 return SDValue();
12713
12714 SelectionDAG &DAG = DCI.DAG;
12715 SDLoc dl(AddcNode);
12716 unsigned Opcode = 0;
12717 SDValue Op0;
12718 SDValue Op1;
12719
12720 if (isS16(Mul.getOperand(0), DAG) && isS16(Mul.getOperand(1), DAG)) {
12721 Opcode = ARMISD::SMLALBB;
12722 Op0 = Mul.getOperand(0);
12723 Op1 = Mul.getOperand(1);
12724 } else if (isS16(Mul.getOperand(0), DAG) && isSRA16(Mul.getOperand(1))) {
12725 Opcode = ARMISD::SMLALBT;
12726 Op0 = Mul.getOperand(0);
12727 Op1 = Mul.getOperand(1).getOperand(0);
12728 } else if (isSRA16(Mul.getOperand(0)) && isS16(Mul.getOperand(1), DAG)) {
12729 Opcode = ARMISD::SMLALTB;
12730 Op0 = Mul.getOperand(0).getOperand(0);
12731 Op1 = Mul.getOperand(1);
12732 } else if (isSRA16(Mul.getOperand(0)) && isSRA16(Mul.getOperand(1))) {
12733 Opcode = ARMISD::SMLALTT;
12734 Op0 = Mul->getOperand(0).getOperand(0);
12735 Op1 = Mul->getOperand(1).getOperand(0);
12736 }
12737
12738 if (!Op0 || !Op1)
12739 return SDValue();
12740
12741 SDValue SMLAL = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
12742 Op0, Op1, Lo, Hi);
12743 // Replace the ADDs' nodes uses by the MLA node's values.
12744 SDValue HiMLALResult(SMLAL.getNode(), 1);
12745 SDValue LoMLALResult(SMLAL.getNode(), 0);
12746
12747 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult);
12748 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult);
12749 DCI.recursivelyDeleteUnusedNodes(AddeNode);
12750
12751 // Return original node to notify the driver to stop replacing.
12752 return SDValue(AddeNode, 0);
12753}
12754
12757 const ARMSubtarget *Subtarget) {
12758 // Look for multiply add opportunities.
12759 // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where
12760 // each add nodes consumes a value from ISD::UMUL_LOHI and there is
12761 // a glue link from the first add to the second add.
12762 // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by
12763 // a S/UMLAL instruction.
12764 // UMUL_LOHI
12765 // / :lo \ :hi
12766 // V \ [no multiline comment]
12767 // loAdd -> ADDC |
12768 // \ :carry /
12769 // V V
12770 // ADDE <- hiAdd
12771 //
12772 // In the special case where only the higher part of a signed result is used
12773 // and the add to the low part of the result of ISD::UMUL_LOHI adds or subtracts
12774 // a constant with the exact value of 0x80000000, we recognize we are dealing
12775 // with a "rounded multiply and add" (or subtract) and transform it into
12776 // either a ARMISD::SMMLAR or ARMISD::SMMLSR respectively.
12777
12778 assert((AddeSubeNode->getOpcode() == ARMISD::ADDE ||
12779 AddeSubeNode->getOpcode() == ARMISD::SUBE) &&
12780 "Expect an ADDE or SUBE");
12781
12782 assert(AddeSubeNode->getNumOperands() == 3 &&
12783 AddeSubeNode->getOperand(2).getValueType() == MVT::i32 &&
12784 "ADDE node has the wrong inputs");
12785
12786 if (AddeSubeNode->hasAnyUseOfValue(1))
12787 return SDValue();
12788
12789 // Check that we are chained to the right ADDC or SUBC node.
12790 SDNode *AddcSubcNode = AddeSubeNode->getOperand(2).getNode();
12791 if ((AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12792 AddcSubcNode->getOpcode() != ARMISD::ADDC) ||
12793 (AddeSubeNode->getOpcode() == ARMISD::SUBE &&
12794 AddcSubcNode->getOpcode() != ARMISD::SUBC))
12795 return SDValue();
12796
12797 SDValue AddcSubcOp0 = AddcSubcNode->getOperand(0);
12798 SDValue AddcSubcOp1 = AddcSubcNode->getOperand(1);
12799
12800 // Check if the two operands are from the same mul_lohi node.
12801 if (AddcSubcOp0.getNode() == AddcSubcOp1.getNode())
12802 return SDValue();
12803
12804 assert(AddcSubcNode->getNumValues() == 2 &&
12805 AddcSubcNode->getValueType(0) == MVT::i32 &&
12806 "Expect ADDC with two result values. First: i32");
12807
12808 // Check that the ADDC adds the low result of the S/UMUL_LOHI. If not, it
12809 // maybe a SMLAL which multiplies two 16-bit values.
12810 if (AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12811 AddcSubcOp0->getOpcode() != ISD::UMUL_LOHI &&
12812 AddcSubcOp0->getOpcode() != ISD::SMUL_LOHI &&
12813 AddcSubcOp1->getOpcode() != ISD::UMUL_LOHI &&
12814 AddcSubcOp1->getOpcode() != ISD::SMUL_LOHI)
12815 return AddCombineTo64BitSMLAL16(AddcSubcNode, AddeSubeNode, DCI, Subtarget);
12816
12817 // Check for the triangle shape.
12818 SDValue AddeSubeOp0 = AddeSubeNode->getOperand(0);
12819 SDValue AddeSubeOp1 = AddeSubeNode->getOperand(1);
12820
12821 // Make sure that the ADDE/SUBE operands are not coming from the same node.
12822 if (AddeSubeOp0.getNode() == AddeSubeOp1.getNode())
12823 return SDValue();
12824
12825 // Find the MUL_LOHI node walking up ADDE/SUBE's operands.
12826 bool IsLeftOperandMUL = false;
12827 SDValue MULOp = findMUL_LOHI(AddeSubeOp0);
12828 if (MULOp == SDValue())
12829 MULOp = findMUL_LOHI(AddeSubeOp1);
12830 else
12831 IsLeftOperandMUL = true;
12832 if (MULOp == SDValue())
12833 return SDValue();
12834
12835 // Figure out the right opcode.
12836 unsigned Opc = MULOp->getOpcode();
12837 unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
12838
12839 // Figure out the high and low input values to the MLAL node.
12840 SDValue *HiAddSub = nullptr;
12841 SDValue *LoMul = nullptr;
12842 SDValue *LowAddSub = nullptr;
12843
12844 // Ensure that ADDE/SUBE is from high result of ISD::xMUL_LOHI.
12845 if ((AddeSubeOp0 != MULOp.getValue(1)) && (AddeSubeOp1 != MULOp.getValue(1)))
12846 return SDValue();
12847
12848 if (IsLeftOperandMUL)
12849 HiAddSub = &AddeSubeOp1;
12850 else
12851 HiAddSub = &AddeSubeOp0;
12852
12853 // Ensure that LoMul and LowAddSub are taken from correct ISD::SMUL_LOHI node
12854 // whose low result is fed to the ADDC/SUBC we are checking.
12855
12856 if (AddcSubcOp0 == MULOp.getValue(0)) {
12857 LoMul = &AddcSubcOp0;
12858 LowAddSub = &AddcSubcOp1;
12859 }
12860 if (AddcSubcOp1 == MULOp.getValue(0)) {
12861 LoMul = &AddcSubcOp1;
12862 LowAddSub = &AddcSubcOp0;
12863 }
12864
12865 if (!LoMul)
12866 return SDValue();
12867
12868 // If HiAddSub is the same node as ADDC/SUBC or is a predecessor of ADDC/SUBC
12869 // the replacement below will create a cycle.
12870 if (AddcSubcNode == HiAddSub->getNode() ||
12871 AddcSubcNode->isPredecessorOf(HiAddSub->getNode()))
12872 return SDValue();
12873
12874 // Create the merged node.
12875 SelectionDAG &DAG = DCI.DAG;
12876
12877 // Start building operand list.
12879 Ops.push_back(LoMul->getOperand(0));
12880 Ops.push_back(LoMul->getOperand(1));
12881
12882 // Check whether we can use SMMLAR, SMMLSR or SMMULR instead. For this to be
12883 // the case, we must be doing signed multiplication and only use the higher
12884 // part of the result of the MLAL, furthermore the LowAddSub must be a constant
12885 // addition or subtraction with the value of 0x800000.
12886 if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && Subtarget->useMulOps() &&
12887 FinalOpc == ARMISD::SMLAL &&
12888 LowAddSub->getNode()->getOpcode() == ISD::Constant &&
12889 static_cast<ConstantSDNode *>(LowAddSub->getNode())->getZExtValue() ==
12890 0x80000000) {
12891 Ops.push_back(*HiAddSub);
12892 if (AddcSubcNode->getOpcode() == ARMISD::SUBC) {
12893 FinalOpc = ARMISD::SMMLSR;
12894 } else {
12895 FinalOpc = ARMISD::SMMLAR;
12896 }
12897 SDValue NewNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode), MVT::i32, Ops);
12898 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), NewNode);
12899
12900 return SDValue(AddeSubeNode, 0);
12901 } else if (AddcSubcNode->getOpcode() == ARMISD::SUBC)
12902 // SMMLS is generated during instruction selection and the rest of this
12903 // function can not handle the case where AddcSubcNode is a SUBC.
12904 return SDValue();
12905
12906 // Finish building the operand list for {U/S}MLAL
12907 Ops.push_back(*LowAddSub);
12908 Ops.push_back(*HiAddSub);
12909
12910 SDValue MLALNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode),
12911 DAG.getVTList(MVT::i32, MVT::i32), Ops);
12912
12913 // Replace the ADDs' nodes uses by the MLA node's values.
12914 SDValue HiMLALResult(MLALNode.getNode(), 1);
12915 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), HiMLALResult);
12916
12917 SDValue LoMLALResult(MLALNode.getNode(), 0);
12918 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcSubcNode, 0), LoMLALResult);
12919
12920 // Return original node to notify the driver to stop replacing.
12921 return SDValue(AddeSubeNode, 0);
12922}
12923
12926 const ARMSubtarget *Subtarget) {
12927 // UMAAL is similar to UMLAL except that it adds two unsigned values.
12928 // While trying to combine for the other MLAL nodes, first search for the
12929 // chance to use UMAAL. Check if Addc uses a node which has already
12930 // been combined into a UMLAL. The other pattern is UMLAL using Addc/Adde
12931 // as the addend, and it's handled in PerformUMLALCombine.
12932
12933 if (AddeNode->hasAnyUseOfValue(1))
12934 return SDValue();
12935
12936 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
12937 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
12938
12939 // Check that we have a glued ADDC node.
12940 SDNode* AddcNode = AddeNode->getOperand(2).getNode();
12941 if (AddcNode->getOpcode() != ARMISD::ADDC)
12942 return SDValue();
12943
12944 // Find the converted UMAAL or quit if it doesn't exist.
12945 SDNode *UmlalNode = nullptr;
12946 SDValue AddHi;
12947 if (AddcNode->getOperand(0).getOpcode() == ARMISD::UMLAL) {
12948 UmlalNode = AddcNode->getOperand(0).getNode();
12949 AddHi = AddcNode->getOperand(1);
12950 } else if (AddcNode->getOperand(1).getOpcode() == ARMISD::UMLAL) {
12951 UmlalNode = AddcNode->getOperand(1).getNode();
12952 AddHi = AddcNode->getOperand(0);
12953 } else {
12954 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
12955 }
12956
12957 // The ADDC should be glued to an ADDE node, which uses the same UMLAL as
12958 // the ADDC as well as Zero.
12959 if (!isNullConstant(UmlalNode->getOperand(3)))
12960 return SDValue();
12961
12962 if ((isNullConstant(AddeNode->getOperand(0)) &&
12963 AddeNode->getOperand(1).getNode() == UmlalNode) ||
12964 (AddeNode->getOperand(0).getNode() == UmlalNode &&
12965 isNullConstant(AddeNode->getOperand(1)))) {
12966 SelectionDAG &DAG = DCI.DAG;
12967 SDValue Ops[] = { UmlalNode->getOperand(0), UmlalNode->getOperand(1),
12968 UmlalNode->getOperand(2), AddHi };
12969 SDValue UMAAL = DAG.getNode(ARMISD::UMAAL, SDLoc(AddcNode),
12970 DAG.getVTList(MVT::i32, MVT::i32), Ops);
12971
12972 // Replace the ADDs' nodes uses by the UMAAL node's values.
12973 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), SDValue(UMAAL.getNode(), 1));
12974 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), SDValue(UMAAL.getNode(), 0));
12975
12976 // Return original node to notify the driver to stop replacing.
12977 return SDValue(AddeNode, 0);
12978 }
12979 return SDValue();
12980}
12981
12983 const ARMSubtarget *Subtarget) {
12984 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
12985 return SDValue();
12986
12987 // Check that we have a pair of ADDC and ADDE as operands.
12988 // Both addends of the ADDE must be zero.
12989 SDNode* AddcNode = N->getOperand(2).getNode();
12990 SDNode* AddeNode = N->getOperand(3).getNode();
12991 if ((AddcNode->getOpcode() == ARMISD::ADDC) &&
12992 (AddeNode->getOpcode() == ARMISD::ADDE) &&
12993 isNullConstant(AddeNode->getOperand(0)) &&
12994 isNullConstant(AddeNode->getOperand(1)) &&
12995 (AddeNode->getOperand(2).getNode() == AddcNode))
12996 return DAG.getNode(ARMISD::UMAAL, SDLoc(N),
12997 DAG.getVTList(MVT::i32, MVT::i32),
12998 {N->getOperand(0), N->getOperand(1),
12999 AddcNode->getOperand(0), AddcNode->getOperand(1)});
13000 else
13001 return SDValue();
13002}
13003
13006 const ARMSubtarget *Subtarget) {
13007 SelectionDAG &DAG(DCI.DAG);
13008
13009 if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
13010 // (SUBC (ADDE 0, 0, C), 1) -> C
13011 SDValue LHS = N->getOperand(0);
13012 SDValue RHS = N->getOperand(1);
13013 if (LHS->getOpcode() == ARMISD::ADDE &&
13014 isNullConstant(LHS->getOperand(0)) &&
13015 isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
13016 return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
13017 }
13018 }
13019
13020 if (Subtarget->isThumb1Only()) {
13021 SDValue RHS = N->getOperand(1);
13023 int32_t imm = C->getSExtValue();
13024 if (imm < 0 && imm > std::numeric_limits<int>::min()) {
13025 SDLoc DL(N);
13026 RHS = DAG.getConstant(-imm, DL, MVT::i32);
13027 unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
13028 : ARMISD::ADDC;
13029 return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
13030 }
13031 }
13032 }
13033
13034 return SDValue();
13035}
13036
13039 const ARMSubtarget *Subtarget) {
13040 if (Subtarget->isThumb1Only()) {
13041 SelectionDAG &DAG = DCI.DAG;
13042 SDValue RHS = N->getOperand(1);
13044 int64_t imm = C->getSExtValue();
13045 if (imm < 0) {
13046 SDLoc DL(N);
13047
13048 // The with-carry-in form matches bitwise not instead of the negation.
13049 // Effectively, the inverse interpretation of the carry flag already
13050 // accounts for part of the negation.
13051 RHS = DAG.getConstant(~imm, DL, MVT::i32);
13052
13053 unsigned Opcode = (N->getOpcode() == ARMISD::ADDE) ? ARMISD::SUBE
13054 : ARMISD::ADDE;
13055 return DAG.getNode(Opcode, DL, N->getVTList(),
13056 N->getOperand(0), RHS, N->getOperand(2));
13057 }
13058 }
13059 } else if (N->getOperand(1)->getOpcode() == ISD::SMUL_LOHI) {
13060 return AddCombineTo64bitMLAL(N, DCI, Subtarget);
13061 }
13062 return SDValue();
13063}
13064
13067 const ARMSubtarget *Subtarget) {
13068 if (!Subtarget->hasMVEIntegerOps())
13069 return SDValue();
13070
13071 SDLoc dl(N);
13072 SDValue SetCC;
13073 SDValue LHS;
13074 SDValue RHS;
13076 SDValue TrueVal;
13077 SDValue FalseVal;
13078
13079 if (N->getOpcode() == ISD::SELECT &&
13080 N->getOperand(0)->getOpcode() == ISD::SETCC) {
13081 SetCC = N->getOperand(0);
13082 LHS = SetCC->getOperand(0);
13083 RHS = SetCC->getOperand(1);
13084 CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
13085 TrueVal = N->getOperand(1);
13086 FalseVal = N->getOperand(2);
13087 } else if (N->getOpcode() == ISD::SELECT_CC) {
13088 LHS = N->getOperand(0);
13089 RHS = N->getOperand(1);
13090 CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
13091 TrueVal = N->getOperand(2);
13092 FalseVal = N->getOperand(3);
13093 } else {
13094 return SDValue();
13095 }
13096
13097 unsigned int Opcode = 0;
13098 if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
13099 FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
13100 (CC == ISD::SETULT || CC == ISD::SETUGT)) {
13101 Opcode = ARMISD::VMINVu;
13102 if (CC == ISD::SETUGT)
13103 std::swap(TrueVal, FalseVal);
13104 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
13105 FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
13106 (CC == ISD::SETLT || CC == ISD::SETGT)) {
13107 Opcode = ARMISD::VMINVs;
13108 if (CC == ISD::SETGT)
13109 std::swap(TrueVal, FalseVal);
13110 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
13111 FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
13112 (CC == ISD::SETUGT || CC == ISD::SETULT)) {
13113 Opcode = ARMISD::VMAXVu;
13114 if (CC == ISD::SETULT)
13115 std::swap(TrueVal, FalseVal);
13116 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
13117 FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
13118 (CC == ISD::SETGT || CC == ISD::SETLT)) {
13119 Opcode = ARMISD::VMAXVs;
13120 if (CC == ISD::SETLT)
13121 std::swap(TrueVal, FalseVal);
13122 } else
13123 return SDValue();
13124
13125 // Normalise to the right hand side being the vector reduction
13126 switch (TrueVal->getOpcode()) {
13131 std::swap(LHS, RHS);
13132 std::swap(TrueVal, FalseVal);
13133 break;
13134 }
13135
13136 EVT VectorType = FalseVal->getOperand(0).getValueType();
13137
13138 if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
13139 VectorType != MVT::v4i32)
13140 return SDValue();
13141
13142 EVT VectorScalarType = VectorType.getVectorElementType();
13143
13144 // The values being selected must also be the ones being compared
13145 if (TrueVal != LHS || FalseVal != RHS)
13146 return SDValue();
13147
13148 EVT LeftType = LHS->getValueType(0);
13149 EVT RightType = RHS->getValueType(0);
13150
13151 // The types must match the reduced type too
13152 if (LeftType != VectorScalarType || RightType != VectorScalarType)
13153 return SDValue();
13154
13155 // Legalise the scalar to an i32
13156 if (VectorScalarType != MVT::i32)
13157 LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
13158
13159 // Generate the reduction as an i32 for legalisation purposes
13160 auto Reduction =
13161 DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
13162
13163 // The result isn't actually an i32 so truncate it back to its original type
13164 if (VectorScalarType != MVT::i32)
13165 Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
13166
13167 return Reduction;
13168}
13169
13170// A special combine for the vqdmulh family of instructions. This is one of the
13171// potential set of patterns that could patch this instruction. The base pattern
13172// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
13173// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
13174// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
13175// the max is unnecessary.
13177 EVT VT = N->getValueType(0);
13178 SDValue Shft;
13179 ConstantSDNode *Clamp;
13180
13181 if (!VT.isVector() || VT.getScalarSizeInBits() > 64)
13182 return SDValue();
13183
13184 if (N->getOpcode() == ISD::SMIN) {
13185 Shft = N->getOperand(0);
13186 Clamp = isConstOrConstSplat(N->getOperand(1));
13187 } else if (N->getOpcode() == ISD::VSELECT) {
13188 // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
13189 SDValue Cmp = N->getOperand(0);
13190 if (Cmp.getOpcode() != ISD::SETCC ||
13191 cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
13192 Cmp.getOperand(0) != N->getOperand(1) ||
13193 Cmp.getOperand(1) != N->getOperand(2))
13194 return SDValue();
13195 Shft = N->getOperand(1);
13196 Clamp = isConstOrConstSplat(N->getOperand(2));
13197 } else
13198 return SDValue();
13199
13200 if (!Clamp)
13201 return SDValue();
13202
13203 MVT ScalarType;
13204 int ShftAmt = 0;
13205 switch (Clamp->getSExtValue()) {
13206 case (1 << 7) - 1:
13207 ScalarType = MVT::i8;
13208 ShftAmt = 7;
13209 break;
13210 case (1 << 15) - 1:
13211 ScalarType = MVT::i16;
13212 ShftAmt = 15;
13213 break;
13214 case (1ULL << 31) - 1:
13215 ScalarType = MVT::i32;
13216 ShftAmt = 31;
13217 break;
13218 default:
13219 return SDValue();
13220 }
13221
13222 if (Shft.getOpcode() != ISD::SRA)
13223 return SDValue();
13225 if (!N1 || N1->getSExtValue() != ShftAmt)
13226 return SDValue();
13227
13228 SDValue Mul = Shft.getOperand(0);
13229 if (Mul.getOpcode() != ISD::MUL)
13230 return SDValue();
13231
13232 SDValue Ext0 = Mul.getOperand(0);
13233 SDValue Ext1 = Mul.getOperand(1);
13234 if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
13235 Ext1.getOpcode() != ISD::SIGN_EXTEND)
13236 return SDValue();
13237 EVT VecVT = Ext0.getOperand(0).getValueType();
13238 if (!VecVT.isPow2VectorType() || VecVT.getVectorNumElements() == 1)
13239 return SDValue();
13240 if (Ext1.getOperand(0).getValueType() != VecVT ||
13241 VecVT.getScalarType() != ScalarType ||
13242 VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
13243 return SDValue();
13244
13245 SDLoc DL(Mul);
13246 unsigned LegalLanes = 128 / (ShftAmt + 1);
13247 EVT LegalVecVT = MVT::getVectorVT(ScalarType, LegalLanes);
13248 // For types smaller than legal vectors extend to be legal and only use needed
13249 // lanes.
13250 if (VecVT.getSizeInBits() < 128) {
13251 EVT ExtVecVT =
13253 VecVT.getVectorNumElements());
13254 SDValue Inp0 =
13255 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext0.getOperand(0));
13256 SDValue Inp1 =
13257 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext1.getOperand(0));
13258 Inp0 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp0);
13259 Inp1 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp1);
13260 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13261 SDValue Trunc = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, ExtVecVT, VQDMULH);
13262 Trunc = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Trunc);
13263 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Trunc);
13264 }
13265
13266 // For larger types, split into legal sized chunks.
13267 assert(VecVT.getSizeInBits() % 128 == 0 && "Expected a power2 type");
13268 unsigned NumParts = VecVT.getSizeInBits() / 128;
13270 for (unsigned I = 0; I < NumParts; ++I) {
13271 SDValue Inp0 =
13272 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext0.getOperand(0),
13273 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13274 SDValue Inp1 =
13275 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext1.getOperand(0),
13276 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13277 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13278 Parts.push_back(VQDMULH);
13279 }
13280 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT,
13281 DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
13282}
13283
13286 const ARMSubtarget *Subtarget) {
13287 if (!Subtarget->hasMVEIntegerOps())
13288 return SDValue();
13289
13290 // Constant fold vselect 0, A, B -> B
13291 // and vselect 0xffff, A, B -> A
13292 if (N->getOperand(0).getOpcode() == ARMISD::PREDICATE_CAST &&
13293 isa<ConstantSDNode>(N->getOperand(0).getOperand(0))) {
13294 unsigned C = N->getOperand(0).getConstantOperandVal(0);
13295 if (C == 0)
13296 return N->getOperand(2);
13297 if (C == 0xffff)
13298 return N->getOperand(1);
13299 }
13300
13301 if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
13302 return V;
13303
13304 // Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
13305 //
13306 // We need to re-implement this optimization here as the implementation in the
13307 // Target-Independent DAGCombiner does not handle the kind of constant we make
13308 // (it calls isConstOrConstSplat with AllowTruncation set to false - and for
13309 // good reason, allowing truncation there would break other targets).
13310 //
13311 // Currently, this is only done for MVE, as it's the only target that benefits
13312 // from this transformation (e.g. VPNOT+VPSEL becomes a single VPSEL).
13313 if (N->getOperand(0).getOpcode() != ISD::XOR)
13314 return SDValue();
13315 SDValue XOR = N->getOperand(0);
13316
13317 // Check if the XOR's RHS is either a 1, or a BUILD_VECTOR of 1s.
13318 // It is important to check with truncation allowed as the BUILD_VECTORs we
13319 // generate in those situations will truncate their operands.
13320 ConstantSDNode *Const =
13321 isConstOrConstSplat(XOR->getOperand(1), /*AllowUndefs*/ false,
13322 /*AllowTruncation*/ true);
13323 if (!Const || !Const->isOne())
13324 return SDValue();
13325
13326 // Rewrite into vselect(cond, rhs, lhs).
13327 SDValue Cond = XOR->getOperand(0);
13328 SDValue LHS = N->getOperand(1);
13329 SDValue RHS = N->getOperand(2);
13330 EVT Type = N->getValueType(0);
13331 return DCI.DAG.getNode(ISD::VSELECT, SDLoc(N), Type, Cond, RHS, LHS);
13332}
13333
13334// Convert vsetcc([0,1,2,..], splat(n), ult) -> vctp n
13337 const ARMSubtarget *Subtarget) {
13338 SDValue Op0 = N->getOperand(0);
13339 SDValue Op1 = N->getOperand(1);
13340 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
13341 EVT VT = N->getValueType(0);
13342
13343 if (!Subtarget->hasMVEIntegerOps() ||
13345 return SDValue();
13346
13347 if (CC == ISD::SETUGT) {
13348 std::swap(Op0, Op1);
13349 CC = ISD::SETULT;
13350 }
13351
13352 if (CC != ISD::SETULT || VT.getScalarSizeInBits() != 1 ||
13354 return SDValue();
13355
13356 // Check first operand is BuildVector of 0,1,2,...
13357 for (unsigned I = 0; I < VT.getVectorNumElements(); I++) {
13358 if (!Op0.getOperand(I).isUndef() &&
13360 Op0.getConstantOperandVal(I) == I))
13361 return SDValue();
13362 }
13363
13364 // The second is a Splat of Op1S
13365 SDValue Op1S = DCI.DAG.getSplatValue(Op1);
13366 if (!Op1S)
13367 return SDValue();
13368
13369 unsigned Opc;
13370 switch (VT.getVectorNumElements()) {
13371 case 4:
13372 Opc = Intrinsic::arm_mve_vctp32;
13373 break;
13374 case 8:
13375 Opc = Intrinsic::arm_mve_vctp16;
13376 break;
13377 case 16:
13378 Opc = Intrinsic::arm_mve_vctp8;
13379 break;
13380 default:
13381 return SDValue();
13382 }
13383
13384 SDLoc DL(N);
13385 return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT,
13386 DCI.DAG.getConstant(Opc, DL, MVT::i32),
13387 DCI.DAG.getZExtOrTrunc(Op1S, DL, MVT::i32));
13388}
13389
13390/// PerformADDECombine - Target-specific dag combine transform from
13391/// ARMISD::ADDC, ARMISD::ADDE, and ISD::MUL_LOHI to MLAL or
13392/// ARMISD::ADDC, ARMISD::ADDE and ARMISD::UMLAL to ARMISD::UMAAL
13395 const ARMSubtarget *Subtarget) {
13396 // Only ARM and Thumb2 support UMLAL/SMLAL.
13397 if (Subtarget->isThumb1Only())
13398 return PerformAddeSubeCombine(N, DCI, Subtarget);
13399
13400 // Only perform the checks after legalize when the pattern is available.
13401 if (DCI.isBeforeLegalize()) return SDValue();
13402
13403 return AddCombineTo64bitUMAAL(N, DCI, Subtarget);
13404}
13405
13406/// PerformADDCombineWithOperands - Try DAG combinations for an ADD with
13407/// operands N0 and N1. This is a helper for PerformADDCombine that is
13408/// called with the default operands, and if that fails, with commuted
13409/// operands.
13412 const ARMSubtarget *Subtarget){
13413 // Attempt to create vpadd for this add.
13414 if (SDValue Result = AddCombineToVPADD(N, N0, N1, DCI, Subtarget))
13415 return Result;
13416
13417 // Attempt to create vpaddl for this add.
13418 if (SDValue Result = AddCombineVUZPToVPADDL(N, N0, N1, DCI, Subtarget))
13419 return Result;
13420 if (SDValue Result = AddCombineBUILD_VECTORToVPADDL(N, N0, N1, DCI,
13421 Subtarget))
13422 return Result;
13423
13424 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
13425 if (N0.getNode()->hasOneUse())
13426 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI))
13427 return Result;
13428 return SDValue();
13429}
13430
13432 EVT VT = N->getValueType(0);
13433 SDValue N0 = N->getOperand(0);
13434 SDValue N1 = N->getOperand(1);
13435 SDLoc dl(N);
13436
13437 auto IsVecReduce = [](SDValue Op) {
13438 switch (Op.getOpcode()) {
13439 case ISD::VECREDUCE_ADD:
13440 case ARMISD::VADDVs:
13441 case ARMISD::VADDVu:
13442 case ARMISD::VMLAVs:
13443 case ARMISD::VMLAVu:
13444 return true;
13445 }
13446 return false;
13447 };
13448
13449 auto DistrubuteAddAddVecReduce = [&](SDValue N0, SDValue N1) {
13450 // Distribute add(X, add(vecreduce(Y), vecreduce(Z))) ->
13451 // add(add(X, vecreduce(Y)), vecreduce(Z))
13452 // to make better use of vaddva style instructions.
13453 if (VT == MVT::i32 && N1.getOpcode() == ISD::ADD && !IsVecReduce(N0) &&
13454 IsVecReduce(N1.getOperand(0)) && IsVecReduce(N1.getOperand(1)) &&
13455 !isa<ConstantSDNode>(N0) && N1->hasOneUse()) {
13456 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0, N1.getOperand(0));
13457 return DAG.getNode(ISD::ADD, dl, VT, Add0, N1.getOperand(1));
13458 }
13459 // And turn add(add(A, reduce(B)), add(C, reduce(D))) ->
13460 // add(add(add(A, C), reduce(B)), reduce(D))
13461 if (VT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
13462 N1.getOpcode() == ISD::ADD && N0->hasOneUse() && N1->hasOneUse()) {
13463 unsigned N0RedOp = 0;
13464 if (!IsVecReduce(N0.getOperand(N0RedOp))) {
13465 N0RedOp = 1;
13466 if (!IsVecReduce(N0.getOperand(N0RedOp)))
13467 return SDValue();
13468 }
13469
13470 unsigned N1RedOp = 0;
13471 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13472 N1RedOp = 1;
13473 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13474 return SDValue();
13475
13476 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0.getOperand(1 - N0RedOp),
13477 N1.getOperand(1 - N1RedOp));
13478 SDValue Add1 =
13479 DAG.getNode(ISD::ADD, dl, VT, Add0, N0.getOperand(N0RedOp));
13480 return DAG.getNode(ISD::ADD, dl, VT, Add1, N1.getOperand(N1RedOp));
13481 }
13482 return SDValue();
13483 };
13484 if (SDValue R = DistrubuteAddAddVecReduce(N0, N1))
13485 return R;
13486 if (SDValue R = DistrubuteAddAddVecReduce(N1, N0))
13487 return R;
13488
13489 // Distribute add(vecreduce(load(Y)), vecreduce(load(Z)))
13490 // Or add(add(X, vecreduce(load(Y))), vecreduce(load(Z)))
13491 // by ascending load offsets. This can help cores prefetch if the order of
13492 // loads is more predictable.
13493 auto DistrubuteVecReduceLoad = [&](SDValue N0, SDValue N1, bool IsForward) {
13494 // Check if two reductions are known to load data where one is before/after
13495 // another. Return negative if N0 loads data before N1, positive if N1 is
13496 // before N0 and 0 otherwise if nothing is known.
13497 auto IsKnownOrderedLoad = [&](SDValue N0, SDValue N1) {
13498 // Look through to the first operand of a MUL, for the VMLA case.
13499 // Currently only looks at the first operand, in the hope they are equal.
13500 if (N0.getOpcode() == ISD::MUL)
13501 N0 = N0.getOperand(0);
13502 if (N1.getOpcode() == ISD::MUL)
13503 N1 = N1.getOperand(0);
13504
13505 // Return true if the two operands are loads to the same object and the
13506 // offset of the first is known to be less than the offset of the second.
13507 LoadSDNode *Load0 = dyn_cast<LoadSDNode>(N0);
13508 LoadSDNode *Load1 = dyn_cast<LoadSDNode>(N1);
13509 if (!Load0 || !Load1 || Load0->getChain() != Load1->getChain() ||
13510 !Load0->isSimple() || !Load1->isSimple() || Load0->isIndexed() ||
13511 Load1->isIndexed())
13512 return 0;
13513
13514 auto BaseLocDecomp0 = BaseIndexOffset::match(Load0, DAG);
13515 auto BaseLocDecomp1 = BaseIndexOffset::match(Load1, DAG);
13516
13517 if (!BaseLocDecomp0.getBase() ||
13518 BaseLocDecomp0.getBase() != BaseLocDecomp1.getBase() ||
13519 !BaseLocDecomp0.hasValidOffset() || !BaseLocDecomp1.hasValidOffset())
13520 return 0;
13521 if (BaseLocDecomp0.getOffset() < BaseLocDecomp1.getOffset())
13522 return -1;
13523 if (BaseLocDecomp0.getOffset() > BaseLocDecomp1.getOffset())
13524 return 1;
13525 return 0;
13526 };
13527
13528 SDValue X;
13529 if (N0.getOpcode() == ISD::ADD && N0->hasOneUse()) {
13530 if (IsVecReduce(N0.getOperand(0)) && IsVecReduce(N0.getOperand(1))) {
13531 int IsBefore = IsKnownOrderedLoad(N0.getOperand(0).getOperand(0),
13532 N0.getOperand(1).getOperand(0));
13533 if (IsBefore < 0) {
13534 X = N0.getOperand(0);
13535 N0 = N0.getOperand(1);
13536 } else if (IsBefore > 0) {
13537 X = N0.getOperand(1);
13538 N0 = N0.getOperand(0);
13539 } else
13540 return SDValue();
13541 } else if (IsVecReduce(N0.getOperand(0))) {
13542 X = N0.getOperand(1);
13543 N0 = N0.getOperand(0);
13544 } else if (IsVecReduce(N0.getOperand(1))) {
13545 X = N0.getOperand(0);
13546 N0 = N0.getOperand(1);
13547 } else
13548 return SDValue();
13549 } else if (IsForward && IsVecReduce(N0) && IsVecReduce(N1) &&
13550 IsKnownOrderedLoad(N0.getOperand(0), N1.getOperand(0)) < 0) {
13551 // Note this is backward to how you would expect. We create
13552 // add(reduce(load + 16), reduce(load + 0)) so that the
13553 // add(reduce(load+16), X) is combined into VADDVA(X, load+16)), leaving
13554 // the X as VADDV(load + 0)
13555 return DAG.getNode(ISD::ADD, dl, VT, N1, N0);
13556 } else
13557 return SDValue();
13558
13559 if (!IsVecReduce(N0) || !IsVecReduce(N1))
13560 return SDValue();
13561
13562 if (IsKnownOrderedLoad(N1.getOperand(0), N0.getOperand(0)) >= 0)
13563 return SDValue();
13564
13565 // Switch from add(add(X, N0), N1) to add(add(X, N1), N0)
13566 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, X, N1);
13567 return DAG.getNode(ISD::ADD, dl, VT, Add0, N0);
13568 };
13569 if (SDValue R = DistrubuteVecReduceLoad(N0, N1, true))
13570 return R;
13571 if (SDValue R = DistrubuteVecReduceLoad(N1, N0, false))
13572 return R;
13573 return SDValue();
13574}
13575
13577 const ARMSubtarget *Subtarget) {
13578 if (!Subtarget->hasMVEIntegerOps())
13579 return SDValue();
13580
13582 return R;
13583
13584 EVT VT = N->getValueType(0);
13585 SDValue N0 = N->getOperand(0);
13586 SDValue N1 = N->getOperand(1);
13587 SDLoc dl(N);
13588
13589 if (VT != MVT::i64)
13590 return SDValue();
13591
13592 // We are looking for a i64 add of a VADDLVx. Due to these being i64's, this
13593 // will look like:
13594 // t1: i32,i32 = ARMISD::VADDLVs x
13595 // t2: i64 = build_pair t1, t1:1
13596 // t3: i64 = add t2, y
13597 // Otherwise we try to push the add up above VADDLVAx, to potentially allow
13598 // the add to be simplified separately.
13599 // We also need to check for sext / zext and commutitive adds.
13600 auto MakeVecReduce = [&](unsigned Opcode, unsigned OpcodeA, SDValue NA,
13601 SDValue NB) {
13602 if (NB->getOpcode() != ISD::BUILD_PAIR)
13603 return SDValue();
13604 SDValue VecRed = NB->getOperand(0);
13605 if ((VecRed->getOpcode() != Opcode && VecRed->getOpcode() != OpcodeA) ||
13606 VecRed.getResNo() != 0 ||
13607 NB->getOperand(1) != SDValue(VecRed.getNode(), 1))
13608 return SDValue();
13609
13610 if (VecRed->getOpcode() == OpcodeA) {
13611 // add(NA, VADDLVA(Inp), Y) -> VADDLVA(add(NA, Inp), Y)
13612 SDValue Inp = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
13613 VecRed.getOperand(0), VecRed.getOperand(1));
13614 NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA);
13615 }
13616
13618 std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32);
13619
13620 unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0;
13621 for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++)
13622 Ops.push_back(VecRed->getOperand(I));
13623 SDValue Red =
13624 DAG.getNode(OpcodeA, dl, DAG.getVTList({MVT::i32, MVT::i32}), Ops);
13625 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Red,
13626 SDValue(Red.getNode(), 1));
13627 };
13628
13629 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N0, N1))
13630 return M;
13631 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N0, N1))
13632 return M;
13633 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N1, N0))
13634 return M;
13635 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N1, N0))
13636 return M;
13637 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N0, N1))
13638 return M;
13639 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N0, N1))
13640 return M;
13641 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N1, N0))
13642 return M;
13643 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N1, N0))
13644 return M;
13645 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N0, N1))
13646 return M;
13647 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N0, N1))
13648 return M;
13649 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N1, N0))
13650 return M;
13651 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
13652 return M;
13653 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
13654 return M;
13655 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
13656 return M;
13657 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
13658 return M;
13659 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
13660 return M;
13661 return SDValue();
13662}
13663
13664bool
13666 CombineLevel Level) const {
13667 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
13668 N->getOpcode() == ISD::SRL) &&
13669 "Expected shift op");
13670
13671 SDValue ShiftLHS = N->getOperand(0);
13672 if (!ShiftLHS->hasOneUse())
13673 return false;
13674
13675 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
13676 !ShiftLHS.getOperand(0)->hasOneUse())
13677 return false;
13678
13679 if (Level == BeforeLegalizeTypes)
13680 return true;
13681
13682 if (N->getOpcode() != ISD::SHL)
13683 return true;
13684
13685 if (Subtarget->isThumb1Only()) {
13686 // Avoid making expensive immediates by commuting shifts. (This logic
13687 // only applies to Thumb1 because ARM and Thumb2 immediates can be shifted
13688 // for free.)
13689 if (N->getOpcode() != ISD::SHL)
13690 return true;
13691 SDValue N1 = N->getOperand(0);
13692 if (N1->getOpcode() != ISD::ADD && N1->getOpcode() != ISD::AND &&
13693 N1->getOpcode() != ISD::OR && N1->getOpcode() != ISD::XOR)
13694 return true;
13695 if (auto *Const = dyn_cast<ConstantSDNode>(N1->getOperand(1))) {
13696 if (Const->getAPIntValue().ult(256))
13697 return false;
13698 if (N1->getOpcode() == ISD::ADD && Const->getAPIntValue().slt(0) &&
13699 Const->getAPIntValue().sgt(-256))
13700 return false;
13701 }
13702 return true;
13703 }
13704
13705 // Turn off commute-with-shift transform after legalization, so it doesn't
13706 // conflict with PerformSHLSimplify. (We could try to detect when
13707 // PerformSHLSimplify would trigger more precisely, but it isn't
13708 // really necessary.)
13709 return false;
13710}
13711
13713 const SDNode *N) const {
13714 assert(N->getOpcode() == ISD::XOR &&
13715 (N->getOperand(0).getOpcode() == ISD::SHL ||
13716 N->getOperand(0).getOpcode() == ISD::SRL) &&
13717 "Expected XOR(SHIFT) pattern");
13718
13719 // Only commute if the entire NOT mask is a hidden shifted mask.
13720 auto *XorC = dyn_cast<ConstantSDNode>(N->getOperand(1));
13721 auto *ShiftC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1));
13722 if (XorC && ShiftC) {
13723 unsigned MaskIdx, MaskLen;
13724 if (XorC->getAPIntValue().isShiftedMask(MaskIdx, MaskLen)) {
13725 unsigned ShiftAmt = ShiftC->getZExtValue();
13726 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
13727 if (N->getOperand(0).getOpcode() == ISD::SHL)
13728 return MaskIdx == ShiftAmt && MaskLen == (BitWidth - ShiftAmt);
13729 return MaskIdx == 0 && MaskLen == (BitWidth - ShiftAmt);
13730 }
13731 }
13732
13733 return false;
13734}
13735
13737 const SDNode *N) const {
13738 assert(((N->getOpcode() == ISD::SHL &&
13739 N->getOperand(0).getOpcode() == ISD::SRL) ||
13740 (N->getOpcode() == ISD::SRL &&
13741 N->getOperand(0).getOpcode() == ISD::SHL)) &&
13742 "Expected shift-shift mask");
13743
13744 if (!Subtarget->isThumb1Only())
13745 return true;
13746
13747 EVT VT = N->getValueType(0);
13748 if (VT.getScalarSizeInBits() > 32)
13749 return true;
13750
13751 return false;
13752}
13753
13755 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
13756 SDValue Y) const {
13757 return Subtarget->hasMVEIntegerOps() && isTypeLegal(VT) &&
13758 SelectOpcode == ISD::VSELECT;
13759}
13760
13762 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps()) {
13763 if (Subtarget->isThumb1Only())
13764 return VT.getScalarSizeInBits() <= 32;
13765 return true;
13766 }
13767 return VT.isScalarInteger();
13768}
13769
13771 EVT VT) const {
13772 if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
13773 return false;
13774
13775 switch (FPVT.getSimpleVT().SimpleTy) {
13776 case MVT::f16:
13777 return Subtarget->hasVFP2Base();
13778 case MVT::f32:
13779 return Subtarget->hasVFP2Base();
13780 case MVT::f64:
13781 return Subtarget->hasFP64();
13782 case MVT::v4f32:
13783 case MVT::v8f16:
13784 return Subtarget->hasMVEFloatOps();
13785 default:
13786 return false;
13787 }
13788}
13789
13792 const ARMSubtarget *ST) {
13793 // Allow the generic combiner to identify potential bswaps.
13794 if (DCI.isBeforeLegalize())
13795 return SDValue();
13796
13797 // DAG combiner will fold:
13798 // (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
13799 // (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2
13800 // Other code patterns that can be also be modified have the following form:
13801 // b + ((a << 1) | 510)
13802 // b + ((a << 1) & 510)
13803 // b + ((a << 1) ^ 510)
13804 // b + ((a << 1) + 510)
13805
13806 // Many instructions can perform the shift for free, but it requires both
13807 // the operands to be registers. If c1 << c2 is too large, a mov immediate
13808 // instruction will needed. So, unfold back to the original pattern if:
13809 // - if c1 and c2 are small enough that they don't require mov imms.
13810 // - the user(s) of the node can perform an shl
13811
13812 // No shifted operands for 16-bit instructions.
13813 if (ST->isThumb1Only())
13814 return SDValue();
13815
13816 // Check that all the users could perform the shl themselves.
13817 for (auto *U : N->users()) {
13818 switch(U->getOpcode()) {
13819 default:
13820 return SDValue();
13821 case ISD::SUB:
13822 case ISD::ADD:
13823 case ISD::AND:
13824 case ISD::OR:
13825 case ISD::XOR:
13826 case ISD::SETCC:
13827 case ARMISD::CMP:
13828 // Check that the user isn't already using a constant because there
13829 // aren't any instructions that support an immediate operand and a
13830 // shifted operand.
13831 if (isa<ConstantSDNode>(U->getOperand(0)) ||
13832 isa<ConstantSDNode>(U->getOperand(1)))
13833 return SDValue();
13834
13835 // Check that it's not already using a shift.
13836 if (U->getOperand(0).getOpcode() == ISD::SHL ||
13837 U->getOperand(1).getOpcode() == ISD::SHL)
13838 return SDValue();
13839 break;
13840 }
13841 }
13842
13843 if (N->getOpcode() != ISD::ADD && N->getOpcode() != ISD::OR &&
13844 N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND)
13845 return SDValue();
13846
13847 if (N->getOperand(0).getOpcode() != ISD::SHL)
13848 return SDValue();
13849
13850 SDValue SHL = N->getOperand(0);
13851
13852 auto *C1ShlC2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
13853 auto *C2 = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
13854 if (!C1ShlC2 || !C2)
13855 return SDValue();
13856
13857 APInt C2Int = C2->getAPIntValue();
13858 APInt C1Int = C1ShlC2->getAPIntValue();
13859 unsigned C2Width = C2Int.getBitWidth();
13860 if (C2Int.uge(C2Width))
13861 return SDValue();
13862 uint64_t C2Value = C2Int.getZExtValue();
13863
13864 // Check that performing a lshr will not lose any information.
13865 APInt Mask = APInt::getHighBitsSet(C2Width, C2Width - C2Value);
13866 if ((C1Int & Mask) != C1Int)
13867 return SDValue();
13868
13869 // Shift the first constant.
13870 C1Int.lshrInPlace(C2Int);
13871
13872 // The immediates are encoded as an 8-bit value that can be rotated.
13873 auto LargeImm = [](const APInt &Imm) {
13874 unsigned Zeros = Imm.countl_zero() + Imm.countr_zero();
13875 return Imm.getBitWidth() - Zeros > 8;
13876 };
13877
13878 if (LargeImm(C1Int) || LargeImm(C2Int))
13879 return SDValue();
13880
13881 SelectionDAG &DAG = DCI.DAG;
13882 SDLoc dl(N);
13883 SDValue X = SHL.getOperand(0);
13884 SDValue BinOp = DAG.getNode(N->getOpcode(), dl, MVT::i32, X,
13885 DAG.getConstant(C1Int, dl, MVT::i32));
13886 // Shift left to compensate for the lshr of C1Int.
13887 SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
13888
13889 LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
13890 SHL.dump(); N->dump());
13891 LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
13892 return Res;
13893}
13894
13895
13896/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
13897///
13900 const ARMSubtarget *Subtarget) {
13901 SDValue N0 = N->getOperand(0);
13902 SDValue N1 = N->getOperand(1);
13903
13904 // Only works one way, because it needs an immediate operand.
13905 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
13906 return Result;
13907
13908 if (SDValue Result = PerformADDVecReduce(N, DCI.DAG, Subtarget))
13909 return Result;
13910
13911 // First try with the default operand order.
13912 if (SDValue Result = PerformADDCombineWithOperands(N, N0, N1, DCI, Subtarget))
13913 return Result;
13914
13915 // If that didn't work, try again with the operands commuted.
13916 return PerformADDCombineWithOperands(N, N1, N0, DCI, Subtarget);
13917}
13918
13919// Combine (sub 0, (csinc X, Y, CC)) -> (csinv -X, Y, CC)
13920// providing -X is as cheap as X (currently, just a constant).
13922 if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
13923 return SDValue();
13924 SDValue CSINC = N->getOperand(1);
13925 if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
13926 return SDValue();
13927
13929 if (!X)
13930 return SDValue();
13931
13932 return DAG.getNode(ARMISD::CSINV, SDLoc(N), MVT::i32,
13933 DAG.getNode(ISD::SUB, SDLoc(N), MVT::i32, N->getOperand(0),
13934 CSINC.getOperand(0)),
13935 CSINC.getOperand(1), CSINC.getOperand(2),
13936 CSINC.getOperand(3));
13937}
13938
13940 // Free to negate.
13942 return 0;
13943
13944 // Will save one instruction.
13945 if (Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)))
13946 return -1;
13947
13948 // Can freely negate by converting sra <-> srl.
13949 if (Op.getOpcode() == ISD::SRA || Op.getOpcode() == ISD::SRL) {
13950 ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1));
13951 if (Op.hasOneUse() && ShiftAmt &&
13952 ShiftAmt->getZExtValue() == Op.getValueType().getScalarSizeInBits() - 1)
13953 return 0;
13954 }
13955
13956 // Will have to create sub.
13957 return 1;
13958}
13959
13960// Try to fold
13961//
13962// (neg (cmov X, Y)) -> (cmov (neg X), (neg Y))
13963//
13964// The folding helps cmov to be matched with csneg without generating
13965// redundant neg instruction.
13967 assert(N->getOpcode() == ISD::SUB);
13968 if (!isNullConstant(N->getOperand(0)))
13969 return SDValue();
13970
13971 SDValue CMov = N->getOperand(1);
13972 if (CMov.getOpcode() != ARMISD::CMOV || !CMov->hasOneUse())
13973 return SDValue();
13974
13975 SDValue N0 = CMov.getOperand(0);
13976 SDValue N1 = CMov.getOperand(1);
13977
13978 // Only perform the fold if we actually save something.
13979 if (getNegationCost(N0) + getNegationCost(N1) > 0)
13980 return SDValue();
13981
13982 SDLoc DL(N);
13983 EVT VT = CMov.getValueType();
13984
13985 SDValue N0N = DAG.getNegative(N0, DL, VT);
13986 SDValue N1N = DAG.getNegative(N1, DL, VT);
13987 return DAG.getNode(ARMISD::CMOV, DL, VT, N0N, N1N, CMov.getOperand(2),
13988 CMov.getOperand(3));
13989}
13990
13991/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
13992///
13995 const ARMSubtarget *Subtarget) {
13996 SDValue N0 = N->getOperand(0);
13997 SDValue N1 = N->getOperand(1);
13998
13999 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
14000 if (N1.getNode()->hasOneUse())
14001 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI))
14002 return Result;
14003
14004 if (SDValue R = PerformSubCSINCCombine(N, DCI.DAG))
14005 return R;
14006
14007 if (SDValue Val = performNegCMovCombine(N, DCI.DAG))
14008 return Val;
14009
14010 if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector())
14011 return SDValue();
14012
14013 // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x))
14014 // so that we can readily pattern match more mve instructions which can use
14015 // a scalar operand.
14016 SDValue VDup = N->getOperand(1);
14017 if (VDup->getOpcode() != ARMISD::VDUP)
14018 return SDValue();
14019
14020 SDValue VMov = N->getOperand(0);
14021 if (VMov->getOpcode() == ISD::BITCAST)
14022 VMov = VMov->getOperand(0);
14023
14024 if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov))
14025 return SDValue();
14026
14027 SDLoc dl(N);
14028 SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32,
14029 DCI.DAG.getConstant(0, dl, MVT::i32),
14030 VDup->getOperand(0));
14031 return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate);
14032}
14033
14034/// PerformVMULCombine
14035/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the
14036/// special multiplier accumulator forwarding.
14037/// vmul d3, d0, d2
14038/// vmla d3, d1, d2
14039/// is faster than
14040/// vadd d3, d0, d1
14041/// vmul d3, d3, d2
14042// However, for (A + B) * (A + B),
14043// vadd d2, d0, d1
14044// vmul d3, d0, d2
14045// vmla d3, d1, d2
14046// is slower than
14047// vadd d2, d0, d1
14048// vmul d3, d2, d2
14051 const ARMSubtarget *Subtarget) {
14052 if (!Subtarget->hasVMLxForwarding())
14053 return SDValue();
14054
14055 SelectionDAG &DAG = DCI.DAG;
14056 SDValue N0 = N->getOperand(0);
14057 SDValue N1 = N->getOperand(1);
14058 unsigned Opcode = N0.getOpcode();
14059 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14060 Opcode != ISD::FADD && Opcode != ISD::FSUB) {
14061 Opcode = N1.getOpcode();
14062 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14063 Opcode != ISD::FADD && Opcode != ISD::FSUB)
14064 return SDValue();
14065 std::swap(N0, N1);
14066 }
14067
14068 if (N0 == N1)
14069 return SDValue();
14070
14071 EVT VT = N->getValueType(0);
14072 SDLoc DL(N);
14073 SDValue N00 = N0->getOperand(0);
14074 SDValue N01 = N0->getOperand(1);
14075 return DAG.getNode(Opcode, DL, VT,
14076 DAG.getNode(ISD::MUL, DL, VT, N00, N1),
14077 DAG.getNode(ISD::MUL, DL, VT, N01, N1));
14078}
14079
14081 const ARMSubtarget *Subtarget) {
14082 EVT VT = N->getValueType(0);
14083 if (VT != MVT::v2i64)
14084 return SDValue();
14085
14086 SDValue N0 = N->getOperand(0);
14087 SDValue N1 = N->getOperand(1);
14088
14089 auto IsSignExt = [&](SDValue Op) {
14090 if (Op->getOpcode() != ISD::SIGN_EXTEND_INREG)
14091 return SDValue();
14092 EVT VT = cast<VTSDNode>(Op->getOperand(1))->getVT();
14093 if (VT.getScalarSizeInBits() == 32)
14094 return Op->getOperand(0);
14095 return SDValue();
14096 };
14097 auto IsZeroExt = [&](SDValue Op) {
14098 // Zero extends are a little more awkward. At the point we are matching
14099 // this, we are looking for an AND with a (-1, 0, -1, 0) buildvector mask.
14100 // That might be before of after a bitcast depending on how the and is
14101 // placed. Because this has to look through bitcasts, it is currently only
14102 // supported on LE.
14103 if (!Subtarget->isLittle())
14104 return SDValue();
14105
14106 SDValue And = Op;
14107 if (And->getOpcode() == ISD::BITCAST)
14108 And = And->getOperand(0);
14109 if (And->getOpcode() != ISD::AND)
14110 return SDValue();
14111 SDValue Mask = And->getOperand(1);
14112 if (Mask->getOpcode() == ISD::BITCAST)
14113 Mask = Mask->getOperand(0);
14114
14115 if (Mask->getOpcode() != ISD::BUILD_VECTOR ||
14116 Mask.getValueType() != MVT::v4i32)
14117 return SDValue();
14118 if (isAllOnesConstant(Mask->getOperand(0)) &&
14119 isNullConstant(Mask->getOperand(1)) &&
14120 isAllOnesConstant(Mask->getOperand(2)) &&
14121 isNullConstant(Mask->getOperand(3)))
14122 return And->getOperand(0);
14123 return SDValue();
14124 };
14125
14126 SDLoc dl(N);
14127 if (SDValue Op0 = IsSignExt(N0)) {
14128 if (SDValue Op1 = IsSignExt(N1)) {
14129 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14130 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14131 return DAG.getNode(ARMISD::VMULLs, dl, VT, New0a, New1a);
14132 }
14133 }
14134 if (SDValue Op0 = IsZeroExt(N0)) {
14135 if (SDValue Op1 = IsZeroExt(N1)) {
14136 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14137 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14138 return DAG.getNode(ARMISD::VMULLu, dl, VT, New0a, New1a);
14139 }
14140 }
14141
14142 return SDValue();
14143}
14144
14147 const ARMSubtarget *Subtarget) {
14148 SelectionDAG &DAG = DCI.DAG;
14149
14150 EVT VT = N->getValueType(0);
14151 if (Subtarget->hasMVEIntegerOps() && VT == MVT::v2i64)
14152 return PerformMVEVMULLCombine(N, DAG, Subtarget);
14153
14154 if (Subtarget->isThumb1Only())
14155 return SDValue();
14156
14157 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14158 return SDValue();
14159
14160 if (VT.is64BitVector() || VT.is128BitVector())
14161 return PerformVMULCombine(N, DCI, Subtarget);
14162 if (VT != MVT::i32)
14163 return SDValue();
14164
14165 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14166 if (!C)
14167 return SDValue();
14168
14169 int64_t MulAmt = C->getSExtValue();
14170 unsigned ShiftAmt = llvm::countr_zero<uint64_t>(MulAmt);
14171
14172 ShiftAmt = ShiftAmt & (32 - 1);
14173 SDValue V = N->getOperand(0);
14174 SDLoc DL(N);
14175
14176 SDValue Res;
14177 MulAmt >>= ShiftAmt;
14178
14179 if (MulAmt >= 0) {
14180 if (llvm::has_single_bit<uint32_t>(MulAmt - 1)) {
14181 // (mul x, 2^N + 1) => (add (shl x, N), x)
14182 Res = DAG.getNode(ISD::ADD, DL, VT,
14183 V,
14184 DAG.getNode(ISD::SHL, DL, VT,
14185 V,
14186 DAG.getConstant(Log2_32(MulAmt - 1), DL,
14187 MVT::i32)));
14188 } else if (llvm::has_single_bit<uint32_t>(MulAmt + 1)) {
14189 // (mul x, 2^N - 1) => (sub (shl x, N), x)
14190 Res = DAG.getNode(ISD::SUB, DL, VT,
14191 DAG.getNode(ISD::SHL, DL, VT,
14192 V,
14193 DAG.getConstant(Log2_32(MulAmt + 1), DL,
14194 MVT::i32)),
14195 V);
14196 } else
14197 return SDValue();
14198 } else {
14199 uint64_t MulAmtAbs = -MulAmt;
14200 if (llvm::has_single_bit<uint32_t>(MulAmtAbs + 1)) {
14201 // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
14202 Res = DAG.getNode(ISD::SUB, DL, VT,
14203 V,
14204 DAG.getNode(ISD::SHL, DL, VT,
14205 V,
14206 DAG.getConstant(Log2_32(MulAmtAbs + 1), DL,
14207 MVT::i32)));
14208 } else if (llvm::has_single_bit<uint32_t>(MulAmtAbs - 1)) {
14209 // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
14210 Res = DAG.getNode(ISD::ADD, DL, VT,
14211 V,
14212 DAG.getNode(ISD::SHL, DL, VT,
14213 V,
14214 DAG.getConstant(Log2_32(MulAmtAbs - 1), DL,
14215 MVT::i32)));
14216 Res = DAG.getNode(ISD::SUB, DL, VT,
14217 DAG.getConstant(0, DL, MVT::i32), Res);
14218 } else
14219 return SDValue();
14220 }
14221
14222 if (ShiftAmt != 0)
14223 Res = DAG.getNode(ISD::SHL, DL, VT,
14224 Res, DAG.getConstant(ShiftAmt, DL, MVT::i32));
14225
14226 // Do not add new nodes to DAG combiner worklist.
14227 DCI.CombineTo(N, Res, false);
14228 return SDValue();
14229}
14230
14233 const ARMSubtarget *Subtarget) {
14234 // Allow DAGCombine to pattern-match before we touch the canonical form.
14235 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14236 return SDValue();
14237
14238 if (N->getValueType(0) != MVT::i32)
14239 return SDValue();
14240
14241 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14242 if (!N1C)
14243 return SDValue();
14244
14245 uint32_t C1 = (uint32_t)N1C->getZExtValue();
14246 // Don't transform uxtb/uxth.
14247 if (C1 == 255 || C1 == 65535)
14248 return SDValue();
14249
14250 SDNode *N0 = N->getOperand(0).getNode();
14251 if (!N0->hasOneUse())
14252 return SDValue();
14253
14254 if (N0->getOpcode() != ISD::SHL && N0->getOpcode() != ISD::SRL)
14255 return SDValue();
14256
14257 bool LeftShift = N0->getOpcode() == ISD::SHL;
14258
14260 if (!N01C)
14261 return SDValue();
14262
14263 uint32_t C2 = (uint32_t)N01C->getZExtValue();
14264 if (!C2 || C2 >= 32)
14265 return SDValue();
14266
14267 // Clear irrelevant bits in the mask.
14268 if (LeftShift)
14269 C1 &= (-1U << C2);
14270 else
14271 C1 &= (-1U >> C2);
14272
14273 SelectionDAG &DAG = DCI.DAG;
14274 SDLoc DL(N);
14275
14276 // We have a pattern of the form "(and (shl x, c2) c1)" or
14277 // "(and (srl x, c2) c1)", where c1 is a shifted mask. Try to
14278 // transform to a pair of shifts, to save materializing c1.
14279
14280 // First pattern: right shift, then mask off leading bits.
14281 // FIXME: Use demanded bits?
14282 if (!LeftShift && isMask_32(C1)) {
14284 if (C2 < C3) {
14285 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14286 DAG.getConstant(C3 - C2, DL, MVT::i32));
14287 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14288 DAG.getConstant(C3, DL, MVT::i32));
14289 }
14290 }
14291
14292 // First pattern, reversed: left shift, then mask off trailing bits.
14293 if (LeftShift && isMask_32(~C1)) {
14295 if (C2 < C3) {
14296 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14297 DAG.getConstant(C3 - C2, DL, MVT::i32));
14298 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14299 DAG.getConstant(C3, DL, MVT::i32));
14300 }
14301 }
14302
14303 // Second pattern: left shift, then mask off leading bits.
14304 // FIXME: Use demanded bits?
14305 if (LeftShift && isShiftedMask_32(C1)) {
14306 uint32_t Trailing = llvm::countr_zero(C1);
14308 if (Trailing == C2 && C2 + C3 < 32) {
14309 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14310 DAG.getConstant(C2 + C3, DL, MVT::i32));
14311 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14312 DAG.getConstant(C3, DL, MVT::i32));
14313 }
14314 }
14315
14316 // Second pattern, reversed: right shift, then mask off trailing bits.
14317 // FIXME: Handle other patterns of known/demanded bits.
14318 if (!LeftShift && isShiftedMask_32(C1)) {
14319 uint32_t Leading = llvm::countl_zero(C1);
14321 if (Leading == C2 && C2 + C3 < 32) {
14322 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14323 DAG.getConstant(C2 + C3, DL, MVT::i32));
14324 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14325 DAG.getConstant(C3, DL, MVT::i32));
14326 }
14327 }
14328
14329 // Transform "(and (shl x, c2) c1)" into "(shl (and x, c1>>c2), c2)"
14330 // if "c1 >> c2" is a cheaper immediate than "c1"
14331 if (LeftShift &&
14332 HasLowerConstantMaterializationCost(C1 >> C2, C1, Subtarget)) {
14333
14334 SDValue And = DAG.getNode(ISD::AND, DL, MVT::i32, N0->getOperand(0),
14335 DAG.getConstant(C1 >> C2, DL, MVT::i32));
14336 return DAG.getNode(ISD::SHL, DL, MVT::i32, And,
14337 DAG.getConstant(C2, DL, MVT::i32));
14338 }
14339
14340 return SDValue();
14341}
14342
14345 const ARMSubtarget *Subtarget) {
14346 // Attempt to use immediate-form VBIC
14347 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14348 SDLoc dl(N);
14349 EVT VT = N->getValueType(0);
14350 SelectionDAG &DAG = DCI.DAG;
14351
14352 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) || VT == MVT::v2i1 ||
14353 VT == MVT::v4i1 || VT == MVT::v8i1 || VT == MVT::v16i1)
14354 return SDValue();
14355
14356 APInt SplatBits, SplatUndef;
14357 unsigned SplatBitSize;
14358 bool HasAnyUndefs;
14359 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14360 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14361 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14362 SplatBitSize == 64) {
14363 EVT VbicVT;
14364 SDValue Val = isVMOVModifiedImm((~SplatBits).getZExtValue(),
14365 SplatUndef.getZExtValue(), SplatBitSize,
14366 DAG, dl, VbicVT, VT, OtherModImm);
14367 if (Val.getNode()) {
14368 SDValue Input =
14369 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VbicVT, N->getOperand(0));
14370 SDValue Vbic = DAG.getNode(ARMISD::VBICIMM, dl, VbicVT, Input, Val);
14371 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vbic);
14372 }
14373 }
14374 }
14375
14376 if (!Subtarget->isThumb1Only()) {
14377 // fold (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))
14378 if (SDValue Result = combineSelectAndUseCommutative(N, true, DCI))
14379 return Result;
14380
14381 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14382 return Result;
14383 }
14384
14385 if (Subtarget->isThumb1Only())
14386 if (SDValue Result = CombineANDShift(N, DCI, Subtarget))
14387 return Result;
14388
14389 return SDValue();
14390}
14391
14392// Try combining OR nodes to SMULWB, SMULWT.
14395 const ARMSubtarget *Subtarget) {
14396 if (!Subtarget->hasV6Ops() ||
14397 (Subtarget->isThumb() &&
14398 (!Subtarget->hasThumb2() || !Subtarget->hasDSP())))
14399 return SDValue();
14400
14401 SDValue SRL = OR->getOperand(0);
14402 SDValue SHL = OR->getOperand(1);
14403
14404 if (SRL.getOpcode() != ISD::SRL || SHL.getOpcode() != ISD::SHL) {
14405 SRL = OR->getOperand(1);
14406 SHL = OR->getOperand(0);
14407 }
14408 if (!isSRL16(SRL) || !isSHL16(SHL))
14409 return SDValue();
14410
14411 // The first operands to the shifts need to be the two results from the
14412 // same smul_lohi node.
14413 if ((SRL.getOperand(0).getNode() != SHL.getOperand(0).getNode()) ||
14414 SRL.getOperand(0).getOpcode() != ISD::SMUL_LOHI)
14415 return SDValue();
14416
14417 SDNode *SMULLOHI = SRL.getOperand(0).getNode();
14418 if (SRL.getOperand(0) != SDValue(SMULLOHI, 0) ||
14419 SHL.getOperand(0) != SDValue(SMULLOHI, 1))
14420 return SDValue();
14421
14422 // Now we have:
14423 // (or (srl (smul_lohi ?, ?), 16), (shl (smul_lohi ?, ?), 16)))
14424 // For SMUL[B|T] smul_lohi will take a 32-bit and a 16-bit arguments.
14425 // For SMUWB the 16-bit value will signed extended somehow.
14426 // For SMULWT only the SRA is required.
14427 // Check both sides of SMUL_LOHI
14428 SDValue OpS16 = SMULLOHI->getOperand(0);
14429 SDValue OpS32 = SMULLOHI->getOperand(1);
14430
14431 SelectionDAG &DAG = DCI.DAG;
14432 if (!isS16(OpS16, DAG) && !isSRA16(OpS16)) {
14433 OpS16 = OpS32;
14434 OpS32 = SMULLOHI->getOperand(0);
14435 }
14436
14437 SDLoc dl(OR);
14438 unsigned Opcode = 0;
14439 if (isS16(OpS16, DAG))
14440 Opcode = ARMISD::SMULWB;
14441 else if (isSRA16(OpS16)) {
14442 Opcode = ARMISD::SMULWT;
14443 OpS16 = OpS16->getOperand(0);
14444 }
14445 else
14446 return SDValue();
14447
14448 SDValue Res = DAG.getNode(Opcode, dl, MVT::i32, OpS32, OpS16);
14449 DAG.ReplaceAllUsesOfValueWith(SDValue(OR, 0), Res);
14450 return SDValue(OR, 0);
14451}
14452
14455 const ARMSubtarget *Subtarget) {
14456 // BFI is only available on V6T2+
14457 if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
14458 return SDValue();
14459
14460 EVT VT = N->getValueType(0);
14461 SDValue N0 = N->getOperand(0);
14462 SDValue N1 = N->getOperand(1);
14463 SelectionDAG &DAG = DCI.DAG;
14464 SDLoc DL(N);
14465 // 1) or (and A, mask), val => ARMbfi A, val, mask
14466 // iff (val & mask) == val
14467 //
14468 // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14469 // 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
14470 // && mask == ~mask2
14471 // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
14472 // && ~mask == mask2
14473 // (i.e., copy a bitfield value into another bitfield of the same width)
14474
14475 if (VT != MVT::i32)
14476 return SDValue();
14477
14478 SDValue N00 = N0.getOperand(0);
14479
14480 // The value and the mask need to be constants so we can verify this is
14481 // actually a bitfield set. If the mask is 0xffff, we can do better
14482 // via a movt instruction, so don't use BFI in that case.
14483 SDValue MaskOp = N0.getOperand(1);
14485 if (!MaskC)
14486 return SDValue();
14487 unsigned Mask = MaskC->getZExtValue();
14488 if (Mask == 0xffff)
14489 return SDValue();
14490 SDValue Res;
14491 // Case (1): or (and A, mask), val => ARMbfi A, val, mask
14493 if (N1C) {
14494 unsigned Val = N1C->getZExtValue();
14495 if ((Val & ~Mask) != Val)
14496 return SDValue();
14497
14498 if (ARM::isBitFieldInvertedMask(Mask)) {
14499 Val >>= llvm::countr_zero(~Mask);
14500
14501 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
14502 DAG.getConstant(Val, DL, MVT::i32),
14503 DAG.getConstant(Mask, DL, MVT::i32));
14504
14505 DCI.CombineTo(N, Res, false);
14506 // Return value from the original node to inform the combiner than N is
14507 // now dead.
14508 return SDValue(N, 0);
14509 }
14510 } else if (N1.getOpcode() == ISD::AND) {
14511 // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14513 if (!N11C)
14514 return SDValue();
14515 unsigned Mask2 = N11C->getZExtValue();
14516
14517 // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
14518 // as is to match.
14519 if (ARM::isBitFieldInvertedMask(Mask) &&
14520 (Mask == ~Mask2)) {
14521 // The pack halfword instruction works better for masks that fit it,
14522 // so use that when it's available.
14523 if (Subtarget->hasDSP() &&
14524 (Mask == 0xffff || Mask == 0xffff0000))
14525 return SDValue();
14526 // 2a
14527 unsigned amt = llvm::countr_zero(Mask2);
14528 Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
14529 DAG.getConstant(amt, DL, MVT::i32));
14530 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
14531 DAG.getConstant(Mask, DL, MVT::i32));
14532 DCI.CombineTo(N, Res, false);
14533 // Return value from the original node to inform the combiner than N is
14534 // now dead.
14535 return SDValue(N, 0);
14536 } else if (ARM::isBitFieldInvertedMask(~Mask) &&
14537 (~Mask == Mask2)) {
14538 // The pack halfword instruction works better for masks that fit it,
14539 // so use that when it's available.
14540 if (Subtarget->hasDSP() &&
14541 (Mask2 == 0xffff || Mask2 == 0xffff0000))
14542 return SDValue();
14543 // 2b
14544 unsigned lsb = llvm::countr_zero(Mask);
14545 Res = DAG.getNode(ISD::SRL, DL, VT, N00,
14546 DAG.getConstant(lsb, DL, MVT::i32));
14547 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
14548 DAG.getConstant(Mask2, DL, MVT::i32));
14549 DCI.CombineTo(N, Res, false);
14550 // Return value from the original node to inform the combiner than N is
14551 // now dead.
14552 return SDValue(N, 0);
14553 }
14554 }
14555
14556 if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
14557 N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
14559 // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
14560 // where lsb(mask) == #shamt and masked bits of B are known zero.
14561 SDValue ShAmt = N00.getOperand(1);
14562 unsigned ShAmtC = ShAmt->getAsZExtVal();
14563 unsigned LSB = llvm::countr_zero(Mask);
14564 if (ShAmtC != LSB)
14565 return SDValue();
14566
14567 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
14568 DAG.getConstant(~Mask, DL, MVT::i32));
14569
14570 DCI.CombineTo(N, Res, false);
14571 // Return value from the original node to inform the combiner than N is
14572 // now dead.
14573 return SDValue(N, 0);
14574 }
14575
14576 return SDValue();
14577}
14578
14579static bool isValidMVECond(unsigned CC, bool IsFloat) {
14580 switch (CC) {
14581 case ARMCC::EQ:
14582 case ARMCC::NE:
14583 case ARMCC::LE:
14584 case ARMCC::GT:
14585 case ARMCC::GE:
14586 case ARMCC::LT:
14587 return true;
14588 case ARMCC::HS:
14589 case ARMCC::HI:
14590 return !IsFloat;
14591 default:
14592 return false;
14593 };
14594}
14595
14597 if (N->getOpcode() == ARMISD::VCMP)
14598 return (ARMCC::CondCodes)N->getConstantOperandVal(2);
14599 else if (N->getOpcode() == ARMISD::VCMPZ)
14600 return (ARMCC::CondCodes)N->getConstantOperandVal(1);
14601 else
14602 llvm_unreachable("Not a VCMP/VCMPZ!");
14603}
14604
14607 return isValidMVECond(CC, N->getOperand(0).getValueType().isFloatingPoint());
14608}
14609
14611 const ARMSubtarget *Subtarget) {
14612 // Try to invert "or A, B" -> "and ~A, ~B", as the "and" is easier to chain
14613 // together with predicates
14614 EVT VT = N->getValueType(0);
14615 SDLoc DL(N);
14616 SDValue N0 = N->getOperand(0);
14617 SDValue N1 = N->getOperand(1);
14618
14619 auto IsFreelyInvertable = [&](SDValue V) {
14620 if (V->getOpcode() == ARMISD::VCMP || V->getOpcode() == ARMISD::VCMPZ)
14621 return CanInvertMVEVCMP(V);
14622 return false;
14623 };
14624
14625 // At least one operand must be freely invertable.
14626 if (!(IsFreelyInvertable(N0) || IsFreelyInvertable(N1)))
14627 return SDValue();
14628
14629 SDValue NewN0 = DAG.getLogicalNOT(DL, N0, VT);
14630 SDValue NewN1 = DAG.getLogicalNOT(DL, N1, VT);
14631 SDValue And = DAG.getNode(ISD::AND, DL, VT, NewN0, NewN1);
14632 return DAG.getLogicalNOT(DL, And, VT);
14633}
14634
14635// Try to form a NEON shift-{right, left}-and-insert (VSRI/VSLI) from:
14636// (or (and X, splat (i32 C1)), (srl Y, splat (i32 C2))) -> VSRI X, Y, #C2
14637// (or (and X, splat (i32 C1)), (shl Y, splat (i32 C2))) -> VSLI X, Y, #C2
14638// where C1 is a mask that preserves the bits not written by the shift/insert,
14639// i.e. `C1 == (1 << C2) - 1`.
14641 SDValue ShiftOp, EVT VT,
14642 SDLoc dl) {
14643 // Match (and X, Mask)
14644 if (AndOp.getOpcode() != ISD::AND)
14645 return SDValue();
14646
14647 SDValue X = AndOp.getOperand(0);
14648 SDValue Mask = AndOp.getOperand(1);
14649
14650 ConstantSDNode *MaskC = isConstOrConstSplat(Mask, false, true);
14651 if (!MaskC)
14652 return SDValue();
14653 APInt MaskBits =
14654 MaskC->getAPIntValue().trunc(Mask.getScalarValueSizeInBits());
14655
14656 // Match shift (srl/shl Y, CntVec)
14657 int64_t Cnt = 0;
14658 bool IsShiftRight = false;
14659 SDValue Y;
14660
14661 if (ShiftOp.getOpcode() == ARMISD::VSHRuIMM) {
14662 IsShiftRight = true;
14663 Y = ShiftOp.getOperand(0);
14664 Cnt = ShiftOp.getConstantOperandVal(1);
14665 } else if (ShiftOp.getOpcode() == ARMISD::VSHLIMM) {
14666 Y = ShiftOp.getOperand(0);
14667 Cnt = ShiftOp.getConstantOperandVal(1);
14668 } else {
14669 return SDValue();
14670 }
14671
14672 unsigned ElemBits = VT.getScalarSizeInBits();
14673 APInt RequiredMask = IsShiftRight
14674 ? APInt::getHighBitsSet(ElemBits, (unsigned)Cnt)
14675 : APInt::getLowBitsSet(ElemBits, (unsigned)Cnt);
14676 if (MaskBits != RequiredMask)
14677 return SDValue();
14678
14679 unsigned Opc = IsShiftRight ? ARMISD::VSRIIMM : ARMISD::VSLIIMM;
14680 return DAG.getNode(Opc, dl, VT, X, Y, DAG.getConstant(Cnt, dl, MVT::i32));
14681}
14682
14683/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
14685 const ARMSubtarget *Subtarget) {
14686 // Attempt to use immediate-form VORR
14687 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14688 SDLoc dl(N);
14689 EVT VT = N->getValueType(0);
14690 SelectionDAG &DAG = DCI.DAG;
14691
14692 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14693 return SDValue();
14694
14695 if (Subtarget->hasMVEIntegerOps() && (VT == MVT::v2i1 || VT == MVT::v4i1 ||
14696 VT == MVT::v8i1 || VT == MVT::v16i1))
14697 return PerformORCombine_i1(N, DAG, Subtarget);
14698
14699 APInt SplatBits, SplatUndef;
14700 unsigned SplatBitSize;
14701 bool HasAnyUndefs;
14702 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14703 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14704 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14705 SplatBitSize == 64) {
14706 EVT VorrVT;
14707 SDValue Val =
14708 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
14709 SplatBitSize, DAG, dl, VorrVT, VT, OtherModImm);
14710 if (Val.getNode()) {
14711 SDValue Input =
14712 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VorrVT, N->getOperand(0));
14713 SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
14714 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vorr);
14715 }
14716 }
14717 }
14718
14719 if (!Subtarget->isThumb1Only()) {
14720 // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
14721 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14722 return Result;
14723 if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
14724 return Result;
14725 }
14726
14727 SDValue N0 = N->getOperand(0);
14728 SDValue N1 = N->getOperand(1);
14729
14730 // (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
14731 // (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
14732 if (VT.isVector() &&
14733 ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
14734 (Subtarget->hasMVEIntegerOps() &&
14735 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
14736 if (SDValue ShiftInsert =
14737 PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
14738 return ShiftInsert;
14739
14740 if (SDValue ShiftInsert =
14741 PerformORCombineToShiftInsert(DAG, N1, N0, VT, dl))
14742 return ShiftInsert;
14743 }
14744
14745 // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
14746 if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
14748
14749 // The code below optimizes (or (and X, Y), Z).
14750 // The AND operand needs to have a single user to make these optimizations
14751 // profitable.
14752 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
14753 return SDValue();
14754
14755 APInt SplatUndef;
14756 unsigned SplatBitSize;
14757 bool HasAnyUndefs;
14758
14759 APInt SplatBits0, SplatBits1;
14762 // Ensure that the second operand of both ands are constants
14763 if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
14764 HasAnyUndefs) && !HasAnyUndefs) {
14765 if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
14766 HasAnyUndefs) && !HasAnyUndefs) {
14767 // Ensure that the bit width of the constants are the same and that
14768 // the splat arguments are logical inverses as per the pattern we
14769 // are trying to simplify.
14770 if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
14771 SplatBits0 == ~SplatBits1) {
14772 // Canonicalize the vector type to make instruction selection
14773 // simpler.
14774 EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
14775 SDValue Mask = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl,
14776 CanonicalVT, N0->getOperand(1));
14777 SDValue LHS = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl,
14778 CanonicalVT, N0->getOperand(0));
14779 SDValue RHS = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl,
14780 CanonicalVT, N1->getOperand(0));
14781 SDValue Result =
14782 DAG.getNode(ARMISD::VBSP, dl, CanonicalVT, Mask, LHS, RHS);
14783 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Result);
14784 }
14785 }
14786 }
14787 }
14788
14789 // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
14790 // reasonable.
14791 if (N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
14792 if (SDValue Res = PerformORCombineToBFI(N, DCI, Subtarget))
14793 return Res;
14794 }
14795
14796 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14797 return Result;
14798
14799 // (or x, (csinc 0, 0, cc)) -> (csinc x, 0, cc)
14800 // providing that the x is 0 or 1.
14801 SDValue CSINC = N1;
14802 SDValue Other = N0;
14803 if (CSINC.getOpcode() != ARMISD::CSINC)
14804 std::swap(CSINC, Other);
14805 if (CSINC.getOpcode() == ARMISD::CSINC &&
14806 isNullConstant(CSINC.getOperand(0)) &&
14807 isNullConstant(CSINC.getOperand(1)) &&
14809 return DAG.getNode(ARMISD::CSINC, dl, VT, Other, CSINC.getOperand(1),
14810 CSINC.getOperand(2), CSINC.getOperand(3));
14811
14812 return SDValue();
14813}
14814
14817 const ARMSubtarget *Subtarget) {
14818 EVT VT = N->getValueType(0);
14819 SelectionDAG &DAG = DCI.DAG;
14820
14821 if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14822 return SDValue();
14823
14824 if (!Subtarget->isThumb1Only()) {
14825 // fold (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
14826 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14827 return Result;
14828
14829 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14830 return Result;
14831 }
14832
14833 if (Subtarget->hasMVEIntegerOps()) {
14834 // fold (xor(vcmp/z, 1)) into a vcmp with the opposite condition.
14835 SDValue N0 = N->getOperand(0);
14836 SDValue N1 = N->getOperand(1);
14837 const TargetLowering *TLI = Subtarget->getTargetLowering();
14838 if (TLI->isConstTrueVal(N1) &&
14839 (N0->getOpcode() == ARMISD::VCMP || N0->getOpcode() == ARMISD::VCMPZ)) {
14840 if (CanInvertMVEVCMP(N0)) {
14841 SDLoc DL(N0);
14843
14845 Ops.push_back(N0->getOperand(0));
14846 if (N0->getOpcode() == ARMISD::VCMP)
14847 Ops.push_back(N0->getOperand(1));
14848 Ops.push_back(DAG.getConstant(CC, DL, MVT::i32));
14849 return DAG.getNode(N0->getOpcode(), DL, N0->getValueType(0), Ops);
14850 }
14851 }
14852 }
14853
14854 return SDValue();
14855}
14856
14857// ParseBFI - given a BFI instruction in N, extract the "from" value (Rn) and return it,
14858// and fill in FromMask and ToMask with (consecutive) bits in "from" to be extracted and
14859// their position in "to" (Rd).
14860static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask) {
14861 assert(N->getOpcode() == ARMISD::BFI);
14862
14863 SDValue From = N->getOperand(1);
14864 ToMask = ~N->getConstantOperandAPInt(2);
14865 FromMask = APInt::getLowBitsSet(ToMask.getBitWidth(), ToMask.popcount());
14866
14867 // If the Base came from a SHR #C, we can deduce that it is really testing bit
14868 // #C in the base of the SHR.
14869 if (From->getOpcode() == ISD::SRL &&
14870 isa<ConstantSDNode>(From->getOperand(1))) {
14871 APInt Shift = From->getConstantOperandAPInt(1);
14872 assert(Shift.getLimitedValue() < 32 && "Shift too large!");
14873 FromMask <<= Shift.getLimitedValue(31);
14874 From = From->getOperand(0);
14875 }
14876
14877 return From;
14878}
14879
14880// If A and B contain one contiguous set of bits, does A | B == A . B?
14881//
14882// Neither A nor B must be zero.
14883static bool BitsProperlyConcatenate(const APInt &A, const APInt &B) {
14884 unsigned LastActiveBitInA = A.countr_zero();
14885 unsigned FirstActiveBitInB = B.getBitWidth() - B.countl_zero() - 1;
14886 return LastActiveBitInA - 1 == FirstActiveBitInB;
14887}
14888
14890 // We have a BFI in N. Find a BFI it can combine with, if one exists.
14891 APInt ToMask, FromMask;
14892 SDValue From = ParseBFI(N, ToMask, FromMask);
14893 SDValue To = N->getOperand(0);
14894
14895 SDValue V = To;
14896 if (V.getOpcode() != ARMISD::BFI)
14897 return SDValue();
14898
14899 APInt NewToMask, NewFromMask;
14900 SDValue NewFrom = ParseBFI(V.getNode(), NewToMask, NewFromMask);
14901 if (NewFrom != From)
14902 return SDValue();
14903
14904 // Do the written bits conflict with any we've seen so far?
14905 if ((NewToMask & ToMask).getBoolValue())
14906 // Conflicting bits.
14907 return SDValue();
14908
14909 // Are the new bits contiguous when combined with the old bits?
14910 if (BitsProperlyConcatenate(ToMask, NewToMask) &&
14911 BitsProperlyConcatenate(FromMask, NewFromMask))
14912 return V;
14913 if (BitsProperlyConcatenate(NewToMask, ToMask) &&
14914 BitsProperlyConcatenate(NewFromMask, FromMask))
14915 return V;
14916
14917 return SDValue();
14918}
14919
14921 SDValue N0 = N->getOperand(0);
14922 SDValue N1 = N->getOperand(1);
14923
14924 if (N1.getOpcode() == ISD::AND) {
14925 // (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
14926 // the bits being cleared by the AND are not demanded by the BFI.
14928 if (!N11C)
14929 return SDValue();
14930 unsigned InvMask = N->getConstantOperandVal(2);
14931 unsigned LSB = llvm::countr_zero(~InvMask);
14932 unsigned Width = llvm::bit_width<unsigned>(~InvMask) - LSB;
14933 assert(Width <
14934 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
14935 "undefined behavior");
14936 unsigned Mask = (1u << Width) - 1;
14937 unsigned Mask2 = N11C->getZExtValue();
14938 if ((Mask & (~Mask2)) == 0)
14939 return DAG.getNode(ARMISD::BFI, SDLoc(N), N->getValueType(0),
14940 N->getOperand(0), N1.getOperand(0), N->getOperand(2));
14941 return SDValue();
14942 }
14943
14944 // Look for another BFI to combine with.
14945 if (SDValue CombineBFI = FindBFIToCombineWith(N)) {
14946 // We've found a BFI.
14947 APInt ToMask1, FromMask1;
14948 SDValue From1 = ParseBFI(N, ToMask1, FromMask1);
14949
14950 APInt ToMask2, FromMask2;
14951 SDValue From2 = ParseBFI(CombineBFI.getNode(), ToMask2, FromMask2);
14952 assert(From1 == From2);
14953 (void)From2;
14954
14955 // Create a new BFI, combining the two together.
14956 APInt NewFromMask = FromMask1 | FromMask2;
14957 APInt NewToMask = ToMask1 | ToMask2;
14958
14959 EVT VT = N->getValueType(0);
14960 SDLoc dl(N);
14961
14962 if (NewFromMask[0] == 0)
14963 From1 = DAG.getNode(ISD::SRL, dl, VT, From1,
14964 DAG.getConstant(NewFromMask.countr_zero(), dl, VT));
14965 return DAG.getNode(ARMISD::BFI, dl, VT, CombineBFI.getOperand(0), From1,
14966 DAG.getConstant(~NewToMask, dl, VT));
14967 }
14968
14969 // Reassociate BFI(BFI (A, B, M1), C, M2) to BFI(BFI (A, C, M2), B, M1) so
14970 // that lower bit insertions are performed first, providing that M1 and M2
14971 // do no overlap. This can allow multiple BFI instructions to be combined
14972 // together by the other folds above.
14973 if (N->getOperand(0).getOpcode() == ARMISD::BFI) {
14974 APInt ToMask1 = ~N->getConstantOperandAPInt(2);
14975 APInt ToMask2 = ~N0.getConstantOperandAPInt(2);
14976
14977 if (!N0.hasOneUse() || (ToMask1 & ToMask2) != 0 ||
14978 ToMask1.countl_zero() < ToMask2.countl_zero())
14979 return SDValue();
14980
14981 EVT VT = N->getValueType(0);
14982 SDLoc dl(N);
14983 SDValue BFI1 = DAG.getNode(ARMISD::BFI, dl, VT, N0.getOperand(0),
14984 N->getOperand(1), N->getOperand(2));
14985 return DAG.getNode(ARMISD::BFI, dl, VT, BFI1, N0.getOperand(1),
14986 N0.getOperand(2));
14987 }
14988
14989 return SDValue();
14990}
14991
14992// Check that N is CMPZ(CSINC(0, 0, CC, X)),
14993// or CMPZ(CMOV(1, 0, CC, X))
14994// return X if valid.
14996 if (Cmp->getOpcode() != ARMISD::CMPZ || !isNullConstant(Cmp->getOperand(1)))
14997 return SDValue();
14998 SDValue CSInc = Cmp->getOperand(0);
14999
15000 // Ignore any `And 1` nodes that may not yet have been removed. We are
15001 // looking for a value that produces 1/0, so these have no effect on the
15002 // code.
15003 while (CSInc.getOpcode() == ISD::AND &&
15004 isa<ConstantSDNode>(CSInc.getOperand(1)) &&
15005 CSInc.getConstantOperandVal(1) == 1 && CSInc->hasOneUse())
15006 CSInc = CSInc.getOperand(0);
15007
15008 if (CSInc.getOpcode() == ARMISD::CSINC &&
15009 isNullConstant(CSInc.getOperand(0)) &&
15010 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15012 return CSInc.getOperand(3);
15013 }
15014 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(0)) &&
15015 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15017 return CSInc.getOperand(3);
15018 }
15019 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(1)) &&
15020 isNullConstant(CSInc.getOperand(0)) && CSInc->hasOneUse()) {
15023 return CSInc.getOperand(3);
15024 }
15025 return SDValue();
15026}
15027
15029 // Given CMPZ(CSINC(C, 0, 0, EQ), 0), we can just use C directly. As in
15030 // t92: flags = ARMISD::CMPZ t74, 0
15031 // t93: i32 = ARMISD::CSINC 0, 0, 1, t92
15032 // t96: flags = ARMISD::CMPZ t93, 0
15033 // t114: i32 = ARMISD::CSINV 0, 0, 0, t96
15035 if (SDValue C = IsCMPZCSINC(N, Cond))
15036 if (Cond == ARMCC::EQ)
15037 return C;
15038 return SDValue();
15039}
15040
15042 // Fold away an unnecessary CMPZ/CSINC
15043 // CSXYZ A, B, C1 (CMPZ (CSINC 0, 0, C2, D), 0) ->
15044 // if C1==EQ -> CSXYZ A, B, C2, D
15045 // if C1==NE -> CSXYZ A, B, NOT(C2), D
15047 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
15048 if (N->getConstantOperandVal(2) == ARMCC::EQ)
15049 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15050 N->getOperand(1),
15051 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
15052 if (N->getConstantOperandVal(2) == ARMCC::NE)
15053 return DAG.getNode(
15054 N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15055 N->getOperand(1),
15057 }
15058 return SDValue();
15059}
15060
15061/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
15062/// ARMISD::VMOVRRD.
15065 const ARMSubtarget *Subtarget) {
15066 // vmovrrd(vmovdrr x, y) -> x,y
15067 SDValue InDouble = N->getOperand(0);
15068 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
15069 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
15070
15071 // vmovrrd(load f64) -> (load i32), (load i32)
15072 SDNode *InNode = InDouble.getNode();
15073 if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
15074 InNode->getValueType(0) == MVT::f64 &&
15075 InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
15076 !cast<LoadSDNode>(InNode)->isVolatile()) {
15077 // TODO: Should this be done for non-FrameIndex operands?
15078 LoadSDNode *LD = cast<LoadSDNode>(InNode);
15079
15080 SelectionDAG &DAG = DCI.DAG;
15081 SDLoc DL(LD);
15082 SDValue BasePtr = LD->getBasePtr();
15083 SDValue NewLD1 =
15084 DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, LD->getPointerInfo(),
15085 LD->getAlign(), LD->getMemOperand()->getFlags());
15086
15087 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
15088 DAG.getConstant(4, DL, MVT::i32));
15089
15090 SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, LD->getChain(), OffsetPtr,
15091 LD->getPointerInfo().getWithOffset(4),
15092 commonAlignment(LD->getAlign(), 4),
15093 LD->getMemOperand()->getFlags());
15094
15095 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
15096 if (DCI.DAG.getDataLayout().isBigEndian())
15097 std::swap (NewLD1, NewLD2);
15098 SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
15099 return Result;
15100 }
15101
15102 // VMOVRRD(extract(..(build_vector(a, b, c, d)))) -> a,b or c,d
15103 // VMOVRRD(extract(insert_vector(insert_vector(.., a, l1), b, l2))) -> a,b
15104 if (InDouble.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15105 isa<ConstantSDNode>(InDouble.getOperand(1))) {
15106 SDValue BV = InDouble.getOperand(0);
15107 // Look up through any nop bitcasts and vector_reg_casts. bitcasts may
15108 // change lane order under big endian.
15109 bool BVSwap = BV.getOpcode() == ISD::BITCAST;
15110 while (
15111 (BV.getOpcode() == ISD::BITCAST ||
15112 BV.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
15113 (BV.getValueType() == MVT::v2f64 || BV.getValueType() == MVT::v2i64)) {
15114 BVSwap = BV.getOpcode() == ISD::BITCAST;
15115 BV = BV.getOperand(0);
15116 }
15117 if (BV.getValueType() != MVT::v4i32)
15118 return SDValue();
15119
15120 // Handle buildvectors, pulling out the correct lane depending on
15121 // endianness.
15122 unsigned Offset = InDouble.getConstantOperandVal(1) == 1 ? 2 : 0;
15123 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
15124 SDValue Op0 = BV.getOperand(Offset);
15125 SDValue Op1 = BV.getOperand(Offset + 1);
15126 if (!Subtarget->isLittle() && BVSwap)
15127 std::swap(Op0, Op1);
15128
15129 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15130 }
15131
15132 // A chain of insert_vectors, grabbing the correct value of the chain of
15133 // inserts.
15134 SDValue Op0, Op1;
15135 while (BV.getOpcode() == ISD::INSERT_VECTOR_ELT) {
15136 if (isa<ConstantSDNode>(BV.getOperand(2))) {
15137 if (BV.getConstantOperandVal(2) == Offset && !Op0)
15138 Op0 = BV.getOperand(1);
15139 if (BV.getConstantOperandVal(2) == Offset + 1 && !Op1)
15140 Op1 = BV.getOperand(1);
15141 }
15142 BV = BV.getOperand(0);
15143 }
15144 if (!Subtarget->isLittle() && BVSwap)
15145 std::swap(Op0, Op1);
15146 if (Op0 && Op1)
15147 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15148 }
15149
15150 return SDValue();
15151}
15152
15153/// PerformVMOVDRRCombine - Target-specific dag combine xforms for
15154/// ARMISD::VMOVDRR. This is also used for BUILD_VECTORs with 2 operands.
15156 // N=vmovrrd(X); vmovdrr(N:0, N:1) -> bit_convert(X)
15157 SDValue Op0 = N->getOperand(0);
15158 SDValue Op1 = N->getOperand(1);
15159 if (Op0.getOpcode() == ISD::BITCAST)
15160 Op0 = Op0.getOperand(0);
15161 if (Op1.getOpcode() == ISD::BITCAST)
15162 Op1 = Op1.getOperand(0);
15163 if (Op0.getOpcode() == ARMISD::VMOVRRD &&
15164 Op0.getNode() == Op1.getNode() &&
15165 Op0.getResNo() == 0 && Op1.getResNo() == 1)
15166 return DAG.getNode(ISD::BITCAST, SDLoc(N),
15167 N->getValueType(0), Op0.getOperand(0));
15168 return SDValue();
15169}
15170
15173 SDValue Op0 = N->getOperand(0);
15174
15175 // VMOVhr (VMOVrh (X)) -> X
15176 if (Op0->getOpcode() == ARMISD::VMOVrh)
15177 return Op0->getOperand(0);
15178
15179 // FullFP16: half values are passed in S-registers, and we don't
15180 // need any of the bitcast and moves:
15181 //
15182 // t2: f32,ch1,gl1? = CopyFromReg ch, Register:f32 %0, gl?
15183 // t5: i32 = bitcast t2
15184 // t18: f16 = ARMISD::VMOVhr t5
15185 // =>
15186 // tN: f16,ch2,gl2? = CopyFromReg ch, Register::f32 %0, gl?
15187 if (Op0->getOpcode() == ISD::BITCAST) {
15188 SDValue Copy = Op0->getOperand(0);
15189 if (Copy.getValueType() == MVT::f32 &&
15190 Copy->getOpcode() == ISD::CopyFromReg) {
15191 bool HasGlue = Copy->getNumOperands() == 3;
15192 SDValue Ops[] = {Copy->getOperand(0), Copy->getOperand(1),
15193 HasGlue ? Copy->getOperand(2) : SDValue()};
15194 EVT OutTys[] = {N->getValueType(0), MVT::Other, MVT::Glue};
15195 SDValue NewCopy =
15197 DCI.DAG.getVTList(ArrayRef(OutTys, HasGlue ? 3 : 2)),
15198 ArrayRef(Ops, HasGlue ? 3 : 2));
15199
15200 // Update Users, Chains, and Potential Glue.
15201 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), NewCopy.getValue(0));
15202 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(1), NewCopy.getValue(1));
15203 if (HasGlue)
15204 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(2),
15205 NewCopy.getValue(2));
15206
15207 return NewCopy;
15208 }
15209 }
15210
15211 // fold (VMOVhr (load x)) -> (load (f16*)x)
15212 if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(Op0)) {
15213 if (LN0->hasOneUse() && LN0->isUnindexed() &&
15214 LN0->getMemoryVT() == MVT::i16) {
15215 SDValue Load =
15216 DCI.DAG.getLoad(N->getValueType(0), SDLoc(N), LN0->getChain(),
15217 LN0->getBasePtr(), LN0->getMemOperand());
15218 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15219 DCI.DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Load.getValue(1));
15220 return Load;
15221 }
15222 }
15223
15224 // Only the bottom 16 bits of the source register are used.
15225 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15226 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15227 if (TLI.SimplifyDemandedBits(Op0, DemandedMask, DCI))
15228 return SDValue(N, 0);
15229
15230 return SDValue();
15231}
15232
15234 SDValue N0 = N->getOperand(0);
15235 EVT VT = N->getValueType(0);
15236
15237 // fold (VMOVrh (fpconst x)) -> const x
15239 APFloat V = C->getValueAPF();
15240 return DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
15241 }
15242
15243 // fold (VMOVrh (load x)) -> (zextload (i16*)x)
15244 if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
15245 LoadSDNode *LN0 = cast<LoadSDNode>(N0);
15246
15247 SDValue Load =
15248 DAG.getExtLoad(ISD::ZEXTLOAD, SDLoc(N), VT, LN0->getChain(),
15249 LN0->getBasePtr(), MVT::i16, LN0->getMemOperand());
15250 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15251 DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
15252 return Load;
15253 }
15254
15255 // Fold VMOVrh(extract(x, n)) -> vgetlaneu(x, n)
15256 if (N0->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15258 return DAG.getNode(ARMISD::VGETLANEu, SDLoc(N), VT, N0->getOperand(0),
15259 N0->getOperand(1));
15260
15261 return SDValue();
15262}
15263
15264/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
15265/// are normal, non-volatile loads. If so, it is profitable to bitcast an
15266/// i64 vector to have f64 elements, since the value can then be loaded
15267/// directly into a VFP register.
15269 unsigned NumElts = N->getValueType(0).getVectorNumElements();
15270 for (unsigned i = 0; i < NumElts; ++i) {
15271 SDNode *Elt = N->getOperand(i).getNode();
15272 if (ISD::isNormalLoad(Elt) && !cast<LoadSDNode>(Elt)->isVolatile())
15273 return true;
15274 }
15275 return false;
15276}
15277
15278/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for
15279/// ISD::BUILD_VECTOR.
15282 const ARMSubtarget *Subtarget) {
15283 // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X):
15284 // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value
15285 // into a pair of GPRs, which is fine when the value is used as a scalar,
15286 // but if the i64 value is converted to a vector, we need to undo the VMOVRRD.
15287 SelectionDAG &DAG = DCI.DAG;
15288 if (N->getNumOperands() == 2)
15289 if (SDValue RV = PerformVMOVDRRCombine(N, DAG))
15290 return RV;
15291
15292 // Load i64 elements as f64 values so that type legalization does not split
15293 // them up into i32 values.
15294 EVT VT = N->getValueType(0);
15295 if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N))
15296 return SDValue();
15297 SDLoc dl(N);
15299 unsigned NumElts = VT.getVectorNumElements();
15300 for (unsigned i = 0; i < NumElts; ++i) {
15301 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i));
15302 Ops.push_back(V);
15303 // Make the DAGCombiner fold the bitcast.
15304 DCI.AddToWorklist(V.getNode());
15305 }
15306 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts);
15307 SDValue BV = DAG.getBuildVector(FloatVT, dl, Ops);
15308 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
15309}
15310
15313 const ARMSubtarget *Subtarget) {
15314 // Type legalization splits a wide load into consecutive legal loads. Combine
15315 // each group used by a legal VECTOR_DEINTERLEAVE into a structured load.
15317 return SDValue();
15318
15319 unsigned NumParts = N->getNumOperands();
15320 if (NumParts < 2 || NumParts > 4)
15321 return SDValue();
15322
15323 if (NumParts == 3 && Subtarget->hasMVEIntegerOps())
15324 return SDValue();
15325
15326 EVT SubVecTy = N->getValueType(0);
15327 if (Subtarget->hasNEON() && !SubVecTy.is64BitVector() &&
15328 !SubVecTy.is128BitVector())
15329 return SDValue();
15330 if (Subtarget->hasMVEIntegerOps() && !SubVecTy.is128BitVector())
15331 return SDValue();
15332 unsigned EltBits = SubVecTy.getScalarSizeInBits();
15333 if (EltBits != 8 && EltBits != 16 && EltBits != 32)
15334 return SDValue();
15335
15337 for (const SDValue &Operand : N->op_values()) {
15338 auto *Load = dyn_cast<LoadSDNode>(Operand);
15339 if (!Load || !Operand.hasOneUse())
15340 return SDValue();
15341 Loads.push_back(Load);
15342 }
15343
15344 LoadSDNode *BaseLoad = Loads[0];
15345 if (Subtarget->hasMVEIntegerOps() && BaseLoad->getAlign() < EltBits / 8)
15346 return SDValue();
15347 unsigned Bytes = SubVecTy.getStoreSize().getFixedValue();
15348 for (auto [Idx, Load] : enumerate(Loads)) {
15349 if (!DAG.areNonVolatileConsecutiveLoads(Load, BaseLoad, Bytes, Idx))
15350 return SDValue();
15351 }
15352
15353 SDLoc DL(N);
15354 EVT MemVT =
15356 SubVecTy.getVectorElementCount() * NumParts);
15358 MachineMemOperand *MMO =
15359 MF.getMachineMemOperand(BaseLoad->getMemOperand(), 0, NumParts * Bytes);
15360
15361 SmallVector<EVT, 5> ResVTs(NumParts, SubVecTy);
15362 ResVTs.push_back(MVT::Other);
15363
15364 SmallVector<SDValue> NewLdOps;
15365 NewLdOps.push_back(BaseLoad->getChain());
15366 Intrinsic::ID IID = 0;
15367 static constexpr Intrinsic::ID NEONLoads[] = {Intrinsic::arm_neon_vld2,
15368 Intrinsic::arm_neon_vld3,
15369 Intrinsic::arm_neon_vld4};
15370 if (Subtarget->hasNEON())
15371 IID = NEONLoads[NumParts - 2];
15372 else
15373 IID = NumParts == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
15374
15375 NewLdOps.push_back(DAG.getTargetConstant(IID, DL, MVT::i64));
15376 NewLdOps.push_back(BaseLoad->getBasePtr());
15377 // We can now generate a structured load!
15378 SDValue NewLoad = DAG.getMemIntrinsicNode(
15379 ISD::INTRINSIC_W_CHAIN, DL, DAG.getVTList(ResVTs), NewLdOps, MemVT, MMO);
15380
15382 for (unsigned I = 0; I != NumParts; ++I)
15383 ResOps.push_back(NewLoad.getValue(I));
15384
15385 // Preserve the memory ordering of each original load with the new load.
15386 for (LoadSDNode *Load : Loads)
15388 NewLoad.getValue(NumParts));
15389 return DCI.CombineTo(N, ResOps, false);
15390}
15391
15392// Combine a deinterleave of adjacent subvectors from one load into a
15393// structured NEON load.
15394static SDValue
15397 const ARMSubtarget *Subtarget) {
15398 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
15399 return SDValue();
15400
15402 Subtarget))
15403 return Res;
15404
15405 if (!DCI.isBeforeLegalize())
15406 return SDValue();
15407
15408 SelectionDAG &DAG = DCI.DAG;
15409 unsigned NumParts = N->getNumOperands();
15410 if (NumParts != 2 && NumParts != 3 && NumParts != 4)
15411 return SDValue();
15412
15413 if (NumParts == 3 && Subtarget->hasMVEIntegerOps())
15414 return SDValue();
15415
15416 EVT SubVecTy = N->getValueType(0);
15417
15418 if (Subtarget->hasNEON() && !SubVecTy.is64BitVector() &&
15419 !SubVecTy.is128BitVector())
15420 return SDValue();
15421 if (Subtarget->hasMVEIntegerOps() && !SubVecTy.is128BitVector())
15422 return SDValue();
15423 unsigned EltBits = SubVecTy.getScalarSizeInBits();
15424 if (EltBits != 8 && EltBits != 16 && EltBits != 32)
15425 return SDValue();
15426
15427 // Make sure each input operand is the correct extract_subvector of the same
15428 // wider vector.
15429 unsigned MinNumElements = SubVecTy.getVectorMinNumElements();
15430 SDValue Op0 = N->getOperand(0);
15431 for (unsigned I = 0; I < NumParts; I++) {
15432 SDValue OpI = N->getOperand(I);
15433 if (!OpI.hasOneUse() || OpI.getOpcode() != ISD::EXTRACT_SUBVECTOR ||
15434 OpI.getOperand(0) != Op0.getOperand(0))
15435 return SDValue();
15436 if (OpI.getConstantOperandVal(1) != (I * MinNumElements))
15437 return SDValue();
15438 }
15439
15440 SDValue WideVec = Op0.getOperand(0);
15441 SDLoc DL(N);
15442
15443 SmallVector<EVT, 5> ResVTs(NumParts, SubVecTy);
15444 ResVTs.push_back(MVT::Other);
15445 SDVTList ResVTList = DAG.getVTList(ResVTs);
15446 auto *Load = dyn_cast<LoadSDNode>(WideVec);
15447 if (!Load || !Load->hasNUsesOfValue(NumParts, 0) || !Load->isSimple() ||
15448 !ISD::isNormalLoad(Load) || !Load->getOffset().isUndef())
15449 return SDValue();
15450 if (Subtarget->hasMVEIntegerOps() && Load->getAlign() < EltBits / 8)
15451 return SDValue();
15452
15453 static constexpr Intrinsic::ID NEONLoads[] = {Intrinsic::arm_neon_vld2,
15454 Intrinsic::arm_neon_vld3,
15455 Intrinsic::arm_neon_vld4};
15456 SmallVector<SDValue> NewLdOps;
15457 Intrinsic::ID IID = 0;
15458 NewLdOps.push_back(Load->getChain());
15459 if (Subtarget->hasNEON())
15460 IID = NEONLoads[NumParts - 2];
15461 else
15462 IID = NumParts == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
15463 NewLdOps.push_back(DAG.getTargetConstant(IID, DL, MVT::i64));
15464
15465 NewLdOps.push_back(Load->getBasePtr());
15466
15467 // We can now generate a structured load!
15468 SDValue Res =
15469 DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, DL, ResVTList, NewLdOps,
15470 Load->getMemoryVT(), Load->getMemOperand());
15471
15472 SmallVector<SDValue, 4> ResOps(NumParts);
15473 for (unsigned Idx = 0; Idx < NumParts; Idx++)
15474 ResOps[Idx] = Res.getValue(Idx);
15475
15476 // Preserve the original load's memory ordering with the new load.
15477 DAG.makeEquivalentMemoryOrdering(WideVec.getValue(1), Res.getValue(NumParts));
15478 return DCI.CombineTo(N, ResOps, false);
15479}
15480
15481/// Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
15482static SDValue
15484 SelectionDAG &DAG = DCI.DAG;
15485 EVT VT = N->getValueType(0);
15486
15487 // Fold buildvector(extractelt(bitcast(build_vector(a,b,_,_))),
15488 // extractelt(bitcast(build_vector(_,_,c,d))))
15489 // -> bitcast(build_vector(a,b,c,d))
15490 if (VT.getScalarSizeInBits() == 64 && N->getNumOperands() == 2) {
15491 auto IsExtractFromBuildVec = [](SDValue V, SDValue &BV, int64_t &Lane) {
15492 if (!sd_match(V, m_ExtractElt(m_Value(BV), m_ConstInt(Lane))))
15493 return false;
15494 while (BV.getOpcode() == ISD::BITCAST)
15495 BV = BV.getOperand(0);
15496 return BV.getOpcode() == ARMISD::BUILD_VECTOR &&
15497 BV.getNumOperands() == 4 &&
15498 BV.getValueType().getScalarSizeInBits() == 32;
15499 };
15500 SDValue BV1, BV2;
15501 int64_t Lane1, Lane2;
15502 if (IsExtractFromBuildVec(N->getOperand(0), BV1, Lane1) &&
15503 IsExtractFromBuildVec(N->getOperand(1), BV2, Lane2))
15504 return DAG.getBitcast(
15505 VT, DAG.getNode(
15506 ARMISD::BUILD_VECTOR, N, MVT::v4f32,
15507 DAG.getBitcast(MVT::f32, BV1->getOperand(Lane1 * 2 + 0)),
15508 DAG.getBitcast(MVT::f32, BV1->getOperand(Lane1 * 2 + 1)),
15509 DAG.getBitcast(MVT::f32, BV2->getOperand(Lane2 * 2 + 0)),
15510 DAG.getBitcast(MVT::f32, BV2->getOperand(Lane2 * 2 + 1))));
15511 }
15512
15513 // ARMISD::BUILD_VECTOR is introduced when legalizing ISD::BUILD_VECTOR.
15514 // At that time, we may have inserted bitcasts from integer to float.
15515 // If these bitcasts have survived DAGCombine, change the lowering of this
15516 // BUILD_VECTOR in something more vector friendly, i.e., that does not
15517 // force to use floating point types.
15518
15519 // Make sure we can change the type of the vector.
15520 // This is possible iff:
15521 // 1. The vector is only used in a bitcast to a integer type. I.e.,
15522 // 1.1. Vector is used only once.
15523 // 1.2. Use is a bit convert to an integer type.
15524 // 2. The size of its operands are 32-bits (64-bits are not legal).
15525 EVT EltVT = VT.getVectorElementType();
15526
15527 // Check 1.1. and 2.
15528 if (EltVT.getSizeInBits() != 32 || !N->hasOneUse())
15529 return SDValue();
15530
15531 // By construction, the input type must be float.
15532 assert(EltVT == MVT::f32 && "Unexpected type!");
15533
15534 // Check 1.2.
15535 SDNode *Use = *N->user_begin();
15536 if (Use->getOpcode() != ISD::BITCAST ||
15537 Use->getValueType(0).isFloatingPoint())
15538 return SDValue();
15539
15540 // Check profitability.
15541 // Model is, if more than half of the relevant operands are bitcast from
15542 // i32, turn the build_vector into a sequence of insert_vector_elt.
15543 // Relevant operands are everything that is not statically
15544 // (i.e., at compile time) bitcasted.
15545 unsigned NumOfBitCastedElts = 0;
15546 unsigned NumElts = VT.getVectorNumElements();
15547 unsigned NumOfRelevantElts = NumElts;
15548 for (unsigned Idx = 0; Idx < NumElts; ++Idx) {
15549 SDValue Elt = N->getOperand(Idx);
15550 if (Elt->getOpcode() == ISD::BITCAST) {
15551 // Assume only bit cast to i32 will go away.
15552 if (Elt->getOperand(0).getValueType() == MVT::i32)
15553 ++NumOfBitCastedElts;
15554 } else if (Elt.isUndef() || isa<ConstantSDNode>(Elt))
15555 // Constants are statically casted, thus do not count them as
15556 // relevant operands.
15557 --NumOfRelevantElts;
15558 }
15559
15560 // Check if more than half of the elements require a non-free bitcast.
15561 if (NumOfBitCastedElts <= NumOfRelevantElts / 2)
15562 return SDValue();
15563
15564 // Create the new vector type.
15565 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
15566 // Check if the type is legal.
15567 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15568 if (!TLI.isTypeLegal(VecVT))
15569 return SDValue();
15570
15571 // Combine:
15572 // ARMISD::BUILD_VECTOR E1, E2, ..., EN.
15573 // => BITCAST INSERT_VECTOR_ELT
15574 // (INSERT_VECTOR_ELT (...), (BITCAST EN-1), N-1),
15575 // (BITCAST EN), N.
15576 SDValue Vec = DAG.getUNDEF(VecVT);
15577 SDLoc dl(N);
15578 for (unsigned Idx = 0 ; Idx < NumElts; ++Idx) {
15579 SDValue V = N->getOperand(Idx);
15580 if (V.isUndef())
15581 continue;
15582 if (V.getOpcode() == ISD::BITCAST &&
15583 V->getOperand(0).getValueType() == MVT::i32)
15584 // Fold obvious case.
15585 V = V.getOperand(0);
15586 else {
15587 V = DAG.getNode(ISD::BITCAST, SDLoc(V), MVT::i32, V);
15588 // Make the DAGCombiner fold the bitcasts.
15589 DCI.AddToWorklist(V.getNode());
15590 }
15591 SDValue LaneIdx = DAG.getConstant(Idx, dl, MVT::i32);
15592 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Vec, V, LaneIdx);
15593 }
15594 Vec = DAG.getNode(ISD::BITCAST, dl, VT, Vec);
15595 // Make the DAGCombiner fold the bitcasts.
15596 DCI.AddToWorklist(Vec.getNode());
15597 return Vec;
15598}
15599
15600static SDValue
15602 EVT VT = N->getValueType(0);
15603 SDValue Op = N->getOperand(0);
15604 SDLoc dl(N);
15605
15606 // PREDICATE_CAST(PREDICATE_CAST(x)) == PREDICATE_CAST(x)
15607 if (Op->getOpcode() == ARMISD::PREDICATE_CAST) {
15608 // If the valuetypes are the same, we can remove the cast entirely.
15609 if (Op->getOperand(0).getValueType() == VT)
15610 return Op->getOperand(0);
15611 return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15612 }
15613
15614 // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
15615 // more VPNOT which might get folded as else predicates.
15616 if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
15617 SDValue X =
15618 DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15619 SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
15620 DCI.DAG.getConstant(65535, dl, MVT::i32));
15621 return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
15622 }
15623
15624 // Only the bottom 16 bits of the source register are used.
15625 if (Op.getValueType() == MVT::i32) {
15626 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15627 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15628 if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
15629 return SDValue(N, 0);
15630 }
15631 return SDValue();
15632}
15633
15635 const ARMSubtarget *ST) {
15636 EVT VT = N->getValueType(0);
15637 SDValue Op = N->getOperand(0);
15638 SDLoc dl(N);
15639
15640 // Under Little endian, a VECTOR_REG_CAST is equivalent to a BITCAST
15641 if (ST->isLittle())
15642 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
15643
15644 // VT VECTOR_REG_CAST (VT Op) -> Op
15645 if (Op.getValueType() == VT)
15646 return Op;
15647 // VECTOR_REG_CAST undef -> undef
15648 if (Op.isUndef())
15649 return DAG.getUNDEF(VT);
15650
15651 // VECTOR_REG_CAST(VECTOR_REG_CAST(x)) == VECTOR_REG_CAST(x)
15652 if (Op->getOpcode() == ARMISD::VECTOR_REG_CAST) {
15653 // If the valuetypes are the same, we can remove the cast entirely.
15654 if (Op->getOperand(0).getValueType() == VT)
15655 return Op->getOperand(0);
15656 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Op->getOperand(0));
15657 }
15658
15659 return SDValue();
15660}
15661
15663 const ARMSubtarget *Subtarget) {
15664 if (!Subtarget->hasMVEIntegerOps())
15665 return SDValue();
15666
15667 EVT VT = N->getValueType(0);
15668 SDValue Op0 = N->getOperand(0);
15669 SDValue Op1 = N->getOperand(1);
15670 ARMCC::CondCodes Cond = (ARMCC::CondCodes)N->getConstantOperandVal(2);
15671 SDLoc dl(N);
15672
15673 // vcmp X, 0, cc -> vcmpz X, cc
15674 if (isZeroVector(Op1))
15675 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op0, N->getOperand(2));
15676
15677 unsigned SwappedCond = getSwappedCondition(Cond);
15678 if (isValidMVECond(SwappedCond, VT.isFloatingPoint())) {
15679 // vcmp 0, X, cc -> vcmpz X, reversed(cc)
15680 if (isZeroVector(Op0))
15681 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op1,
15682 DAG.getConstant(SwappedCond, dl, MVT::i32));
15683 // vcmp vdup(Y), X, cc -> vcmp X, vdup(Y), reversed(cc)
15684 if (Op0->getOpcode() == ARMISD::VDUP && Op1->getOpcode() != ARMISD::VDUP)
15685 return DAG.getNode(ARMISD::VCMP, dl, VT, Op1, Op0,
15686 DAG.getConstant(SwappedCond, dl, MVT::i32));
15687 }
15688
15689 return SDValue();
15690}
15691
15692/// PerformInsertEltCombine - Target-specific dag combine xforms for
15693/// ISD::INSERT_VECTOR_ELT.
15696 // Bitcast an i64 load inserted into a vector to f64.
15697 // Otherwise, the i64 value will be legalized to a pair of i32 values.
15698 EVT VT = N->getValueType(0);
15699 SDNode *Elt = N->getOperand(1).getNode();
15700 if (VT.getVectorElementType() != MVT::i64 ||
15701 !ISD::isNormalLoad(Elt) || cast<LoadSDNode>(Elt)->isVolatile())
15702 return SDValue();
15703
15704 SelectionDAG &DAG = DCI.DAG;
15705 SDLoc dl(N);
15706 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
15708 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0));
15709 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1));
15710 // Make the DAGCombiner fold the bitcasts.
15711 DCI.AddToWorklist(Vec.getNode());
15712 DCI.AddToWorklist(V.getNode());
15713 SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT,
15714 Vec, V, N->getOperand(2));
15715 return DAG.getNode(ISD::BITCAST, dl, VT, InsElt);
15716}
15717
15718// Convert a pair of extracts from the same base vector to a VMOVRRD. Either
15719// directly or bitcast to an integer if the original is a float vector.
15720// extract(x, n); extract(x, n+1) -> VMOVRRD(extract v2f64 x, n/2)
15721// bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD(extract x, n/2)
15722static SDValue
15724 EVT VT = N->getValueType(0);
15725 SDLoc dl(N);
15726
15727 if (!DCI.isAfterLegalizeDAG() || VT != MVT::i32 ||
15728 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(MVT::f64))
15729 return SDValue();
15730
15731 SDValue Ext = SDValue(N, 0);
15732 if (Ext.getOpcode() == ISD::BITCAST &&
15733 Ext.getOperand(0).getValueType() == MVT::f32)
15734 Ext = Ext.getOperand(0);
15735 if (Ext.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
15737 Ext.getConstantOperandVal(1) % 2 != 0)
15738 return SDValue();
15739 if (Ext->hasOneUse() && (Ext->user_begin()->getOpcode() == ISD::SINT_TO_FP ||
15740 Ext->user_begin()->getOpcode() == ISD::UINT_TO_FP))
15741 return SDValue();
15742
15743 SDValue Op0 = Ext.getOperand(0);
15744 EVT VecVT = Op0.getValueType();
15745 unsigned ResNo = Op0.getResNo();
15746 unsigned Lane = Ext.getConstantOperandVal(1);
15747 if (VecVT.getVectorNumElements() != 4)
15748 return SDValue();
15749
15750 // Find another extract, of Lane + 1
15751 auto OtherIt = find_if(Op0->users(), [&](SDNode *V) {
15752 return V->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15753 isa<ConstantSDNode>(V->getOperand(1)) &&
15754 V->getConstantOperandVal(1) == Lane + 1 &&
15755 V->getOperand(0).getResNo() == ResNo;
15756 });
15757 if (OtherIt == Op0->users().end())
15758 return SDValue();
15759
15760 // For float extracts, we need to be converting to a i32 for both vector
15761 // lanes.
15762 SDValue OtherExt(*OtherIt, 0);
15763 if (OtherExt.getValueType() != MVT::i32) {
15764 if (!OtherExt->hasOneUse() ||
15765 OtherExt->user_begin()->getOpcode() != ISD::BITCAST ||
15766 OtherExt->user_begin()->getValueType(0) != MVT::i32)
15767 return SDValue();
15768 OtherExt = SDValue(*OtherExt->user_begin(), 0);
15769 }
15770
15771 // Convert the type to a f64 and extract with a VMOVRRD.
15772 SDValue F64 = DCI.DAG.getNode(
15773 ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
15774 DCI.DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v2f64, Op0),
15775 DCI.DAG.getConstant(Ext.getConstantOperandVal(1) / 2, dl, MVT::i32));
15776 SDValue VMOVRRD =
15777 DCI.DAG.getNode(ARMISD::VMOVRRD, dl, {MVT::i32, MVT::i32}, F64);
15778
15779 DCI.CombineTo(OtherExt.getNode(), SDValue(VMOVRRD.getNode(), 1));
15780 return VMOVRRD;
15781}
15782
15785 const ARMSubtarget *ST) {
15786 SDValue Op0 = N->getOperand(0);
15787 EVT VT = N->getValueType(0);
15788 SDLoc dl(N);
15789
15790 // extract (vdup x) -> x
15791 if (Op0->getOpcode() == ARMISD::VDUP) {
15792 SDValue X = Op0->getOperand(0);
15793 if (VT == MVT::f16 && X.getValueType() == MVT::i32)
15794 return DCI.DAG.getNode(ARMISD::VMOVhr, dl, VT, X);
15795 if (VT == MVT::i32 && X.getValueType() == MVT::f16)
15796 return DCI.DAG.getNode(ARMISD::VMOVrh, dl, VT, X);
15797 if (VT == MVT::f32 && X.getValueType() == MVT::i32)
15798 return DCI.DAG.getNode(ISD::BITCAST, dl, VT, X);
15799
15800 while (X.getValueType() != VT && X->getOpcode() == ISD::BITCAST)
15801 X = X->getOperand(0);
15802 if (X.getValueType() == VT)
15803 return X;
15804 }
15805
15806 // extract ARM_BUILD_VECTOR -> x
15807 if (Op0->getOpcode() == ARMISD::BUILD_VECTOR &&
15808 isa<ConstantSDNode>(N->getOperand(1)) &&
15809 N->getConstantOperandVal(1) < Op0.getNumOperands()) {
15810 return Op0.getOperand(N->getConstantOperandVal(1));
15811 }
15812
15813 // extract(bitcast(BUILD_VECTOR(VMOVDRR(a, b), ..))) -> a or b
15814 if (Op0.getValueType() == MVT::v4i32 &&
15815 isa<ConstantSDNode>(N->getOperand(1)) &&
15816 Op0.getOpcode() == ISD::BITCAST &&
15818 Op0.getOperand(0).getValueType() == MVT::v2f64) {
15819 SDValue BV = Op0.getOperand(0);
15820 unsigned Offset = N->getConstantOperandVal(1);
15821 SDValue MOV = BV.getOperand(Offset < 2 ? 0 : 1);
15822 if (MOV.getOpcode() == ARMISD::VMOVDRR)
15823 return MOV.getOperand(ST->isLittle() ? Offset % 2 : 1 - Offset % 2);
15824 }
15825
15826 // extract x, n; extract x, n+1 -> VMOVRRD x
15827 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
15828 return R;
15829
15830 // extract (MVETrunc(x)) -> extract x
15831 if (Op0->getOpcode() == ARMISD::MVETRUNC) {
15832 unsigned Idx = N->getConstantOperandVal(1);
15833 unsigned Vec =
15835 unsigned SubIdx =
15837 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Op0.getOperand(Vec),
15838 DCI.DAG.getConstant(SubIdx, dl, MVT::i32));
15839 }
15840
15841 // extract(bitcast(BUILD_VECTOR(extract(bitcast(a)), ..))) -> extract(a)
15842 if (ST->isLittle() && Op0.getOpcode() == ISD::BITCAST &&
15844 isa<ConstantSDNode>(N->getOperand(1)) &&
15847 unsigned Lane = N->getConstantOperandVal(1);
15848 EVT ExtVT = Op0.getValueType();
15849 EVT BVVT = Op0.getOperand(0).getValueType();
15850 unsigned BVLane =
15851 (Lane * BVVT.getVectorNumElements()) / ExtVT.getVectorNumElements();
15852 assert(BVLane < Op0.getOperand(0).getNumOperands());
15853 SDValue Ext = Op0.getOperand(0).getOperand(BVLane);
15854 if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15855 Ext.getOperand(0).getOpcode() == ISD::BITCAST &&
15857 Ext.getOperand(0).getOperand(0).getValueType() == ExtVT) {
15858 unsigned InnerLane = Ext.getConstantOperandVal(1);
15859 unsigned BVSubLane = Lane - (BVLane * ExtVT.getVectorNumElements()) /
15860 BVVT.getVectorNumElements();
15861 unsigned FinalLane = (InnerLane * ExtVT.getVectorNumElements()) /
15862 BVVT.getVectorNumElements() +
15863 BVSubLane;
15864 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT,
15865 Ext.getOperand(0).getOperand(0),
15866 DCI.DAG.getConstant(FinalLane, dl, MVT::i32));
15867 }
15868 }
15869
15870 return SDValue();
15871}
15872
15874 SDValue Op = N->getOperand(0);
15875 EVT VT = N->getValueType(0);
15876
15877 // sext_inreg(VGETLANEu) -> VGETLANEs
15878 if (Op.getOpcode() == ARMISD::VGETLANEu &&
15879 cast<VTSDNode>(N->getOperand(1))->getVT() ==
15880 Op.getOperand(0).getValueType().getScalarType())
15881 return DAG.getNode(ARMISD::VGETLANEs, SDLoc(N), VT, Op.getOperand(0),
15882 Op.getOperand(1));
15883
15884 return SDValue();
15885}
15886
15887static SDValue
15889 SDValue Vec = N->getOperand(0);
15890 SDValue SubVec = N->getOperand(1);
15891 uint64_t IdxVal = N->getConstantOperandVal(2);
15892 EVT VecVT = Vec.getValueType();
15893 EVT SubVT = SubVec.getValueType();
15894
15895 // Only do this for legal fixed vector types.
15896 if (!VecVT.isFixedLengthVector() ||
15897 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(VecVT) ||
15899 return SDValue();
15900
15901 // Ignore widening patterns.
15902 if (IdxVal == 0 && Vec.isUndef())
15903 return SDValue();
15904
15905 // Subvector must be half the width and an "aligned" insertion.
15906 unsigned NumSubElts = SubVT.getVectorNumElements();
15907 if ((SubVT.getSizeInBits() * 2) != VecVT.getSizeInBits() ||
15908 (IdxVal != 0 && IdxVal != NumSubElts))
15909 return SDValue();
15910
15911 // Fold insert_subvector -> concat_vectors
15912 // insert_subvector(Vec,Sub,lo) -> concat_vectors(Sub,extract(Vec,hi))
15913 // insert_subvector(Vec,Sub,hi) -> concat_vectors(extract(Vec,lo),Sub)
15914 SDLoc DL(N);
15915 SDValue Lo, Hi;
15916 if (IdxVal == 0) {
15917 Lo = SubVec;
15918 Hi = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15919 DCI.DAG.getVectorIdxConstant(NumSubElts, DL));
15920 } else {
15921 Lo = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15922 DCI.DAG.getVectorIdxConstant(0, DL));
15923 Hi = SubVec;
15924 }
15925 return DCI.DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Lo, Hi);
15926}
15927
15928// shuffle(MVETrunc(x, y)) -> VMOVN(x, y)
15930 SelectionDAG &DAG) {
15931 SDValue Trunc = N->getOperand(0);
15932 EVT VT = Trunc.getValueType();
15933 if (Trunc.getOpcode() != ARMISD::MVETRUNC || !N->getOperand(1).isUndef())
15934 return SDValue();
15935
15936 SDLoc DL(Trunc);
15937 if (isVMOVNTruncMask(N->getMask(), VT, false))
15938 return DAG.getNode(
15939 ARMISD::VMOVN, DL, VT,
15940 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15941 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15942 DAG.getConstant(1, DL, MVT::i32));
15943 else if (isVMOVNTruncMask(N->getMask(), VT, true))
15944 return DAG.getNode(
15945 ARMISD::VMOVN, DL, VT,
15946 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15947 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15948 DAG.getConstant(1, DL, MVT::i32));
15949 return SDValue();
15950}
15951
15952/// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for
15953/// ISD::VECTOR_SHUFFLE.
15956 return R;
15957
15958 // The LLVM shufflevector instruction does not require the shuffle mask
15959 // length to match the operand vector length, but ISD::VECTOR_SHUFFLE does
15960 // have that requirement. When translating to ISD::VECTOR_SHUFFLE, if the
15961 // operands do not match the mask length, they are extended by concatenating
15962 // them with undef vectors. That is probably the right thing for other
15963 // targets, but for NEON it is better to concatenate two double-register
15964 // size vector operands into a single quad-register size vector. Do that
15965 // transformation here:
15966 // shuffle(concat(v1, undef), concat(v2, undef)) ->
15967 // shuffle(concat(v1, v2), undef)
15968 SDValue Op0 = N->getOperand(0);
15969 SDValue Op1 = N->getOperand(1);
15970 if (Op0.getOpcode() != ISD::CONCAT_VECTORS ||
15971 Op1.getOpcode() != ISD::CONCAT_VECTORS ||
15972 Op0.getNumOperands() != 2 ||
15973 Op1.getNumOperands() != 2)
15974 return SDValue();
15975 SDValue Concat0Op1 = Op0.getOperand(1);
15976 SDValue Concat1Op1 = Op1.getOperand(1);
15977 if (!Concat0Op1.isUndef() || !Concat1Op1.isUndef())
15978 return SDValue();
15979 // Skip the transformation if any of the types are illegal.
15980 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15981 EVT VT = N->getValueType(0);
15982 if (!TLI.isTypeLegal(VT) ||
15983 !TLI.isTypeLegal(Concat0Op1.getValueType()) ||
15984 !TLI.isTypeLegal(Concat1Op1.getValueType()))
15985 return SDValue();
15986
15987 SDValue NewConcat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT,
15988 Op0.getOperand(0), Op1.getOperand(0));
15989 // Translate the shuffle mask.
15990 SmallVector<int, 16> NewMask;
15991 unsigned NumElts = VT.getVectorNumElements();
15992 unsigned HalfElts = NumElts/2;
15994 for (unsigned n = 0; n < NumElts; ++n) {
15995 int MaskElt = SVN->getMaskElt(n);
15996 int NewElt = -1;
15997 if (MaskElt < (int)HalfElts)
15998 NewElt = MaskElt;
15999 else if (MaskElt >= (int)NumElts && MaskElt < (int)(NumElts + HalfElts))
16000 NewElt = HalfElts + MaskElt - NumElts;
16001 NewMask.push_back(NewElt);
16002 }
16003 return DAG.getVectorShuffle(VT, SDLoc(N), NewConcat,
16004 DAG.getUNDEF(VT), NewMask);
16005}
16006
16007/// Load/store instruction that can be merged with a base address
16008/// update
16013 unsigned AddrOpIdx;
16014};
16015
16017 /// Instruction that updates a pointer
16019 /// Pointer increment operand
16021 /// Pointer increment value if it is a constant, or 0 otherwise
16022 unsigned ConstInc;
16023};
16024
16026 // Check that the add is independent of the load/store.
16027 // Otherwise, folding it would create a cycle. Search through Addr
16028 // as well, since the User may not be a direct user of Addr and
16029 // only share a base pointer.
16032 Worklist.push_back(N);
16033 Worklist.push_back(User);
16034 const unsigned MaxSteps = 1024;
16035 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16036 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16037 return false;
16038 return true;
16039}
16040
16042 struct BaseUpdateUser &User,
16043 bool SimpleConstIncOnly,
16045 SelectionDAG &DAG = DCI.DAG;
16046 SDNode *N = Target.N;
16047 MemSDNode *MemN = cast<MemSDNode>(N);
16048 SDLoc dl(N);
16049
16050 // Find the new opcode for the updating load/store.
16051 bool isLoadOp = true;
16052 bool isLaneOp = false;
16053 // Workaround for vst1x and vld1x intrinsics which do not have alignment
16054 // as an operand.
16055 bool hasAlignment = true;
16056 unsigned NewOpc = 0;
16057 unsigned NumVecs = 0;
16058 if (Target.isIntrinsic) {
16059 unsigned IntNo = N->getConstantOperandVal(1);
16060 switch (IntNo) {
16061 default:
16062 llvm_unreachable("unexpected intrinsic for Neon base update");
16063 case Intrinsic::arm_neon_vld1:
16064 NewOpc = ARMISD::VLD1_UPD;
16065 NumVecs = 1;
16066 break;
16067 case Intrinsic::arm_neon_vld2:
16068 NewOpc = ARMISD::VLD2_UPD;
16069 NumVecs = 2;
16070 break;
16071 case Intrinsic::arm_neon_vld3:
16072 NewOpc = ARMISD::VLD3_UPD;
16073 NumVecs = 3;
16074 break;
16075 case Intrinsic::arm_neon_vld4:
16076 NewOpc = ARMISD::VLD4_UPD;
16077 NumVecs = 4;
16078 break;
16079 case Intrinsic::arm_neon_vld1x2:
16080 NewOpc = ARMISD::VLD1x2_UPD;
16081 NumVecs = 2;
16082 hasAlignment = false;
16083 break;
16084 case Intrinsic::arm_neon_vld1x3:
16085 NewOpc = ARMISD::VLD1x3_UPD;
16086 NumVecs = 3;
16087 hasAlignment = false;
16088 break;
16089 case Intrinsic::arm_neon_vld1x4:
16090 NewOpc = ARMISD::VLD1x4_UPD;
16091 NumVecs = 4;
16092 hasAlignment = false;
16093 break;
16094 case Intrinsic::arm_neon_vld2dup:
16095 NewOpc = ARMISD::VLD2DUP_UPD;
16096 NumVecs = 2;
16097 break;
16098 case Intrinsic::arm_neon_vld3dup:
16099 NewOpc = ARMISD::VLD3DUP_UPD;
16100 NumVecs = 3;
16101 break;
16102 case Intrinsic::arm_neon_vld4dup:
16103 NewOpc = ARMISD::VLD4DUP_UPD;
16104 NumVecs = 4;
16105 break;
16106 case Intrinsic::arm_neon_vld2lane:
16107 NewOpc = ARMISD::VLD2LN_UPD;
16108 NumVecs = 2;
16109 isLaneOp = true;
16110 break;
16111 case Intrinsic::arm_neon_vld3lane:
16112 NewOpc = ARMISD::VLD3LN_UPD;
16113 NumVecs = 3;
16114 isLaneOp = true;
16115 break;
16116 case Intrinsic::arm_neon_vld4lane:
16117 NewOpc = ARMISD::VLD4LN_UPD;
16118 NumVecs = 4;
16119 isLaneOp = true;
16120 break;
16121 case Intrinsic::arm_neon_vst1:
16122 NewOpc = ARMISD::VST1_UPD;
16123 NumVecs = 1;
16124 isLoadOp = false;
16125 break;
16126 case Intrinsic::arm_neon_vst2:
16127 NewOpc = ARMISD::VST2_UPD;
16128 NumVecs = 2;
16129 isLoadOp = false;
16130 break;
16131 case Intrinsic::arm_neon_vst3:
16132 NewOpc = ARMISD::VST3_UPD;
16133 NumVecs = 3;
16134 isLoadOp = false;
16135 break;
16136 case Intrinsic::arm_neon_vst4:
16137 NewOpc = ARMISD::VST4_UPD;
16138 NumVecs = 4;
16139 isLoadOp = false;
16140 break;
16141 case Intrinsic::arm_neon_vst2lane:
16142 NewOpc = ARMISD::VST2LN_UPD;
16143 NumVecs = 2;
16144 isLoadOp = false;
16145 isLaneOp = true;
16146 break;
16147 case Intrinsic::arm_neon_vst3lane:
16148 NewOpc = ARMISD::VST3LN_UPD;
16149 NumVecs = 3;
16150 isLoadOp = false;
16151 isLaneOp = true;
16152 break;
16153 case Intrinsic::arm_neon_vst4lane:
16154 NewOpc = ARMISD::VST4LN_UPD;
16155 NumVecs = 4;
16156 isLoadOp = false;
16157 isLaneOp = true;
16158 break;
16159 case Intrinsic::arm_neon_vst1x2:
16160 NewOpc = ARMISD::VST1x2_UPD;
16161 NumVecs = 2;
16162 isLoadOp = false;
16163 hasAlignment = false;
16164 break;
16165 case Intrinsic::arm_neon_vst1x3:
16166 NewOpc = ARMISD::VST1x3_UPD;
16167 NumVecs = 3;
16168 isLoadOp = false;
16169 hasAlignment = false;
16170 break;
16171 case Intrinsic::arm_neon_vst1x4:
16172 NewOpc = ARMISD::VST1x4_UPD;
16173 NumVecs = 4;
16174 isLoadOp = false;
16175 hasAlignment = false;
16176 break;
16177 }
16178 } else {
16179 isLaneOp = true;
16180 switch (N->getOpcode()) {
16181 default:
16182 llvm_unreachable("unexpected opcode for Neon base update");
16183 case ARMISD::VLD1DUP:
16184 NewOpc = ARMISD::VLD1DUP_UPD;
16185 NumVecs = 1;
16186 break;
16187 case ARMISD::VLD2DUP:
16188 NewOpc = ARMISD::VLD2DUP_UPD;
16189 NumVecs = 2;
16190 break;
16191 case ARMISD::VLD3DUP:
16192 NewOpc = ARMISD::VLD3DUP_UPD;
16193 NumVecs = 3;
16194 break;
16195 case ARMISD::VLD4DUP:
16196 NewOpc = ARMISD::VLD4DUP_UPD;
16197 NumVecs = 4;
16198 break;
16199 case ISD::LOAD:
16200 NewOpc = ARMISD::VLD1_UPD;
16201 NumVecs = 1;
16202 isLaneOp = false;
16203 break;
16204 case ISD::STORE:
16205 NewOpc = ARMISD::VST1_UPD;
16206 NumVecs = 1;
16207 isLaneOp = false;
16208 isLoadOp = false;
16209 break;
16210 }
16211 }
16212
16213 // Find the size of memory referenced by the load/store.
16214 EVT VecTy;
16215 if (isLoadOp) {
16216 VecTy = N->getValueType(0);
16217 } else if (Target.isIntrinsic) {
16218 VecTy = N->getOperand(Target.AddrOpIdx + 1).getValueType();
16219 } else {
16220 assert(Target.isStore &&
16221 "Node has to be a load, a store, or an intrinsic!");
16222 VecTy = N->getOperand(1).getValueType();
16223 }
16224
16225 bool isVLDDUPOp =
16226 NewOpc == ARMISD::VLD1DUP_UPD || NewOpc == ARMISD::VLD2DUP_UPD ||
16227 NewOpc == ARMISD::VLD3DUP_UPD || NewOpc == ARMISD::VLD4DUP_UPD;
16228
16229 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16230 if (isLaneOp || isVLDDUPOp)
16231 NumBytes /= VecTy.getVectorNumElements();
16232
16233 if (NumBytes >= 3 * 16 && User.ConstInc != NumBytes) {
16234 // VLD3/4 and VST3/4 for 128-bit vectors are implemented with two
16235 // separate instructions that make it harder to use a non-constant update.
16236 return false;
16237 }
16238
16239 if (SimpleConstIncOnly && User.ConstInc != NumBytes)
16240 return false;
16241
16242 if (!isValidBaseUpdate(N, User.N))
16243 return false;
16244
16245 // OK, we found an ADD we can fold into the base update.
16246 // Now, create a _UPD node, taking care of not breaking alignment.
16247
16248 EVT AlignedVecTy = VecTy;
16249 Align Alignment = MemN->getAlign();
16250
16251 // If this is a less-than-standard-aligned load/store, change the type to
16252 // match the standard alignment.
16253 // The alignment is overlooked when selecting _UPD variants; and it's
16254 // easier to introduce bitcasts here than fix that.
16255 // There are 3 ways to get to this base-update combine:
16256 // - intrinsics: they are assumed to be properly aligned (to the standard
16257 // alignment of the memory type), so we don't need to do anything.
16258 // - ARMISD::VLDx nodes: they are only generated from the aforementioned
16259 // intrinsics, so, likewise, there's nothing to do.
16260 // - generic load/store instructions: the alignment is specified as an
16261 // explicit operand, rather than implicitly as the standard alignment
16262 // of the memory type (like the intrinsics). We need to change the
16263 // memory type to match the explicit alignment. That way, we don't
16264 // generate non-standard-aligned ARMISD::VLDx nodes.
16265 if (isa<LSBaseSDNode>(N)) {
16266 if (Alignment.value() < VecTy.getScalarSizeInBits() / 8) {
16267 MVT EltTy = MVT::getIntegerVT(Alignment.value() * 8);
16268 assert(NumVecs == 1 && "Unexpected multi-element generic load/store.");
16269 assert(!isLaneOp && "Unexpected generic load/store lane.");
16270 unsigned NumElts = NumBytes / (EltTy.getSizeInBits() / 8);
16271 AlignedVecTy = MVT::getVectorVT(EltTy, NumElts);
16272 }
16273 // Don't set an explicit alignment on regular load/stores that we want
16274 // to transform to VLD/VST 1_UPD nodes.
16275 // This matches the behavior of regular load/stores, which only get an
16276 // explicit alignment if the MMO alignment is larger than the standard
16277 // alignment of the memory type.
16278 // Intrinsics, however, always get an explicit alignment, set to the
16279 // alignment of the MMO.
16280 Alignment = Align(1);
16281 }
16282
16283 // Create the new updating load/store node.
16284 // First, create an SDVTList for the new updating node's results.
16285 EVT Tys[6];
16286 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16287 unsigned n;
16288 for (n = 0; n < NumResultVecs; ++n)
16289 Tys[n] = AlignedVecTy;
16290 Tys[n++] = MVT::i32;
16291 Tys[n] = MVT::Other;
16292 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16293
16294 // Then, gather the new node's operands.
16296 Ops.push_back(N->getOperand(0)); // incoming chain
16297 Ops.push_back(N->getOperand(Target.AddrOpIdx));
16298 Ops.push_back(User.Inc);
16299
16300 if (StoreSDNode *StN = dyn_cast<StoreSDNode>(N)) {
16301 // Try to match the intrinsic's signature
16302 Ops.push_back(StN->getValue());
16303 } else {
16304 // Loads (and of course intrinsics) match the intrinsics' signature,
16305 // so just add all but the alignment operand.
16306 unsigned LastOperand =
16307 hasAlignment ? N->getNumOperands() - 1 : N->getNumOperands();
16308 for (unsigned i = Target.AddrOpIdx + 1; i < LastOperand; ++i)
16309 Ops.push_back(N->getOperand(i));
16310 }
16311
16312 // For all node types, the alignment operand is always the last one.
16313 Ops.push_back(DAG.getConstant(Alignment.value(), dl, MVT::i32));
16314
16315 // If this is a non-standard-aligned STORE, the penultimate operand is the
16316 // stored value. Bitcast it to the aligned type.
16317 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::STORE) {
16318 SDValue &StVal = Ops[Ops.size() - 2];
16319 StVal = DAG.getNode(ISD::BITCAST, dl, AlignedVecTy, StVal);
16320 }
16321
16322 EVT LoadVT = isLaneOp ? VecTy.getVectorElementType() : AlignedVecTy;
16323 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, LoadVT,
16324 MemN->getMemOperand());
16325
16326 // Update the uses.
16327 SmallVector<SDValue, 5> NewResults;
16328 for (unsigned i = 0; i < NumResultVecs; ++i)
16329 NewResults.push_back(SDValue(UpdN.getNode(), i));
16330
16331 // If this is an non-standard-aligned LOAD, the first result is the loaded
16332 // value. Bitcast it to the expected result type.
16333 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::LOAD) {
16334 SDValue &LdVal = NewResults[0];
16335 LdVal = DAG.getNode(ISD::BITCAST, dl, VecTy, LdVal);
16336 }
16337
16338 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16339 DCI.CombineTo(N, NewResults);
16340 DCI.CombineTo(User.N, SDValue(UpdN.getNode(), NumResultVecs));
16341
16342 return true;
16343}
16344
16345// If (opcode ptr inc) is and ADD-like instruction, return the
16346// increment value. Otherwise return 0.
16347static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr,
16348 SDValue Inc, const SelectionDAG &DAG) {
16350 if (!CInc)
16351 return 0;
16352
16353 switch (Opcode) {
16354 case ARMISD::VLD1_UPD:
16355 case ISD::ADD:
16356 return CInc->getZExtValue();
16357 case ISD::OR: {
16358 if (DAG.haveNoCommonBitsSet(Ptr, Inc)) {
16359 // (OR ptr inc) is the same as (ADD ptr inc)
16360 return CInc->getZExtValue();
16361 }
16362 return 0;
16363 }
16364 default:
16365 return 0;
16366 }
16367}
16368
16370 switch (N->getOpcode()) {
16371 case ISD::ADD:
16372 case ISD::OR: {
16373 if (isa<ConstantSDNode>(N->getOperand(1))) {
16374 *Ptr = N->getOperand(0);
16375 *CInc = N->getOperand(1);
16376 return true;
16377 }
16378 return false;
16379 }
16380 case ARMISD::VLD1_UPD: {
16381 if (isa<ConstantSDNode>(N->getOperand(2))) {
16382 *Ptr = N->getOperand(1);
16383 *CInc = N->getOperand(2);
16384 return true;
16385 }
16386 return false;
16387 }
16388 default:
16389 return false;
16390 }
16391}
16392
16393/// CombineBaseUpdate - Target-specific DAG combine function for VLDDUP,
16394/// NEON load/store intrinsics, and generic vector load/stores, to merge
16395/// base address updates.
16396/// For generic load/stores, the memory type is assumed to be a vector.
16397/// The caller is assumed to have checked legality.
16400 const bool isIntrinsic = (N->getOpcode() == ISD::INTRINSIC_VOID ||
16401 N->getOpcode() == ISD::INTRINSIC_W_CHAIN);
16402 const bool isStore = N->getOpcode() == ISD::STORE;
16403 const unsigned AddrOpIdx = ((isIntrinsic || isStore) ? 2 : 1);
16404 BaseUpdateTarget Target = {N, isIntrinsic, isStore, AddrOpIdx};
16405
16406 // Limit the number of possible base-updates we look at to prevent degenerate
16407 // cases.
16408 unsigned MaxBaseUpdates = ArmMaxBaseUpdatesToCheck;
16409
16410 SDValue Addr = N->getOperand(AddrOpIdx);
16411
16413
16414 // Search for a use of the address operand that is an increment.
16415 for (SDUse &Use : Addr->uses()) {
16416 SDNode *User = Use.getUser();
16417 if (Use.getResNo() != Addr.getResNo() || User->getNumOperands() != 2)
16418 continue;
16419
16420 SDValue Inc = User->getOperand(Use.getOperandNo() == 1 ? 0 : 1);
16421 unsigned ConstInc =
16422 getPointerConstIncrement(User->getOpcode(), Addr, Inc, DCI.DAG);
16423
16424 if (ConstInc || User->getOpcode() == ISD::ADD) {
16425 BaseUpdates.push_back({User, Inc, ConstInc});
16426 if (BaseUpdates.size() >= MaxBaseUpdates)
16427 break;
16428 }
16429 }
16430
16431 // If the address is a constant pointer increment itself, find
16432 // another constant increment that has the same base operand
16433 SDValue Base;
16434 SDValue CInc;
16435 if (findPointerConstIncrement(Addr.getNode(), &Base, &CInc)) {
16436 unsigned Offset =
16437 getPointerConstIncrement(Addr->getOpcode(), Base, CInc, DCI.DAG);
16438 if (Offset) {
16439 for (SDUse &Use : Base->uses()) {
16440
16441 SDNode *User = Use.getUser();
16442 if (Use.getResNo() != Base.getResNo() || User == Addr.getNode() ||
16443 User->getNumOperands() != 2)
16444 continue;
16445
16446 SDValue UserInc = User->getOperand(Use.getOperandNo() == 0 ? 1 : 0);
16447 unsigned UserOffset =
16448 getPointerConstIncrement(User->getOpcode(), Base, UserInc, DCI.DAG);
16449
16450 if (!UserOffset || UserOffset <= Offset)
16451 continue;
16452
16453 unsigned NewConstInc = UserOffset - Offset;
16454 SDValue NewInc = DCI.DAG.getConstant(NewConstInc, SDLoc(N), MVT::i32);
16455 BaseUpdates.push_back({User, NewInc, NewConstInc});
16456 if (BaseUpdates.size() >= MaxBaseUpdates)
16457 break;
16458 }
16459 }
16460 }
16461
16462 // Try to fold the load/store with an update that matches memory
16463 // access size. This should work well for sequential loads.
16464 unsigned NumValidUpd = BaseUpdates.size();
16465 for (unsigned I = 0; I < NumValidUpd; I++) {
16466 BaseUpdateUser &User = BaseUpdates[I];
16467 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/true, DCI))
16468 return SDValue();
16469 }
16470
16471 // Try to fold with other users. Non-constant updates are considered
16472 // first, and constant updates are sorted to not break a sequence of
16473 // strided accesses (if there is any).
16474 llvm::stable_sort(BaseUpdates,
16475 [](const BaseUpdateUser &LHS, const BaseUpdateUser &RHS) {
16476 return LHS.ConstInc < RHS.ConstInc;
16477 });
16478 for (BaseUpdateUser &User : BaseUpdates) {
16479 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/false, DCI))
16480 return SDValue();
16481 }
16482 return SDValue();
16483}
16484
16487 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16488 return SDValue();
16489
16490 return CombineBaseUpdate(N, DCI);
16491}
16492
16495 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16496 return SDValue();
16497
16498 SelectionDAG &DAG = DCI.DAG;
16499 SDValue Addr = N->getOperand(2);
16500 MemSDNode *MemN = cast<MemSDNode>(N);
16501 SDLoc dl(N);
16502
16503 // For the stores, where there are multiple intrinsics we only actually want
16504 // to post-inc the last of the them.
16505 unsigned IntNo = N->getConstantOperandVal(1);
16506 if (IntNo == Intrinsic::arm_mve_vst2q && N->getConstantOperandVal(5) != 1)
16507 return SDValue();
16508 if (IntNo == Intrinsic::arm_mve_vst4q && N->getConstantOperandVal(7) != 3)
16509 return SDValue();
16510
16511 // Search for a use of the address operand that is an increment.
16512 for (SDUse &Use : Addr->uses()) {
16513 SDNode *User = Use.getUser();
16514 if (User->getOpcode() != ISD::ADD || Use.getResNo() != Addr.getResNo())
16515 continue;
16516
16517 // Check that the add is independent of the load/store. Otherwise, folding
16518 // it would create a cycle. We can avoid searching through Addr as it's a
16519 // predecessor to both.
16522 Visited.insert(Addr.getNode());
16523 Worklist.push_back(N);
16524 Worklist.push_back(User);
16525 const unsigned MaxSteps = 1024;
16526 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16527 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16528 continue;
16529
16530 // Find the new opcode for the updating load/store.
16531 bool isLoadOp = true;
16532 unsigned NewOpc = 0;
16533 unsigned NumVecs = 0;
16534 switch (IntNo) {
16535 default:
16536 llvm_unreachable("unexpected intrinsic for MVE VLDn combine");
16537 case Intrinsic::arm_mve_vld2q:
16538 NewOpc = ARMISD::VLD2_UPD;
16539 NumVecs = 2;
16540 break;
16541 case Intrinsic::arm_mve_vld4q:
16542 NewOpc = ARMISD::VLD4_UPD;
16543 NumVecs = 4;
16544 break;
16545 case Intrinsic::arm_mve_vst2q:
16546 NewOpc = ARMISD::VST2_UPD;
16547 NumVecs = 2;
16548 isLoadOp = false;
16549 break;
16550 case Intrinsic::arm_mve_vst4q:
16551 NewOpc = ARMISD::VST4_UPD;
16552 NumVecs = 4;
16553 isLoadOp = false;
16554 break;
16555 }
16556
16557 // Find the size of memory referenced by the load/store.
16558 EVT VecTy;
16559 if (isLoadOp) {
16560 VecTy = N->getValueType(0);
16561 } else {
16562 VecTy = N->getOperand(3).getValueType();
16563 }
16564
16565 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16566
16567 // If the increment is a constant, it must match the memory ref size.
16568 SDValue Inc = User->getOperand(User->getOperand(0) == Addr ? 1 : 0);
16570 if (!CInc || CInc->getZExtValue() != NumBytes)
16571 continue;
16572
16573 // Create the new updating load/store node.
16574 // First, create an SDVTList for the new updating node's results.
16575 EVT Tys[6];
16576 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16577 unsigned n;
16578 for (n = 0; n < NumResultVecs; ++n)
16579 Tys[n] = VecTy;
16580 Tys[n++] = MVT::i32;
16581 Tys[n] = MVT::Other;
16582 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16583
16584 // Then, gather the new node's operands.
16586 Ops.push_back(N->getOperand(0)); // incoming chain
16587 Ops.push_back(N->getOperand(2)); // ptr
16588 Ops.push_back(Inc);
16589
16590 for (unsigned i = 3; i < N->getNumOperands(); ++i)
16591 Ops.push_back(N->getOperand(i));
16592
16593 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, VecTy,
16594 MemN->getMemOperand());
16595
16596 // Update the uses.
16597 SmallVector<SDValue, 5> NewResults;
16598 for (unsigned i = 0; i < NumResultVecs; ++i)
16599 NewResults.push_back(SDValue(UpdN.getNode(), i));
16600
16601 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16602 DCI.CombineTo(N, NewResults);
16603 DCI.CombineTo(User, SDValue(UpdN.getNode(), NumResultVecs));
16604
16605 break;
16606 }
16607
16608 return SDValue();
16609}
16610
16611/// CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a
16612/// vldN-lane (N > 1) intrinsic, and if all the other uses of that intrinsic
16613/// are also VDUPLANEs. If so, combine them to a vldN-dup operation and
16614/// return true.
16616 SelectionDAG &DAG = DCI.DAG;
16617 EVT VT = N->getValueType(0);
16618 // vldN-dup instructions only support 64-bit vectors for N > 1.
16619 if (!VT.is64BitVector())
16620 return false;
16621
16622 // Check if the VDUPLANE operand is a vldN-dup intrinsic.
16623 SDNode *VLD = N->getOperand(0).getNode();
16624 if (VLD->getOpcode() != ISD::INTRINSIC_W_CHAIN)
16625 return false;
16626 unsigned NumVecs = 0;
16627 unsigned NewOpc = 0;
16628 unsigned IntNo = VLD->getConstantOperandVal(1);
16629 if (IntNo == Intrinsic::arm_neon_vld2lane) {
16630 NumVecs = 2;
16631 NewOpc = ARMISD::VLD2DUP;
16632 } else if (IntNo == Intrinsic::arm_neon_vld3lane) {
16633 NumVecs = 3;
16634 NewOpc = ARMISD::VLD3DUP;
16635 } else if (IntNo == Intrinsic::arm_neon_vld4lane) {
16636 NumVecs = 4;
16637 NewOpc = ARMISD::VLD4DUP;
16638 } else {
16639 return false;
16640 }
16641
16642 // First check that all the vldN-lane uses are VDUPLANEs and that the lane
16643 // numbers match the load.
16644 unsigned VLDLaneNo = VLD->getConstantOperandVal(NumVecs + 3);
16645 for (SDUse &Use : VLD->uses()) {
16646 // Ignore uses of the chain result.
16647 if (Use.getResNo() == NumVecs)
16648 continue;
16649 SDNode *User = Use.getUser();
16650 if (User->getOpcode() != ARMISD::VDUPLANE ||
16651 VLDLaneNo != User->getConstantOperandVal(1))
16652 return false;
16653 }
16654
16655 // Create the vldN-dup node.
16656 EVT Tys[5];
16657 unsigned n;
16658 for (n = 0; n < NumVecs; ++n)
16659 Tys[n] = VT;
16660 Tys[n] = MVT::Other;
16661 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumVecs + 1));
16662 SDValue Ops[] = { VLD->getOperand(0), VLD->getOperand(2) };
16664 SDValue VLDDup = DAG.getMemIntrinsicNode(NewOpc, SDLoc(VLD), SDTys,
16665 Ops, VLDMemInt->getMemoryVT(),
16666 VLDMemInt->getMemOperand());
16667
16668 // Update the uses.
16669 for (SDUse &Use : VLD->uses()) {
16670 unsigned ResNo = Use.getResNo();
16671 // Ignore uses of the chain result.
16672 if (ResNo == NumVecs)
16673 continue;
16674 DCI.CombineTo(Use.getUser(), SDValue(VLDDup.getNode(), ResNo));
16675 }
16676
16677 // Now the vldN-lane intrinsic is dead except for its chain result.
16678 // Update uses of the chain.
16679 std::vector<SDValue> VLDDupResults;
16680 for (unsigned n = 0; n < NumVecs; ++n)
16681 VLDDupResults.push_back(SDValue(VLDDup.getNode(), n));
16682 VLDDupResults.push_back(SDValue(VLDDup.getNode(), NumVecs));
16683 DCI.CombineTo(VLD, VLDDupResults);
16684
16685 return true;
16686}
16687
16688/// PerformVDUPLANECombine - Target-specific dag combine xforms for
16689/// ARMISD::VDUPLANE.
16692 const ARMSubtarget *Subtarget) {
16693 SDValue Op = N->getOperand(0);
16694 EVT VT = N->getValueType(0);
16695
16696 // On MVE, we just convert the VDUPLANE to a VDUP with an extract.
16697 if (Subtarget->hasMVEIntegerOps()) {
16698 EVT ExtractVT = VT.getVectorElementType();
16699 // We need to ensure we are creating a legal type.
16700 if (!DCI.DAG.getTargetLoweringInfo().isTypeLegal(ExtractVT))
16701 ExtractVT = MVT::i32;
16702 SDValue Extract = DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), ExtractVT,
16703 N->getOperand(0), N->getOperand(1));
16704 return DCI.DAG.getNode(ARMISD::VDUP, SDLoc(N), VT, Extract);
16705 }
16706
16707 // If the source is a vldN-lane (N > 1) intrinsic, and all the other uses
16708 // of that intrinsic are also VDUPLANEs, combine them to a vldN-dup operation.
16709 if (CombineVLDDUP(N, DCI))
16710 return SDValue(N, 0);
16711
16712 // If the source is already a VMOVIMM or VMVNIMM splat, the VDUPLANE is
16713 // redundant. Ignore bit_converts for now; element sizes are checked below.
16714 while (Op.getOpcode() == ISD::BITCAST)
16715 Op = Op.getOperand(0);
16716 if (Op.getOpcode() != ARMISD::VMOVIMM && Op.getOpcode() != ARMISD::VMVNIMM)
16717 return SDValue();
16718
16719 // Make sure the VMOV element size is not bigger than the VDUPLANE elements.
16720 unsigned EltSize = Op.getScalarValueSizeInBits();
16721 // The canonical VMOV for a zero vector uses a 32-bit element size.
16722 unsigned Imm = Op.getConstantOperandVal(0);
16723 unsigned EltBits;
16724 if (ARM_AM::decodeVMOVModImm(Imm, EltBits) == 0)
16725 EltSize = 8;
16726 if (EltSize > VT.getScalarSizeInBits())
16727 return SDValue();
16728
16729 return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
16730}
16731
16732/// PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
16734 const ARMSubtarget *Subtarget) {
16735 SDValue Op = N->getOperand(0);
16736 SDLoc dl(N);
16737
16738 if (Subtarget->hasMVEIntegerOps()) {
16739 // Convert VDUP f32 -> VDUP BITCAST i32 under MVE, as we know the value will
16740 // need to come from a GPR.
16741 if (Op.getValueType() == MVT::f32)
16742 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16743 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op));
16744 else if (Op.getValueType() == MVT::f16)
16745 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16746 DAG.getNode(ARMISD::VMOVrh, dl, MVT::i32, Op));
16747 }
16748
16749 if (!Subtarget->hasNEON())
16750 return SDValue();
16751
16752 // Match VDUP(LOAD) -> VLD1DUP.
16753 // We match this pattern here rather than waiting for isel because the
16754 // transform is only legal for unindexed loads.
16755 LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode());
16756 if (LD && Op.hasOneUse() && LD->isUnindexed() &&
16757 LD->getMemoryVT() == N->getValueType(0).getVectorElementType()) {
16758 SDValue Ops[] = {LD->getOperand(0), LD->getOperand(1),
16759 DAG.getConstant(LD->getAlign().value(), SDLoc(N), MVT::i32)};
16760 SDVTList SDTys = DAG.getVTList(N->getValueType(0), MVT::Other);
16761 SDValue VLDDup =
16763 LD->getMemoryVT(), LD->getMemOperand());
16764 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), VLDDup.getValue(1));
16765 return VLDDup;
16766 }
16767
16768 return SDValue();
16769}
16770
16773 const ARMSubtarget *Subtarget) {
16774 EVT VT = N->getValueType(0);
16775 // Let the deinterleave combine form a structured load first.
16777 for (SDUse &Use : N->uses())
16778 if (Use.getUser()->getOpcode() == ISD::VECTOR_DEINTERLEAVE)
16779 return SDValue();
16780 // If this is a legal vector load, try to combine it into a VLD1_UPD.
16781 if (Subtarget->hasNEON() && ISD::isNormalLoad(N) && VT.isVector() &&
16783 return CombineBaseUpdate(N, DCI);
16784
16785 return SDValue();
16786}
16787
16788// Optimize trunc store (of multiple scalars) to shuffle and store. First,
16789// pack all of the elements in one place. Next, store to memory in fewer
16790// chunks.
16792 SelectionDAG &DAG) {
16793 SDValue StVal = St->getValue();
16794 EVT VT = StVal.getValueType();
16795 if (!St->isTruncatingStore() || !VT.isVector())
16796 return SDValue();
16797 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
16798 EVT StVT = St->getMemoryVT();
16799 unsigned NumElems = VT.getVectorNumElements();
16800 assert(StVT != VT && "Cannot truncate to the same type");
16801 unsigned FromEltSz = VT.getScalarSizeInBits();
16802 unsigned ToEltSz = StVT.getScalarSizeInBits();
16803
16804 // From, To sizes and ElemCount must be pow of two
16805 if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz))
16806 return SDValue();
16807
16808 // We are going to use the original vector elt for storing.
16809 // Accumulated smaller vector elements must be a multiple of the store size.
16810 if (0 != (NumElems * FromEltSz) % ToEltSz)
16811 return SDValue();
16812
16813 unsigned SizeRatio = FromEltSz / ToEltSz;
16814 assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
16815
16816 // Create a type on which we perform the shuffle.
16817 EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
16818 NumElems * SizeRatio);
16819 assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
16820
16821 SDLoc DL(St);
16822 SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
16823 SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
16824 for (unsigned i = 0; i < NumElems; ++i)
16825 ShuffleVec[i] = DAG.getDataLayout().isBigEndian() ? (i + 1) * SizeRatio - 1
16826 : i * SizeRatio;
16827
16828 // Can't shuffle using an illegal type.
16829 if (!TLI.isTypeLegal(WideVecVT))
16830 return SDValue();
16831
16832 SDValue Shuff = DAG.getVectorShuffle(
16833 WideVecVT, DL, WideVec, DAG.getUNDEF(WideVec.getValueType()), ShuffleVec);
16834 // At this point all of the data is stored at the bottom of the
16835 // register. We now need to save it to mem.
16836
16837 // Find the largest store unit
16838 MVT StoreType = MVT::i8;
16839 for (MVT Tp : MVT::integer_valuetypes()) {
16840 if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
16841 StoreType = Tp;
16842 }
16843 // Didn't find a legal store type.
16844 if (!TLI.isTypeLegal(StoreType))
16845 return SDValue();
16846
16847 // Bitcast the original vector into a vector of store-size units
16848 EVT StoreVecVT =
16849 EVT::getVectorVT(*DAG.getContext(), StoreType,
16850 VT.getSizeInBits() / EVT(StoreType).getSizeInBits());
16851 assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
16852 SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
16854 SDValue Increment = DAG.getConstant(StoreType.getSizeInBits() / 8, DL,
16855 TLI.getPointerTy(DAG.getDataLayout()));
16856 SDValue BasePtr = St->getBasePtr();
16857
16858 // Perform one or more big stores into memory.
16859 unsigned E = (ToEltSz * NumElems) / StoreType.getSizeInBits();
16860 for (unsigned I = 0; I < E; I++) {
16861 SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreType,
16862 ShuffWide, DAG.getIntPtrConstant(I, DL));
16863 SDValue Ch =
16864 DAG.getStore(St->getChain(), DL, SubVec, BasePtr, St->getPointerInfo(),
16865 St->getAlign(), St->getMemOperand()->getFlags());
16866 BasePtr =
16867 DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr, Increment);
16868 Chains.push_back(Ch);
16869 }
16870 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
16871}
16872
16873// Try taking a single vector store from an fpround (which would otherwise turn
16874// into an expensive buildvector) and splitting it into a series of narrowing
16875// stores.
16877 SelectionDAG &DAG) {
16878 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16879 return SDValue();
16880 SDValue Trunc = St->getValue();
16881 if (Trunc->getOpcode() != ISD::FP_ROUND)
16882 return SDValue();
16883 EVT FromVT = Trunc->getOperand(0).getValueType();
16884 EVT ToVT = Trunc.getValueType();
16885 if (!ToVT.isVector())
16886 return SDValue();
16888 EVT ToEltVT = ToVT.getVectorElementType();
16889 EVT FromEltVT = FromVT.getVectorElementType();
16890
16891 if (FromEltVT != MVT::f32 || ToEltVT != MVT::f16)
16892 return SDValue();
16893
16894 unsigned NumElements = 4;
16895 if (FromVT.getVectorNumElements() % NumElements != 0)
16896 return SDValue();
16897
16898 // Test if the Trunc will be convertible to a VMOVN with a shuffle, and if so
16899 // use the VMOVN over splitting the store. We are looking for patterns of:
16900 // !rev: 0 N 1 N+1 2 N+2 ...
16901 // rev: N 0 N+1 1 N+2 2 ...
16902 // The shuffle may either be a single source (in which case N = NumElts/2) or
16903 // two inputs extended with concat to the same size (in which case N =
16904 // NumElts).
16905 auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
16906 ArrayRef<int> M = SVN->getMask();
16907 unsigned NumElts = ToVT.getVectorNumElements();
16908 if (SVN->getOperand(1).isUndef())
16909 NumElts /= 2;
16910
16911 unsigned Off0 = Rev ? NumElts : 0;
16912 unsigned Off1 = Rev ? 0 : NumElts;
16913
16914 for (unsigned I = 0; I < NumElts; I += 2) {
16915 if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
16916 return false;
16917 if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
16918 return false;
16919 }
16920
16921 return true;
16922 };
16923
16924 if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
16925 if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
16926 return SDValue();
16927
16928 LLVMContext &C = *DAG.getContext();
16929 SDLoc DL(St);
16930 // Details about the old store
16931 SDValue Ch = St->getChain();
16932 SDValue BasePtr = St->getBasePtr();
16933 Align Alignment = St->getBaseAlign();
16934 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16935 AAMDNodes AAInfo = St->getAAInfo();
16936
16937 // We split the store into slices of NumElements. fp16 trunc stores are vcvt
16938 // and then stored as truncating integer stores.
16939 EVT NewFromVT = EVT::getVectorVT(C, FromEltVT, NumElements);
16940 EVT NewToVT = EVT::getVectorVT(
16941 C, EVT::getIntegerVT(C, ToEltVT.getSizeInBits()), NumElements);
16942
16944 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
16945 unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
16946 SDValue NewPtr =
16947 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16948
16949 SDValue Extract =
16950 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
16951 DAG.getConstant(i * NumElements, DL, MVT::i32));
16952
16953 SDValue FPTrunc =
16954 DAG.getNode(ARMISD::VCVTN, DL, MVT::v8f16, DAG.getUNDEF(MVT::v8f16),
16955 Extract, DAG.getConstant(0, DL, MVT::i32));
16956 Extract = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v4i32, FPTrunc);
16957
16959 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16960 NewToVT, Alignment, MMOFlags, AAInfo);
16961 Stores.push_back(Store);
16962 }
16963 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16964}
16965
16966// Try taking a single vector store from an MVETRUNC (which would otherwise turn
16967// into an expensive buildvector) and splitting it into a series of narrowing
16968// stores.
16970 SelectionDAG &DAG) {
16971 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16972 return SDValue();
16973 SDValue Trunc = St->getValue();
16974 if (Trunc->getOpcode() != ARMISD::MVETRUNC)
16975 return SDValue();
16976 EVT FromVT = Trunc->getOperand(0).getValueType();
16977 EVT ToVT = Trunc.getValueType();
16978
16979 LLVMContext &C = *DAG.getContext();
16980 SDLoc DL(St);
16981 // Details about the old store
16982 SDValue Ch = St->getChain();
16983 SDValue BasePtr = St->getBasePtr();
16984 Align Alignment = St->getBaseAlign();
16985 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16986 AAMDNodes AAInfo = St->getAAInfo();
16987
16988 EVT NewToVT = EVT::getVectorVT(C, ToVT.getVectorElementType(),
16989 FromVT.getVectorNumElements());
16990
16992 for (unsigned i = 0; i < Trunc.getNumOperands(); i++) {
16993 unsigned NewOffset =
16994 i * FromVT.getVectorNumElements() * ToVT.getScalarSizeInBits() / 8;
16995 SDValue NewPtr =
16996 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16997
16998 SDValue Extract = Trunc.getOperand(i);
17000 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
17001 NewToVT, Alignment, MMOFlags, AAInfo);
17002 Stores.push_back(Store);
17003 }
17004 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
17005}
17006
17007// Given a floating point store from an extracted vector, with an integer
17008// VGETLANE that already exists, store the existing VGETLANEu directly. This can
17009// help reduce fp register pressure, doesn't require the fp extract and allows
17010// use of more integer post-inc stores not available with vstr.
17012 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
17013 return SDValue();
17014 SDValue Extract = St->getValue();
17015 EVT VT = Extract.getValueType();
17016 // For now only uses f16. This may be useful for f32 too, but that will
17017 // be bitcast(extract), not the VGETLANEu we currently check here.
17018 if (VT != MVT::f16 || Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
17019 return SDValue();
17020
17021 SDNode *GetLane =
17022 DAG.getNodeIfExists(ARMISD::VGETLANEu, DAG.getVTList(MVT::i32),
17023 {Extract.getOperand(0), Extract.getOperand(1)});
17024 if (!GetLane)
17025 return SDValue();
17026
17027 LLVMContext &C = *DAG.getContext();
17028 SDLoc DL(St);
17029 // Create a new integer store to replace the existing floating point version.
17030 SDValue Ch = St->getChain();
17031 SDValue BasePtr = St->getBasePtr();
17032 Align Alignment = St->getBaseAlign();
17033 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
17034 AAMDNodes AAInfo = St->getAAInfo();
17035 EVT NewToVT = EVT::getIntegerVT(C, VT.getSizeInBits());
17036 SDValue Store = DAG.getTruncStore(Ch, DL, SDValue(GetLane, 0), BasePtr,
17037 St->getPointerInfo(), NewToVT, Alignment,
17038 MMOFlags, AAInfo);
17039
17040 return Store;
17041}
17042
17043// Combine stores of all VECTOR_INTERLEAVE results into a structured store
17044// (vstN) when they access consecutive memory. Running this after type
17045// legalization let wider vector types to be split into legal types, so each
17046// split can form a structured store.
17049 const ARMSubtarget *Subtarget) {
17051 return SDValue();
17052
17053 if (!ISD::isNormalStore(ST) || !ST->isSimple() || !ST->getOffset().isUndef())
17054 return SDValue();
17055
17056 SDValue StoredValue = ST->getValue();
17057 SDNode *Interleave = StoredValue.getNode();
17058 if (Interleave->getOpcode() != ISD::VECTOR_INTERLEAVE)
17059 return SDValue();
17060
17061 unsigned NumParts = Interleave->getNumOperands();
17062 if (NumParts < 2 || NumParts > 4)
17063 return SDValue();
17064
17065 if (NumParts == 3 && Subtarget->hasMVEIntegerOps())
17066 return SDValue();
17067
17068 EVT SubVecTy = Interleave->getValueType(0);
17069 if (Subtarget->hasNEON() && !SubVecTy.is64BitVector() &&
17070 !SubVecTy.is128BitVector())
17071 return SDValue();
17072 if (Subtarget->hasMVEIntegerOps() && !SubVecTy.is128BitVector())
17073 return SDValue();
17074 unsigned EltBits = SubVecTy.getScalarSizeInBits();
17075 if (EltBits != 8 && EltBits != 16 && EltBits != 32)
17076 return SDValue();
17077
17078 SmallVector<StoreSDNode *, 4> Stores(NumParts, nullptr);
17079 for (SDUse &Use : Interleave->uses()) {
17080 unsigned ResNo = Use.getResNo();
17082 if (Stores[ResNo] || !Store)
17083 return SDValue();
17084 Stores[ResNo] = Store;
17085 }
17086
17087 if (llvm::is_contained(Stores, nullptr))
17088 return SDValue();
17089
17090 StoreSDNode *BaseStore = Stores[0];
17091 if (Subtarget->hasMVEIntegerOps() && BaseStore->getAlign() < EltBits / 8)
17092 return SDValue();
17093 unsigned Bytes = SubVecTy.getStoreSize().getFixedValue();
17094 for (auto [Idx, Store] : enumerate(Stores)) {
17095 if (!DAG.areNonVolatileConsecutiveStores(Store, BaseStore, Bytes, Idx))
17096 return SDValue();
17097 }
17098
17099 static constexpr Intrinsic::ID NEONStores[] = {Intrinsic::arm_neon_vst2,
17100 Intrinsic::arm_neon_vst3,
17101 Intrinsic::arm_neon_vst4};
17102 SDLoc DL(Interleave);
17104
17105 Ops.push_back(BaseStore->getChain());
17106 Intrinsic::ID IID = 0;
17107 if (Subtarget->hasNEON())
17108 IID = NEONStores[NumParts - 2];
17109 else
17110 IID = NumParts == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
17111
17112 Ops.push_back(DAG.getTargetConstant(IID, DL, MVT::i64));
17113
17114 Ops.push_back(BaseStore->getBasePtr());
17115 Ops.append(Interleave->op_begin(), Interleave->op_end());
17116 Ops.push_back(DAG.getConstant(BaseStore->getAlign().value(), DL, MVT::i32));
17117
17118 EVT MemVT =
17120 SubVecTy.getVectorElementCount() * NumParts);
17122 MachineMemOperand *MMO =
17123 MF.getMachineMemOperand(BaseStore->getMemOperand(), 0, NumParts * Bytes);
17124 SDValue NewStore;
17125 if (Subtarget->hasNEON()) {
17126 NewStore = DAG.getMemIntrinsicNode(
17127 ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), Ops, MemVT, MMO);
17128 } else {
17129 // MVE
17130 for (unsigned Stage = 0; Stage < NumParts; Stage++) {
17131 Ops.back() = DAG.getConstant(Stage, DL, MVT::i32);
17132 NewStore = DAG.getMemIntrinsicNode(
17133 ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), Ops, MemVT, MMO);
17134 Ops.front() = NewStore;
17135 }
17136 }
17137 for (StoreSDNode *Store : Stores) {
17138 DAG.makeEquivalentMemoryOrdering(SDValue(Store, 0), NewStore);
17139 if (Store != ST)
17140 DCI.CombineTo(Store, NewStore);
17141 }
17142 return NewStore;
17143}
17144
17145static bool
17147 if (N->getOpcode() != ISD::CONCAT_VECTORS)
17148 return false;
17149
17150 unsigned NumParts = N->getNumOperands();
17151
17152 // We should be concatenating each sequential result from a
17153 // VECTOR_INTERLEAVE.
17154 SDNode *InterleaveOp = N->getOperand(0).getNode();
17155 if (InterleaveOp->getOpcode() != ISD::VECTOR_INTERLEAVE ||
17156 InterleaveOp->getNumOperands() != NumParts)
17157 return false;
17158
17159 for (unsigned I = 0; I < NumParts; I++)
17160 if (N->getOperand(I) != SDValue(InterleaveOp, I))
17161 return false;
17162
17163 Ops.append(InterleaveOp->op_begin(), InterleaveOp->op_end());
17164 return true;
17165}
17166
17169 const ARMSubtarget *Subtarget) {
17170 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
17171 return SDValue();
17172 if (SDValue Res =
17173 PerformLegalizedInterleavedStoreCombine(ST, DCI, DAG, Subtarget))
17174 return Res;
17175
17176 if (!DCI.isBeforeLegalize())
17177 return SDValue();
17178
17179 if (!ISD::isNormalStore(ST) || !ST->isSimple() || !ST->getOffset().isUndef())
17180 return SDValue();
17181
17182 SDValue WideValue = ST->getValue();
17183 SmallVector<SDValue, 4> ValueInterleaveOps;
17185 ValueInterleaveOps))
17186 return SDValue();
17187
17188 if (!WideValue.hasOneUse())
17189 return SDValue();
17190
17191 unsigned NumParts = ValueInterleaveOps.size();
17192 if (NumParts != 2 && NumParts != 3 && NumParts != 4)
17193 return SDValue();
17194
17195 if (NumParts == 3 && Subtarget->hasMVEIntegerOps())
17196 return SDValue();
17197
17198 EVT SubVecTy = ValueInterleaveOps[0].getValueType();
17199 if (Subtarget->hasNEON() && !SubVecTy.is64BitVector() &&
17200 !SubVecTy.is128BitVector())
17201 return SDValue();
17202 if (Subtarget->hasMVEIntegerOps() && !SubVecTy.is128BitVector())
17203 return SDValue();
17204 unsigned EltBits = SubVecTy.getScalarSizeInBits();
17205 if (EltBits != 8 && EltBits != 16 && EltBits != 32)
17206 return SDValue();
17207 if (Subtarget->hasMVEIntegerOps() && ST->getAlign() < EltBits / 8)
17208 return SDValue();
17209 static constexpr Intrinsic::ID NEONStores[] = {Intrinsic::arm_neon_vst2,
17210 Intrinsic::arm_neon_vst3,
17211 Intrinsic::arm_neon_vst4};
17212 SDLoc DL(ST);
17214 Ops.push_back(ST->getChain());
17215 Intrinsic::ID IID = 0;
17216 if (Subtarget->hasNEON())
17217 IID = NEONStores[NumParts - 2];
17218 else
17219 IID = NumParts == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
17220
17221 Ops.push_back(DAG.getTargetConstant(IID, DL, MVT::i64));
17222
17223 Ops.push_back(ST->getBasePtr());
17224 Ops.append(ValueInterleaveOps);
17225
17226 Ops.push_back(DAG.getConstant(ST->getAlign().value(), DL, MVT::i32));
17227 if (Subtarget->hasNEON())
17229 DAG.getVTList(MVT::Other), Ops,
17230 ST->getMemoryVT(), ST->getMemOperand());
17231 // MVE
17232 SDValue NewStore;
17233 for (unsigned Stage = 0; Stage < NumParts; Stage++) {
17234 Ops.back() = DAG.getConstant(Stage, DL, MVT::i32);
17236 DAG.getVTList(MVT::Other), Ops,
17237 ST->getMemoryVT(), ST->getMemOperand());
17238 Ops.front() = NewStore;
17239 }
17240 return NewStore;
17241}
17242
17243/// PerformSTORECombine - Target-specific dag combine xforms for
17244/// ISD::STORE.
17247 const ARMSubtarget *Subtarget) {
17249 if (St->isVolatile())
17250 return SDValue();
17251 SDValue StVal = St->getValue();
17252 EVT VT = StVal.getValueType();
17253 if (SDValue Store =
17254 PerformInterleavedStoreCombine(St, DCI, DCI.DAG, Subtarget))
17255 return Store;
17256
17257 if (Subtarget->hasNEON())
17259 return Store;
17260
17261 if (Subtarget->hasMVEFloatOps())
17262 if (SDValue NewToken = PerformSplittingToNarrowingStores(St, DCI.DAG))
17263 return NewToken;
17264
17265 if (Subtarget->hasMVEIntegerOps()) {
17266 if (SDValue NewChain = PerformExtractFpToIntStores(St, DCI.DAG))
17267 return NewChain;
17268 if (SDValue NewToken =
17270 return NewToken;
17271 }
17272
17273 if (!ISD::isNormalStore(St))
17274 return SDValue();
17275
17276 // Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
17277 // ARM stores of arguments in the same cache line.
17278 if (StVal.getOpcode() == ARMISD::VMOVDRR && StVal->hasOneUse()) {
17279 SelectionDAG &DAG = DCI.DAG;
17280 bool isBigEndian = DAG.getDataLayout().isBigEndian();
17281 SDLoc DL(St);
17282 SDValue BasePtr = St->getBasePtr();
17283 SDValue NewST1 =
17284 DAG.getStore(St->getChain(), DL, StVal.getOperand(isBigEndian ? 1 : 0),
17285 BasePtr, St->getPointerInfo(), St->getBaseAlign(),
17286 St->getMemOperand()->getFlags());
17287
17288 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
17289 DAG.getConstant(4, DL, MVT::i32));
17290 return DAG.getStore(NewST1.getValue(0), DL,
17291 StVal.getOperand(isBigEndian ? 0 : 1), OffsetPtr,
17292 St->getPointerInfo().getWithOffset(4),
17293 St->getBaseAlign(), St->getMemOperand()->getFlags());
17294 }
17295
17296 if (StVal.getValueType() == MVT::i64 &&
17298 // Bitcast an i64 store extracted from a vector to f64.
17299 // Otherwise, the i64 value will be legalized to a pair of i32 values.
17300 SelectionDAG &DAG = DCI.DAG;
17301 SDLoc dl(StVal);
17302 SDValue IntVec = StVal.getOperand(0);
17303 EVT FloatVT =
17304 EVT::getVectorVT(*DAG.getContext(), MVT::f64,
17306 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
17307 SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Vec,
17308 StVal.getOperand(1));
17309 dl = SDLoc(N);
17310 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
17311 // Make the DAGCombiner fold the bitcasts.
17312 DCI.AddToWorklist(Vec.getNode());
17313 DCI.AddToWorklist(ExtElt.getNode());
17314 DCI.AddToWorklist(V.getNode());
17315 return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
17316 St->getPointerInfo(), St->getAlign(),
17317 St->getMemOperand()->getFlags(), St->getAAInfo());
17318 }
17319
17320 // If this is a legal vector store, try to combine it into a VST1_UPD.
17321 if (Subtarget->hasNEON() && ISD::isNormalStore(N) && VT.isVector() &&
17323 return CombineBaseUpdate(N, DCI);
17324
17325 return SDValue();
17326}
17327
17328/// PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD)
17329/// can replace combinations of VMUL and VCVT (floating-point to integer)
17330/// when the VMUL has a constant operand that is a power of 2.
17331///
17332/// Example (assume d17 = <float 8.000000e+00, float 8.000000e+00>):
17333/// vmul.f32 d16, d17, d16
17334/// vcvt.s32.f32 d16, d16
17335/// becomes:
17336/// vcvt.s32.f32 d16, d16, #3
17338 const ARMSubtarget *Subtarget) {
17339 if (!Subtarget->hasNEON())
17340 return SDValue();
17341
17342 SDValue Op = N->getOperand(0);
17343 if (!Op.getValueType().isVector() || !Op.getValueType().isSimple() ||
17344 Op.getOpcode() != ISD::FMUL)
17345 return SDValue();
17346
17347 SDValue ConstVec = Op->getOperand(1);
17348 if (!isa<BuildVectorSDNode>(ConstVec))
17349 return SDValue();
17350
17351 MVT FloatTy = Op.getSimpleValueType().getVectorElementType();
17352 uint32_t FloatBits = FloatTy.getSizeInBits();
17353 MVT IntTy = N->getSimpleValueType(0).getVectorElementType();
17354 uint32_t IntBits = IntTy.getSizeInBits();
17355 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17356 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17357 // These instructions only exist converting from f32 to i32. We can handle
17358 // smaller integers by generating an extra truncate, but larger ones would
17359 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17360 // these instructions only support v2i32/v4i32 types.
17361 return SDValue();
17362 }
17363
17364 BitVector UndefElements;
17366 int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33);
17367 if (C == -1 || C == 0 || C > 32)
17368 return SDValue();
17369
17370 SDLoc dl(N);
17371 bool isSigned = N->getOpcode() == ISD::FP_TO_SINT;
17372 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfp2fxs :
17373 Intrinsic::arm_neon_vcvtfp2fxu;
17374 SDValue FixConv = DAG.getNode(
17375 ISD::INTRINSIC_WO_CHAIN, dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32,
17376 DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), Op->getOperand(0),
17377 DAG.getConstant(C, dl, MVT::i32));
17378
17379 if (IntBits < FloatBits)
17380 FixConv = DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), FixConv);
17381
17382 return FixConv;
17383}
17384
17386 const ARMSubtarget *Subtarget) {
17387 if (!Subtarget->hasMVEFloatOps())
17388 return SDValue();
17389
17390 // Turn (fadd x, (vselect c, y, -0.0)) into (vselect c, (fadd x, y), x)
17391 // The second form can be more easily turned into a predicated vadd, and
17392 // possibly combined into a fma to become a predicated vfma.
17393 SDValue Op0 = N->getOperand(0);
17394 SDValue Op1 = N->getOperand(1);
17395 EVT VT = N->getValueType(0);
17396 SDLoc DL(N);
17397
17398 // The identity element for a fadd is -0.0 or +0.0 when the nsz flag is set,
17399 // which these VMOV's represent.
17400 auto isIdentitySplat = [&](SDValue Op, bool NSZ) {
17401 if (Op.getOpcode() != ISD::BITCAST ||
17402 Op.getOperand(0).getOpcode() != ARMISD::VMOVIMM)
17403 return false;
17404 uint64_t ImmVal = Op.getOperand(0).getConstantOperandVal(0);
17405 if (VT == MVT::v4f32 && (ImmVal == 1664 || (ImmVal == 0 && NSZ)))
17406 return true;
17407 if (VT == MVT::v8f16 && (ImmVal == 2688 || (ImmVal == 0 && NSZ)))
17408 return true;
17409 return false;
17410 };
17411
17412 if (Op0.getOpcode() == ISD::VSELECT && Op1.getOpcode() != ISD::VSELECT)
17413 std::swap(Op0, Op1);
17414
17415 if (Op1.getOpcode() != ISD::VSELECT)
17416 return SDValue();
17417
17418 SDNodeFlags FaddFlags = N->getFlags();
17419 bool NSZ = FaddFlags.hasNoSignedZeros();
17420 if (!isIdentitySplat(Op1.getOperand(2), NSZ))
17421 return SDValue();
17422
17423 SDValue FAdd =
17424 DAG.getNode(ISD::FADD, DL, VT, Op0, Op1.getOperand(1), FaddFlags);
17425 return DAG.getNode(ISD::VSELECT, DL, VT, Op1.getOperand(0), FAdd, Op0, FaddFlags);
17426}
17427
17429 SDValue LHS = N->getOperand(0);
17430 SDValue RHS = N->getOperand(1);
17431 EVT VT = N->getValueType(0);
17432 SDLoc DL(N);
17433
17434 if (!N->getFlags().hasAllowReassociation())
17435 return SDValue();
17436
17437 // Combine fadd(a, vcmla(b, c, d)) -> vcmla(fadd(a, b), b, c)
17438 auto ReassocComplex = [&](SDValue A, SDValue B) {
17439 if (A.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
17440 return SDValue();
17441 unsigned Opc = A.getConstantOperandVal(0);
17442 if (Opc != Intrinsic::arm_mve_vcmlaq)
17443 return SDValue();
17444 SDValue VCMLA = DAG.getNode(
17445 ISD::INTRINSIC_WO_CHAIN, DL, VT, A.getOperand(0), A.getOperand(1),
17446 DAG.getNode(ISD::FADD, DL, VT, A.getOperand(2), B, N->getFlags()),
17447 A.getOperand(3), A.getOperand(4));
17448 VCMLA->setFlags(A->getFlags());
17449 return VCMLA;
17450 };
17451 if (SDValue R = ReassocComplex(LHS, RHS))
17452 return R;
17453 if (SDValue R = ReassocComplex(RHS, LHS))
17454 return R;
17455
17456 return SDValue();
17457}
17458
17460 const ARMSubtarget *Subtarget) {
17461 if (SDValue S = PerformFAddVSelectCombine(N, DAG, Subtarget))
17462 return S;
17463 if (SDValue S = PerformFADDVCMLACombine(N, DAG))
17464 return S;
17465 return SDValue();
17466}
17467
17468/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD)
17469/// can replace combinations of VCVT (integer to floating-point) and VMUL
17470/// when the VMUL has a constant operand that is a power of 2.
17471///
17472/// Example (assume d17 = <float 0.125, float 0.125>):
17473/// vcvt.f32.s32 d16, d16
17474/// vmul.f32 d16, d16, d17
17475/// becomes:
17476/// vcvt.f32.s32 d16, d16, #3
17478 const ARMSubtarget *Subtarget) {
17479 if (!Subtarget->hasNEON())
17480 return SDValue();
17481
17482 SDValue Op = N->getOperand(0);
17483 unsigned OpOpcode = Op.getNode()->getOpcode();
17484 if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple() ||
17485 (OpOpcode != ISD::SINT_TO_FP && OpOpcode != ISD::UINT_TO_FP))
17486 return SDValue();
17487
17488 SDValue ConstVec = N->getOperand(1);
17489 if (!isa<BuildVectorSDNode>(ConstVec))
17490 return SDValue();
17491
17492 MVT FloatTy = N->getSimpleValueType(0).getVectorElementType();
17493 uint32_t FloatBits = FloatTy.getSizeInBits();
17494 MVT IntTy = Op.getOperand(0).getSimpleValueType().getVectorElementType();
17495 uint32_t IntBits = IntTy.getSizeInBits();
17496 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17497 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17498 // These instructions only exist converting from i32 to f32. We can handle
17499 // smaller integers by generating an extra extend, but larger ones would
17500 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17501 // these instructions only support v2i32/v4i32 types.
17502 return SDValue();
17503 }
17504
17505 ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true);
17506 APFloat Recip(0.0f);
17507 if (!CN || !CN->getValueAPF().getExactInverse(&Recip))
17508 return SDValue();
17509
17510 bool IsExact;
17511 APSInt IntVal(33);
17512 if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
17513 APFloat::opOK ||
17514 !IsExact)
17515 return SDValue();
17516
17517 int32_t C = IntVal.exactLogBase2();
17518 if (C == -1 || C == 0 || C > 32)
17519 return SDValue();
17520
17521 SDLoc DL(N);
17522 bool isSigned = OpOpcode == ISD::SINT_TO_FP;
17523 SDValue ConvInput = Op.getOperand(0);
17524 if (IntBits < FloatBits)
17526 NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput);
17527
17528 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp
17529 : Intrinsic::arm_neon_vcvtfxu2fp;
17530 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
17531 DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput,
17532 DAG.getConstant(C, DL, MVT::i32));
17533}
17534
17536 const ARMSubtarget *ST) {
17537 if (!ST->hasMVEIntegerOps())
17538 return SDValue();
17539
17540 assert(N->getOpcode() == ISD::VECREDUCE_ADD);
17541 EVT ResVT = N->getValueType(0);
17542 SDValue N0 = N->getOperand(0);
17543 SDLoc dl(N);
17544
17545 // Try to turn vecreduce_add(add(x, y)) into vecreduce(x) + vecreduce(y)
17546 if (ResVT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
17547 (N0.getValueType() == MVT::v4i32 || N0.getValueType() == MVT::v8i16 ||
17548 N0.getValueType() == MVT::v16i8)) {
17549 SDValue Red0 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(0));
17550 SDValue Red1 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(1));
17551 return DAG.getNode(ISD::ADD, dl, ResVT, Red0, Red1);
17552 }
17553
17554 // We are looking for something that will have illegal types if left alone,
17555 // but that we can convert to a single instruction under MVE. For example
17556 // vecreduce_add(sext(A, v8i32)) => VADDV.s16 A
17557 // or
17558 // vecreduce_add(mul(zext(A, v16i32), zext(B, v16i32))) => VMLADAV.u8 A, B
17559
17560 // The legal cases are:
17561 // VADDV u/s 8/16/32
17562 // VMLAV u/s 8/16/32
17563 // VADDLV u/s 32
17564 // VMLALV u/s 16/32
17565
17566 // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
17567 // extend it and use v4i32 instead.
17568 auto ExtTypeMatches = [](SDValue A, ArrayRef<MVT> ExtTypes) {
17569 EVT AVT = A.getValueType();
17570 return any_of(ExtTypes, [&](MVT Ty) {
17571 return AVT.getVectorNumElements() == Ty.getVectorNumElements() &&
17572 AVT.bitsLE(Ty);
17573 });
17574 };
17575 auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
17576 EVT AVT = A.getValueType();
17577 if (!AVT.is128BitVector())
17578 A = DAG.getNode(
17579 ExtendCode, dl,
17581 *DAG.getContext(),
17583 A);
17584 return A;
17585 };
17586 auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
17587 if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
17588 return SDValue();
17589 SDValue A = N0->getOperand(0);
17590 if (ExtTypeMatches(A, ExtTypes))
17591 return ExtendIfNeeded(A, ExtendCode);
17592 return SDValue();
17593 };
17594 auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
17595 ArrayRef<MVT> ExtTypes, SDValue &Mask) {
17596 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17598 return SDValue();
17599 Mask = N0->getOperand(0);
17600 SDValue Ext = N0->getOperand(1);
17601 if (Ext->getOpcode() != ExtendCode)
17602 return SDValue();
17603 SDValue A = Ext->getOperand(0);
17604 if (ExtTypeMatches(A, ExtTypes))
17605 return ExtendIfNeeded(A, ExtendCode);
17606 return SDValue();
17607 };
17608 auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17609 SDValue &A, SDValue &B) {
17610 // For a vmla we are trying to match a larger pattern:
17611 // ExtA = sext/zext A
17612 // ExtB = sext/zext B
17613 // Mul = mul ExtA, ExtB
17614 // vecreduce.add Mul
17615 // There might also be en extra extend between the mul and the addreduce, so
17616 // long as the bitwidth is high enough to make them equivalent (for example
17617 // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
17618 if (ResVT != RetTy)
17619 return false;
17620 SDValue Mul = N0;
17621 if (Mul->getOpcode() == ExtendCode &&
17622 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17623 ResVT.getScalarSizeInBits())
17624 Mul = Mul->getOperand(0);
17625 if (Mul->getOpcode() != ISD::MUL)
17626 return false;
17627 SDValue ExtA = Mul->getOperand(0);
17628 SDValue ExtB = Mul->getOperand(1);
17629 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17630 return false;
17631 A = ExtA->getOperand(0);
17632 B = ExtB->getOperand(0);
17633 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17634 A = ExtendIfNeeded(A, ExtendCode);
17635 B = ExtendIfNeeded(B, ExtendCode);
17636 return true;
17637 }
17638 return false;
17639 };
17640 auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17641 SDValue &A, SDValue &B, SDValue &Mask) {
17642 // Same as the pattern above with a select for the zero predicated lanes
17643 // ExtA = sext/zext A
17644 // ExtB = sext/zext B
17645 // Mul = mul ExtA, ExtB
17646 // N0 = select Mask, Mul, 0
17647 // vecreduce.add N0
17648 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17650 return false;
17651 Mask = N0->getOperand(0);
17652 SDValue Mul = N0->getOperand(1);
17653 if (Mul->getOpcode() == ExtendCode &&
17654 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17655 ResVT.getScalarSizeInBits())
17656 Mul = Mul->getOperand(0);
17657 if (Mul->getOpcode() != ISD::MUL)
17658 return false;
17659 SDValue ExtA = Mul->getOperand(0);
17660 SDValue ExtB = Mul->getOperand(1);
17661 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17662 return false;
17663 A = ExtA->getOperand(0);
17664 B = ExtB->getOperand(0);
17665 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17666 A = ExtendIfNeeded(A, ExtendCode);
17667 B = ExtendIfNeeded(B, ExtendCode);
17668 return true;
17669 }
17670 return false;
17671 };
17672 auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
17673 // Split illegal MVT::v16i8->i64 vector reductions into two legal v8i16->i64
17674 // reductions. The operands are extended with MVEEXT, but as they are
17675 // reductions the lane orders do not matter. MVEEXT may be combined with
17676 // loads to produce two extending loads, or else they will be expanded to
17677 // VREV/VMOVL.
17678 EVT VT = Ops[0].getValueType();
17679 if (VT == MVT::v16i8) {
17680 assert((Opcode == ARMISD::VMLALVs || Opcode == ARMISD::VMLALVu) &&
17681 "Unexpected illegal long reduction opcode");
17682 bool IsUnsigned = Opcode == ARMISD::VMLALVu;
17683
17684 SDValue Ext0 =
17685 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17686 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[0]);
17687 SDValue Ext1 =
17688 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17689 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[1]);
17690
17691 SDValue MLA0 = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
17692 Ext0, Ext1);
17693 SDValue MLA1 =
17694 DAG.getNode(IsUnsigned ? ARMISD::VMLALVAu : ARMISD::VMLALVAs, dl,
17695 DAG.getVTList(MVT::i32, MVT::i32), MLA0, MLA0.getValue(1),
17696 Ext0.getValue(1), Ext1.getValue(1));
17697 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, MLA1, MLA1.getValue(1));
17698 }
17699 SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
17700 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
17701 SDValue(Node.getNode(), 1));
17702 };
17703
17704 SDValue A, B;
17705 SDValue Mask;
17706 if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17707 return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
17708 if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17709 return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
17710 if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17711 A, B))
17712 return Create64bitNode(ARMISD::VMLALVs, {A, B});
17713 if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17714 A, B))
17715 return Create64bitNode(ARMISD::VMLALVu, {A, B});
17716 if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
17717 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17718 DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
17719 if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
17720 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17721 DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
17722
17723 if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17724 Mask))
17725 return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
17726 if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17727 Mask))
17728 return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
17729 if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17730 Mask))
17731 return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
17732 if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17733 Mask))
17734 return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
17735 if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
17736 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17737 DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
17738 if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
17739 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17740 DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
17741
17742 if (SDValue A = IsVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}))
17743 return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
17744 if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
17745 return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
17746 if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}))
17747 return Create64bitNode(ARMISD::VADDLVs, {A});
17748 if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}))
17749 return Create64bitNode(ARMISD::VADDLVu, {A});
17750 if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
17751 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17752 DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
17753 if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
17754 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17755 DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
17756
17757 if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17758 return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
17759 if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17760 return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
17761 if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}, Mask))
17762 return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
17763 if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}, Mask))
17764 return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
17765 if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
17766 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17767 DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
17768 if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
17769 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17770 DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
17771
17772 // Some complications. We can get a case where the two inputs of the mul are
17773 // the same, then the output sext will have been helpfully converted to a
17774 // zext. Turn it back.
17775 SDValue Op = N0;
17776 if (Op->getOpcode() == ISD::VSELECT)
17777 Op = Op->getOperand(1);
17778 if (Op->getOpcode() == ISD::ZERO_EXTEND &&
17779 Op->getOperand(0)->getOpcode() == ISD::MUL) {
17780 SDValue Mul = Op->getOperand(0);
17781 if (Mul->getOperand(0) == Mul->getOperand(1) &&
17782 Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
17783 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
17784 if (Op != N0)
17785 Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
17786 N0->getOperand(0), Ext, N0->getOperand(2));
17787 return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
17788 }
17789 }
17790
17791 return SDValue();
17792}
17793
17794// Looks for vaddv(shuffle) or vmlav(shuffle, shuffle), with a shuffle where all
17795// the lanes are used. Due to the reduction being commutative the shuffle can be
17796// removed.
17798 unsigned VecOp = N->getOperand(0).getValueType().isVector() ? 0 : 2;
17799 auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp));
17800 if (!Shuf || !Shuf->getOperand(1).isUndef())
17801 return SDValue();
17802
17803 // Check all elements are used once in the mask.
17804 ArrayRef<int> Mask = Shuf->getMask();
17805 APInt SetElts(Mask.size(), 0);
17806 for (int E : Mask) {
17807 if (E < 0 || E >= (int)Mask.size())
17808 return SDValue();
17809 SetElts.setBit(E);
17810 }
17811 if (!SetElts.isAllOnes())
17812 return SDValue();
17813
17814 if (N->getNumOperands() != VecOp + 1) {
17815 auto *Shuf2 = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp + 1));
17816 if (!Shuf2 || !Shuf2->getOperand(1).isUndef() || Shuf2->getMask() != Mask)
17817 return SDValue();
17818 }
17819
17821 for (SDValue Op : N->ops()) {
17822 if (Op.getValueType().isVector())
17823 Ops.push_back(Op.getOperand(0));
17824 else
17825 Ops.push_back(Op);
17826 }
17827 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Ops);
17828}
17829
17832 SDValue Op0 = N->getOperand(0);
17833 SDValue Op1 = N->getOperand(1);
17834 unsigned IsTop = N->getConstantOperandVal(2);
17835
17836 // VMOVNT a undef -> a
17837 // VMOVNB a undef -> a
17838 // VMOVNB undef a -> a
17839 if (Op1->isUndef())
17840 return Op0;
17841 if (Op0->isUndef() && !IsTop)
17842 return Op1;
17843
17844 // VMOVNt(c, VQMOVNb(a, b)) => VQMOVNt(c, b)
17845 // VMOVNb(c, VQMOVNb(a, b)) => VQMOVNb(c, b)
17846 if ((Op1->getOpcode() == ARMISD::VQMOVNs ||
17847 Op1->getOpcode() == ARMISD::VQMOVNu) &&
17848 Op1->getConstantOperandVal(2) == 0)
17849 return DCI.DAG.getNode(Op1->getOpcode(), SDLoc(Op1), N->getValueType(0),
17850 Op0, Op1->getOperand(1), N->getOperand(2));
17851
17852 // Only the bottom lanes from Qm (Op1) and either the top or bottom lanes from
17853 // Qd (Op0) are demanded from a VMOVN, depending on whether we are inserting
17854 // into the top or bottom lanes.
17855 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17856 APInt Op1DemandedElts = APInt::getSplat(NumElts, APInt::getLowBitsSet(2, 1));
17857 APInt Op0DemandedElts =
17858 IsTop ? Op1DemandedElts
17859 : APInt::getSplat(NumElts, APInt::getHighBitsSet(2, 1));
17860
17861 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17862 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17863 return SDValue(N, 0);
17864 if (TLI.SimplifyDemandedVectorElts(Op1, Op1DemandedElts, DCI))
17865 return SDValue(N, 0);
17866
17867 return SDValue();
17868}
17869
17872 SDValue Op0 = N->getOperand(0);
17873 unsigned IsTop = N->getConstantOperandVal(2);
17874
17875 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17876 APInt Op0DemandedElts =
17877 APInt::getSplat(NumElts, IsTop ? APInt::getLowBitsSet(2, 1)
17878 : APInt::getHighBitsSet(2, 1));
17879
17880 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17881 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17882 return SDValue(N, 0);
17883 return SDValue();
17884}
17885
17888 EVT VT = N->getValueType(0);
17889 SDValue LHS = N->getOperand(0);
17890 SDValue RHS = N->getOperand(1);
17891
17892 auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
17893 auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
17894 // Turn VQDMULH(shuffle, shuffle) -> shuffle(VQDMULH)
17895 if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&
17896 LHS.getOperand(1).isUndef() && RHS.getOperand(1).isUndef() &&
17897 (LHS.hasOneUse() || RHS.hasOneUse() || LHS == RHS)) {
17898 SDLoc DL(N);
17899 SDValue NewBinOp = DCI.DAG.getNode(N->getOpcode(), DL, VT,
17900 LHS.getOperand(0), RHS.getOperand(0));
17901 SDValue UndefV = LHS.getOperand(1);
17902 return DCI.DAG.getVectorShuffle(VT, DL, NewBinOp, UndefV, Shuf0->getMask());
17903 }
17904 return SDValue();
17905}
17906
17908 SDLoc DL(N);
17909 SDValue Op0 = N->getOperand(0);
17910 SDValue Op1 = N->getOperand(1);
17911
17912 // Turn X << -C -> X >> C and viceversa. The negative shifts can come up from
17913 // uses of the intrinsics.
17914 if (auto C = dyn_cast<ConstantSDNode>(N->getOperand(2))) {
17915 int ShiftAmt = C->getSExtValue();
17916 if (ShiftAmt == 0) {
17917 SDValue Merge = DAG.getMergeValues({Op0, Op1}, DL);
17918 DAG.ReplaceAllUsesWith(N, Merge.getNode());
17919 return SDValue();
17920 }
17921
17922 if (ShiftAmt >= -32 && ShiftAmt < 0) {
17923 unsigned NewOpcode =
17924 N->getOpcode() == ARMISD::LSLL ? ARMISD::LSRL : ARMISD::LSLL;
17925 SDValue NewShift = DAG.getNode(NewOpcode, DL, N->getVTList(), Op0, Op1,
17926 DAG.getConstant(-ShiftAmt, DL, MVT::i32));
17927 DAG.ReplaceAllUsesWith(N, NewShift.getNode());
17928 return NewShift;
17929 }
17930 }
17931
17932 return SDValue();
17933}
17934
17935/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
17937 DAGCombinerInfo &DCI) const {
17938 SelectionDAG &DAG = DCI.DAG;
17939 unsigned IntNo = N->getConstantOperandVal(0);
17940 switch (IntNo) {
17941 default:
17942 // Don't do anything for most intrinsics.
17943 break;
17944
17945 // Vector shifts: check for immediate versions and lower them.
17946 // Note: This is done during DAG combining instead of DAG legalizing because
17947 // the build_vectors for 64-bit vector element shift counts are generally
17948 // not legal, and it is hard to see their values after they get legalized to
17949 // loads from a constant pool.
17950 case Intrinsic::arm_neon_vshifts:
17951 case Intrinsic::arm_neon_vshiftu:
17952 case Intrinsic::arm_neon_vrshifts:
17953 case Intrinsic::arm_neon_vrshiftu:
17954 case Intrinsic::arm_neon_vrshiftn:
17955 case Intrinsic::arm_neon_vqshifts:
17956 case Intrinsic::arm_neon_vqshiftu:
17957 case Intrinsic::arm_neon_vqshiftsu:
17958 case Intrinsic::arm_neon_vqshiftns:
17959 case Intrinsic::arm_neon_vqshiftnu:
17960 case Intrinsic::arm_neon_vqshiftnsu:
17961 case Intrinsic::arm_neon_vqrshiftns:
17962 case Intrinsic::arm_neon_vqrshiftnu:
17963 case Intrinsic::arm_neon_vqrshiftnsu: {
17964 EVT VT = N->getOperand(1).getValueType();
17965 int64_t Cnt;
17966 unsigned VShiftOpc = 0;
17967
17968 switch (IntNo) {
17969 case Intrinsic::arm_neon_vshifts:
17970 case Intrinsic::arm_neon_vshiftu:
17971 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) {
17972 VShiftOpc = ARMISD::VSHLIMM;
17973 break;
17974 }
17975 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) {
17976 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? ARMISD::VSHRsIMM
17977 : ARMISD::VSHRuIMM);
17978 break;
17979 }
17980 return SDValue();
17981
17982 case Intrinsic::arm_neon_vrshifts:
17983 case Intrinsic::arm_neon_vrshiftu:
17984 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt))
17985 break;
17986 return SDValue();
17987
17988 case Intrinsic::arm_neon_vqshifts:
17989 case Intrinsic::arm_neon_vqshiftu:
17990 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17991 break;
17992 return SDValue();
17993
17994 case Intrinsic::arm_neon_vqshiftsu:
17995 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17996 break;
17997 llvm_unreachable("invalid shift count for vqshlu intrinsic");
17998
17999 case Intrinsic::arm_neon_vrshiftn:
18000 case Intrinsic::arm_neon_vqshiftns:
18001 case Intrinsic::arm_neon_vqshiftnu:
18002 case Intrinsic::arm_neon_vqshiftnsu:
18003 case Intrinsic::arm_neon_vqrshiftns:
18004 case Intrinsic::arm_neon_vqrshiftnu:
18005 case Intrinsic::arm_neon_vqrshiftnsu:
18006 // Narrowing shifts require an immediate right shift.
18007 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt))
18008 break;
18009 llvm_unreachable("invalid shift count for narrowing vector shift "
18010 "intrinsic");
18011
18012 default:
18013 llvm_unreachable("unhandled vector shift");
18014 }
18015
18016 switch (IntNo) {
18017 case Intrinsic::arm_neon_vshifts:
18018 case Intrinsic::arm_neon_vshiftu:
18019 // Opcode already set above.
18020 break;
18021 case Intrinsic::arm_neon_vrshifts:
18022 VShiftOpc = ARMISD::VRSHRsIMM;
18023 break;
18024 case Intrinsic::arm_neon_vrshiftu:
18025 VShiftOpc = ARMISD::VRSHRuIMM;
18026 break;
18027 case Intrinsic::arm_neon_vrshiftn:
18028 VShiftOpc = ARMISD::VRSHRNIMM;
18029 break;
18030 case Intrinsic::arm_neon_vqshifts:
18031 VShiftOpc = ARMISD::VQSHLsIMM;
18032 break;
18033 case Intrinsic::arm_neon_vqshiftu:
18034 VShiftOpc = ARMISD::VQSHLuIMM;
18035 break;
18036 case Intrinsic::arm_neon_vqshiftsu:
18037 VShiftOpc = ARMISD::VQSHLsuIMM;
18038 break;
18039 case Intrinsic::arm_neon_vqshiftns:
18040 VShiftOpc = ARMISD::VQSHRNsIMM;
18041 break;
18042 case Intrinsic::arm_neon_vqshiftnu:
18043 VShiftOpc = ARMISD::VQSHRNuIMM;
18044 break;
18045 case Intrinsic::arm_neon_vqshiftnsu:
18046 VShiftOpc = ARMISD::VQSHRNsuIMM;
18047 break;
18048 case Intrinsic::arm_neon_vqrshiftns:
18049 VShiftOpc = ARMISD::VQRSHRNsIMM;
18050 break;
18051 case Intrinsic::arm_neon_vqrshiftnu:
18052 VShiftOpc = ARMISD::VQRSHRNuIMM;
18053 break;
18054 case Intrinsic::arm_neon_vqrshiftnsu:
18055 VShiftOpc = ARMISD::VQRSHRNsuIMM;
18056 break;
18057 }
18058
18059 SDLoc dl(N);
18060 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
18061 N->getOperand(1), DAG.getConstant(Cnt, dl, MVT::i32));
18062 }
18063
18064 case Intrinsic::arm_neon_vshiftins: {
18065 EVT VT = N->getOperand(1).getValueType();
18066 int64_t Cnt;
18067 unsigned VShiftOpc = 0;
18068
18069 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt))
18070 VShiftOpc = ARMISD::VSLIIMM;
18071 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt))
18072 VShiftOpc = ARMISD::VSRIIMM;
18073 else {
18074 llvm_unreachable("invalid shift count for vsli/vsri intrinsic");
18075 }
18076
18077 SDLoc dl(N);
18078 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
18079 N->getOperand(1), N->getOperand(2),
18080 DAG.getConstant(Cnt, dl, MVT::i32));
18081 }
18082
18083 case Intrinsic::arm_neon_vqrshifts:
18084 case Intrinsic::arm_neon_vqrshiftu:
18085 // No immediate versions of these to check for.
18086 break;
18087
18088 case Intrinsic::arm_neon_vbsl: {
18089 SDLoc dl(N);
18090 return DAG.getNode(ARMISD::VBSP, dl, N->getValueType(0), N->getOperand(1),
18091 N->getOperand(2), N->getOperand(3));
18092 }
18093 case Intrinsic::arm_mve_vqdmlah:
18094 case Intrinsic::arm_mve_vqdmlash:
18095 case Intrinsic::arm_mve_vqrdmlah:
18096 case Intrinsic::arm_mve_vqrdmlash:
18097 case Intrinsic::arm_mve_vmla_n_predicated:
18098 case Intrinsic::arm_mve_vmlas_n_predicated:
18099 case Intrinsic::arm_mve_vqdmlah_predicated:
18100 case Intrinsic::arm_mve_vqdmlash_predicated:
18101 case Intrinsic::arm_mve_vqrdmlah_predicated:
18102 case Intrinsic::arm_mve_vqrdmlash_predicated: {
18103 // These intrinsics all take an i32 scalar operand which is narrowed to the
18104 // size of a single lane of the vector type they return. So we don't need
18105 // any bits of that operand above that point, which allows us to eliminate
18106 // uxth/sxth.
18107 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
18108 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
18109 if (SimplifyDemandedBits(N->getOperand(3), DemandedMask, DCI))
18110 return SDValue();
18111 break;
18112 }
18113
18114 case Intrinsic::arm_mve_minv:
18115 case Intrinsic::arm_mve_maxv:
18116 case Intrinsic::arm_mve_minav:
18117 case Intrinsic::arm_mve_maxav:
18118 case Intrinsic::arm_mve_minv_predicated:
18119 case Intrinsic::arm_mve_maxv_predicated:
18120 case Intrinsic::arm_mve_minav_predicated:
18121 case Intrinsic::arm_mve_maxav_predicated: {
18122 // These intrinsics all take an i32 scalar operand which is narrowed to the
18123 // size of a single lane of the vector type they take as the other input.
18124 unsigned BitWidth = N->getOperand(2)->getValueType(0).getScalarSizeInBits();
18125 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
18126 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
18127 return SDValue();
18128 break;
18129 }
18130
18131 case Intrinsic::arm_mve_addv: {
18132 // Turn this intrinsic straight into the appropriate ARMISD::VADDV node,
18133 // which allow PerformADDVecReduce to turn it into VADDLV when possible.
18134 bool Unsigned = N->getConstantOperandVal(2);
18135 unsigned Opc = Unsigned ? ARMISD::VADDVu : ARMISD::VADDVs;
18136 return DAG.getNode(Opc, SDLoc(N), N->getVTList(), N->getOperand(1));
18137 }
18138
18139 case Intrinsic::arm_mve_addlv:
18140 case Intrinsic::arm_mve_addlv_predicated: {
18141 // Same for these, but ARMISD::VADDLV has to be followed by a BUILD_PAIR
18142 // which recombines the two outputs into an i64
18143 bool Unsigned = N->getConstantOperandVal(2);
18144 unsigned Opc = IntNo == Intrinsic::arm_mve_addlv ?
18145 (Unsigned ? ARMISD::VADDLVu : ARMISD::VADDLVs) :
18146 (Unsigned ? ARMISD::VADDLVpu : ARMISD::VADDLVps);
18147
18149 for (unsigned i = 1, e = N->getNumOperands(); i < e; i++)
18150 if (i != 2) // skip the unsigned flag
18151 Ops.push_back(N->getOperand(i));
18152
18153 SDLoc dl(N);
18154 SDValue val = DAG.getNode(Opc, dl, {MVT::i32, MVT::i32}, Ops);
18155 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, val.getValue(0),
18156 val.getValue(1));
18157 }
18158 }
18159
18160 return SDValue();
18161}
18162
18164 EVT VT = Y.getValueType();
18165 if (!VT.isVector())
18166 return hasAndNotCompare(Y);
18167 if (Subtarget->hasMVEIntegerOps())
18168 return VT.is128BitVector();
18169 if (Subtarget->hasNEON())
18170 return VT.is64BitVector() || VT.is128BitVector();
18171 return false;
18172}
18173
18174/// PerformShiftCombine - Checks for immediate versions of vector shifts and
18175/// lowers them. As with the vector shift intrinsics, this is done during DAG
18176/// combining instead of DAG legalizing because the build_vectors for 64-bit
18177/// vector element shift counts are generally not legal, and it is hard to see
18178/// their values after they get legalized to loads from a constant pool.
18181 const ARMSubtarget *ST) {
18182 SelectionDAG &DAG = DCI.DAG;
18183 EVT VT = N->getValueType(0);
18184
18185 if (ST->isThumb1Only() && N->getOpcode() == ISD::SHL && VT == MVT::i32 &&
18186 N->getOperand(0)->getOpcode() == ISD::AND &&
18187 N->getOperand(0)->hasOneUse()) {
18188 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
18189 return SDValue();
18190 // Look for the pattern (shl (and x, AndMask), ShiftAmt). This doesn't
18191 // usually show up because instcombine prefers to canonicalize it to
18192 // (and (shl x, ShiftAmt) (shl AndMask, ShiftAmt)), but the shift can come
18193 // out of GEP lowering in some cases.
18194 SDValue N0 = N->getOperand(0);
18195 ConstantSDNode *ShiftAmtNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
18196 if (!ShiftAmtNode)
18197 return SDValue();
18198 uint32_t ShiftAmt = static_cast<uint32_t>(ShiftAmtNode->getZExtValue());
18199 ConstantSDNode *AndMaskNode = dyn_cast<ConstantSDNode>(N0->getOperand(1));
18200 if (!AndMaskNode)
18201 return SDValue();
18202 uint32_t AndMask = static_cast<uint32_t>(AndMaskNode->getZExtValue());
18203 // Don't transform uxtb/uxth.
18204 if (AndMask == 255 || AndMask == 65535)
18205 return SDValue();
18206 if (isMask_32(AndMask)) {
18207 uint32_t MaskedBits = llvm::countl_zero(AndMask);
18208 if (MaskedBits > ShiftAmt) {
18209 SDLoc DL(N);
18210 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
18211 DAG.getConstant(MaskedBits, DL, MVT::i32));
18212 return DAG.getNode(
18213 ISD::SRL, DL, MVT::i32, SHL,
18214 DAG.getConstant(MaskedBits - ShiftAmt, DL, MVT::i32));
18215 }
18216 }
18217 }
18218
18219 // Nothing to be done for scalar shifts.
18220 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18221 if (!VT.isVector() || !TLI.isTypeLegal(VT))
18222 return SDValue();
18223 if (ST->hasMVEIntegerOps())
18224 return SDValue();
18225
18226 int64_t Cnt;
18227
18228 switch (N->getOpcode()) {
18229 default: llvm_unreachable("unexpected shift opcode");
18230
18231 case ISD::SHL:
18232 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) {
18233 SDLoc dl(N);
18234 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
18235 DAG.getConstant(Cnt, dl, MVT::i32));
18236 }
18237 break;
18238
18239 case ISD::SRA:
18240 case ISD::SRL:
18241 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
18242 unsigned VShiftOpc =
18243 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
18244 SDLoc dl(N);
18245 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
18246 DAG.getConstant(Cnt, dl, MVT::i32));
18247 }
18248 }
18249 return SDValue();
18250}
18251
18252// Look for a sign/zero/fpextend extend of a larger than legal load. This can be
18253// split into multiple extending loads, which are simpler to deal with than an
18254// arbitrary extend. For fp extends we use an integer extending load and a VCVTL
18255// to convert the type to an f32.
18257 SDValue N0 = N->getOperand(0);
18258 if (N0.getOpcode() != ISD::LOAD)
18259 return SDValue();
18261 if (!LD->isSimple() || !N0.hasOneUse() || LD->isIndexed() ||
18262 LD->getExtensionType() != ISD::NON_EXTLOAD)
18263 return SDValue();
18264 EVT FromVT = LD->getValueType(0);
18265 EVT ToVT = N->getValueType(0);
18266 if (!ToVT.isVector())
18267 return SDValue();
18269 EVT ToEltVT = ToVT.getVectorElementType();
18270 EVT FromEltVT = FromVT.getVectorElementType();
18271
18272 unsigned NumElements = 0;
18273 if (ToEltVT == MVT::i32 && FromEltVT == MVT::i8)
18274 NumElements = 4;
18275 if (ToEltVT == MVT::f32 && FromEltVT == MVT::f16)
18276 NumElements = 4;
18277 if (NumElements == 0 ||
18278 (FromEltVT != MVT::f16 && FromVT.getVectorNumElements() == NumElements) ||
18279 FromVT.getVectorNumElements() % NumElements != 0 ||
18280 !isPowerOf2_32(NumElements))
18281 return SDValue();
18282
18283 LLVMContext &C = *DAG.getContext();
18284 SDLoc DL(LD);
18285 // Details about the old load
18286 SDValue Ch = LD->getChain();
18287 SDValue BasePtr = LD->getBasePtr();
18288 Align Alignment = LD->getBaseAlign();
18289 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18290 AAMDNodes AAInfo = LD->getAAInfo();
18291
18292 ISD::LoadExtType NewExtType =
18293 N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18294 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
18295 EVT NewFromVT = EVT::getVectorVT(
18296 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
18297 EVT NewToVT = EVT::getVectorVT(
18298 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18299
18302 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18303 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18304 SDValue NewPtr =
18305 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18306
18307 SDValue NewLoad =
18308 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18309 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18310 Alignment, MMOFlags, AAInfo);
18311 Loads.push_back(NewLoad);
18312 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18313 }
18314
18315 // Float truncs need to extended with VCVTB's into their floating point types.
18316 if (FromEltVT == MVT::f16) {
18318
18319 for (unsigned i = 0; i < Loads.size(); i++) {
18320 SDValue LoadBC =
18321 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v8f16, Loads[i]);
18322 SDValue FPExt = DAG.getNode(ARMISD::VCVTL, DL, MVT::v4f32, LoadBC,
18323 DAG.getConstant(0, DL, MVT::i32));
18324 Extends.push_back(FPExt);
18325 }
18326
18327 Loads = Extends;
18328 }
18329
18330 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18331 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18332 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Loads);
18333}
18334
18335/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND,
18336/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND.
18338 const ARMSubtarget *ST) {
18339 SDValue N0 = N->getOperand(0);
18340 EVT VT = N->getValueType(0);
18341 SDLoc DL(N);
18342
18343 // Check for sign- and zero-extensions of vector extract operations of 8- and
18344 // 16-bit vector elements. NEON and MVE support these directly. They are
18345 // handled during DAG combining because type legalization will promote them
18346 // to 32-bit types and it is messy to recognize the operations after that.
18347 if ((ST->hasNEON() || ST->hasMVEIntegerOps()) &&
18349 SDValue Vec = N0.getOperand(0);
18350 SDValue Lane = N0.getOperand(1);
18351 EVT EltVT = N0.getValueType();
18352 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18353
18354 if (VT == MVT::i32 &&
18355 (EltVT == MVT::i8 || EltVT == MVT::i16) &&
18356 TLI.isTypeLegal(Vec.getValueType()) &&
18357 isa<ConstantSDNode>(Lane)) {
18358
18359 unsigned Opc = 0;
18360 switch (N->getOpcode()) {
18361 default: llvm_unreachable("unexpected opcode");
18362 case ISD::SIGN_EXTEND:
18363 Opc = ARMISD::VGETLANEs;
18364 break;
18365 case ISD::ZERO_EXTEND:
18366 case ISD::ANY_EXTEND:
18367 Opc = ARMISD::VGETLANEu;
18368 break;
18369 }
18370 return DAG.getNode(Opc, DL, VT, Vec, Lane);
18371 }
18372 }
18373
18374 if (ST->hasMVEIntegerOps())
18375 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18376 return NewLoad;
18377
18378 // Combine sext(buildvector(..)) to buildvector(sext(..)) to help avoid
18379 // difficult to lower i1 buildvector.
18380 if (ST->hasMVEIntegerOps() && N0.getValueType().getScalarSizeInBits() == 1 &&
18381 N0.getOpcode() == ISD::BUILD_VECTOR && VT.getScalarSizeInBits() <= 32) {
18383 for (unsigned I = 0; I < N0.getNumOperands(); I++) {
18384 SDValue InReg = N0.getOperand(I);
18385 if (N->getOpcode() == ISD::ZERO_EXTEND)
18386 InReg = DAG.getNode(ISD::AND, DL, InReg.getValueType(), InReg,
18387 DAG.getConstant(1, DL, InReg.getValueType()));
18388 else if (N->getOpcode() == ISD::SIGN_EXTEND)
18389 InReg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InReg.getValueType(),
18390 InReg, DAG.getValueType(MVT::i1));
18391 SDValue Ext = DAG.getNode(N->getOpcode(), DL, MVT::i32, InReg);
18392 Ops.push_back(Ext);
18393 }
18394 return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
18395 }
18396
18397 return SDValue();
18398}
18399
18401 const ARMSubtarget *ST) {
18402 if (ST->hasMVEFloatOps())
18403 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18404 return NewLoad;
18405
18406 return SDValue();
18407}
18408
18409// Lower smin(smax(x, C1), C2) to ssat or usat, if they have saturating
18410// constant bounds.
18412 const ARMSubtarget *Subtarget) {
18413 if ((Subtarget->isThumb() || !Subtarget->hasV6Ops()) &&
18414 !Subtarget->isThumb2())
18415 return SDValue();
18416
18417 EVT VT = Op.getValueType();
18418 SDValue Op0 = Op.getOperand(0);
18419
18420 if (VT != MVT::i32 ||
18421 (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
18422 !isa<ConstantSDNode>(Op.getOperand(1)) ||
18424 return SDValue();
18425
18426 SDValue Min = Op;
18427 SDValue Max = Op0;
18428 SDValue Input = Op0.getOperand(0);
18429 if (Min.getOpcode() == ISD::SMAX)
18430 std::swap(Min, Max);
18431
18432 if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX)
18433 return SDValue();
18434
18435 APInt MinC = Min.getConstantOperandAPInt(1);
18436 APInt MaxC = Max.getConstantOperandAPInt(1);
18437 if (MaxC.sgt(MinC))
18438 return SDValue();
18439
18440 SDLoc DL(Op);
18441
18442 // A clamp whose bounds are already a saturation range maps to a single
18443 // SSAT / USAT.
18444 if ((MinC + 1).isPowerOf2()) {
18445 if (MinC == ~MaxC)
18446 return DAG.getNode(ARMISD::SSAT, DL, VT, Input,
18447 DAG.getConstant(MinC.countr_one(), DL, VT));
18448 if (MaxC == 0)
18449 return DAG.getNode(ARMISD::USAT, DL, VT, Input,
18450 DAG.getConstant(MinC.countr_one(), DL, VT));
18451 }
18452
18453 // For power-of-two clamp widths, convert the range to be zero-centered,
18454 // apply SSAT, and convert the result back.
18455 //
18456 // Width = Hi - Lo + 1
18457 // Center = Lo + Width / 2
18458 // Result = ssat(X - Center) + Center
18459 //
18460 // The idea is to shift the input so that the clamp range is centered
18461 // around zero, apply ssat, and then shift the result back.
18462 //
18463 // For example clamp(X, -118, 137) -> Width = 256, Center = 10, so it becomes
18464 // ssat(X - 10, 8) + 10
18465
18466 APInt Width = MinC - MaxC + 1;
18467 if (!Width.isPowerOf2() || Width.isOne())
18468 return SDValue();
18469 unsigned SatBit = Width.logBase2() - 1; // ssat to SatBit + 1 signed bits
18470 APInt Center = MaxC + Width.lshr(1);
18471
18472 // The rewrite is only valid when X - Center does not overflow;
18473 SDValue NegC = DAG.getConstant(-Center, DL, VT);
18475 return SDValue();
18476
18477 SDValue Shifted = DAG.getNode(ISD::ADD, DL, VT, Input, NegC);
18478 SDValue Sat = DAG.getNode(ARMISD::SSAT, DL, VT, Shifted,
18479 DAG.getConstant(SatBit, DL, VT));
18480 return DAG.getNode(ISD::ADD, DL, VT, Sat, DAG.getConstant(Center, DL, VT));
18481}
18482
18483/// PerformMinMaxCombine - Target-specific DAG combining for creating truncating
18484/// saturates.
18486 const ARMSubtarget *ST) {
18487 EVT VT = N->getValueType(0);
18488 SDValue N0 = N->getOperand(0);
18489
18490 if (VT == MVT::i32)
18491 return PerformMinMaxToSatCombine(SDValue(N, 0), DAG, ST);
18492
18493 if (!ST->hasMVEIntegerOps())
18494 return SDValue();
18495
18496 if (SDValue V = PerformVQDMULHCombine(N, DAG))
18497 return V;
18498
18499 if (VT != MVT::v4i32 && VT != MVT::v8i16)
18500 return SDValue();
18501
18502 auto IsSignedSaturate = [&](SDNode *Min, SDNode *Max) {
18503 // Check one is a smin and the other is a smax
18504 if (Min->getOpcode() != ISD::SMIN)
18505 std::swap(Min, Max);
18506 if (Min->getOpcode() != ISD::SMIN || Max->getOpcode() != ISD::SMAX)
18507 return false;
18508
18509 APInt SaturateC;
18510 if (VT == MVT::v4i32)
18511 SaturateC = APInt(32, (1 << 15) - 1, true);
18512 else //if (VT == MVT::v8i16)
18513 SaturateC = APInt(16, (1 << 7) - 1, true);
18514
18515 APInt MinC, MaxC;
18516 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18517 MinC != SaturateC)
18518 return false;
18519 if (!ISD::isConstantSplatVector(Max->getOperand(1).getNode(), MaxC) ||
18520 MaxC != ~SaturateC)
18521 return false;
18522 return true;
18523 };
18524
18525 if (IsSignedSaturate(N, N0.getNode())) {
18526 SDLoc DL(N);
18527 MVT ExtVT, HalfVT;
18528 if (VT == MVT::v4i32) {
18529 HalfVT = MVT::v8i16;
18530 ExtVT = MVT::v4i16;
18531 } else { // if (VT == MVT::v8i16)
18532 HalfVT = MVT::v16i8;
18533 ExtVT = MVT::v8i8;
18534 }
18535
18536 // Create a VQMOVNB with undef top lanes, then signed extended into the top
18537 // half. That extend will hopefully be removed if only the bottom bits are
18538 // demanded (though a truncating store, for example).
18539 SDValue VQMOVN =
18540 DAG.getNode(ARMISD::VQMOVNs, DL, HalfVT, DAG.getUNDEF(HalfVT),
18541 N0->getOperand(0), DAG.getConstant(0, DL, MVT::i32));
18542 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18543 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Bitcast,
18544 DAG.getValueType(ExtVT));
18545 }
18546
18547 auto IsUnsignedSaturate = [&](SDNode *Min) {
18548 // For unsigned, we just need to check for <= 0xffff
18549 if (Min->getOpcode() != ISD::UMIN)
18550 return false;
18551
18552 APInt SaturateC;
18553 if (VT == MVT::v4i32)
18554 SaturateC = APInt(32, (1 << 16) - 1, true);
18555 else //if (VT == MVT::v8i16)
18556 SaturateC = APInt(16, (1 << 8) - 1, true);
18557
18558 APInt MinC;
18559 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18560 MinC != SaturateC)
18561 return false;
18562 return true;
18563 };
18564
18565 if (IsUnsignedSaturate(N)) {
18566 SDLoc DL(N);
18567 MVT HalfVT;
18568 unsigned ExtConst;
18569 if (VT == MVT::v4i32) {
18570 HalfVT = MVT::v8i16;
18571 ExtConst = 0x0000FFFF;
18572 } else { //if (VT == MVT::v8i16)
18573 HalfVT = MVT::v16i8;
18574 ExtConst = 0x00FF;
18575 }
18576
18577 // Create a VQMOVNB with undef top lanes, then ZExt into the top half with
18578 // an AND. That extend will hopefully be removed if only the bottom bits are
18579 // demanded (though a truncating store, for example).
18580 SDValue VQMOVN =
18581 DAG.getNode(ARMISD::VQMOVNu, DL, HalfVT, DAG.getUNDEF(HalfVT), N0,
18582 DAG.getConstant(0, DL, MVT::i32));
18583 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18584 return DAG.getNode(ISD::AND, DL, VT, Bitcast,
18585 DAG.getConstant(ExtConst, DL, VT));
18586 }
18587
18588 return SDValue();
18589}
18590
18593 if (!C)
18594 return nullptr;
18595 const APInt *CV = &C->getAPIntValue();
18596 return CV->isPowerOf2() ? CV : nullptr;
18597}
18598
18600 // If we have a CMOV, OR and AND combination such as:
18601 // if (x & CN)
18602 // y |= CM;
18603 //
18604 // And:
18605 // * CN is a single bit;
18606 // * All bits covered by CM are known zero in y
18607 //
18608 // Then we can convert this into a sequence of BFI instructions. This will
18609 // always be a win if CM is a single bit, will always be no worse than the
18610 // TST&OR sequence if CM is two bits, and for thumb will be no worse if CM is
18611 // three bits (due to the extra IT instruction).
18612
18613 SDValue Op0 = CMOV->getOperand(0);
18614 SDValue Op1 = CMOV->getOperand(1);
18615 auto CC = CMOV->getConstantOperandAPInt(2).getLimitedValue();
18616 SDValue CmpZ = CMOV->getOperand(3);
18617
18618 // The compare must be against zero.
18619 if (!isNullConstant(CmpZ->getOperand(1)))
18620 return SDValue();
18621
18622 assert(CmpZ->getOpcode() == ARMISD::CMPZ);
18623 SDValue And = CmpZ->getOperand(0);
18624 if (And->getOpcode() != ISD::AND)
18625 return SDValue();
18626 const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
18627 if (!AndC)
18628 return SDValue();
18629 SDValue X = And->getOperand(0);
18630
18631 if (CC == ARMCC::EQ) {
18632 // We're performing an "equal to zero" compare. Swap the operands so we
18633 // canonicalize on a "not equal to zero" compare.
18634 std::swap(Op0, Op1);
18635 } else {
18636 assert(CC == ARMCC::NE && "How can a CMPZ node not be EQ or NE?");
18637 }
18638
18639 if (Op1->getOpcode() != ISD::OR)
18640 return SDValue();
18641
18643 if (!OrC)
18644 return SDValue();
18645 SDValue Y = Op1->getOperand(0);
18646
18647 if (Op0 != Y)
18648 return SDValue();
18649
18650 // Now, is it profitable to continue?
18651 APInt OrCI = OrC->getAPIntValue();
18652 unsigned Heuristic = Subtarget->isThumb() ? 3 : 2;
18653 if (OrCI.popcount() > Heuristic)
18654 return SDValue();
18655
18656 // Lastly, can we determine that the bits defined by OrCI
18657 // are zero in Y?
18659 if ((OrCI & Known.Zero) != OrCI)
18660 return SDValue();
18661
18662 // OK, we can do the combine.
18663 SDValue V = Y;
18664 SDLoc dl(X);
18665 EVT VT = X.getValueType();
18666 unsigned BitInX = AndC->logBase2();
18667
18668 if (BitInX != 0) {
18669 // We must shift X first.
18670 X = DAG.getNode(ISD::SRL, dl, VT, X,
18671 DAG.getConstant(BitInX, dl, VT));
18672 }
18673
18674 for (unsigned BitInY = 0, NumActiveBits = OrCI.getActiveBits();
18675 BitInY < NumActiveBits; ++BitInY) {
18676 if (OrCI[BitInY] == 0)
18677 continue;
18678 APInt Mask(VT.getSizeInBits(), 0);
18679 Mask.setBit(BitInY);
18680 V = DAG.getNode(ARMISD::BFI, dl, VT, V, X,
18681 // Confusingly, the operand is an *inverted* mask.
18682 DAG.getConstant(~Mask, dl, VT));
18683 }
18684
18685 return V;
18686}
18687
18688// Given N, the value controlling the conditional branch, search for the loop
18689// intrinsic, returning it, along with how the value is used. We need to handle
18690// patterns such as the following:
18691// (brcond (xor (setcc (loop.decrement), 0, ne), 1), exit)
18692// (brcond (setcc (loop.decrement), 0, eq), exit)
18693// (brcond (setcc (loop.decrement), 0, ne), header)
18695 bool &Negate) {
18696 switch (N->getOpcode()) {
18697 default:
18698 break;
18699 case ISD::XOR: {
18700 if (!isa<ConstantSDNode>(N.getOperand(1)))
18701 return SDValue();
18702 if (!cast<ConstantSDNode>(N.getOperand(1))->isOne())
18703 return SDValue();
18704 Negate = !Negate;
18705 return SearchLoopIntrinsic(N.getOperand(0), CC, Imm, Negate);
18706 }
18707 case ISD::SETCC: {
18708 auto *Const = dyn_cast<ConstantSDNode>(N.getOperand(1));
18709 if (!Const)
18710 return SDValue();
18711 if (Const->isZero())
18712 Imm = 0;
18713 else if (Const->isOne())
18714 Imm = 1;
18715 else
18716 return SDValue();
18717 CC = cast<CondCodeSDNode>(N.getOperand(2))->get();
18718 return SearchLoopIntrinsic(N->getOperand(0), CC, Imm, Negate);
18719 }
18721 unsigned IntOp = N.getConstantOperandVal(1);
18722 if (IntOp != Intrinsic::test_start_loop_iterations &&
18723 IntOp != Intrinsic::loop_decrement_reg)
18724 return SDValue();
18725 return N;
18726 }
18727 }
18728 return SDValue();
18729}
18730
18733 const ARMSubtarget *ST) {
18734
18735 // The hwloop intrinsics that we're interested are used for control-flow,
18736 // either for entering or exiting the loop:
18737 // - test.start.loop.iterations will test whether its operand is zero. If it
18738 // is zero, the proceeding branch should not enter the loop.
18739 // - loop.decrement.reg also tests whether its operand is zero. If it is
18740 // zero, the proceeding branch should not branch back to the beginning of
18741 // the loop.
18742 // So here, we need to check that how the brcond is using the result of each
18743 // of the intrinsics to ensure that we're branching to the right place at the
18744 // right time.
18745
18747 SDValue Cond;
18748 int Imm = 1;
18749 bool Negate = false;
18750 SDValue Chain = N->getOperand(0);
18751 SDValue Dest;
18752
18753 if (N->getOpcode() == ISD::BRCOND) {
18754 CC = ISD::SETEQ;
18755 Cond = N->getOperand(1);
18756 Dest = N->getOperand(2);
18757 } else {
18758 assert(N->getOpcode() == ISD::BR_CC && "Expected BRCOND or BR_CC!");
18759 CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
18760 Cond = N->getOperand(2);
18761 Dest = N->getOperand(4);
18762 if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(3))) {
18763 if (!Const->isOne() && !Const->isZero())
18764 return SDValue();
18765 Imm = Const->getZExtValue();
18766 } else
18767 return SDValue();
18768 }
18769
18771 if (!Int)
18772 return SDValue();
18773
18774 if (Negate)
18775 CC = ISD::getSetCCInverse(CC, /* Integer inverse */ MVT::i32);
18776
18777 auto IsTrueIfZero = [](ISD::CondCode CC, int Imm) {
18778 return (CC == ISD::SETEQ && Imm == 0) ||
18779 (CC == ISD::SETNE && Imm == 1) ||
18780 (CC == ISD::SETLT && Imm == 1) ||
18781 (CC == ISD::SETULT && Imm == 1);
18782 };
18783
18784 auto IsFalseIfZero = [](ISD::CondCode CC, int Imm) {
18785 return (CC == ISD::SETEQ && Imm == 1) ||
18786 (CC == ISD::SETNE && Imm == 0) ||
18787 (CC == ISD::SETGT && Imm == 0) ||
18788 (CC == ISD::SETUGT && Imm == 0) ||
18789 (CC == ISD::SETGE && Imm == 1) ||
18790 (CC == ISD::SETUGE && Imm == 1);
18791 };
18792
18793 assert((IsTrueIfZero(CC, Imm) || IsFalseIfZero(CC, Imm)) &&
18794 "unsupported condition");
18795
18796 SDLoc dl(Int);
18797 SelectionDAG &DAG = DCI.DAG;
18798 SDValue Elements = Int.getOperand(2);
18799 unsigned IntOp = Int->getConstantOperandVal(1);
18800 assert((N->hasOneUse() && N->user_begin()->getOpcode() == ISD::BR) &&
18801 "expected single br user");
18802 SDNode *Br = *N->user_begin();
18803 SDValue OtherTarget = Br->getOperand(1);
18804
18805 // Update the unconditional branch to branch to the given Dest.
18806 auto UpdateUncondBr = [](SDNode *Br, SDValue Dest, SelectionDAG &DAG) {
18807 SDValue NewBrOps[] = { Br->getOperand(0), Dest };
18808 SDValue NewBr = DAG.getNode(ISD::BR, SDLoc(Br), MVT::Other, NewBrOps);
18809 DAG.ReplaceAllUsesOfValueWith(SDValue(Br, 0), NewBr);
18810 };
18811
18812 if (IntOp == Intrinsic::test_start_loop_iterations) {
18813 SDValue Res;
18814 SDValue Setup = DAG.getNode(ARMISD::WLSSETUP, dl, MVT::i32, Elements);
18815 // We expect this 'instruction' to branch when the counter is zero.
18816 if (IsTrueIfZero(CC, Imm)) {
18817 SDValue Ops[] = {Chain, Setup, Dest};
18818 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18819 } else {
18820 // The logic is the reverse of what we need for WLS, so find the other
18821 // basic block target: the target of the proceeding br.
18822 UpdateUncondBr(Br, Dest, DAG);
18823
18824 SDValue Ops[] = {Chain, Setup, OtherTarget};
18825 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18826 }
18827 // Update LR count to the new value
18828 DAG.ReplaceAllUsesOfValueWith(Int.getValue(0), Setup);
18829 // Update chain
18830 DAG.ReplaceAllUsesOfValueWith(Int.getValue(2), Int.getOperand(0));
18831 return Res;
18832 } else {
18833 SDValue Size =
18834 DAG.getTargetConstant(Int.getConstantOperandVal(3), dl, MVT::i32);
18835 SDValue Args[] = { Int.getOperand(0), Elements, Size, };
18836 SDValue LoopDec = DAG.getNode(ARMISD::LOOP_DEC, dl,
18837 DAG.getVTList(MVT::i32, MVT::Other), Args);
18838 DAG.ReplaceAllUsesWith(Int.getNode(), LoopDec.getNode());
18839
18840 // We expect this instruction to branch when the count is not zero.
18841 SDValue Target = IsFalseIfZero(CC, Imm) ? Dest : OtherTarget;
18842
18843 // Update the unconditional branch to target the loop preheader if we've
18844 // found the condition has been reversed.
18845 if (Target == OtherTarget)
18846 UpdateUncondBr(Br, Dest, DAG);
18847
18848 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
18849 SDValue(LoopDec.getNode(), 1), Chain);
18850
18851 SDValue EndArgs[] = { Chain, SDValue(LoopDec.getNode(), 0), Target };
18852 return DAG.getNode(ARMISD::LE, dl, MVT::Other, EndArgs);
18853 }
18854 return SDValue();
18855}
18856
18857/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
18858SDValue
18860 SDValue Cmp = N->getOperand(3);
18861 if (Cmp.getOpcode() != ARMISD::CMPZ)
18862 // Only looking at NE cases.
18863 return SDValue();
18864
18865 SDLoc dl(N);
18866 SDValue LHS = Cmp.getOperand(0);
18867 SDValue RHS = Cmp.getOperand(1);
18868 SDValue Chain = N->getOperand(0);
18869 SDValue BB = N->getOperand(1);
18870 SDValue ARMcc = N->getOperand(2);
18872
18873 // (brcond Chain BB ne (cmpz (and (cmov 0 1 CC Flags) 1) 0))
18874 // -> (brcond Chain BB CC Flags)
18875 if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
18876 LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
18877 LHS->getOperand(0)->hasOneUse() &&
18878 isNullConstant(LHS->getOperand(0)->getOperand(0)) &&
18879 isOneConstant(LHS->getOperand(0)->getOperand(1)) &&
18880 isOneConstant(LHS->getOperand(1)) && isNullConstant(RHS)) {
18881 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, BB,
18882 LHS->getOperand(0)->getOperand(2),
18883 LHS->getOperand(0)->getOperand(3));
18884 }
18885
18886 return SDValue();
18887}
18888
18889/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
18890SDValue
18892 SDLoc dl(N);
18893 EVT VT = N->getValueType(0);
18894 SDValue FalseVal = N->getOperand(0);
18895 SDValue TrueVal = N->getOperand(1);
18896 SDValue ARMcc = N->getOperand(2);
18897 SDValue Cmp = N->getOperand(3);
18898
18899 // Try to form CSINV etc.
18900 unsigned Opcode;
18901 bool InvertCond;
18902 if (SDValue CSetOp =
18903 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
18904 if (InvertCond) {
18905 ARMCC::CondCodes CondCode =
18906 (ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
18907 CondCode = ARMCC::getOppositeCondition(CondCode);
18908 ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
18909 }
18910 return DAG.getNode(Opcode, dl, VT, CSetOp, CSetOp, ARMcc, Cmp);
18911 }
18912
18913 if (Cmp.getOpcode() != ARMISD::CMPZ)
18914 // Only looking at EQ and NE cases.
18915 return SDValue();
18916
18917 SDValue LHS = Cmp.getOperand(0);
18918 SDValue RHS = Cmp.getOperand(1);
18920
18921 // BFI is only available on V6T2+.
18922 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops()) {
18924 if (R)
18925 return R;
18926 }
18927
18928 // Simplify
18929 // mov r1, r0
18930 // cmp r1, x
18931 // mov r0, y
18932 // moveq r0, x
18933 // to
18934 // cmp r0, x
18935 // movne r0, y
18936 //
18937 // mov r1, r0
18938 // cmp r1, x
18939 // mov r0, x
18940 // movne r0, y
18941 // to
18942 // cmp r0, x
18943 // movne r0, y
18944 /// FIXME: Turn this into a target neutral optimization?
18945 SDValue Res;
18946 if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) {
18947 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, Cmp);
18948 } else if (CC == ARMCC::EQ && TrueVal == RHS) {
18949 SDValue ARMcc;
18950 SDValue NewCmp = getARMCmp(LHS, RHS, ISD::SETNE, ARMcc, DAG, dl);
18951 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, FalseVal, ARMcc, NewCmp);
18952 }
18953
18954 // (cmov F T ne (cmpz (cmov 0 1 CC Flags) 0))
18955 // -> (cmov F T CC Flags)
18956 if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse() &&
18957 isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
18958 isNullConstant(RHS)) {
18959 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
18960 LHS->getOperand(2), LHS->getOperand(3));
18961 }
18962
18963 if (!VT.isInteger())
18964 return SDValue();
18965
18966 // Fold away an unnecessary CMPZ/CMOV
18967 // CMOV A, B, C1, (CMPZ (CMOV 1, 0, C2, D), 0) ->
18968 // if C1==EQ -> CMOV A, B, C2, D
18969 // if C1==NE -> CMOV A, B, NOT(C2), D
18970 if (N->getConstantOperandVal(2) == ARMCC::EQ ||
18971 N->getConstantOperandVal(2) == ARMCC::NE) {
18973 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
18974 if (N->getConstantOperandVal(2) == ARMCC::NE)
18976 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
18977 N->getOperand(1),
18978 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
18979 }
18980 }
18981
18982 // Materialize a boolean comparison for integers so we can avoid branching.
18983 if (isNullConstant(FalseVal)) {
18984 if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
18985 if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
18986 // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
18987 // right 5 bits will make that 32 be 1, otherwise it will be 0.
18988 // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
18989 SDValue Value;
18990 if (VT == MVT::i32 && Subtarget->isThumb2() && isNullConstant(RHS) &&
18991 Cmp.hasOneUse())
18992 Value = getShiftedLowMaskZeroTest(LHS, DAG, dl);
18993 if (!Value)
18994 Value = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18995 Res =
18996 DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Value),
18997 DAG.getConstant(5, dl, MVT::i32));
18998 } else {
18999 // CMOV 0, 1, ==, (CMPZ x, y) ->
19000 // (UADDO_CARRY (SUB x, y), t:0, t:1)
19001 // where t = (USUBO_CARRY 0, (SUB x, y), 0)
19002 //
19003 // The USUBO_CARRY computes 0 - (x - y) and this will give a borrow when
19004 // x != y. In other words, a carry C == 1 when x == y, C == 0
19005 // otherwise.
19006 // The final UADDO_CARRY computes
19007 // x - y + (0 - (x - y)) + C == C
19008 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
19009 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
19010 SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
19011 // ISD::USUBO_CARRY returns a borrow but we want the carry here
19012 // actually.
19013 SDValue Carry =
19014 DAG.getNode(ISD::SUB, dl, MVT::i32,
19015 DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
19016 Res = DAG.getNode(ISD::UADDO_CARRY, dl, VTs, Sub, Neg, Carry);
19017 }
19018 } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
19019 (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
19020 // This seems pointless but will allow us to combine it further below.
19021 // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
19022 SDValue Sub =
19023 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
19024 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
19025 Sub.getValue(1));
19026 FalseVal = Sub;
19027 }
19028 } else if (isNullConstant(TrueVal)) {
19029 if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
19030 (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
19031 // This seems pointless but will allow us to combine it further below
19032 // Note that we change == for != as this is the dual for the case above.
19033 // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
19034 SDValue Sub =
19035 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
19036 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
19037 DAG.getConstant(ARMCC::NE, dl, MVT::i32),
19038 Sub.getValue(1));
19039 FalseVal = Sub;
19040 }
19041 }
19042
19043 // On Thumb1, the DAG above may be further combined if z is a power of 2
19044 // (z == 2 ^ K).
19045 // CMOV (SUBC x, y), z, !=, (SUBC x, y):1 ->
19046 // t1 = (USUBO (SUB x, y), 1)
19047 // t2 = (USUBO_CARRY (SUB x, y), t1:0, t1:1)
19048 // Result = if K != 0 then (SHL t2:0, K) else t2:0
19049 //
19050 // This also handles the special case of comparing against zero; it's
19051 // essentially, the same pattern, except there's no SUBC:
19052 // CMOV x, z, !=, (CMPZ x, 0) ->
19053 // t1 = (USUBO x, 1)
19054 // t2 = (USUBO_CARRY x, t1:0, t1:1)
19055 // Result = if K != 0 then (SHL t2:0, K) else t2:0
19056 const APInt *TrueConst;
19057 if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
19058 ((FalseVal.getOpcode() == ARMISD::SUBC && FalseVal.getOperand(0) == LHS &&
19059 FalseVal.getOperand(1) == RHS) ||
19060 (FalseVal == LHS && isNullConstant(RHS))) &&
19061 (TrueConst = isPowerOf2Constant(TrueVal))) {
19062 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
19063 unsigned ShiftAmount = TrueConst->logBase2();
19064 if (ShiftAmount)
19065 TrueVal = DAG.getConstant(1, dl, VT);
19066 SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
19067 Res = DAG.getNode(ISD::USUBO_CARRY, dl, VTs, FalseVal, Subc,
19068 Subc.getValue(1));
19069
19070 if (ShiftAmount)
19071 Res = DAG.getNode(ISD::SHL, dl, VT, Res,
19072 DAG.getConstant(ShiftAmount, dl, MVT::i32));
19073 }
19074
19075 if (Res.getNode()) {
19077 // Capture demanded bits information that would be otherwise lost.
19078 if (Known.Zero == 0xfffffffe)
19079 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
19080 DAG.getValueType(MVT::i1));
19081 else if (Known.Zero == 0xffffff00)
19082 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
19083 DAG.getValueType(MVT::i8));
19084 else if (Known.Zero == 0xffff0000)
19085 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
19086 DAG.getValueType(MVT::i16));
19087 }
19088
19089 return Res;
19090}
19091
19094 const ARMSubtarget *ST) {
19095 SelectionDAG &DAG = DCI.DAG;
19096 SDValue Src = N->getOperand(0);
19097 EVT DstVT = N->getValueType(0);
19098
19099 // Convert v4f32 bitcast (v4i32 vdup (i32)) -> v4f32 vdup (i32) under MVE.
19100 if (ST->hasMVEIntegerOps() && Src.getOpcode() == ARMISD::VDUP) {
19101 EVT SrcVT = Src.getValueType();
19102 if (SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits())
19103 return DAG.getNode(ARMISD::VDUP, SDLoc(N), DstVT, Src.getOperand(0));
19104 }
19105
19106 // We may have a bitcast of something that has already had this bitcast
19107 // combine performed on it, so skip past any VECTOR_REG_CASTs.
19108 if (Src.getOpcode() == ARMISD::VECTOR_REG_CAST &&
19109 Src.getOperand(0).getValueType().getScalarSizeInBits() <=
19110 Src.getValueType().getScalarSizeInBits())
19111 Src = Src.getOperand(0);
19112
19113 // Bitcast from element-wise VMOV or VMVN doesn't need VREV if the VREV that
19114 // would be generated is at least the width of the element type.
19115 EVT SrcVT = Src.getValueType();
19116 if ((Src.getOpcode() == ARMISD::VMOVIMM ||
19117 Src.getOpcode() == ARMISD::VMVNIMM ||
19118 Src.getOpcode() == ARMISD::VMOVFPIMM) &&
19119 SrcVT.getScalarSizeInBits() <= DstVT.getScalarSizeInBits() &&
19120 DAG.getDataLayout().isBigEndian())
19121 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(N), DstVT, Src);
19122
19123 // bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD x
19124 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
19125 return R;
19126
19127 return SDValue();
19128}
19129
19130// Some combines for the MVETrunc truncations legalizer helper. Also lowers the
19131// node into stack operations after legalizeOps.
19134 SelectionDAG &DAG = DCI.DAG;
19135 EVT VT = N->getValueType(0);
19136 SDLoc DL(N);
19137
19138 // MVETrunc(Undef, Undef) -> Undef
19139 if (all_of(N->ops(), [](SDValue Op) { return Op.isUndef(); }))
19140 return DAG.getUNDEF(VT);
19141
19142 // MVETrunc(MVETrunc a b, MVETrunc c, d) -> MVETrunc
19143 if (N->getNumOperands() == 2 &&
19144 N->getOperand(0).getOpcode() == ARMISD::MVETRUNC &&
19145 N->getOperand(1).getOpcode() == ARMISD::MVETRUNC)
19146 return DAG.getNode(ARMISD::MVETRUNC, DL, VT, N->getOperand(0).getOperand(0),
19147 N->getOperand(0).getOperand(1),
19148 N->getOperand(1).getOperand(0),
19149 N->getOperand(1).getOperand(1));
19150
19151 // MVETrunc(shuffle, shuffle) -> VMOVN
19152 if (N->getNumOperands() == 2 &&
19153 N->getOperand(0).getOpcode() == ISD::VECTOR_SHUFFLE &&
19154 N->getOperand(1).getOpcode() == ISD::VECTOR_SHUFFLE) {
19155 auto *S0 = cast<ShuffleVectorSDNode>(N->getOperand(0).getNode());
19156 auto *S1 = cast<ShuffleVectorSDNode>(N->getOperand(1).getNode());
19157
19158 if (S0->getOperand(0) == S1->getOperand(0) &&
19159 S0->getOperand(1) == S1->getOperand(1)) {
19160 // Construct complete shuffle mask
19161 SmallVector<int, 8> Mask(S0->getMask());
19162 Mask.append(S1->getMask().begin(), S1->getMask().end());
19163
19164 if (isVMOVNTruncMask(Mask, VT, false))
19165 return DAG.getNode(
19166 ARMISD::VMOVN, DL, VT,
19167 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
19168 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
19169 DAG.getConstant(1, DL, MVT::i32));
19170 if (isVMOVNTruncMask(Mask, VT, true))
19171 return DAG.getNode(
19172 ARMISD::VMOVN, DL, VT,
19173 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
19174 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
19175 DAG.getConstant(1, DL, MVT::i32));
19176 }
19177 }
19178
19179 // For MVETrunc of a buildvector or shuffle, it can be beneficial to lower the
19180 // truncate to a buildvector to allow the generic optimisations to kick in.
19181 if (all_of(N->ops(), [](SDValue Op) {
19182 return Op.getOpcode() == ISD::BUILD_VECTOR ||
19183 Op.getOpcode() == ISD::VECTOR_SHUFFLE ||
19184 (Op.getOpcode() == ISD::BITCAST &&
19185 Op.getOperand(0).getOpcode() == ISD::BUILD_VECTOR);
19186 })) {
19187 SmallVector<SDValue, 8> Extracts;
19188 for (unsigned Op = 0; Op < N->getNumOperands(); Op++) {
19189 SDValue O = N->getOperand(Op);
19190 for (unsigned i = 0; i < O.getValueType().getVectorNumElements(); i++) {
19191 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, O,
19192 DAG.getConstant(i, DL, MVT::i32));
19193 Extracts.push_back(Ext);
19194 }
19195 }
19196 return DAG.getBuildVector(VT, DL, Extracts);
19197 }
19198
19199 // If we are late in the legalization process and nothing has optimised
19200 // the trunc to anything better, lower it to a stack store and reload,
19201 // performing the truncation whilst keeping the lanes in the correct order:
19202 // VSTRH.32 a, stack; VSTRH.32 b, stack+8; VLDRW.32 stack;
19203 if (!DCI.isAfterLegalizeDAG())
19204 return SDValue();
19205
19206 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19207 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19208 int NumIns = N->getNumOperands();
19209 assert((NumIns == 2 || NumIns == 4) &&
19210 "Expected 2 or 4 inputs to an MVETrunc");
19211 EVT StoreVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
19212 if (N->getNumOperands() == 4)
19213 StoreVT = StoreVT.getHalfNumVectorElementsVT(*DAG.getContext());
19214
19215 SmallVector<SDValue> Chains;
19216 for (int I = 0; I < NumIns; I++) {
19217 SDValue Ptr = DAG.getNode(
19218 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19219 DAG.getConstant(I * 16 / NumIns, DL, StackPtr.getValueType()));
19221 DAG.getMachineFunction(), SPFI, I * 16 / NumIns);
19222 SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), DL, N->getOperand(I),
19223 Ptr, MPI, StoreVT, Align(4));
19224 Chains.push_back(Ch);
19225 }
19226
19227 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
19228 MachinePointerInfo MPI =
19230 return DAG.getLoad(VT, DL, Chain, StackPtr, MPI, Align(4));
19231}
19232
19233// Take a MVEEXT(load x) and split that into (extload x, extload x+8)
19235 SelectionDAG &DAG) {
19236 SDValue N0 = N->getOperand(0);
19238 if (!LD || !LD->isSimple() || !N0.hasOneUse() || LD->isIndexed())
19239 return SDValue();
19240
19241 EVT FromVT = LD->getMemoryVT();
19242 EVT ToVT = N->getValueType(0);
19243 if (!ToVT.isVector())
19244 return SDValue();
19245 assert(FromVT.getVectorNumElements() == ToVT.getVectorNumElements() * 2);
19246 EVT ToEltVT = ToVT.getVectorElementType();
19247 EVT FromEltVT = FromVT.getVectorElementType();
19248
19249 unsigned NumElements = 0;
19250 if (ToEltVT == MVT::i32 && (FromEltVT == MVT::i16 || FromEltVT == MVT::i8))
19251 NumElements = 4;
19252 if (ToEltVT == MVT::i16 && FromEltVT == MVT::i8)
19253 NumElements = 8;
19254 assert(NumElements != 0);
19255
19256 ISD::LoadExtType NewExtType =
19257 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
19258 if (LD->getExtensionType() != ISD::NON_EXTLOAD &&
19259 LD->getExtensionType() != ISD::EXTLOAD &&
19260 LD->getExtensionType() != NewExtType)
19261 return SDValue();
19262
19263 LLVMContext &C = *DAG.getContext();
19264 SDLoc DL(LD);
19265 // Details about the old load
19266 SDValue Ch = LD->getChain();
19267 SDValue BasePtr = LD->getBasePtr();
19268 Align Alignment = LD->getBaseAlign();
19269 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
19270 AAMDNodes AAInfo = LD->getAAInfo();
19271
19272 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
19273 EVT NewFromVT = EVT::getVectorVT(
19274 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
19275 EVT NewToVT = EVT::getVectorVT(
19276 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
19277
19280 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
19281 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
19282 SDValue NewPtr =
19283 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
19284
19285 SDValue NewLoad =
19286 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
19287 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
19288 Alignment, MMOFlags, AAInfo);
19289 Loads.push_back(NewLoad);
19290 Chains.push_back(SDValue(NewLoad.getNode(), 1));
19291 }
19292
19293 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
19294 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
19295 return DAG.getMergeValues(Loads, DL);
19296}
19297
19298// Perform combines for MVEEXT. If it has not be optimized to anything better
19299// before lowering, it gets converted to stack store and extloads performing the
19300// extend whilst still keeping the same lane ordering.
19303 SelectionDAG &DAG = DCI.DAG;
19304 EVT VT = N->getValueType(0);
19305 SDLoc DL(N);
19306 assert(N->getNumValues() == 2 && "Expected MVEEXT with 2 elements");
19307 assert((VT == MVT::v4i32 || VT == MVT::v8i16) && "Unexpected MVEEXT type");
19308
19309 EVT ExtVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19310 *DAG.getContext());
19311 auto Extend = [&](SDValue V) {
19312 SDValue VVT = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, V);
19313 return N->getOpcode() == ARMISD::MVESEXT
19314 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, VVT,
19315 DAG.getValueType(ExtVT))
19316 : DAG.getZeroExtendInReg(VVT, DL, ExtVT);
19317 };
19318
19319 // MVEEXT(VDUP) -> SIGN_EXTEND_INREG(VDUP)
19320 if (N->getOperand(0).getOpcode() == ARMISD::VDUP) {
19321 SDValue Ext = Extend(N->getOperand(0));
19322 return DAG.getMergeValues({Ext, Ext}, DL);
19323 }
19324
19325 // MVEEXT(shuffle) -> SIGN_EXTEND_INREG/ZERO_EXTEND_INREG
19326 if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N->getOperand(0))) {
19327 ArrayRef<int> Mask = SVN->getMask();
19328 assert(Mask.size() == 2 * VT.getVectorNumElements());
19329 assert(Mask.size() == SVN->getValueType(0).getVectorNumElements());
19330 unsigned Rev = VT == MVT::v4i32 ? ARMISD::VREV32 : ARMISD::VREV16;
19331 SDValue Op0 = SVN->getOperand(0);
19332 SDValue Op1 = SVN->getOperand(1);
19333
19334 auto CheckInregMask = [&](int Start, int Offset) {
19335 for (int Idx = 0, E = VT.getVectorNumElements(); Idx < E; ++Idx)
19336 if (Mask[Start + Idx] >= 0 && Mask[Start + Idx] != Idx * 2 + Offset)
19337 return false;
19338 return true;
19339 };
19340 SDValue V0 = SDValue(N, 0);
19341 SDValue V1 = SDValue(N, 1);
19342 if (CheckInregMask(0, 0))
19343 V0 = Extend(Op0);
19344 else if (CheckInregMask(0, 1))
19345 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19346 else if (CheckInregMask(0, Mask.size()))
19347 V0 = Extend(Op1);
19348 else if (CheckInregMask(0, Mask.size() + 1))
19349 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19350
19351 if (CheckInregMask(VT.getVectorNumElements(), Mask.size()))
19352 V1 = Extend(Op1);
19353 else if (CheckInregMask(VT.getVectorNumElements(), Mask.size() + 1))
19354 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19355 else if (CheckInregMask(VT.getVectorNumElements(), 0))
19356 V1 = Extend(Op0);
19357 else if (CheckInregMask(VT.getVectorNumElements(), 1))
19358 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19359
19360 if (V0.getNode() != N || V1.getNode() != N)
19361 return DAG.getMergeValues({V0, V1}, DL);
19362 }
19363
19364 // MVEEXT(load) -> extload, extload
19365 if (N->getOperand(0)->getOpcode() == ISD::LOAD)
19367 return L;
19368
19369 if (!DCI.isAfterLegalizeDAG())
19370 return SDValue();
19371
19372 // Lower to a stack store and reload:
19373 // VSTRW.32 a, stack; VLDRH.32 stack; VLDRH.32 stack+8;
19374 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19375 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19376 int NumOuts = N->getNumValues();
19377 assert((NumOuts == 2 || NumOuts == 4) &&
19378 "Expected 2 or 4 outputs to an MVEEXT");
19379 EVT LoadVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19380 *DAG.getContext());
19381 if (N->getNumOperands() == 4)
19382 LoadVT = LoadVT.getHalfNumVectorElementsVT(*DAG.getContext());
19383
19384 MachinePointerInfo MPI =
19386 SDValue Chain = DAG.getStore(DAG.getEntryNode(), DL, N->getOperand(0),
19387 StackPtr, MPI, Align(4));
19388
19390 for (int I = 0; I < NumOuts; I++) {
19391 SDValue Ptr = DAG.getNode(
19392 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19393 DAG.getConstant(I * 16 / NumOuts, DL, StackPtr.getValueType()));
19395 DAG.getMachineFunction(), SPFI, I * 16 / NumOuts);
19396 SDValue Load = DAG.getExtLoad(
19397 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD, DL,
19398 VT, Chain, Ptr, MPI, LoadVT, Align(4));
19399 Loads.push_back(Load);
19400 }
19401
19402 return DAG.getMergeValues(Loads, DL);
19403}
19404
19406 DAGCombinerInfo &DCI) const {
19407 switch (N->getOpcode()) {
19408 default: break;
19409 case ISD::SELECT_CC:
19410 case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
19411 case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
19412 case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
19413 case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
19414 case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
19415 case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget);
19416 case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget);
19417 case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget);
19418 case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
19419 case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
19420 case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
19421 case ISD::BRCOND:
19422 case ISD::BR_CC: return PerformHWLoopCombine(N, DCI, Subtarget);
19423 case ARMISD::ADDC:
19424 case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
19425 case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI, Subtarget);
19426 case ARMISD::BFI: return PerformBFICombine(N, DCI.DAG);
19427 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
19428 case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG);
19429 case ARMISD::VMOVhr: return PerformVMOVhrCombine(N, DCI);
19430 case ARMISD::VMOVrh: return PerformVMOVrhCombine(N, DCI.DAG);
19431 case ISD::STORE: return PerformSTORECombine(N, DCI, Subtarget);
19432 case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI, Subtarget);
19435 return PerformExtractEltCombine(N, DCI, Subtarget);
19439 case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI, Subtarget);
19440 case ARMISD::VDUP: return PerformVDUPCombine(N, DCI.DAG, Subtarget);
19441 case ISD::FP_TO_SINT:
19442 case ISD::FP_TO_UINT:
19443 return PerformVCVTCombine(N, DCI.DAG, Subtarget);
19444 case ISD::FADD:
19445 return PerformFADDCombine(N, DCI.DAG, Subtarget);
19446 case ISD::FMUL:
19447 return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget);
19449 return PerformIntrinsicCombine(N, DCI);
19450 case ISD::SHL:
19451 case ISD::SRA:
19452 case ISD::SRL:
19453 return PerformShiftCombine(N, DCI, Subtarget);
19454 case ISD::SIGN_EXTEND:
19455 case ISD::ZERO_EXTEND:
19456 case ISD::ANY_EXTEND:
19457 return PerformExtendCombine(N, DCI.DAG, Subtarget);
19458 case ISD::FP_EXTEND:
19459 return PerformFPExtendCombine(N, DCI.DAG, Subtarget);
19460 case ISD::SMIN:
19461 case ISD::UMIN:
19462 case ISD::SMAX:
19463 case ISD::UMAX:
19464 return PerformMinMaxCombine(N, DCI.DAG, Subtarget);
19465 case ARMISD::CMOV:
19466 return PerformCMOVCombine(N, DCI.DAG);
19467 case ARMISD::BRCOND:
19468 return PerformBRCONDCombine(N, DCI.DAG);
19469 case ARMISD::CMPZ:
19470 return PerformCMPZCombine(N, DCI.DAG);
19471 case ARMISD::CSINC:
19472 case ARMISD::CSINV:
19473 case ARMISD::CSNEG:
19474 return PerformCSETCombine(N, DCI.DAG);
19475 case ISD::LOAD:
19476 return PerformLOADCombine(N, DCI, Subtarget);
19478 return PerformVECTOR_DEINTERLEAVECombine(N, DCI, Subtarget);
19479 case ARMISD::VLD1DUP:
19480 case ARMISD::VLD2DUP:
19481 case ARMISD::VLD3DUP:
19482 case ARMISD::VLD4DUP:
19483 return PerformVLDCombine(N, DCI);
19485 return PerformARMBUILD_VECTORCombine(N, DCI);
19486 case ISD::BITCAST:
19487 return PerformBITCASTCombine(N, DCI, Subtarget);
19488 case ARMISD::PREDICATE_CAST:
19489 return PerformPREDICATE_CASTCombine(N, DCI);
19490 case ARMISD::VECTOR_REG_CAST:
19491 return PerformVECTOR_REG_CASTCombine(N, DCI.DAG, Subtarget);
19492 case ARMISD::MVETRUNC:
19493 return PerformMVETruncCombine(N, DCI);
19494 case ARMISD::MVESEXT:
19495 case ARMISD::MVEZEXT:
19496 return PerformMVEExtCombine(N, DCI);
19497 case ARMISD::VCMP:
19498 return PerformVCMPCombine(N, DCI.DAG, Subtarget);
19499 case ISD::VECREDUCE_ADD:
19500 return PerformVECREDUCE_ADDCombine(N, DCI.DAG, Subtarget);
19501 case ARMISD::VADDVs:
19502 case ARMISD::VADDVu:
19503 case ARMISD::VADDLVs:
19504 case ARMISD::VADDLVu:
19505 case ARMISD::VADDLVAs:
19506 case ARMISD::VADDLVAu:
19507 case ARMISD::VMLAVs:
19508 case ARMISD::VMLAVu:
19509 case ARMISD::VMLALVs:
19510 case ARMISD::VMLALVu:
19511 case ARMISD::VMLALVAs:
19512 case ARMISD::VMLALVAu:
19513 return PerformReduceShuffleCombine(N, DCI.DAG);
19514 case ARMISD::VMOVN:
19515 return PerformVMOVNCombine(N, DCI);
19516 case ARMISD::VQMOVNs:
19517 case ARMISD::VQMOVNu:
19518 return PerformVQMOVNCombine(N, DCI);
19519 case ARMISD::VQDMULH:
19520 return PerformVQDMULHCombine(N, DCI);
19521 case ARMISD::ASRL:
19522 case ARMISD::LSRL:
19523 case ARMISD::LSLL:
19524 return PerformLongShiftCombine(N, DCI.DAG);
19525 case ARMISD::SMULWB: {
19526 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19527 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19528 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19529 return SDValue();
19530 break;
19531 }
19532 case ARMISD::SMULWT: {
19533 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19534 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19535 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19536 return SDValue();
19537 break;
19538 }
19539 case ARMISD::SMLALBB:
19540 case ARMISD::QADD16b:
19541 case ARMISD::QSUB16b:
19542 case ARMISD::UQADD16b:
19543 case ARMISD::UQSUB16b: {
19544 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19545 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19546 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19547 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19548 return SDValue();
19549 break;
19550 }
19551 case ARMISD::SMLALBT: {
19552 unsigned LowWidth = N->getOperand(0).getValueType().getSizeInBits();
19553 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19554 unsigned HighWidth = N->getOperand(1).getValueType().getSizeInBits();
19555 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19556 if ((SimplifyDemandedBits(N->getOperand(0), LowMask, DCI)) ||
19557 (SimplifyDemandedBits(N->getOperand(1), HighMask, DCI)))
19558 return SDValue();
19559 break;
19560 }
19561 case ARMISD::SMLALTB: {
19562 unsigned HighWidth = N->getOperand(0).getValueType().getSizeInBits();
19563 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19564 unsigned LowWidth = N->getOperand(1).getValueType().getSizeInBits();
19565 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19566 if ((SimplifyDemandedBits(N->getOperand(0), HighMask, DCI)) ||
19567 (SimplifyDemandedBits(N->getOperand(1), LowMask, DCI)))
19568 return SDValue();
19569 break;
19570 }
19571 case ARMISD::SMLALTT: {
19572 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19573 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19574 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19575 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19576 return SDValue();
19577 break;
19578 }
19579 case ARMISD::QADD8b:
19580 case ARMISD::QSUB8b:
19581 case ARMISD::UQADD8b:
19582 case ARMISD::UQSUB8b: {
19583 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19584 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
19585 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19586 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19587 return SDValue();
19588 break;
19589 }
19590 case ARMISD::VBSP:
19591 if (N->getOperand(1) == N->getOperand(2))
19592 return N->getOperand(1);
19593 return SDValue();
19596 switch (N->getConstantOperandVal(1)) {
19597 case Intrinsic::arm_neon_vld1:
19598 case Intrinsic::arm_neon_vld1x2:
19599 case Intrinsic::arm_neon_vld1x3:
19600 case Intrinsic::arm_neon_vld1x4:
19601 case Intrinsic::arm_neon_vld2:
19602 case Intrinsic::arm_neon_vld3:
19603 case Intrinsic::arm_neon_vld4:
19604 case Intrinsic::arm_neon_vld2lane:
19605 case Intrinsic::arm_neon_vld3lane:
19606 case Intrinsic::arm_neon_vld4lane:
19607 case Intrinsic::arm_neon_vld2dup:
19608 case Intrinsic::arm_neon_vld3dup:
19609 case Intrinsic::arm_neon_vld4dup:
19610 case Intrinsic::arm_neon_vst1:
19611 case Intrinsic::arm_neon_vst1x2:
19612 case Intrinsic::arm_neon_vst1x3:
19613 case Intrinsic::arm_neon_vst1x4:
19614 case Intrinsic::arm_neon_vst2:
19615 case Intrinsic::arm_neon_vst3:
19616 case Intrinsic::arm_neon_vst4:
19617 case Intrinsic::arm_neon_vst2lane:
19618 case Intrinsic::arm_neon_vst3lane:
19619 case Intrinsic::arm_neon_vst4lane:
19620 return PerformVLDCombine(N, DCI);
19621 case Intrinsic::arm_mve_vld2q:
19622 case Intrinsic::arm_mve_vld4q:
19623 case Intrinsic::arm_mve_vst2q:
19624 case Intrinsic::arm_mve_vst4q:
19625 return PerformMVEVLDCombine(N, DCI);
19626 default: break;
19627 }
19628 break;
19629 }
19630 return SDValue();
19631}
19632
19634 EVT VT) const {
19635 return (VT == MVT::f32) && (Opc == ISD::LOAD || Opc == ISD::STORE);
19636}
19637
19639 Align Alignment,
19641 unsigned *Fast) const {
19642 // Depends what it gets converted into if the type is weird.
19643 if (!VT.isSimple())
19644 return false;
19645
19646 // The AllowsUnaligned flag models the SCTLR.A setting in ARM cpus
19647 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
19648 auto Ty = VT.getSimpleVT().SimpleTy;
19649
19650 if (Ty == MVT::i8 || Ty == MVT::i16 || Ty == MVT::i32) {
19651 // Unaligned access can use (for example) LRDB, LRDH, LDR
19652 if (AllowsUnaligned) {
19653 if (Fast)
19654 *Fast = Subtarget->hasV7Ops();
19655 return true;
19656 }
19657 }
19658
19659 if (Ty == MVT::f64 || Ty == MVT::v2f64) {
19660 // For any little-endian targets with neon, we can support unaligned ld/st
19661 // of D and Q (e.g. {D0,D1}) registers by using vld1.i8/vst1.i8.
19662 // A big-endian target may also explicitly support unaligned accesses
19663 if (Subtarget->hasNEON() && (AllowsUnaligned || Subtarget->isLittle())) {
19664 if (Fast)
19665 *Fast = 1;
19666 return true;
19667 }
19668 }
19669
19670 if (!Subtarget->hasMVEIntegerOps())
19671 return false;
19672
19673 // These are for predicates
19674 if ((Ty == MVT::v16i1 || Ty == MVT::v8i1 || Ty == MVT::v4i1 ||
19675 Ty == MVT::v2i1)) {
19676 if (Fast)
19677 *Fast = 1;
19678 return true;
19679 }
19680
19681 // These are for truncated stores/narrowing loads. They are fine so long as
19682 // the alignment is at least the size of the item being loaded
19683 if ((Ty == MVT::v4i8 || Ty == MVT::v8i8 || Ty == MVT::v4i16) &&
19684 Alignment >= VT.getScalarSizeInBits() / 8) {
19685 if (Fast)
19686 *Fast = true;
19687 return true;
19688 }
19689
19690 // In little-endian MVE, the store instructions VSTRB.U8, VSTRH.U16 and
19691 // VSTRW.U32 all store the vector register in exactly the same format, and
19692 // differ only in the range of their immediate offset field and the required
19693 // alignment. So there is always a store that can be used, regardless of
19694 // actual type.
19695 //
19696 // For big endian, that is not the case. But can still emit a (VSTRB.U8;
19697 // VREV64.8) pair and get the same effect. This will likely be better than
19698 // aligning the vector through the stack.
19699 if (Ty == MVT::v16i8 || Ty == MVT::v8i16 || Ty == MVT::v8f16 ||
19700 Ty == MVT::v4i32 || Ty == MVT::v4f32 || Ty == MVT::v2i64 ||
19701 Ty == MVT::v2f64) {
19702 if (Fast)
19703 *Fast = 1;
19704 return true;
19705 }
19706
19707 return false;
19708}
19709
19711 LLVMContext &Context, const MemOp &Op,
19712 const AttributeList &FuncAttributes) const {
19713 // See if we can use NEON instructions for this...
19714 if ((Op.isMemcpyOrMemmove() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
19715 !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
19716 unsigned Fast;
19717 if (Op.size() >= 16 &&
19718 (Op.isAligned(Align(16)) ||
19719 (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
19721 Fast))) {
19722 return MVT::v2f64;
19723 } else if (Op.size() >= 8 &&
19724 (Op.isAligned(Align(8)) ||
19726 MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
19727 Fast))) {
19728 return MVT::f64;
19729 }
19730 }
19731
19732 // Let the target-independent logic figure it out.
19733 return MVT::Other;
19734}
19735
19736// 64-bit integers are split into their high and low parts and held in two
19737// different registers, so the trunc is free since the low register can just
19738// be used.
19739bool ARMTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
19740 if (!SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
19741 return false;
19742 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
19743 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
19744 return (SrcBits == 64 && DestBits == 32);
19745}
19746
19748 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
19749 !DstVT.isInteger())
19750 return false;
19751 unsigned SrcBits = SrcVT.getSizeInBits();
19752 unsigned DestBits = DstVT.getSizeInBits();
19753 return (SrcBits == 64 && DestBits == 32);
19754}
19755
19757 if (Val.getOpcode() != ISD::LOAD)
19758 return false;
19759
19760 EVT VT1 = Val.getValueType();
19761 if (!VT1.isSimple() || !VT1.isInteger() ||
19762 !VT2.isSimple() || !VT2.isInteger())
19763 return false;
19764
19765 switch (VT1.getSimpleVT().SimpleTy) {
19766 default: break;
19767 case MVT::i1:
19768 case MVT::i8:
19769 case MVT::i16:
19770 // 8-bit and 16-bit loads implicitly zero-extend to 32-bits.
19771 return true;
19772 }
19773
19774 return false;
19775}
19776
19778 if (!VT.isSimple())
19779 return false;
19780
19781 // There are quite a few FP16 instructions (e.g. VNMLA, VNMLS, etc.) that
19782 // negate values directly (fneg is free). So, we don't want to let the DAG
19783 // combiner rewrite fneg into xors and some other instructions. For f16 and
19784 // FullFP16 argument passing, some bitcast nodes may be introduced,
19785 // triggering this DAG combine rewrite, so we are avoiding that with this.
19786 switch (VT.getSimpleVT().SimpleTy) {
19787 default: break;
19788 case MVT::f16:
19789 return Subtarget->hasFullFP16();
19790 }
19791
19792 return false;
19793}
19794
19796 if (!Subtarget->hasMVEIntegerOps())
19797 return nullptr;
19798 Type *SVIType = SVI->getType();
19799 Type *ScalarType = SVIType->getScalarType();
19800
19801 if (ScalarType->isFloatTy())
19802 return Type::getInt32Ty(SVIType->getContext());
19803 if (ScalarType->isHalfTy())
19804 return Type::getInt16Ty(SVIType->getContext());
19805 return nullptr;
19806}
19807
19809 EVT VT = ExtVal.getValueType();
19810
19811 if (!isTypeLegal(VT))
19812 return false;
19813
19814 if (auto *Ld = dyn_cast<MaskedLoadSDNode>(ExtVal.getOperand(0))) {
19815 if (Ld->isExpandingLoad())
19816 return false;
19817 }
19818
19819 if (Subtarget->hasMVEIntegerOps())
19820 return true;
19821
19822 // Don't create a loadext if we can fold the extension into a wide/long
19823 // instruction.
19824 // If there's more than one user instruction, the loadext is desirable no
19825 // matter what. There can be two uses by the same instruction.
19826 if (ExtVal->use_empty() ||
19827 !ExtVal->user_begin()->isOnlyUserOf(ExtVal.getNode()))
19828 return true;
19829
19830 SDNode *U = *ExtVal->user_begin();
19831 if ((U->getOpcode() == ISD::ADD || U->getOpcode() == ISD::SUB ||
19832 U->getOpcode() == ISD::SHL || U->getOpcode() == ARMISD::VSHLIMM))
19833 return false;
19834
19835 return true;
19836}
19837
19839 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
19840 return false;
19841
19842 if (!isTypeLegal(EVT::getEVT(Ty1)))
19843 return false;
19844
19845 assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");
19846
19847 // Assuming the caller doesn't have a zeroext or signext return parameter,
19848 // truncation all the way down to i1 is valid.
19849 return true;
19850}
19851
19852/// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
19853/// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
19854/// expanded to FMAs when this method returns true, otherwise fmuladd is
19855/// expanded to fmul + fadd.
19856///
19857/// ARM supports both fused and unfused multiply-add operations; we already
19858/// lower a pair of fmul and fadd to the latter so it's not clear that there
19859/// would be a gain or that the gain would be worthwhile enough to risk
19860/// correctness bugs.
19861///
19862/// For MVE, we set this to true as it helps simplify the need for some
19863/// patterns (and we don't have the non-fused floating point instruction).
19864bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
19865 EVT VT) const {
19866 if (Subtarget->useSoftFloat())
19867 return false;
19868
19869 if (!VT.isSimple())
19870 return false;
19871
19872 switch (VT.getSimpleVT().SimpleTy) {
19873 case MVT::v4f32:
19874 case MVT::v8f16:
19875 return Subtarget->hasMVEFloatOps();
19876 case MVT::f16:
19877 return Subtarget->useFPVFMx16();
19878 case MVT::f32:
19879 return Subtarget->useFPVFMx();
19880 case MVT::f64:
19881 return Subtarget->useFPVFMx64();
19882 default:
19883 break;
19884 }
19885
19886 return false;
19887}
19888
19889static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
19890 if (V < 0)
19891 return false;
19892
19893 unsigned Scale = 1;
19894 switch (VT.getSimpleVT().SimpleTy) {
19895 case MVT::i1:
19896 case MVT::i8:
19897 // Scale == 1;
19898 break;
19899 case MVT::i16:
19900 // Scale == 2;
19901 Scale = 2;
19902 break;
19903 default:
19904 // On thumb1 we load most things (i32, i64, floats, etc) with a LDR
19905 // Scale == 4;
19906 Scale = 4;
19907 break;
19908 }
19909
19910 if ((V & (Scale - 1)) != 0)
19911 return false;
19912 return isUInt<5>(V / Scale);
19913}
19914
19915static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
19916 const ARMSubtarget *Subtarget) {
19917 if (!VT.isInteger() && !VT.isFloatingPoint())
19918 return false;
19919 if (VT.isVector() && Subtarget->hasNEON())
19920 return false;
19921 if (VT.isVector() && VT.isFloatingPoint() && Subtarget->hasMVEIntegerOps() &&
19922 !Subtarget->hasMVEFloatOps())
19923 return false;
19924
19925 bool IsNeg = false;
19926 if (V < 0) {
19927 IsNeg = true;
19928 V = -V;
19929 }
19930
19931 unsigned NumBytes = std::max((unsigned)VT.getSizeInBits() / 8, 1U);
19932
19933 // MVE: size * imm7
19934 if (VT.isVector() && Subtarget->hasMVEIntegerOps()) {
19935 switch (VT.getSimpleVT().getVectorElementType().SimpleTy) {
19936 case MVT::i32:
19937 case MVT::f32:
19938 return isShiftedUInt<7,2>(V);
19939 case MVT::i16:
19940 case MVT::f16:
19941 return isShiftedUInt<7,1>(V);
19942 case MVT::i8:
19943 return isUInt<7>(V);
19944 default:
19945 return false;
19946 }
19947 }
19948
19949 // half VLDR: 2 * imm8
19950 if (VT.isFloatingPoint() && NumBytes == 2 && Subtarget->hasFPRegs16())
19951 return isShiftedUInt<8, 1>(V);
19952 // VLDR and LDRD: 4 * imm8
19953 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
19954 return isShiftedUInt<8, 2>(V);
19955
19956 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
19957 // + imm12 or - imm8
19958 if (IsNeg)
19959 return isUInt<8>(V);
19960 return isUInt<12>(V);
19961 }
19962
19963 return false;
19964}
19965
19966/// isLegalAddressImmediate - Return true if the integer value can be used
19967/// as the offset of the target addressing mode for load / store of the
19968/// given type.
19969static bool isLegalAddressImmediate(int64_t V, EVT VT,
19970 const ARMSubtarget *Subtarget) {
19971 if (V == 0)
19972 return true;
19973
19974 if (!VT.isSimple())
19975 return false;
19976
19977 if (Subtarget->isThumb1Only())
19978 return isLegalT1AddressImmediate(V, VT);
19979 else if (Subtarget->isThumb2())
19980 return isLegalT2AddressImmediate(V, VT, Subtarget);
19981
19982 // ARM mode.
19983 if (V < 0)
19984 V = - V;
19985 switch (VT.getSimpleVT().SimpleTy) {
19986 default: return false;
19987 case MVT::i1:
19988 case MVT::i8:
19989 case MVT::i32:
19990 // +- imm12
19991 return isUInt<12>(V);
19992 case MVT::i16:
19993 // +- imm8
19994 return isUInt<8>(V);
19995 case MVT::f32:
19996 case MVT::f64:
19997 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
19998 return false;
19999 return isShiftedUInt<8, 2>(V);
20000 }
20001}
20002
20004 EVT VT) const {
20005 int Scale = AM.Scale;
20006 if (Scale < 0)
20007 return false;
20008
20009 switch (VT.getSimpleVT().SimpleTy) {
20010 default: return false;
20011 case MVT::i1:
20012 case MVT::i8:
20013 case MVT::i16:
20014 case MVT::i32:
20015 if (Scale == 1)
20016 return true;
20017 // r + r << imm
20018 Scale = Scale & ~1;
20019 return Scale == 2 || Scale == 4 || Scale == 8;
20020 case MVT::i64:
20021 // FIXME: What are we trying to model here? ldrd doesn't have an r + r
20022 // version in Thumb mode.
20023 // r + r
20024 if (Scale == 1)
20025 return true;
20026 // r * 2 (this can be lowered to r + r).
20027 if (!AM.HasBaseReg && Scale == 2)
20028 return true;
20029 return false;
20030 case MVT::isVoid:
20031 // Note, we allow "void" uses (basically, uses that aren't loads or
20032 // stores), because arm allows folding a scale into many arithmetic
20033 // operations. This should be made more precise and revisited later.
20034
20035 // Allow r << imm, but the imm has to be a multiple of two.
20036 if (Scale & 1) return false;
20037 return isPowerOf2_32(Scale);
20038 }
20039}
20040
20042 EVT VT) const {
20043 const int Scale = AM.Scale;
20044
20045 // Negative scales are not supported in Thumb1.
20046 if (Scale < 0)
20047 return false;
20048
20049 // Thumb1 addressing modes do not support register scaling excepting the
20050 // following cases:
20051 // 1. Scale == 1 means no scaling.
20052 // 2. Scale == 2 this can be lowered to r + r if there is no base register.
20053 return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
20054}
20055
20056/// isLegalAddressingMode - Return true if the addressing mode represented
20057/// by AM is legal for this target, for a load/store of the specified type.
20059 const AddrMode &AM, Type *Ty,
20060 unsigned AS, Instruction *I) const {
20061 EVT VT = getValueType(DL, Ty, true);
20062 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget))
20063 return false;
20064
20065 // Can never fold addr of global into load/store.
20066 if (AM.BaseGV)
20067 return false;
20068
20069 switch (AM.Scale) {
20070 case 0: // no scale reg, must be "r+i" or "r", or "i".
20071 break;
20072 default:
20073 // ARM doesn't support any R+R*scale+imm addr modes.
20074 if (AM.BaseOffs)
20075 return false;
20076
20077 if (!VT.isSimple())
20078 return false;
20079
20080 if (Subtarget->isThumb1Only())
20081 return isLegalT1ScaledAddressingMode(AM, VT);
20082
20083 if (Subtarget->isThumb2())
20084 return isLegalT2ScaledAddressingMode(AM, VT);
20085
20086 int Scale = AM.Scale;
20087 switch (VT.getSimpleVT().SimpleTy) {
20088 default: return false;
20089 case MVT::i1:
20090 case MVT::i8:
20091 case MVT::i32:
20092 if (Scale < 0) Scale = -Scale;
20093 if (Scale == 1)
20094 return true;
20095 // r + r << imm
20096 return isPowerOf2_32(Scale & ~1);
20097 case MVT::i16:
20098 case MVT::i64:
20099 // r +/- r
20100 if (Scale == 1 || (AM.HasBaseReg && Scale == -1))
20101 return true;
20102 // r * 2 (this can be lowered to r + r).
20103 if (!AM.HasBaseReg && Scale == 2)
20104 return true;
20105 return false;
20106
20107 case MVT::isVoid:
20108 // Note, we allow "void" uses (basically, uses that aren't loads or
20109 // stores), because arm allows folding a scale into many arithmetic
20110 // operations. This should be made more precise and revisited later.
20111
20112 // Allow r << imm, but the imm has to be a multiple of two.
20113 if (Scale & 1) return false;
20114 return isPowerOf2_32(Scale);
20115 }
20116 }
20117 return true;
20118}
20119
20120/// isLegalICmpImmediate - Return true if the specified immediate is legal
20121/// icmp immediate, that is the target has icmp instructions which can compare
20122/// a register against the immediate without having to materialize the
20123/// immediate into a register.
20125 // Thumb2 and ARM modes can use cmn for negative immediates.
20126 if (!Subtarget->isThumb())
20127 return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
20129 if (Subtarget->isThumb2())
20130 return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
20132 // Thumb1 doesn't have cmn, and only 8-bit immediates.
20133 return Imm >= 0 && Imm <= 255;
20134}
20135
20136/// isLegalAddImmediate - Return true if the specified immediate is a legal add
20137/// *or sub* immediate, that is the target has add or sub instructions which can
20138/// add a register with the immediate without having to materialize the
20139/// immediate into a register.
20141 // Same encoding for add/sub, just flip the sign.
20142 uint64_t AbsImm = AbsoluteValue(Imm);
20143 if (!Subtarget->isThumb())
20144 return ARM_AM::getSOImmVal(AbsImm) != -1;
20145 if (Subtarget->isThumb2())
20146 return ARM_AM::getT2SOImmVal(AbsImm) != -1;
20147 // Thumb1 only has 8-bit unsigned immediate.
20148 return AbsImm <= 255;
20149}
20150
20151// Return false to prevent folding
20152// (mul (add r, c0), c1) -> (add (mul r, c1), c0*c1) in DAGCombine,
20153// if the folding leads to worse code.
20155 SDValue ConstNode) const {
20156 // Let the DAGCombiner decide for vector types and large types.
20157 const EVT VT = AddNode.getValueType();
20158 if (VT.isVector() || VT.getScalarSizeInBits() > 32)
20159 return true;
20160
20161 // It is worse if c0 is legal add immediate, while c1*c0 is not
20162 // and has to be composed by at least two instructions.
20163 const ConstantSDNode *C0Node = cast<ConstantSDNode>(AddNode.getOperand(1));
20164 const ConstantSDNode *C1Node = cast<ConstantSDNode>(ConstNode);
20165 const int64_t C0 = C0Node->getSExtValue();
20166 APInt CA = C0Node->getAPIntValue() * C1Node->getAPIntValue();
20168 return true;
20169 if (ConstantMaterializationCost((unsigned)CA.getZExtValue(), Subtarget) > 1)
20170 return false;
20171
20172 // Default to true and let the DAGCombiner decide.
20173 return true;
20174}
20175
20177 bool isSEXTLoad, SDValue &Base,
20178 SDValue &Offset, bool &isInc,
20179 SelectionDAG &DAG) {
20180 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
20181 return false;
20182
20183 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
20184 // AddressingMode 3
20185 Base = Ptr->getOperand(0);
20187 int RHSC = (int)RHS->getZExtValue();
20188 if (RHSC < 0 && RHSC > -256) {
20189 assert(Ptr->getOpcode() == ISD::ADD);
20190 isInc = false;
20191 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20192 return true;
20193 }
20194 }
20195 isInc = (Ptr->getOpcode() == ISD::ADD);
20196 Offset = Ptr->getOperand(1);
20197 return true;
20198 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
20199 // AddressingMode 2
20201 int RHSC = (int)RHS->getZExtValue();
20202 if (RHSC < 0 && RHSC > -0x1000) {
20203 assert(Ptr->getOpcode() == ISD::ADD);
20204 isInc = false;
20205 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20206 Base = Ptr->getOperand(0);
20207 return true;
20208 }
20209 }
20210
20211 if (Ptr->getOpcode() == ISD::ADD) {
20212 isInc = true;
20213 ARM_AM::ShiftOpc ShOpcVal=
20215 if (ShOpcVal != ARM_AM::no_shift) {
20216 Base = Ptr->getOperand(1);
20217 Offset = Ptr->getOperand(0);
20218 } else {
20219 Base = Ptr->getOperand(0);
20220 Offset = Ptr->getOperand(1);
20221 }
20222 return true;
20223 }
20224
20225 isInc = (Ptr->getOpcode() == ISD::ADD);
20226 Base = Ptr->getOperand(0);
20227 Offset = Ptr->getOperand(1);
20228 return true;
20229 }
20230
20231 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
20232 return false;
20233}
20234
20236 bool isSEXTLoad, SDValue &Base,
20237 SDValue &Offset, bool &isInc,
20238 SelectionDAG &DAG) {
20239 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
20240 return false;
20241
20242 Base = Ptr->getOperand(0);
20244 int RHSC = (int)RHS->getZExtValue();
20245 if (RHSC < 0 && RHSC > -0x100) { // 8 bits.
20246 assert(Ptr->getOpcode() == ISD::ADD);
20247 isInc = false;
20248 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20249 return true;
20250 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero.
20251 isInc = Ptr->getOpcode() == ISD::ADD;
20252 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
20253 return true;
20254 }
20255 }
20256
20257 return false;
20258}
20259
20260static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment,
20261 bool isSEXTLoad, bool IsMasked, bool isLE,
20263 bool &isInc, SelectionDAG &DAG) {
20264 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
20265 return false;
20266 if (!isa<ConstantSDNode>(Ptr->getOperand(1)))
20267 return false;
20268
20269 // We allow LE non-masked loads to change the type (for example use a vldrb.8
20270 // as opposed to a vldrw.32). This can allow extra addressing modes or
20271 // alignments for what is otherwise an equivalent instruction.
20272 bool CanChangeType = isLE && !IsMasked;
20273
20275 int RHSC = (int)RHS->getZExtValue();
20276
20277 auto IsInRange = [&](int RHSC, int Limit, int Scale) {
20278 if (RHSC < 0 && RHSC > -Limit * Scale && RHSC % Scale == 0) {
20279 assert(Ptr->getOpcode() == ISD::ADD);
20280 isInc = false;
20281 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20282 return true;
20283 } else if (RHSC > 0 && RHSC < Limit * Scale && RHSC % Scale == 0) {
20284 isInc = Ptr->getOpcode() == ISD::ADD;
20285 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
20286 return true;
20287 }
20288 return false;
20289 };
20290
20291 // Try to find a matching instruction based on s/zext, Alignment, Offset and
20292 // (in BE/masked) type.
20293 Base = Ptr->getOperand(0);
20294 if (VT == MVT::v4i16) {
20295 if (Alignment >= 2 && IsInRange(RHSC, 0x80, 2))
20296 return true;
20297 } else if (VT == MVT::v4i8 || VT == MVT::v8i8) {
20298 if (IsInRange(RHSC, 0x80, 1))
20299 return true;
20300 } else if (Alignment >= 4 &&
20301 (CanChangeType || VT == MVT::v4i32 || VT == MVT::v4f32) &&
20302 IsInRange(RHSC, 0x80, 4))
20303 return true;
20304 else if (Alignment >= 2 &&
20305 (CanChangeType || VT == MVT::v8i16 || VT == MVT::v8f16) &&
20306 IsInRange(RHSC, 0x80, 2))
20307 return true;
20308 else if ((CanChangeType || VT == MVT::v16i8) && IsInRange(RHSC, 0x80, 1))
20309 return true;
20310 return false;
20311}
20312
20313/// getPreIndexedAddressParts - returns true by value, base pointer and
20314/// offset pointer and addressing mode by reference if the node's address
20315/// can be legally represented as pre-indexed load / store address.
20316bool
20318 SDValue &Offset,
20320 SelectionDAG &DAG) const {
20321 if (Subtarget->isThumb1Only())
20322 return false;
20323
20324 EVT VT;
20325 SDValue Ptr;
20326 Align Alignment;
20327 unsigned AS = 0;
20328 bool isSEXTLoad = false;
20329 bool IsMasked = false;
20330 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20331 Ptr = LD->getBasePtr();
20332 VT = LD->getMemoryVT();
20333 Alignment = LD->getAlign();
20334 AS = LD->getAddressSpace();
20335 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20336 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20337 Ptr = ST->getBasePtr();
20338 VT = ST->getMemoryVT();
20339 Alignment = ST->getAlign();
20340 AS = ST->getAddressSpace();
20341 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20342 Ptr = LD->getBasePtr();
20343 VT = LD->getMemoryVT();
20344 Alignment = LD->getAlign();
20345 AS = LD->getAddressSpace();
20346 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20347 IsMasked = true;
20349 Ptr = ST->getBasePtr();
20350 VT = ST->getMemoryVT();
20351 Alignment = ST->getAlign();
20352 AS = ST->getAddressSpace();
20353 IsMasked = true;
20354 } else
20355 return false;
20356
20357 unsigned Fast = 0;
20358 if (!allowsMisalignedMemoryAccesses(VT, AS, Alignment,
20360 // Only generate post-increment or pre-increment forms when a real
20361 // hardware instruction exists for them. Do not emit postinc/preinc
20362 // if the operation will end up as a libcall.
20363 return false;
20364 }
20365
20366 bool isInc;
20367 bool isLegal = false;
20368 if (VT.isVector())
20369 isLegal = Subtarget->hasMVEIntegerOps() &&
20371 Ptr.getNode(), VT, Alignment, isSEXTLoad, IsMasked,
20372 Subtarget->isLittle(), Base, Offset, isInc, DAG);
20373 else {
20374 if (Subtarget->isThumb2())
20375 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20376 Offset, isInc, DAG);
20377 else
20378 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20379 Offset, isInc, DAG);
20380 }
20381 if (!isLegal)
20382 return false;
20383
20384 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
20385 return true;
20386}
20387
20388/// getPostIndexedAddressParts - returns true by value, base pointer and
20389/// offset pointer and addressing mode by reference if this node can be
20390/// combined with a load / store to form a post-indexed load / store.
20392 SDValue &Base,
20393 SDValue &Offset,
20395 SelectionDAG &DAG) const {
20396 EVT VT;
20397 SDValue Ptr;
20398 Align Alignment;
20399 bool isSEXTLoad = false, isNonExt;
20400 bool IsMasked = false;
20401 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20402 VT = LD->getMemoryVT();
20403 Ptr = LD->getBasePtr();
20404 Alignment = LD->getAlign();
20405 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20406 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20407 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20408 VT = ST->getMemoryVT();
20409 Ptr = ST->getBasePtr();
20410 Alignment = ST->getAlign();
20411 isNonExt = !ST->isTruncatingStore();
20412 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20413 VT = LD->getMemoryVT();
20414 Ptr = LD->getBasePtr();
20415 Alignment = LD->getAlign();
20416 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20417 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20418 IsMasked = true;
20420 VT = ST->getMemoryVT();
20421 Ptr = ST->getBasePtr();
20422 Alignment = ST->getAlign();
20423 isNonExt = !ST->isTruncatingStore();
20424 IsMasked = true;
20425 } else
20426 return false;
20427
20428 if (Subtarget->isThumb1Only()) {
20429 // Thumb-1 can do a limited post-inc load or store as an updating LDM. It
20430 // must be non-extending/truncating, i32, with an offset of 4.
20431 assert(Op->getValueType(0) == MVT::i32 && "Non-i32 post-inc op?!");
20432 if (Op->getOpcode() != ISD::ADD || !isNonExt)
20433 return false;
20434 auto *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1));
20435 if (!RHS || RHS->getZExtValue() != 4)
20436 return false;
20437 if (Alignment < Align(4))
20438 return false;
20439
20440 Offset = Op->getOperand(1);
20441 Base = Op->getOperand(0);
20442 AM = ISD::POST_INC;
20443 return true;
20444 }
20445
20446 bool isInc;
20447 bool isLegal = false;
20448 if (VT.isVector())
20449 isLegal = Subtarget->hasMVEIntegerOps() &&
20450 getMVEIndexedAddressParts(Op, VT, Alignment, isSEXTLoad, IsMasked,
20451 Subtarget->isLittle(), Base, Offset,
20452 isInc, DAG);
20453 else {
20454 if (Subtarget->isThumb2())
20455 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20456 isInc, DAG);
20457 else
20458 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20459 isInc, DAG);
20460 }
20461 if (!isLegal)
20462 return false;
20463
20464 if (Ptr != Base) {
20465 // Swap base ptr and offset to catch more post-index load / store when
20466 // it's legal. In Thumb2 mode, offset must be an immediate.
20467 if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
20468 !Subtarget->isThumb2())
20470
20471 // Post-indexed load / store update the base pointer.
20472 if (Ptr != Base)
20473 return false;
20474 }
20475
20476 AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
20477 return true;
20478}
20479
20482 const APInt &DemandedElts,
20483 const SelectionDAG &DAG,
20484 unsigned Depth) const {
20485 unsigned BitWidth = Known.getBitWidth();
20486 Known.resetAll();
20487 switch (Op.getOpcode()) {
20488 default: break;
20489 case ARMISD::ADDC:
20490 case ARMISD::ADDE:
20491 case ARMISD::SUBC:
20492 case ARMISD::SUBE:
20493 // Special cases when we convert a carry to a boolean.
20494 if (Op.getResNo() == 0) {
20495 SDValue LHS = Op.getOperand(0);
20496 SDValue RHS = Op.getOperand(1);
20497 // (ADDE 0, 0, C) will give us a single bit.
20498 if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
20499 isNullConstant(RHS)) {
20501 return;
20502 }
20503 }
20504 break;
20505 case ARMISD::CMOV: {
20506 // Bits are known zero/one if known on the LHS and RHS.
20507 Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
20508 if (Known.isUnknown())
20509 return;
20510
20511 KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
20512 Known = Known.intersectWith(KnownRHS);
20513 return;
20514 }
20516 Intrinsic::ID IntID =
20517 static_cast<Intrinsic::ID>(Op->getConstantOperandVal(1));
20518 switch (IntID) {
20519 default: return;
20520 case Intrinsic::arm_ldaex:
20521 case Intrinsic::arm_ldrex: {
20522 EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
20523 unsigned MemBits = VT.getScalarSizeInBits();
20524 Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20525 return;
20526 }
20527 }
20528 }
20529 case ARMISD::BFI: {
20530 // Conservatively, we can recurse down the first operand
20531 // and just mask out all affected bits.
20532 Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20533
20534 // The operand to BFI is already a mask suitable for removing the bits it
20535 // sets.
20536 const APInt &Mask = Op.getConstantOperandAPInt(2);
20537 Known.Zero &= Mask;
20538 Known.One &= Mask;
20539 return;
20540 }
20541 case ARMISD::VGETLANEs:
20542 case ARMISD::VGETLANEu: {
20543 const SDValue &SrcSV = Op.getOperand(0);
20544 EVT VecVT = SrcSV.getValueType();
20545 assert(VecVT.isVector() && "VGETLANE expected a vector type");
20546 const unsigned NumSrcElts = VecVT.getVectorNumElements();
20547 ConstantSDNode *Pos = cast<ConstantSDNode>(Op.getOperand(1).getNode());
20548 assert(Pos->getAPIntValue().ult(NumSrcElts) &&
20549 "VGETLANE index out of bounds");
20550 unsigned Idx = Pos->getZExtValue();
20551 APInt DemandedElt = APInt::getOneBitSet(NumSrcElts, Idx);
20552 Known = DAG.computeKnownBits(SrcSV, DemandedElt, Depth + 1);
20553
20554 EVT VT = Op.getValueType();
20555 const unsigned DstSz = VT.getScalarSizeInBits();
20556 const unsigned SrcSz = VecVT.getVectorElementType().getSizeInBits();
20557 (void)SrcSz;
20558 assert(SrcSz == Known.getBitWidth());
20559 assert(DstSz > SrcSz);
20560 if (Op.getOpcode() == ARMISD::VGETLANEs)
20561 Known = Known.sext(DstSz);
20562 else {
20563 Known = Known.zext(DstSz);
20564 }
20565 assert(DstSz == Known.getBitWidth());
20566 break;
20567 }
20568 case ARMISD::VMOVrh: {
20569 KnownBits KnownOp = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20570 assert(KnownOp.getBitWidth() == 16);
20571 Known = KnownOp.zext(32);
20572 break;
20573 }
20574 case ARMISD::CSINC:
20575 case ARMISD::CSINV:
20576 case ARMISD::CSNEG: {
20577 KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20578 KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
20579
20580 // The result is either:
20581 // CSINC: KnownOp0 or KnownOp1 + 1
20582 // CSINV: KnownOp0 or ~KnownOp1
20583 // CSNEG: KnownOp0 or KnownOp1 * -1
20584 if (Op.getOpcode() == ARMISD::CSINC)
20585 KnownOp1 =
20586 KnownBits::add(KnownOp1, KnownBits::makeConstant(APInt(32, 1)));
20587 else if (Op.getOpcode() == ARMISD::CSINV)
20588 std::swap(KnownOp1.Zero, KnownOp1.One);
20589 else if (Op.getOpcode() == ARMISD::CSNEG)
20590 KnownOp1 = KnownBits::mul(KnownOp1,
20592
20593 Known = KnownOp0.intersectWith(KnownOp1);
20594 break;
20595 }
20596 case ARMISD::VORRIMM:
20597 case ARMISD::VBICIMM: {
20598 unsigned Encoded = Op.getConstantOperandVal(1);
20599 unsigned DecEltBits = 0;
20600 uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
20601
20602 unsigned EltBits = Op.getScalarValueSizeInBits();
20603 if (EltBits != DecEltBits) {
20604 // Be conservative: only update Known when EltBits == DecEltBits.
20605 // This is believed to always be true for VORRIMM/VBICIMM today, but if
20606 // that changes in the future, doing nothing here is safer than risking
20607 // subtle bugs.
20608 break;
20609 }
20610
20611 KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20612 bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
20613 APInt Imm(DecEltBits, DecodedVal);
20614
20615 Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
20616 Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
20617 break;
20618 }
20619 }
20620}
20621
20622static bool isLegalLogicalImmediate(unsigned Imm,
20623 const ARMSubtarget *Subtarget) {
20624 if (!Subtarget->isThumb())
20625 return ARM_AM::getSOImmVal(Imm) != -1;
20626 if (Subtarget->isThumb2())
20627 return ARM_AM::getT2SOImmVal(Imm) != -1;
20628 // Thumb1 only has 8-bit unsigned immediate.
20629 return Imm <= 255;
20630}
20631
20632/// Refine i32 AND/OR/XOR with a constant RHS using demanded bits: replace the
20633/// immediate with an equivalent constant that ARM/Thumb can encode as a
20634/// logical immediate (or that selects better lowering), without changing the
20635/// computed result on those demanded bits.
20636static bool optimizeLogicalImm(SDValue Op, unsigned Imm,
20637 const APInt &DemandedBits,
20638 const ARMSubtarget *Subtarget,
20640
20641 if (Imm == 0 || Imm == ~0U)
20642 return false;
20643
20644 unsigned Opc = Op.getOpcode();
20645 unsigned Demanded = DemandedBits.getZExtValue();
20646 EVT VT = Op.getValueType();
20647
20648 unsigned ShrunkImm = Imm & Demanded;
20649 unsigned ExpandedImm = Imm | ~Demanded;
20650
20651 auto IsLegalImm = [ShrunkImm, ExpandedImm](unsigned CandidateImm) -> bool {
20652 return (ShrunkImm & CandidateImm) == ShrunkImm &&
20653 (~ExpandedImm & CandidateImm) == 0;
20654 };
20655 auto UseImm = [Imm, Opc, Op, VT, &TLO](unsigned NewImm) -> bool {
20656 if (NewImm == Imm)
20657 return true;
20658 SDLoc DL(Op);
20659 SDValue NewC = TLO.DAG.getConstant(NewImm, DL, VT);
20660 SDValue NewOp =
20661 TLO.DAG.getNode(Opc, DL, VT, Op.getOperand(0), NewC, Op->getFlags());
20662 return TLO.CombineTo(Op, NewOp);
20663 };
20664
20665 // Shrunk immediate is 0: AND becomes zero; OR/XOR with 0 leaves the other
20666 // operand (still valid on demanded bits).
20667 if (ShrunkImm == 0) {
20668 ++NumOptimizedImms;
20669 return UseImm(ShrunkImm);
20670 }
20671
20672 // If the immediate is all ones: for AND this removes the operation; for
20673 // OR/XOR it remains a transform valid on demanded bits. (Target-independent
20674 // shrink may not fold this, so keep it to avoid obscure combine loops.)
20675 if (ExpandedImm == ~0U) {
20676 ++NumOptimizedImms;
20677 return UseImm(ExpandedImm);
20678 }
20679
20680 // Thumb1: prefer 0xFF / 0xFFFF when they fit the demanded-bit envelope so
20681 // lowering can match uxtb / uxth (AND immediates only; OR/XOR do not use
20682 // that). Run this before strict ShrunkImm: a tight 8-bit ShrunkImm can be
20683 // legal while 0xFF still matches the envelope and yields better isel (uxtb).
20684 if (Opc == ISD::AND && Subtarget->hasV6Ops()) {
20685 if (IsLegalImm(0xFF)) {
20686 ++NumOptimizedImms;
20687 return UseImm(0xFF);
20688 }
20689
20690 if (IsLegalImm(0xFFFF)) {
20691 ++NumOptimizedImms;
20692 return UseImm(0xFFFF);
20693 }
20694 }
20695
20696 // Don't optimize if it is legal.
20697 if (isLegalLogicalImmediate(Imm, Subtarget))
20698 return false;
20699
20700 // FIXME: Check for BIC being legal causes infinite loop due to target
20701 // independent DAG combine undoing this.
20702
20703 // Prefer strict shrink when ShrunkImm encodes for this target, before
20704 // complement expansion.
20705 if (isLegalLogicalImmediate(ShrunkImm, Subtarget)) {
20706 ++NumOptimizedImms;
20707 return UseImm(ShrunkImm);
20708 }
20709
20710 // Complement expansion: if all undemanded bits are already one, ExpandedImm
20711 // is Imm with every non-demanded bit set. When (~ExpandedImm) < 256, the
20712 // complement fits in an 8-bit unsigned value, i.e. bits 8–31 of ExpandedImm
20713 // are all ones; only the low byte may differ from ~0. Use that expanded
20714 // constant so isel sees a mask shape that fits logical-immediate patterns.
20715 if ((~ExpandedImm) < 256) {
20716 ++NumOptimizedImms;
20717 return UseImm(ExpandedImm);
20718 }
20719
20720 // FIXME: The check for v6 is because this interferes with some ubfx
20721 // optimizations.
20722 if (Opc == ISD::AND && isLegalLogicalImmediate(~ExpandedImm, Subtarget) &&
20723 !Subtarget->hasV6Ops()) {
20724 ++NumOptimizedImms;
20725 return UseImm(ExpandedImm);
20726 }
20727
20728 // Potential improvements:
20729 //
20730 // We could try to recognize lsls+lsrs or lsrs+lsls pairs here.
20731 // We could try to prefer Thumb1 immediates which can be lowered to a
20732 // two-instruction sequence.
20733
20734 return false;
20735}
20736
20738 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
20739 TargetLoweringOpt &TLO) const {
20740 // Delay this optimization to as late as possible.
20741 if (!TLO.LegalOps)
20742 return false;
20743
20744 EVT VT = Op.getValueType();
20745
20746 // Ignore vectors.
20747 if (VT.isVector())
20748 return false;
20749
20750 unsigned Size = VT.getSizeInBits();
20751
20752 if (Size != 32)
20753 return false;
20754
20755 // Exit early if we demand all bits.
20756 if (DemandedBits.isAllOnes())
20757 return false;
20758
20759 switch (Op.getOpcode()) {
20760 default:
20761 return false;
20762 case ISD::AND:
20763 case ISD::OR:
20764 case ISD::XOR:
20765 break;
20766 }
20767 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20768 if (!C)
20769 return false;
20770 unsigned Imm = C->getZExtValue();
20771 return optimizeLogicalImm(Op, Imm, DemandedBits, Subtarget, TLO);
20772}
20773
20775 SDValue Op, const APInt &OriginalDemandedBits,
20776 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
20777 unsigned Depth) const {
20778 unsigned Opc = Op.getOpcode();
20779
20780 switch (Opc) {
20781 case ARMISD::ASRL:
20782 case ARMISD::LSRL: {
20783 // If this is result 0 and the other result is unused, see if the demand
20784 // bits allow us to shrink this long shift into a standard small shift in
20785 // the opposite direction.
20786 if (Op.getResNo() == 0 && !Op->hasAnyUseOfValue(1) &&
20787 isa<ConstantSDNode>(Op->getOperand(2))) {
20788 unsigned ShAmt = Op->getConstantOperandVal(2);
20789 if (ShAmt < 32 && OriginalDemandedBits.isSubsetOf(APInt::getAllOnes(32)
20790 << (32 - ShAmt)))
20791 return TLO.CombineTo(
20792 Op, TLO.DAG.getNode(
20793 ISD::SHL, SDLoc(Op), MVT::i32, Op.getOperand(1),
20794 TLO.DAG.getConstant(32 - ShAmt, SDLoc(Op), MVT::i32)));
20795 }
20796 break;
20797 }
20798 case ARMISD::VBICIMM: {
20799 SDValue Op0 = Op.getOperand(0);
20800 unsigned ModImm = Op.getConstantOperandVal(1);
20801 unsigned EltBits = 0;
20802 uint64_t Mask = ARM_AM::decodeVMOVModImm(ModImm, EltBits);
20803 if ((OriginalDemandedBits & Mask) == 0)
20804 return TLO.CombineTo(Op, Op0);
20805 }
20806 }
20807
20809 Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
20810}
20811
20812//===----------------------------------------------------------------------===//
20813// ARM Inline Assembly Support
20814//===----------------------------------------------------------------------===//
20815
20816const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
20817 // At this point, we have to lower this constraint to something else, so we
20818 // lower it to an "r" or "w". However, by doing this we will force the result
20819 // to be in register, while the X constraint is much more permissive.
20820 //
20821 // Although we are correct (we are free to emit anything, without
20822 // constraints), we might break use cases that would expect us to be more
20823 // efficient and emit something else.
20824 if (!Subtarget->hasVFP2Base())
20825 return "r";
20826 if (ConstraintVT.isFloatingPoint())
20827 return "w";
20828 if (ConstraintVT.isVector() && Subtarget->hasNEON() &&
20829 (ConstraintVT.getSizeInBits() == 64 ||
20830 ConstraintVT.getSizeInBits() == 128))
20831 return "w";
20832
20833 return "r";
20834}
20835
20836/// getConstraintType - Given a constraint letter, return the type of
20837/// constraint it is for this target.
20840 unsigned S = Constraint.size();
20841 if (S == 1) {
20842 switch (Constraint[0]) {
20843 default: break;
20844 case 'l': return C_RegisterClass;
20845 case 'w': return C_RegisterClass;
20846 case 'h': return C_RegisterClass;
20847 case 'x': return C_RegisterClass;
20848 case 't': return C_RegisterClass;
20849 case 'j': return C_Immediate; // Constant for movw.
20850 // An address with a single base register. Due to the way we
20851 // currently handle addresses it is the same as an 'r' memory constraint.
20852 case 'Q': return C_Memory;
20853 }
20854 } else if (S == 2) {
20855 switch (Constraint[0]) {
20856 default: break;
20857 case 'T': return C_RegisterClass;
20858 // All 'U+' constraints are addresses.
20859 case 'U': return C_Memory;
20860 }
20861 }
20862 return TargetLowering::getConstraintType(Constraint);
20863}
20864
20865/// Examine constraint type and operand type and determine a weight value.
20866/// This object must already have been set up with the operand type
20867/// and the current alternative constraint selected.
20870 AsmOperandInfo &info, const char *constraint) const {
20872 Value *CallOperandVal = info.CallOperandVal;
20873 // If we don't have a value, we can't do a match,
20874 // but allow it at the lowest weight.
20875 if (!CallOperandVal)
20876 return CW_Default;
20877 Type *type = CallOperandVal->getType();
20878 // Look at the constraint type.
20879 switch (*constraint) {
20880 default:
20882 break;
20883 case 'l':
20884 if (type->isIntegerTy()) {
20885 if (Subtarget->isThumb())
20886 weight = CW_SpecificReg;
20887 else
20888 weight = CW_Register;
20889 }
20890 break;
20891 case 'w':
20892 if (type->isFloatingPointTy())
20893 weight = CW_Register;
20894 break;
20895 }
20896 return weight;
20897}
20898
20899static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
20900 if (PR == 0 || VT == MVT::Other)
20901 return false;
20902 if (ARM::SPRRegClass.contains(PR))
20903 return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32;
20904 if (ARM::DPRRegClass.contains(PR))
20905 return VT != MVT::f64 && !VT.is64BitVector();
20906 return false;
20907}
20908
20909using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
20910
20912 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
20913 switch (Constraint.size()) {
20914 case 1:
20915 // GCC ARM Constraint Letters
20916 switch (Constraint[0]) {
20917 case 'l': // Low regs or general regs.
20918 if (Subtarget->isThumb())
20919 return RCPair(0U, &ARM::tGPRRegClass);
20920 return RCPair(0U, &ARM::GPRRegClass);
20921 case 'h': // High regs or no regs.
20922 if (Subtarget->isThumb())
20923 return RCPair(0U, &ARM::hGPRRegClass);
20924 break;
20925 case 'r':
20926 if (Subtarget->isThumb1Only())
20927 return RCPair(0U, &ARM::tGPRRegClass);
20928 return RCPair(0U, &ARM::GPRRegClass);
20929 case 'w':
20930 if (VT == MVT::Other)
20931 break;
20932 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20933 return RCPair(0U, &ARM::SPRRegClass);
20934 if (VT.getSizeInBits() == 64)
20935 return RCPair(0U, &ARM::DPRRegClass);
20936 if (VT.getSizeInBits() == 128)
20937 return RCPair(0U, &ARM::QPRRegClass);
20938 break;
20939 case 'x':
20940 if (VT == MVT::Other)
20941 break;
20942 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20943 return RCPair(0U, &ARM::SPR_8RegClass);
20944 if (VT.getSizeInBits() == 64)
20945 return RCPair(0U, &ARM::DPR_8RegClass);
20946 if (VT.getSizeInBits() == 128)
20947 return RCPair(0U, &ARM::QPR_8RegClass);
20948 break;
20949 case 't':
20950 if (VT == MVT::Other)
20951 break;
20952 if (VT == MVT::f32 || VT == MVT::i32 || VT == MVT::f16 || VT == MVT::bf16)
20953 return RCPair(0U, &ARM::SPRRegClass);
20954 if (VT.getSizeInBits() == 64)
20955 return RCPair(0U, &ARM::DPR_VFP2RegClass);
20956 if (VT.getSizeInBits() == 128)
20957 return RCPair(0U, &ARM::QPR_VFP2RegClass);
20958 break;
20959 }
20960 break;
20961
20962 case 2:
20963 if (Constraint[0] == 'T') {
20964 switch (Constraint[1]) {
20965 default:
20966 break;
20967 case 'e':
20968 return RCPair(0U, &ARM::tGPREvenRegClass);
20969 case 'o':
20970 return RCPair(0U, &ARM::tGPROddRegClass);
20971 }
20972 }
20973 break;
20974
20975 default:
20976 break;
20977 }
20978
20979 if (StringRef("{cc}").equals_insensitive(Constraint))
20980 return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
20981
20982 // r14 is an alias of lr.
20983 if (StringRef("{r14}").equals_insensitive(Constraint))
20984 Constraint = "{lr}";
20985
20986 auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
20987 if (isIncompatibleReg(RCP.first, VT))
20988 return {0, nullptr};
20989 return RCP;
20990}
20991
20992/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
20993/// vector. If it is invalid, don't add anything to Ops.
20995 StringRef Constraint,
20996 std::vector<SDValue> &Ops,
20997 SelectionDAG &DAG) const {
20998 SDValue Result;
20999
21000 // Currently only support length 1 constraints.
21001 if (Constraint.size() != 1)
21002 return;
21003
21004 char ConstraintLetter = Constraint[0];
21005 switch (ConstraintLetter) {
21006 default: break;
21007 case 'j':
21008 case 'I': case 'J': case 'K': case 'L':
21009 case 'M': case 'N': case 'O':
21011 if (!C)
21012 return;
21013
21014 int64_t CVal64 = C->getSExtValue();
21015 int CVal = (int) CVal64;
21016 // None of these constraints allow values larger than 32 bits. Check
21017 // that the value fits in an int.
21018 if (CVal != CVal64)
21019 return;
21020
21021 switch (ConstraintLetter) {
21022 case 'j':
21023 // Constant suitable for movw, must be between 0 and
21024 // 65535.
21025 if (Subtarget->hasV6T2Ops() || (Subtarget->hasV8MBaselineOps()))
21026 if (CVal >= 0 && CVal <= 65535)
21027 break;
21028 return;
21029 case 'I':
21030 if (Subtarget->isThumb1Only()) {
21031 // This must be a constant between 0 and 255, for ADD
21032 // immediates.
21033 if (CVal >= 0 && CVal <= 255)
21034 break;
21035 } else if (Subtarget->isThumb2()) {
21036 // A constant that can be used as an immediate value in a
21037 // data-processing instruction.
21038 if (ARM_AM::getT2SOImmVal(CVal) != -1)
21039 break;
21040 } else {
21041 // A constant that can be used as an immediate value in a
21042 // data-processing instruction.
21043 if (ARM_AM::getSOImmVal(CVal) != -1)
21044 break;
21045 }
21046 return;
21047
21048 case 'J':
21049 if (Subtarget->isThumb1Only()) {
21050 // This must be a constant between -255 and -1, for negated ADD
21051 // immediates. This can be used in GCC with an "n" modifier that
21052 // prints the negated value, for use with SUB instructions. It is
21053 // not useful otherwise but is implemented for compatibility.
21054 if (CVal >= -255 && CVal <= -1)
21055 break;
21056 } else {
21057 // This must be a constant between -4095 and 4095. This is suitable
21058 // for use as the immediate offset field in LDR and STR instructions
21059 // such as LDR r0,[r1,#offset].
21060 if (CVal >= -4095 && CVal <= 4095)
21061 break;
21062 }
21063 return;
21064
21065 case 'K':
21066 if (Subtarget->isThumb1Only()) {
21067 // A 32-bit value where only one byte has a nonzero value. Exclude
21068 // zero to match GCC. This constraint is used by GCC internally for
21069 // constants that can be loaded with a move/shift combination.
21070 // It is not useful otherwise but is implemented for compatibility.
21071 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal))
21072 break;
21073 } else if (Subtarget->isThumb2()) {
21074 // A constant whose bitwise inverse can be used as an immediate
21075 // value in a data-processing instruction. This can be used in GCC
21076 // with a "B" modifier that prints the inverted value, for use with
21077 // BIC and MVN instructions. It is not useful otherwise but is
21078 // implemented for compatibility.
21079 if (ARM_AM::getT2SOImmVal(~CVal) != -1)
21080 break;
21081 } else {
21082 // A constant whose bitwise inverse can be used as an immediate
21083 // value in a data-processing instruction. This can be used in GCC
21084 // with a "B" modifier that prints the inverted value, for use with
21085 // BIC and MVN instructions. It is not useful otherwise but is
21086 // implemented for compatibility.
21087 if (ARM_AM::getSOImmVal(~CVal) != -1)
21088 break;
21089 }
21090 return;
21091
21092 case 'L':
21093 if (Subtarget->isThumb1Only()) {
21094 // This must be a constant between -7 and 7,
21095 // for 3-operand ADD/SUB immediate instructions.
21096 if (CVal >= -7 && CVal < 7)
21097 break;
21098 } else if (Subtarget->isThumb2()) {
21099 // A constant whose negation can be used as an immediate value in a
21100 // data-processing instruction. This can be used in GCC with an "n"
21101 // modifier that prints the negated value, for use with SUB
21102 // instructions. It is not useful otherwise but is implemented for
21103 // compatibility.
21104 if (ARM_AM::getT2SOImmVal(-CVal) != -1)
21105 break;
21106 } else {
21107 // A constant whose negation can be used as an immediate value in a
21108 // data-processing instruction. This can be used in GCC with an "n"
21109 // modifier that prints the negated value, for use with SUB
21110 // instructions. It is not useful otherwise but is implemented for
21111 // compatibility.
21112 if (ARM_AM::getSOImmVal(-CVal) != -1)
21113 break;
21114 }
21115 return;
21116
21117 case 'M':
21118 if (Subtarget->isThumb1Only()) {
21119 // This must be a multiple of 4 between 0 and 1020, for
21120 // ADD sp + immediate.
21121 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0))
21122 break;
21123 } else {
21124 // A power of two or a constant between 0 and 32. This is used in
21125 // GCC for the shift amount on shifted register operands, but it is
21126 // useful in general for any shift amounts.
21127 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0))
21128 break;
21129 }
21130 return;
21131
21132 case 'N':
21133 if (Subtarget->isThumb1Only()) {
21134 // This must be a constant between 0 and 31, for shift amounts.
21135 if (CVal >= 0 && CVal <= 31)
21136 break;
21137 }
21138 return;
21139
21140 case 'O':
21141 if (Subtarget->isThumb1Only()) {
21142 // This must be a multiple of 4 between -508 and 508, for
21143 // ADD/SUB sp = sp + immediate.
21144 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0))
21145 break;
21146 }
21147 return;
21148 }
21149 Result = DAG.getSignedTargetConstant(CVal, SDLoc(Op), Op.getValueType());
21150 break;
21151 }
21152
21153 if (Result.getNode()) {
21154 Ops.push_back(Result);
21155 return;
21156 }
21157 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
21158}
21159
21160static RTLIB::Libcall getDivRemLibcall(
21161 const SDNode *N, MVT::SimpleValueType SVT) {
21162 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
21163 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
21164 "Unhandled Opcode in getDivRemLibcall");
21165 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
21166 N->getOpcode() == ISD::SREM;
21167 RTLIB::Libcall LC;
21168 switch (SVT) {
21169 default: llvm_unreachable("Unexpected request for libcall!");
21170 case MVT::i8: LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break;
21171 case MVT::i16: LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break;
21172 case MVT::i32: LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break;
21173 case MVT::i64: LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break;
21174 }
21175 return LC;
21176}
21177
21180 const AttributeList &FuncAttrs, RTLIB::LibcallImpl LCImpl) {
21181 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
21182 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
21183 "Unhandled Opcode in getDivRemArgList");
21184 SDValue Ops[2] = {N->getOperand(0), N->getOperand(1)};
21185
21186 // The Windows __rt_*div* helpers take the divisor before the dividend.
21187 switch (LCImpl) {
21188 case RTLIB::impl___rt_sdiv:
21189 case RTLIB::impl___rt_udiv:
21190 case RTLIB::impl___rt_sdiv64:
21191 case RTLIB::impl___rt_udiv64:
21192 std::swap(Ops[0], Ops[1]);
21193 break;
21194 default:
21195 break;
21196 }
21197
21198 return TargetLowering::getArgListForFunctionType(FuncTy, FuncAttrs, Ops);
21199}
21200
21201SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
21202 assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
21203 Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
21204 Subtarget->isTargetFuchsia() || Subtarget->isTargetWindows()) &&
21205 "Register-based DivRem lowering only");
21206 unsigned Opcode = Op->getOpcode();
21207 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
21208 "Invalid opcode for Div/Rem lowering");
21209 bool isSigned = (Opcode == ISD::SDIVREM);
21210 EVT VT = Op->getValueType(0);
21211 SDLoc dl(Op);
21212
21213 if (VT == MVT::i64 && isa<ConstantSDNode>(Op.getOperand(1))) {
21215 if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i32, DAG)) {
21216 SDValue Res0 =
21217 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[0], Result[1]);
21218 SDValue Res1 =
21219 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[2], Result[3]);
21220 return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
21221 {Res0, Res1});
21222 }
21223 }
21224
21225 // If the target has hardware divide, use divide + multiply + subtract:
21226 // div = a / b
21227 // rem = a - b * div
21228 // return {div, rem}
21229 // This should be lowered into UDIV/SDIV + MLS later on.
21230 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
21231 : Subtarget->hasDivideInARMMode();
21232 if (hasDivide && Op->getValueType(0).isSimple() &&
21233 Op->getSimpleValueType(0) == MVT::i32) {
21234 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
21235 const SDValue Dividend = Op->getOperand(0);
21236 const SDValue Divisor = Op->getOperand(1);
21237 SDValue Div = DAG.getNode(DivOpcode, dl, VT, Dividend, Divisor);
21238 SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Div, Divisor);
21239 SDValue Rem = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
21240
21241 SDValue Values[2] = {Div, Rem};
21242 return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VT, VT), Values);
21243 }
21244
21245 RTLIB::Libcall LC = getDivRemLibcall(Op.getNode(),
21246 VT.getSimpleVT().SimpleTy);
21247 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21248 if (LCImpl == RTLIB::Unsupported)
21249 return SDValue();
21250
21251 auto [FuncTy, FuncAttrs] =
21253 *DAG.getContext(), getTM().getTargetTriple(), DAG.getDataLayout(),
21254 LCImpl);
21255 Type *RetTy = FuncTy->getReturnType();
21256
21257 SDValue InChain = DAG.getEntryNode();
21258
21260 getDivRemArgList(Op.getNode(), FuncTy, FuncAttrs, LCImpl);
21261
21262 SDValue Callee =
21263 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21264
21265 if (getTM().getTargetTriple().isOSWindows())
21266 InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
21267
21268 TargetLowering::CallLoweringInfo CLI(DAG);
21269 CLI.setDebugLoc(dl)
21270 .setChain(InChain)
21271 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21272 Callee, std::move(Args))
21273 .setInRegister()
21276
21277 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
21278 return CallInfo.first;
21279}
21280
21281// Lowers REM using divmod helpers
21282// see RTABI section 4.2/4.3
21283SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
21284 EVT VT = N->getValueType(0);
21285
21286 if (VT == MVT::i64 && isa<ConstantSDNode>(N->getOperand(1))) {
21288 if (expandDIVREMByConstant(N, Result, MVT::i32, DAG))
21289 return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), N->getValueType(0),
21290 Result[0], Result[1]);
21291 }
21292
21293 RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
21294 SimpleTy);
21295 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21296 if (LCImpl == RTLIB::Unsupported)
21297 return SDValue();
21298
21299 auto [FuncTy, FuncAttrs] =
21301 *DAG.getContext(), getTM().getTargetTriple(), DAG.getDataLayout(),
21302 LCImpl);
21303 Type *RetTy = FuncTy->getReturnType();
21304
21305 SDValue InChain = DAG.getEntryNode();
21307 getDivRemArgList(N, FuncTy, FuncAttrs, LCImpl);
21308 bool isSigned = N->getOpcode() == ISD::SREM;
21309
21310 SDValue Callee =
21311 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21312
21313 if (getTM().getTargetTriple().isOSWindows())
21314 InChain = WinDBZCheckDenominator(DAG, N, InChain);
21315
21316 // Lower call
21317 CallLoweringInfo CLI(DAG);
21318 CLI.setChain(InChain)
21319 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21320 Callee, std::move(Args))
21323 .setDebugLoc(SDLoc(N));
21324 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
21325
21326 // Return second (rem) result operand (first contains div)
21327 SDNode *ResNode = CallResult.first.getNode();
21328 assert(ResNode->getNumOperands() == 2 && "divmod should return two operands");
21329 return ResNode->getOperand(1);
21330}
21331
21332SDValue
21333ARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
21334 assert(getTM().getTargetTriple().isOSWindows() &&
21335 "unsupported target platform");
21336 SDLoc DL(Op);
21337
21338 // Get the inputs.
21339 SDValue Chain = Op.getOperand(0);
21340 SDValue Size = Op.getOperand(1);
21341
21343 "no-stack-arg-probe")) {
21344 MaybeAlign Align =
21345 cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
21346 SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21347 Chain = SP.getValue(1);
21348 SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
21349 if (Align)
21350 SP = DAG.getNode(ISD::AND, DL, MVT::i32, SP.getValue(0),
21351 DAG.getSignedConstant(-Align->value(), DL, MVT::i32));
21352 Chain = DAG.getCopyToReg(Chain, DL, ARM::SP, SP);
21353 SDValue Ops[2] = { SP, Chain };
21354 return DAG.getMergeValues(Ops, DL);
21355 }
21356
21357 SDValue Words = DAG.getNode(ISD::SRL, DL, MVT::i32, Size,
21358 DAG.getConstant(2, DL, MVT::i32));
21359
21360 SDValue Glue;
21361 Chain = DAG.getCopyToReg(Chain, DL, ARM::R4, Words, Glue);
21362 Glue = Chain.getValue(1);
21363
21364 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
21365 Chain = DAG.getNode(ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Glue);
21366
21367 SDValue NewSP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21368 Chain = NewSP.getValue(1);
21369
21370 SDValue Ops[2] = { NewSP, Chain };
21371 return DAG.getMergeValues(Ops, DL);
21372}
21373
21374SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
21375 bool IsStrict = Op->isStrictFPOpcode();
21376 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21377 const unsigned DstSz = Op.getValueType().getSizeInBits();
21378 const unsigned SrcSz = SrcVal.getValueType().getSizeInBits();
21379 assert(DstSz > SrcSz && DstSz <= 64 && SrcSz >= 16 &&
21380 "Unexpected type for custom-lowering FP_EXTEND");
21381
21382 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21383 "With both FP DP and 16, any FP conversion is legal!");
21384
21385 assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
21386 "With FP16, 16 to 32 conversion is legal!");
21387
21388 // Converting from 32 -> 64 is valid if we have FP64.
21389 if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
21390 // FIXME: Remove this when we have strict fp instruction selection patterns
21391 if (IsStrict) {
21392 SDLoc Loc(Op);
21393 SDValue Result = DAG.getNode(ISD::FP_EXTEND,
21394 Loc, Op.getValueType(), SrcVal);
21395 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
21396 }
21397 return Op;
21398 }
21399
21400 // Either we are converting from 16 -> 64, without FP16 and/or
21401 // FP.double-precision or without Armv8-fp. So we must do it in two
21402 // steps.
21403 // Or we are converting from 32 -> 64 without fp.double-precision or 16 -> 32
21404 // without FP16. So we must do a function call.
21405 SDLoc Loc(Op);
21406 RTLIB::Libcall LC;
21407 MakeLibCallOptions CallOptions;
21408 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21409 for (unsigned Sz = SrcSz; Sz <= 32 && Sz < DstSz; Sz *= 2) {
21410 bool Supported = (Sz == 16 ? Subtarget->hasFP16() : Subtarget->hasFP64());
21411 MVT SrcVT = (Sz == 16 ? MVT::f16 : MVT::f32);
21412 MVT DstVT = (Sz == 16 ? MVT::f32 : MVT::f64);
21413 if (Supported) {
21414 if (IsStrict) {
21415 SrcVal = DAG.getNode(ISD::STRICT_FP_EXTEND, Loc,
21416 {DstVT, MVT::Other}, {Chain, SrcVal});
21417 Chain = SrcVal.getValue(1);
21418 } else {
21419 SrcVal = DAG.getNode(ISD::FP_EXTEND, Loc, DstVT, SrcVal);
21420 }
21421 } else {
21422 LC = RTLIB::getFPEXT(SrcVT, DstVT);
21423 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21424 "Unexpected type for custom-lowering FP_EXTEND");
21425 std::tie(SrcVal, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21426 Loc, Chain);
21427 }
21428 }
21429
21430 return IsStrict ? DAG.getMergeValues({SrcVal, Chain}, Loc) : SrcVal;
21431}
21432
21433SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
21434 bool IsStrict = Op->isStrictFPOpcode();
21435
21436 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21437 EVT SrcVT = SrcVal.getValueType();
21438 EVT DstVT = Op.getValueType();
21439
21440 if (DstVT == MVT::bf16) {
21441 if (Subtarget->hasBF16() && SrcVT == MVT::f32)
21442 return Op;
21443 return SDValue();
21444 }
21445
21446 const unsigned DstSz = Op.getValueType().getSizeInBits();
21447 const unsigned SrcSz = SrcVT.getSizeInBits();
21448 (void)DstSz;
21449 assert(DstSz < SrcSz && SrcSz <= 64 && DstSz >= 16 &&
21450 "Unexpected type for custom-lowering FP_ROUND");
21451
21452 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21453 "With both FP DP and 16, any FP conversion is legal!");
21454
21455 SDLoc Loc(Op);
21456
21457 // Instruction from 32 -> 16 if hasFP16 is valid
21458 if (SrcSz == 32 && Subtarget->hasFP16())
21459 return Op;
21460
21461 // Lib call from 32 -> 16 / 64 -> [32, 16]
21462 RTLIB::Libcall LC = RTLIB::getFPROUND(SrcVT, DstVT);
21463 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21464 "Unexpected type for custom-lowering FP_ROUND");
21465 MakeLibCallOptions CallOptions;
21466 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21467 SDValue Result;
21468 std::tie(Result, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21469 Loc, Chain);
21470 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
21471}
21472
21473bool
21475 // The ARM target isn't yet aware of offsets.
21476 return false;
21477}
21478
21480 if (v == 0xffffffff)
21481 return false;
21482
21483 // there can be 1's on either or both "outsides", all the "inside"
21484 // bits must be 0's
21485 return isShiftedMask_32(~v);
21486}
21487
21488/// Returns how to materialize the specified FP immediate.
21491 bool ForCodeSize) const {
21492 if (!Subtarget->hasVFP3Base())
21494 if (VT == MVT::f16 && Subtarget->hasFullFP16())
21497 if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
21499 return FPImmAction::Legal;
21500 if (VT == MVT::f32)
21503 if (VT == MVT::f64 && Subtarget->hasFP64())
21507}
21508
21511 bool ForCodeSize) const {
21512 if (Subtarget->useSoftFloat() || !Subtarget->hasVFP2Base())
21513 return FPImmAction::Bitcast;
21515}
21516
21517/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
21518/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
21519/// specified in the intrinsic calls.
21522 MachineFunction &MF, unsigned Intrinsic) const {
21523 IntrinsicInfo Info;
21524 switch (Intrinsic) {
21525 case Intrinsic::arm_neon_vld1:
21526 case Intrinsic::arm_neon_vld2:
21527 case Intrinsic::arm_neon_vld3:
21528 case Intrinsic::arm_neon_vld4:
21529 case Intrinsic::arm_neon_vld2lane:
21530 case Intrinsic::arm_neon_vld3lane:
21531 case Intrinsic::arm_neon_vld4lane:
21532 case Intrinsic::arm_neon_vld2dup:
21533 case Intrinsic::arm_neon_vld3dup:
21534 case Intrinsic::arm_neon_vld4dup: {
21535 Info.opc = ISD::INTRINSIC_W_CHAIN;
21536 // Conservatively set memVT to the entire set of vectors loaded.
21537 auto &DL = I.getDataLayout();
21538 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21539 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21540 Info.ptrVal = I.getArgOperand(0);
21541 Info.offset = 0;
21542 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21543 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21544 // volatile loads with NEON intrinsics not supported
21545 Info.flags = MachineMemOperand::MOLoad;
21546 Infos.push_back(Info);
21547 return;
21548 }
21549 case Intrinsic::arm_neon_vld1x2:
21550 case Intrinsic::arm_neon_vld1x3:
21551 case Intrinsic::arm_neon_vld1x4: {
21552 Info.opc = ISD::INTRINSIC_W_CHAIN;
21553 // Conservatively set memVT to the entire set of vectors loaded.
21554 auto &DL = I.getDataLayout();
21555 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21556 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21557 Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
21558 Info.offset = 0;
21559 Info.align = I.getParamAlign(I.arg_size() - 1).valueOrOne();
21560 // volatile loads with NEON intrinsics not supported
21561 Info.flags = MachineMemOperand::MOLoad;
21562 Infos.push_back(Info);
21563 return;
21564 }
21565 case Intrinsic::arm_neon_vst1:
21566 case Intrinsic::arm_neon_vst2:
21567 case Intrinsic::arm_neon_vst3:
21568 case Intrinsic::arm_neon_vst4:
21569 case Intrinsic::arm_neon_vst2lane:
21570 case Intrinsic::arm_neon_vst3lane:
21571 case Intrinsic::arm_neon_vst4lane: {
21572 Info.opc = ISD::INTRINSIC_VOID;
21573 // Conservatively set memVT to the entire set of vectors stored.
21574 auto &DL = I.getDataLayout();
21575 unsigned NumElts = 0;
21576 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21577 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21578 if (!ArgTy->isVectorTy())
21579 break;
21580 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21581 }
21582 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21583 Info.ptrVal = I.getArgOperand(0);
21584 Info.offset = 0;
21585 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21586 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21587 // volatile stores with NEON intrinsics not supported
21588 Info.flags = MachineMemOperand::MOStore;
21589 Infos.push_back(Info);
21590 return;
21591 }
21592 case Intrinsic::arm_neon_vst1x2:
21593 case Intrinsic::arm_neon_vst1x3:
21594 case Intrinsic::arm_neon_vst1x4: {
21595 Info.opc = ISD::INTRINSIC_VOID;
21596 // Conservatively set memVT to the entire set of vectors stored.
21597 auto &DL = I.getDataLayout();
21598 unsigned NumElts = 0;
21599 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21600 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21601 if (!ArgTy->isVectorTy())
21602 break;
21603 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21604 }
21605 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21606 Info.ptrVal = I.getArgOperand(0);
21607 Info.offset = 0;
21608 Info.align = I.getParamAlign(0).valueOrOne();
21609 // volatile stores with NEON intrinsics not supported
21610 Info.flags = MachineMemOperand::MOStore;
21611 Infos.push_back(Info);
21612 return;
21613 }
21614 case Intrinsic::arm_mve_vld2q:
21615 case Intrinsic::arm_mve_vld4q: {
21616 Info.opc = ISD::INTRINSIC_W_CHAIN;
21617 // Conservatively set memVT to the entire set of vectors loaded.
21618 Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
21619 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
21620 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21621 Info.ptrVal = I.getArgOperand(0);
21622 Info.offset = 0;
21623 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21624 // volatile loads with MVE intrinsics not supported
21625 Info.flags = MachineMemOperand::MOLoad;
21626 Infos.push_back(Info);
21627 return;
21628 }
21629 case Intrinsic::arm_mve_vst2q:
21630 case Intrinsic::arm_mve_vst4q: {
21631 Info.opc = ISD::INTRINSIC_VOID;
21632 // Conservatively set memVT to the entire set of vectors stored.
21633 Type *VecTy = I.getArgOperand(1)->getType();
21634 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vst2q ? 2 : 4;
21635 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21636 Info.ptrVal = I.getArgOperand(0);
21637 Info.offset = 0;
21638 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21639 // volatile stores with MVE intrinsics not supported
21640 Info.flags = MachineMemOperand::MOStore;
21641 Infos.push_back(Info);
21642 return;
21643 }
21644 case Intrinsic::arm_mve_vldr_gather_base:
21645 case Intrinsic::arm_mve_vldr_gather_base_predicated: {
21646 Info.opc = ISD::INTRINSIC_W_CHAIN;
21647 Info.ptrVal = nullptr;
21648 Info.memVT = MVT::getVT(I.getType());
21649 Info.align = Align(1);
21650 Info.flags |= MachineMemOperand::MOLoad;
21651 Infos.push_back(Info);
21652 return;
21653 }
21654 case Intrinsic::arm_mve_vldr_gather_base_wb:
21655 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: {
21656 Info.opc = ISD::INTRINSIC_W_CHAIN;
21657 Info.ptrVal = nullptr;
21658 Info.memVT = MVT::getVT(I.getType()->getContainedType(0));
21659 Info.align = Align(1);
21660 Info.flags |= MachineMemOperand::MOLoad;
21661 Infos.push_back(Info);
21662 return;
21663 }
21664 case Intrinsic::arm_mve_vldr_gather_offset:
21665 case Intrinsic::arm_mve_vldr_gather_offset_predicated: {
21666 Info.opc = ISD::INTRINSIC_W_CHAIN;
21667 Info.ptrVal = nullptr;
21668 MVT DataVT = MVT::getVT(I.getType());
21669 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
21670 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21671 DataVT.getVectorNumElements());
21672 Info.align = Align(1);
21673 Info.flags |= MachineMemOperand::MOLoad;
21674 Infos.push_back(Info);
21675 return;
21676 }
21677 case Intrinsic::arm_mve_vstr_scatter_base:
21678 case Intrinsic::arm_mve_vstr_scatter_base_predicated: {
21679 Info.opc = ISD::INTRINSIC_VOID;
21680 Info.ptrVal = nullptr;
21681 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21682 Info.align = Align(1);
21683 Info.flags |= MachineMemOperand::MOStore;
21684 Infos.push_back(Info);
21685 return;
21686 }
21687 case Intrinsic::arm_mve_vstr_scatter_base_wb:
21688 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated: {
21689 Info.opc = ISD::INTRINSIC_W_CHAIN;
21690 Info.ptrVal = nullptr;
21691 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21692 Info.align = Align(1);
21693 Info.flags |= MachineMemOperand::MOStore;
21694 Infos.push_back(Info);
21695 return;
21696 }
21697 case Intrinsic::arm_mve_vstr_scatter_offset:
21698 case Intrinsic::arm_mve_vstr_scatter_offset_predicated: {
21699 Info.opc = ISD::INTRINSIC_VOID;
21700 Info.ptrVal = nullptr;
21701 MVT DataVT = MVT::getVT(I.getArgOperand(2)->getType());
21702 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
21703 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21704 DataVT.getVectorNumElements());
21705 Info.align = Align(1);
21706 Info.flags |= MachineMemOperand::MOStore;
21707 Infos.push_back(Info);
21708 return;
21709 }
21710 case Intrinsic::arm_ldaex:
21711 case Intrinsic::arm_ldrex: {
21712 auto &DL = I.getDataLayout();
21713 Type *ValTy = I.getParamElementType(0);
21714 Info.opc = ISD::INTRINSIC_W_CHAIN;
21715 Info.memVT = MVT::getVT(ValTy);
21716 Info.ptrVal = I.getArgOperand(0);
21717 Info.offset = 0;
21718 Info.align = DL.getABITypeAlign(ValTy);
21720 Infos.push_back(Info);
21721 return;
21722 }
21723 case Intrinsic::arm_stlex:
21724 case Intrinsic::arm_strex: {
21725 auto &DL = I.getDataLayout();
21726 Type *ValTy = I.getParamElementType(1);
21727 Info.opc = ISD::INTRINSIC_W_CHAIN;
21728 Info.memVT = MVT::getVT(ValTy);
21729 Info.ptrVal = I.getArgOperand(1);
21730 Info.offset = 0;
21731 Info.align = DL.getABITypeAlign(ValTy);
21733 Infos.push_back(Info);
21734 return;
21735 }
21736 case Intrinsic::arm_stlexd:
21737 case Intrinsic::arm_strexd:
21738 Info.opc = ISD::INTRINSIC_W_CHAIN;
21739 Info.memVT = MVT::i64;
21740 Info.ptrVal = I.getArgOperand(2);
21741 Info.offset = 0;
21742 Info.align = Align(8);
21744 Infos.push_back(Info);
21745 return;
21746
21747 case Intrinsic::arm_ldaexd:
21748 case Intrinsic::arm_ldrexd:
21749 Info.opc = ISD::INTRINSIC_W_CHAIN;
21750 Info.memVT = MVT::i64;
21751 Info.ptrVal = I.getArgOperand(0);
21752 Info.offset = 0;
21753 Info.align = Align(8);
21755 Infos.push_back(Info);
21756 return;
21757
21758 default:
21759 break;
21760 }
21761}
21762
21763/// Returns true if it is beneficial to convert a load of a constant
21764/// to just the constant itself.
21766 Type *Ty) const {
21767 assert(Ty->isIntegerTy());
21768
21769 unsigned Bits = Ty->getPrimitiveSizeInBits();
21770 if (Bits == 0 || Bits > 32)
21771 return false;
21772 return true;
21773}
21774
21777 unsigned Index) const {
21780
21781 if (Index == 0 || Index == ResVT.getVectorNumElements())
21784}
21785
21787 ARM_MB::MemBOpt Domain) const {
21788 // First, if the target has no DMB, see what fallback we can use.
21789 if (!Subtarget->hasDataBarrier()) {
21790 // Some ARMv6 cpus can support data barriers with an mcr instruction.
21791 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
21792 // here.
21793 if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
21794 Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
21795 Builder.getInt32(0), Builder.getInt32(7),
21796 Builder.getInt32(10), Builder.getInt32(5)};
21797 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_mcr, args);
21798 }
21799 // Instead of using barriers, atomic accesses on these subtargets use
21800 // libcalls.
21801 llvm_unreachable("makeDMB on a target so old that it has no barriers");
21802 } else {
21803 // Only a full system barrier exists in the M-class architectures.
21804 Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
21805 Constant *CDomain = Builder.getInt32(Domain);
21806 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_dmb, CDomain);
21807 }
21808}
21809
21810// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
21812 Instruction *Inst,
21813 AtomicOrdering Ord) const {
21814 switch (Ord) {
21817 llvm_unreachable("Invalid fence: unordered/non-atomic");
21820 return nullptr; // Nothing to do
21822 if (!Inst->hasAtomicStore())
21823 return nullptr; // Nothing to do
21824 [[fallthrough]];
21827 if (Subtarget->preferISHSTBarriers())
21828 return makeDMB(Builder, ARM_MB::ISHST);
21829 // FIXME: add a comment with a link to documentation justifying this.
21830 else
21831 return makeDMB(Builder, ARM_MB::ISH);
21832 }
21833 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
21834}
21835
21837 Instruction *Inst,
21838 AtomicOrdering Ord) const {
21839 switch (Ord) {
21842 llvm_unreachable("Invalid fence: unordered/not-atomic");
21845 return nullptr; // Nothing to do
21849 return makeDMB(Builder, ARM_MB::ISH);
21850 }
21851 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
21852}
21853
21854// Loads and stores less than 64-bits are already atomic; ones above that
21855// are doomed anyway, so defer to the default libcall and blame the OS when
21856// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21857// anything for those.
21860 bool has64BitAtomicStore;
21861 if (Subtarget->isMClass())
21862 has64BitAtomicStore = false;
21863 else if (Subtarget->isThumb())
21864 has64BitAtomicStore = Subtarget->hasV7Ops();
21865 else
21866 has64BitAtomicStore = Subtarget->hasV6Ops();
21867
21868 unsigned Size = SI->getValueOperand()->getType()->getPrimitiveSizeInBits();
21869 return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind::Expand
21871}
21872
21873// Loads and stores less than 64-bits are already atomic; ones above that
21874// are doomed anyway, so defer to the default libcall and blame the OS when
21875// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21876// anything for those.
21877// FIXME: ldrd and strd are atomic if the CPU has LPAE (e.g. A15 has that
21878// guarantee, see DDI0406C ARM architecture reference manual,
21879// sections A8.8.72-74 LDRD)
21882 bool has64BitAtomicLoad;
21883 if (Subtarget->isMClass())
21884 has64BitAtomicLoad = false;
21885 else if (Subtarget->isThumb())
21886 has64BitAtomicLoad = Subtarget->hasV7Ops();
21887 else
21888 has64BitAtomicLoad = Subtarget->hasV6Ops();
21889
21890 unsigned Size = LI->getType()->getPrimitiveSizeInBits();
21891 return (Size == 64 && has64BitAtomicLoad) ? AtomicExpansionKind::LLOnly
21893}
21894
21895// For the real atomic operations, we have ldrex/strex up to 32 bits,
21896// and up to 64 bits on the non-M profiles
21899 if (AI->isFloatingPointOperation())
21901
21902 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
21903 bool hasAtomicRMW;
21904 if (Subtarget->isMClass())
21905 hasAtomicRMW = Subtarget->hasV8MBaselineOps();
21906 else if (Subtarget->isThumb())
21907 hasAtomicRMW = Subtarget->hasV7Ops();
21908 else
21909 hasAtomicRMW = Subtarget->hasV6Ops();
21910 if (Size <= (Subtarget->isMClass() ? 32U : 64U) && hasAtomicRMW) {
21911 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21912 // implement atomicrmw without spilling. If the target address is also on
21913 // the stack and close enough to the spill slot, this can lead to a
21914 // situation where the monitor always gets cleared and the atomic operation
21915 // can never succeed. So at -O0 lower this operation to a CAS loop.
21916 if (getTargetMachine().getOptLevel() == CodeGenOptLevel::None)
21919 }
21921}
21922
21923// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
21924// bits, and up to 64 bits on the non-M profiles.
21927 const AtomicCmpXchgInst *AI) const {
21928 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21929 // implement cmpxchg without spilling. If the address being exchanged is also
21930 // on the stack and close enough to the spill slot, this can lead to a
21931 // situation where the monitor always gets cleared and the atomic operation
21932 // can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
21933 unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
21934 bool HasAtomicCmpXchg;
21935 if (Subtarget->isMClass())
21936 HasAtomicCmpXchg = Subtarget->hasV8MBaselineOps();
21937 else if (Subtarget->isThumb())
21938 HasAtomicCmpXchg = Subtarget->hasV7Ops();
21939 else
21940 HasAtomicCmpXchg = Subtarget->hasV6Ops();
21941 if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None &&
21942 HasAtomicCmpXchg && Size <= (Subtarget->isMClass() ? 32U : 64U))
21945}
21946
21948 const Instruction *I) const {
21949 return InsertFencesForAtomic;
21950}
21951
21953 // ROPI/RWPI are not supported currently.
21954 return !Subtarget->isROPI() && !Subtarget->isRWPI();
21955}
21956
21958 Module &M, const LibcallLoweringInfo &Libcalls) const {
21959 // MSVC CRT provides functionalities for stack protection.
21960 RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21961 Libcalls.getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21962
21963 RTLIB::LibcallImpl SecurityCookieVar =
21964 Libcalls.getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
21965 if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
21966 SecurityCookieVar != RTLIB::Unsupported) {
21967 // MSVC CRT has a global variable holding security cookie.
21968 M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
21969 PointerType::getUnqual(M.getContext()));
21970
21971 // MSVC CRT has a function to validate security cookie.
21972 FunctionCallee SecurityCheckCookie =
21973 M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall),
21974 Type::getVoidTy(M.getContext()),
21975 PointerType::getUnqual(M.getContext()));
21976 if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee()))
21977 F->addParamAttr(0, Attribute::AttrKind::InReg);
21978 }
21979
21981}
21982
21984 unsigned &Cost) const {
21985 // If we do not have NEON, vector types are not natively supported.
21986 if (!Subtarget->hasNEON())
21987 return false;
21988
21989 // Floating point values and vector values map to the same register file.
21990 // Therefore, although we could do a store extract of a vector type, this is
21991 // better to leave at float as we have more freedom in the addressing mode for
21992 // those.
21993 if (VectorTy->isFPOrFPVectorTy())
21994 return false;
21995
21996 // If the index is unknown at compile time, this is very expensive to lower
21997 // and it is not possible to combine the store with the extract.
21998 if (!isa<ConstantInt>(Idx))
21999 return false;
22000
22001 assert(VectorTy->isVectorTy() && "VectorTy is not a vector type");
22002 unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
22003 // We can do a store + vector extract on any vector that fits perfectly in a D
22004 // or Q register.
22005 if (BitWidth == 64 || BitWidth == 128) {
22006 Cost = 0;
22007 return true;
22008 }
22009 return false;
22010}
22011
22013 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
22014 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
22015 unsigned Opcode = Op.getOpcode();
22016 switch (Opcode) {
22017 case ARMISD::VORRIMM:
22018 case ARMISD::VBICIMM:
22019 return false;
22020 }
22022 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
22023}
22024
22026 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
22027}
22028
22030 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
22031}
22032
22034 const Instruction &AndI) const {
22035 if (!Subtarget->hasV7Ops())
22036 return false;
22037
22038 // Sink the `and` instruction only if the mask would fit into a modified
22039 // immediate operand.
22041 if (!Mask || Mask->getValue().getBitWidth() > 32u)
22042 return false;
22043 auto MaskVal = unsigned(Mask->getValue().getZExtValue());
22044 return (Subtarget->isThumb2() ? ARM_AM::getT2SOImmVal(MaskVal)
22045 : ARM_AM::getSOImmVal(MaskVal)) != -1;
22046}
22047
22050 SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const {
22051 if (Subtarget->hasMinSize() && !getTM().getTargetTriple().isOSWindows())
22054 ExpansionFactor);
22055}
22056
22058 Value *Addr,
22059 AtomicOrdering Ord) const {
22060 Module *M = Builder.getModule();
22061 bool IsAcquire = isAcquireOrStronger(Ord);
22062
22063 // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd
22064 // intrinsic must return {i32, i32} and we have to recombine them into a
22065 // single i64 here.
22066 if (ValueTy->getPrimitiveSizeInBits() == 64) {
22068 IsAcquire ? Intrinsic::arm_ldaexd : Intrinsic::arm_ldrexd;
22069
22070 Value *LoHi =
22071 Builder.CreateIntrinsic(Int, Addr, /*FMFSource=*/nullptr, "lohi");
22072
22073 Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
22074 Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
22075 if (!Subtarget->isLittle())
22076 std::swap (Lo, Hi);
22077 Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
22078 Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
22079 return Builder.CreateOr(
22080 Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 32)), "val64");
22081 }
22082
22083 Type *Tys[] = { Addr->getType() };
22084 Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex;
22085 CallInst *CI = Builder.CreateIntrinsicWithoutFolding(Int, Tys, Addr);
22086
22087 CI->addParamAttr(
22088 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy));
22089 return Builder.CreateTruncOrBitCast(CI, ValueTy);
22090}
22091
22093 IRBuilderBase &Builder) const {
22094 if (!Subtarget->hasV7Ops())
22095 return;
22096 Builder.CreateIntrinsic(Intrinsic::arm_clrex, {});
22097}
22098
22100 Value *Val, Value *Addr,
22101 AtomicOrdering Ord) const {
22102 Module *M = Builder.getModule();
22103 bool IsRelease = isReleaseOrStronger(Ord);
22104
22105 // Since the intrinsics must have legal type, the i64 intrinsics take two
22106 // parameters: "i32, i32". We must marshal Val into the appropriate form
22107 // before the call.
22108 if (Val->getType()->getPrimitiveSizeInBits() == 64) {
22110 IsRelease ? Intrinsic::arm_stlexd : Intrinsic::arm_strexd;
22111 Type *Int32Ty = Type::getInt32Ty(M->getContext());
22112
22113 Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
22114 Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
22115 if (!Subtarget->isLittle())
22116 std::swap(Lo, Hi);
22117 return Builder.CreateIntrinsic(Int, {Lo, Hi, Addr});
22118 }
22119
22120 Intrinsic::ID Int = IsRelease ? Intrinsic::arm_stlex : Intrinsic::arm_strex;
22121 Type *Tys[] = { Addr->getType() };
22123
22124 CallInst *CI = Builder.CreateCall(
22125 Strex, {Builder.CreateZExtOrBitCast(
22126 Val, Strex->getFunctionType()->getParamType(0)),
22127 Addr});
22128 CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType,
22129 Val->getType()));
22130 return CI;
22131}
22132
22133
22135 return Subtarget->isMClass();
22136}
22137
22138/// A helper function for determining the number of interleaved accesses we
22139/// will generate when lowering accesses of the given type.
22140unsigned
22142 const DataLayout &DL) const {
22143 return (DL.getTypeSizeInBits(VecTy) + 127) / 128;
22144}
22145
22147 unsigned Factor, FixedVectorType *VecTy, Align Alignment,
22148 const DataLayout &DL) const {
22149
22150 unsigned VecSize = DL.getTypeSizeInBits(VecTy);
22151 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
22152
22153 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
22154 return false;
22155
22156 // Ensure the vector doesn't have f16 elements. Even though we could do an
22157 // i16 vldN, we can't hold the f16 vectors and will end up converting via
22158 // f32.
22159 if (Subtarget->hasNEON() && VecTy->getElementType()->isHalfTy())
22160 return false;
22161 if (Subtarget->hasMVEIntegerOps() && Factor == 3)
22162 return false;
22163
22164 // Ensure the number of vector elements is greater than 1.
22165 if (VecTy->getNumElements() < 2)
22166 return false;
22167
22168 // Ensure the element type is legal.
22169 if (ElSize != 8 && ElSize != 16 && ElSize != 32)
22170 return false;
22171 // And the alignment if high enough under MVE.
22172 if (Subtarget->hasMVEIntegerOps() && Alignment < ElSize / 8)
22173 return false;
22174
22175 // Ensure the total vector size is 64 or a multiple of 128. Types larger than
22176 // 128 will be split into multiple interleaved accesses.
22177 if (Subtarget->hasNEON() && VecSize == 64)
22178 return true;
22179 return VecSize % 128 == 0;
22180}
22181
22183 if (Subtarget->hasNEON())
22184 return 4;
22185 if (Subtarget->hasMVEIntegerOps())
22188}
22189
22190/// Lower an interleaved load into a vldN intrinsic.
22191///
22192/// E.g. Lower an interleaved load (Factor = 2):
22193/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr, align 4
22194/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
22195/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
22196///
22197/// Into:
22198/// %vld2 = { <4 x i32>, <4 x i32> } call llvm.arm.neon.vld2(%ptr, 4)
22199/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 0
22200/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 1
22203 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
22204 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22205 "Invalid interleave factor");
22206 assert(!Shuffles.empty() && "Empty shufflevector input");
22207 assert(Shuffles.size() == Indices.size() &&
22208 "Unmatched number of shufflevectors and indices");
22209
22210 auto *LI = dyn_cast<LoadInst>(Load);
22211 if (!LI)
22212 return false;
22213 assert(!Mask && GapMask.popcount() == Factor && "Unexpected mask on a load");
22214
22215 auto *VecTy = cast<FixedVectorType>(Shuffles[0]->getType());
22216 Type *EltTy = VecTy->getElementType();
22217
22218 const DataLayout &DL = LI->getDataLayout();
22219 Align Alignment = LI->getAlign();
22220
22221 // Skip if we do not have NEON and skip illegal vector types. We can
22222 // "legalize" wide vector types into multiple interleaved accesses as long as
22223 // the vector types are divisible by 128.
22224 if (!isLegalInterleavedAccessType(Factor, VecTy, Alignment, DL))
22225 return false;
22226
22227 unsigned NumLoads = getNumInterleavedAccesses(VecTy, DL);
22228
22229 // A pointer vector can not be the return type of the ldN intrinsics. Need to
22230 // load integer vectors first and then convert to pointer vectors.
22231 if (EltTy->isPointerTy())
22232 VecTy = FixedVectorType::get(DL.getIntPtrType(EltTy), VecTy);
22233
22234 IRBuilder<> Builder(LI);
22235
22236 // The base address of the load.
22237 Value *BaseAddr = LI->getPointerOperand();
22238
22239 if (NumLoads > 1) {
22240 // If we're going to generate more than one load, reset the sub-vector type
22241 // to something legal.
22242 VecTy = FixedVectorType::get(VecTy->getElementType(),
22243 VecTy->getNumElements() / NumLoads);
22244 }
22245
22246 assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!");
22247
22248 auto createLoadIntrinsic = [&](Value *BaseAddr) {
22249 if (Subtarget->hasNEON()) {
22250 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
22251 Type *Tys[] = {VecTy, PtrTy};
22252 static const Intrinsic::ID LoadInts[3] = {Intrinsic::arm_neon_vld2,
22253 Intrinsic::arm_neon_vld3,
22254 Intrinsic::arm_neon_vld4};
22255
22257 Ops.push_back(BaseAddr);
22258 Ops.push_back(Builder.getInt32(LI->getAlign().value()));
22259
22260 return Builder.CreateIntrinsic(LoadInts[Factor - 2], Tys, Ops,
22261 /*FMFSource=*/nullptr, "vldN");
22262 } else {
22263 assert((Factor == 2 || Factor == 4) &&
22264 "expected interleave factor of 2 or 4 for MVE");
22265 Intrinsic::ID LoadInts =
22266 Factor == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
22267 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
22268 Type *Tys[] = {VecTy, PtrTy};
22269
22271 Ops.push_back(BaseAddr);
22272 return Builder.CreateIntrinsic(LoadInts, Tys, Ops, /*FMFSource=*/nullptr,
22273 "vldN");
22274 }
22275 };
22276
22277 // Holds sub-vectors extracted from the load intrinsic return values. The
22278 // sub-vectors are associated with the shufflevector instructions they will
22279 // replace.
22281
22282 for (unsigned LoadCount = 0; LoadCount < NumLoads; ++LoadCount) {
22283 // If we're generating more than one load, compute the base address of
22284 // subsequent loads as an offset from the previous.
22285 if (LoadCount > 0)
22286 BaseAddr = Builder.CreateConstGEP1_32(VecTy->getElementType(), BaseAddr,
22287 VecTy->getNumElements() * Factor);
22288
22289 Value *VldN = createLoadIntrinsic(BaseAddr);
22290
22291 // Replace uses of each shufflevector with the corresponding vector loaded
22292 // by ldN.
22293 for (unsigned i = 0; i < Shuffles.size(); i++) {
22294 ShuffleVectorInst *SV = Shuffles[i];
22295 unsigned Index = Indices[i];
22296
22297 Value *SubVec = Builder.CreateExtractValue(VldN, Index);
22298
22299 // Convert the integer vector to pointer vector if the element is pointer.
22300 if (EltTy->isPointerTy())
22301 SubVec = Builder.CreateIntToPtr(
22302 SubVec,
22303 FixedVectorType::get(SV->getType()->getElementType(), VecTy));
22304
22305 SubVecs[SV].push_back(SubVec);
22306 }
22307 }
22308
22309 // Replace uses of the shufflevector instructions with the sub-vectors
22310 // returned by the load intrinsic. If a shufflevector instruction is
22311 // associated with more than one sub-vector, those sub-vectors will be
22312 // concatenated into a single wide vector.
22313 for (ShuffleVectorInst *SVI : Shuffles) {
22314 auto &SubVec = SubVecs[SVI];
22315 auto *WideVec =
22316 SubVec.size() > 1 ? concatenateVectors(Builder, SubVec) : SubVec[0];
22317 SVI->replaceAllUsesWith(WideVec);
22318 }
22319
22320 return true;
22321}
22322
22323/// Lower an interleaved store into a vstN intrinsic.
22324///
22325/// E.g. Lower an interleaved store (Factor = 3):
22326/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
22327/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
22328/// store <12 x i32> %i.vec, <12 x i32>* %ptr, align 4
22329///
22330/// Into:
22331/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
22332/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
22333/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
22334/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22335///
22336/// Note that the new shufflevectors will be removed and we'll only generate one
22337/// vst3 instruction in CodeGen.
22338///
22339/// Example for a more general valid mask (Factor 3). Lower:
22340/// %i.vec = shuffle <32 x i32> %v0, <32 x i32> %v1,
22341/// <4, 32, 16, 5, 33, 17, 6, 34, 18, 7, 35, 19>
22342/// store <12 x i32> %i.vec, <12 x i32>* %ptr
22343///
22344/// Into:
22345/// %sub.v0 = shuffle <32 x i32> %v0, <32 x i32> v1, <4, 5, 6, 7>
22346/// %sub.v1 = shuffle <32 x i32> %v0, <32 x i32> v1, <32, 33, 34, 35>
22347/// %sub.v2 = shuffle <32 x i32> %v0, <32 x i32> v1, <16, 17, 18, 19>
22348/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22350 Value *LaneMask,
22351 ShuffleVectorInst *SVI,
22352 unsigned Factor,
22353 const APInt &GapMask) const {
22354 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22355 "Invalid interleave factor");
22356 auto *SI = dyn_cast<StoreInst>(Store);
22357 if (!SI)
22358 return false;
22359 assert(!LaneMask && GapMask.popcount() == Factor &&
22360 "Unexpected mask on store");
22361
22362 auto *VecTy = cast<FixedVectorType>(SVI->getType());
22363 assert(VecTy->getNumElements() % Factor == 0 && "Invalid interleaved store");
22364
22365 unsigned LaneLen = VecTy->getNumElements() / Factor;
22366 Type *EltTy = VecTy->getElementType();
22367 auto *SubVecTy = FixedVectorType::get(EltTy, LaneLen);
22368
22369 const DataLayout &DL = SI->getDataLayout();
22370 Align Alignment = SI->getAlign();
22371
22372 // Skip if we do not have NEON and skip illegal vector types. We can
22373 // "legalize" wide vector types into multiple interleaved accesses as long as
22374 // the vector types are divisible by 128.
22375 if (!isLegalInterleavedAccessType(Factor, SubVecTy, Alignment, DL))
22376 return false;
22377
22378 unsigned NumStores = getNumInterleavedAccesses(SubVecTy, DL);
22379
22380 Value *Op0 = SVI->getOperand(0);
22381 Value *Op1 = SVI->getOperand(1);
22382 IRBuilder<> Builder(SI);
22383
22384 // StN intrinsics don't support pointer vectors as arguments. Convert pointer
22385 // vectors to integer vectors.
22386 if (EltTy->isPointerTy()) {
22387 Type *IntTy = DL.getIntPtrType(EltTy);
22388
22389 // Convert to the corresponding integer vector.
22390 auto *IntVecTy =
22392 Op0 = Builder.CreatePtrToInt(Op0, IntVecTy);
22393 Op1 = Builder.CreatePtrToInt(Op1, IntVecTy);
22394
22395 SubVecTy = FixedVectorType::get(IntTy, LaneLen);
22396 }
22397
22398 // The base address of the store.
22399 Value *BaseAddr = SI->getPointerOperand();
22400
22401 if (NumStores > 1) {
22402 // If we're going to generate more than one store, reset the lane length
22403 // and sub-vector type to something legal.
22404 LaneLen /= NumStores;
22405 SubVecTy = FixedVectorType::get(SubVecTy->getElementType(), LaneLen);
22406 }
22407
22408 assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!");
22409
22410 auto Mask = SVI->getShuffleMask();
22411
22412 auto createStoreIntrinsic = [&](Value *BaseAddr,
22413 SmallVectorImpl<Value *> &Shuffles) {
22414 if (Subtarget->hasNEON()) {
22415 static const Intrinsic::ID StoreInts[3] = {Intrinsic::arm_neon_vst2,
22416 Intrinsic::arm_neon_vst3,
22417 Intrinsic::arm_neon_vst4};
22418 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22419 Type *Tys[] = {PtrTy, SubVecTy};
22420
22422 Ops.push_back(BaseAddr);
22423 append_range(Ops, Shuffles);
22424 Ops.push_back(Builder.getInt32(SI->getAlign().value()));
22425 Builder.CreateIntrinsic(StoreInts[Factor - 2], Tys, Ops);
22426 } else {
22427 assert((Factor == 2 || Factor == 4) &&
22428 "expected interleave factor of 2 or 4 for MVE");
22429 Intrinsic::ID StoreInts =
22430 Factor == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
22431 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22432 Type *Tys[] = {PtrTy, SubVecTy};
22433
22435 Ops.push_back(BaseAddr);
22436 append_range(Ops, Shuffles);
22437 for (unsigned F = 0; F < Factor; F++) {
22438 Ops.push_back(Builder.getInt32(F));
22439 Builder.CreateIntrinsic(StoreInts, Tys, Ops);
22440 Ops.pop_back();
22441 }
22442 }
22443 };
22444
22445 for (unsigned StoreCount = 0; StoreCount < NumStores; ++StoreCount) {
22446 // If we generating more than one store, we compute the base address of
22447 // subsequent stores as an offset from the previous.
22448 if (StoreCount > 0)
22449 BaseAddr = Builder.CreateConstGEP1_32(SubVecTy->getElementType(),
22450 BaseAddr, LaneLen * Factor);
22451
22452 SmallVector<Value *, 4> Shuffles;
22453
22454 // Split the shufflevector operands into sub vectors for the new vstN call.
22455 for (unsigned i = 0; i < Factor; i++) {
22456 unsigned IdxI = StoreCount * LaneLen * Factor + i;
22457 if (Mask[IdxI] >= 0) {
22458 Shuffles.push_back(Builder.CreateShuffleVector(
22459 Op0, Op1, createSequentialMask(Mask[IdxI], LaneLen, 0)));
22460 } else {
22461 unsigned StartMask = 0;
22462 for (unsigned j = 1; j < LaneLen; j++) {
22463 unsigned IdxJ = StoreCount * LaneLen * Factor + j;
22464 if (Mask[IdxJ * Factor + IdxI] >= 0) {
22465 StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
22466 break;
22467 }
22468 }
22469 // Note: If all elements in a chunk are undefs, StartMask=0!
22470 // Note: Filling undef gaps with random elements is ok, since
22471 // those elements were being written anyway (with undefs).
22472 // In the case of all undefs we're defaulting to using elems from 0
22473 // Note: StartMask cannot be negative, it's checked in
22474 // isReInterleaveMask
22475 Shuffles.push_back(Builder.CreateShuffleVector(
22476 Op0, Op1, createSequentialMask(StartMask, LaneLen, 0)));
22477 }
22478 }
22479
22480 createStoreIntrinsic(BaseAddr, Shuffles);
22481 }
22482 return true;
22483}
22484
22492
22494 uint64_t &Members) {
22495 if (auto *ST = dyn_cast<StructType>(Ty)) {
22496 for (unsigned i = 0; i < ST->getNumElements(); ++i) {
22497 uint64_t SubMembers = 0;
22498 if (!isHomogeneousAggregate(ST->getElementType(i), Base, SubMembers))
22499 return false;
22500 Members += SubMembers;
22501 }
22502 } else if (auto *AT = dyn_cast<ArrayType>(Ty)) {
22503 uint64_t SubMembers = 0;
22504 if (!isHomogeneousAggregate(AT->getElementType(), Base, SubMembers))
22505 return false;
22506 Members += SubMembers * AT->getNumElements();
22507 } else if (Ty->isFloatTy()) {
22508 if (Base != HA_UNKNOWN && Base != HA_FLOAT)
22509 return false;
22510 Members = 1;
22511 Base = HA_FLOAT;
22512 } else if (Ty->isDoubleTy()) {
22513 if (Base != HA_UNKNOWN && Base != HA_DOUBLE)
22514 return false;
22515 Members = 1;
22516 Base = HA_DOUBLE;
22517 } else if (auto *VT = dyn_cast<VectorType>(Ty)) {
22518 Members = 1;
22519 switch (Base) {
22520 case HA_FLOAT:
22521 case HA_DOUBLE:
22522 return false;
22523 case HA_VECT64:
22524 return VT->getPrimitiveSizeInBits().getFixedValue() == 64;
22525 case HA_VECT128:
22526 return VT->getPrimitiveSizeInBits().getFixedValue() == 128;
22527 case HA_UNKNOWN:
22528 switch (VT->getPrimitiveSizeInBits().getFixedValue()) {
22529 case 64:
22530 Base = HA_VECT64;
22531 return true;
22532 case 128:
22533 Base = HA_VECT128;
22534 return true;
22535 default:
22536 return false;
22537 }
22538 }
22539 }
22540
22541 return (Members > 0 && Members <= 4);
22542}
22543
22544/// Return the correct alignment for the current calling convention.
22546 Type *ArgTy, const DataLayout &DL) const {
22547 const Align ABITypeAlign = DL.getABITypeAlign(ArgTy);
22548 if (!ArgTy->isVectorTy())
22549 return ABITypeAlign;
22550
22551 // Avoid over-aligning vector parameters. It would require realigning the
22552 // stack and waste space for no real benefit.
22553 MaybeAlign StackAlign = DL.getStackAlignment();
22554 assert(StackAlign && "data layout string is missing stack alignment");
22555 return std::min(ABITypeAlign, *StackAlign);
22556}
22557
22558/// Return true if a type is an AAPCS-VFP homogeneous aggregate or one of
22559/// [N x i32] or [N x i64]. This allows front-ends to skip emitting padding when
22560/// passing according to AAPCS rules.
22562 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
22563 const DataLayout &DL) const {
22564 if (getEffectiveCallingConv(CallConv, isVarArg) !=
22566 return false;
22567
22569 uint64_t Members = 0;
22570 bool IsHA = isHomogeneousAggregate(Ty, Base, Members);
22571 LLVM_DEBUG(dbgs() << "isHA: " << IsHA << " "; Ty->dump());
22572
22573 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
22574 return IsHA || IsIntArray;
22575}
22576
22578 ExceptionHandling EH, const Constant *PersonalityFn) const {
22579 // Platforms which do not use SjLj EH may return values in these registers
22580 // via the personality function.
22581 return EH == ExceptionHandling::SjLj ? Register() : ARM::R0;
22582}
22583
22585 ExceptionHandling EH, const Constant *PersonalityFn) const {
22586 // Platforms which do not use SjLj EH may return values in these registers
22587 // via the personality function.
22588 return EH == ExceptionHandling::SjLj ? Register() : ARM::R1;
22589}
22590
22591void ARMTargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
22592 // Update IsSplitCSR in ARMFunctionInfo.
22593 ARMFunctionInfo *AFI = Entry->getParent()->getInfo<ARMFunctionInfo>();
22594 AFI->setIsSplitCSR(true);
22595}
22596
22597void ARMTargetLowering::insertCopiesSplitCSR(
22598 MachineBasicBlock *Entry,
22599 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
22600 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
22601 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
22602 if (!IStart)
22603 return;
22604
22605 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
22606 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
22607 MachineBasicBlock::iterator MBBI = Entry->begin();
22608 for (const MCPhysReg *I = IStart; *I; ++I) {
22609 const TargetRegisterClass *RC = nullptr;
22610 if (ARM::GPRRegClass.contains(*I))
22611 RC = &ARM::GPRRegClass;
22612 else if (ARM::DPRRegClass.contains(*I))
22613 RC = &ARM::DPRRegClass;
22614 else
22615 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
22616
22617 Register NewVR = MRI->createVirtualRegister(RC);
22618 // Create copy from CSR to a virtual register.
22619 // FIXME: this currently does not emit CFI pseudo-instructions, it works
22620 // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
22621 // nounwind. If we want to generalize this later, we may need to emit
22622 // CFI pseudo-instructions.
22623 assert(Entry->getParent()->getFunction().hasFnAttribute(
22624 Attribute::NoUnwind) &&
22625 "Function should be nounwind in insertCopiesSplitCSR!");
22626 Entry->addLiveIn(*I);
22627 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
22628 .addReg(*I);
22629
22630 // Insert the copy-back instructions right before the terminator.
22631 for (auto *Exit : Exits)
22632 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
22633 TII->get(TargetOpcode::COPY), *I)
22634 .addReg(NewVR);
22635 }
22636}
22637
22642
22644 return Subtarget->hasMVEIntegerOps();
22645}
22646
22648 ComplexDeinterleavingOperation Operation, Type *Ty) const {
22649 auto *VTy = dyn_cast<FixedVectorType>(Ty);
22650 if (!VTy)
22651 return false;
22652
22653 auto *ScalarTy = VTy->getScalarType();
22654 unsigned NumElements = VTy->getNumElements();
22655
22656 unsigned VTyWidth = VTy->getScalarSizeInBits() * NumElements;
22657 if (VTyWidth < 128 || !llvm::isPowerOf2_32(VTyWidth))
22658 return false;
22659
22660 // Both VCADD and VCMUL/VCMLA support the same types, F16 and F32
22661 if (ScalarTy->isHalfTy() || ScalarTy->isFloatTy())
22662 return Subtarget->hasMVEFloatOps();
22663
22664 if (Operation != ComplexDeinterleavingOperation::CAdd)
22665 return false;
22666
22667 return Subtarget->hasMVEIntegerOps() &&
22668 (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
22669 ScalarTy->isIntegerTy(32));
22670}
22671
22673 static const MCPhysReg RCRegs[] = {ARM::FPSCR_RM};
22674 return RCRegs;
22675}
22676
22679 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
22680 Value *Accumulator) const {
22681
22683
22684 unsigned TyWidth = Ty->getScalarSizeInBits() * Ty->getNumElements();
22685
22686 assert(TyWidth >= 128 && "Width of vector type must be at least 128 bits");
22687
22688 if (TyWidth > 128) {
22689 int Stride = Ty->getNumElements() / 2;
22690 auto SplitSeq = llvm::seq<int>(0, Ty->getNumElements());
22691 auto SplitSeqVec = llvm::to_vector(SplitSeq);
22692 ArrayRef<int> LowerSplitMask(&SplitSeqVec[0], Stride);
22693 ArrayRef<int> UpperSplitMask(&SplitSeqVec[Stride], Stride);
22694
22695 auto *LowerSplitA = B.CreateShuffleVector(InputA, LowerSplitMask);
22696 auto *LowerSplitB = B.CreateShuffleVector(InputB, LowerSplitMask);
22697 auto *UpperSplitA = B.CreateShuffleVector(InputA, UpperSplitMask);
22698 auto *UpperSplitB = B.CreateShuffleVector(InputB, UpperSplitMask);
22699 Value *LowerSplitAcc = nullptr;
22700 Value *UpperSplitAcc = nullptr;
22701
22702 if (Accumulator) {
22703 LowerSplitAcc = B.CreateShuffleVector(Accumulator, LowerSplitMask);
22704 UpperSplitAcc = B.CreateShuffleVector(Accumulator, UpperSplitMask);
22705 }
22706
22707 auto *LowerSplitInt = createComplexDeinterleavingIR(
22708 B, OperationType, Rotation, LowerSplitA, LowerSplitB, LowerSplitAcc);
22709 auto *UpperSplitInt = createComplexDeinterleavingIR(
22710 B, OperationType, Rotation, UpperSplitA, UpperSplitB, UpperSplitAcc);
22711
22712 ArrayRef<int> JoinMask(&SplitSeqVec[0], Ty->getNumElements());
22713 return B.CreateShuffleVector(LowerSplitInt, UpperSplitInt, JoinMask);
22714 }
22715
22716 auto *IntTy = Type::getInt32Ty(B.getContext());
22717
22718 ConstantInt *ConstRotation = nullptr;
22719 if (OperationType == ComplexDeinterleavingOperation::CMulPartial) {
22720 ConstRotation = ConstantInt::get(IntTy, (int)Rotation);
22721
22722 if (Accumulator)
22723 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmlaq, Ty,
22724 {ConstRotation, Accumulator, InputB, InputA});
22725 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmulq, Ty,
22726 {ConstRotation, InputB, InputA});
22727 }
22728
22729 if (OperationType == ComplexDeinterleavingOperation::CAdd) {
22730 // 1 means the value is not halved.
22731 auto *ConstHalving = ConstantInt::get(IntTy, 1);
22732
22734 ConstRotation = ConstantInt::get(IntTy, 0);
22736 ConstRotation = ConstantInt::get(IntTy, 1);
22737
22738 if (!ConstRotation)
22739 return nullptr; // Invalid rotation for arm_mve_vcaddq
22740
22741 return B.CreateIntrinsic(Intrinsic::arm_mve_vcaddq, Ty,
22742 {ConstHalving, ConstRotation, InputA, InputB});
22743 }
22744
22745 return nullptr;
22746}
static bool isAddSubSExt(SDValue N, SelectionDAG &DAG)
static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, int64_t &Cnt)
isVShiftRImm - Check if this is a valid build_vector for the immediate operand of a vector shift righ...
static bool isExtendedBUILD_VECTOR(SDValue N, SelectionDAG &DAG, bool isSigned)
static SDValue carryFlagToValue(SDValue Glue, EVT VT, SelectionDAG &DAG, bool Invert)
static SDValue overflowFlagToValue(SDValue Glue, EVT VT, SelectionDAG &DAG)
static bool isZeroExtended(SDValue N, SelectionDAG &DAG)
static bool isCMN(SDValue Op, ISD::CondCode CC, SelectionDAG &DAG)
static const MCPhysReg GPRArgRegs[]
static SDValue valueToCarryFlag(SDValue Value, SelectionDAG &DAG, bool Invert)
constexpr MVT FlagsVT
Value type used for NZCV flags.
static unsigned getCmpOperandFoldingProfit(SDValue Op, bool AllowExtend)
Returns how profitable it is to fold a comparison's operand's shift and/or extension operations.
static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt)
getVShiftImm - Check if this is a valid build_vector for the immediate operand of a vector shift oper...
static bool optimizeLogicalImm(SDValue Op, unsigned Size, uint64_t Imm, const APInt &Demanded, TargetLowering::TargetLoweringOpt &TLO, unsigned NewOpc)
static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG)
static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG)
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static bool isAddSubZExt(SDValue N, SelectionDAG &DAG)
static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt)
isVShiftLImm - Check if this is a valid build_vector for the immediate operand of a vector shift left...
static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls)
Return true if the calling convention is one that we can guarantee TCO for.
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
uint64_t uint64_t
uint64_t Imm
static bool isConstant(const MachineInstr &MI)
constexpr LLT F64
constexpr LLT S1
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
static bool isStore(int Opcode)
static bool isThumb(const MCSubtargetInfo &STI)
static SDValue PerformExtractEltToVMOVRRD(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT)
static SDValue PerformVQDMULHCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformVECTOR_DEINTERLEAVECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerBUILD_VECTOR_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerShift(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue AddRequiredExtensionForVMULL(SDValue N, SelectionDAG &DAG, const EVT &OrigTy, const EVT &ExtTy, unsigned ExtOpcode)
AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total value size to 64 bits.
static cl::opt< unsigned > ConstpoolPromotionMaxSize("arm-promote-constant-max-size", cl::Hidden, cl::desc("Maximum size of constant to promote into a constant pool"), cl::init(64))
static bool isZeroOrAllOnes(SDValue N, bool AllOnes)
static SDValue LowerINSERT_VECTOR_ELT_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isVTBLMask(ArrayRef< int > M, EVT VT)
static SDValue PerformSUBCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
static cl::opt< bool > EnableConstpoolPromotion("arm-promote-constant", cl::Hidden, cl::desc("Enable / disable promotion of unnamed_addr constants into " "constant pools"), cl::init(false))
static SDValue PerformFAddVSelectCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformExtractFpToIntStores(StoreSDNode *St, SelectionDAG &DAG)
static SDValue PerformVDUPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
static SDValue PerformExtractEltCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static const APInt * isPowerOf2Constant(SDValue V)
static SDValue PerformVCVTCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD) can replace combinations of ...
static SDValue PerformVMOVhrCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerVectorFP_TO_INT(SDValue Op, SelectionDAG &DAG)
static SDValue LowerVECTOR_SHUFFLEUsingOneOff(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static bool isValidMVECond(unsigned CC, bool IsFloat)
static SDValue PerformPREDICATE_CASTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC)
IntCCToARMCC - Convert a DAG integer condition code to an ARM CC.
static SDValue PerformSTORECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSTORECombine - Target-specific dag combine xforms for ISD::STORE.
static SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isGTorGE(ISD::CondCode CC)
static bool CombineVLDDUP(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a vldN-lane (N > 1) intrinsic,...
static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask)
static bool isReverseMask(ArrayRef< int > M, EVT VT)
static SDValue PerformLegalizedVECTOR_DEINTERLEAVECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue AddCombineTo64bitUMAAL(SDNode *AddeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformVECTOR_REG_CASTCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVMulVCTPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD) can replace combinations...
static SDValue createGPRPairNode2xi32(SelectionDAG &DAG, SDValue V0, SDValue V1)
static SDValue bitcastf32Toi32(SDValue Op, SelectionDAG &DAG)
static bool findPointerConstIncrement(SDNode *N, SDValue *Ptr, SDValue *CInc)
static SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool CanInvertMVEVCMP(SDValue N)
static SDValue PerformLongShiftCombine(SDNode *N, SelectionDAG &DAG)
static SDValue AddCombineToVPADD(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformShiftCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
PerformShiftCombine - Checks for immediate versions of vector shifts and lowers them.
static void FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, ARMCC::CondCodes &CondCode2)
FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
static void ExpandREAD_REGISTER(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static EVT getVectorTyFromPredicateVector(EVT VT)
static SDValue PerformFADDVCMLACombine(SDNode *N, SelectionDAG &DAG)
static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg, SelectionDAG &DAG, const SDLoc &DL)
static SDValue PerformARMBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
static bool isSRL16(const SDValue &Op)
static SDValue PerformVMOVrhCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformLOADCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue IsCMPZCSINC(SDNode *Cmp, ARMCC::CondCodes &CC)
static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr, SDValue Inc, const SelectionDAG &DAG)
static SDValue combineSelectAndUseCommutative(SDNode *N, bool AllOnes, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static Register genTPEntry(MachineBasicBlock *TpEntry, MachineBasicBlock *TpLoopBody, MachineBasicBlock *TpExit, Register OpSizeReg, const TargetInstrInfo *TII, DebugLoc Dl, MachineRegisterInfo &MRI)
Adds logic in loop entry MBB to calculate loop iteration count and adds t2WhileLoopSetup and t2WhileL...
static SDValue createGPRPairNodei64(SelectionDAG &DAG, SDValue V)
static bool isLTorLE(ISD::CondCode CC)
static SDValue PerformVCMPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformMVEVMULLCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerSDIV_v4i16(SDValue N0, SDValue N1, const SDLoc &dl, SelectionDAG &DAG)
static SDValue performNegCMovCombine(SDNode *N, SelectionDAG &DAG)
static EVT getExtensionTo64Bits(const EVT &OrigVT)
static TargetLowering::ArgListTy getDivRemArgList(const SDNode *N, FunctionType *FuncTy, const AttributeList &FuncAttrs, RTLIB::LibcallImpl LCImpl)
static SDValue PerformBITCASTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue AddCombineTo64bitMLAL(SDNode *AddeSubeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG)
static bool checkAndUpdateCPSRKill(MachineBasicBlock::iterator SelectItr, MachineBasicBlock *BB, const TargetRegisterInfo *TRI)
static SDValue PerformInterleavedStoreCombine(StoreSDNode *ST, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformCMPZCombine(SDNode *N, SelectionDAG &DAG)
static bool hasNormalLoadOperand(SDNode *N)
hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node are normal,...
static SDValue PerformInsertEltCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
PerformInsertEltCombine - Target-specific dag combine xforms for ISD::INSERT_VECTOR_ELT.
static SDValue PerformVDUPLANECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVDUPLANECombine - Target-specific dag combine xforms for ARMISD::VDUPLANE.
static SDValue LowerBuildVectorOfFPTrunc(SDValue BV, SelectionDAG &DAG, const ARMSubtarget *ST)
static cl::opt< unsigned > ConstpoolPromotionMaxTotal("arm-promote-constant-max-total", cl::Hidden, cl::desc("Maximum size of ALL constants to promote into a constant pool"), cl::init(128))
static SDValue LowerTruncatei1(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static RTLIB::Libcall getDivRemLibcall(const SDNode *N, MVT::SimpleValueType SVT)
static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG &DAG)
SkipLoadExtensionForVMULL - return a load of the original vector size that does not do any sign/zero ...
static SDValue AddCombineVUZPToVPADDL(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformADDCombineWithOperands(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDCombineWithOperands - Try DAG combinations for an ADD with operands N0 and N1.
static SDValue PromoteMVEPredVector(SDLoc dl, SDValue Pred, EVT VT, SelectionDAG &DAG)
static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal, SDValue FalseVal, const ARMSubtarget *Subtarget)
static bool isSequentialConcatOfVectorInterleave(SDNode *N, SmallVectorImpl< SDValue > &Ops)
static SDValue PerformORCombineToSMULWBT(SDNode *OR, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerUDIV(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue FindBFIToCombineWith(SDNode *N)
static SDValue LowerADDSUBSAT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static void checkVSELConstraints(ISD::CondCode CC, ARMCC::CondCodes &CondCode, bool &swpCmpOps, bool &swpVselOps)
static void ReplaceLongIntrinsic(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static bool isS16(const SDValue &Op, SelectionDAG &DAG)
static bool isSRA16(const SDValue &Op)
static SDValue AddCombineBUILD_VECTORToVPADDL(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerVECTOR_SHUFFLEUsingMovs(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static SDValue LowerInterruptReturn(SmallVectorImpl< SDValue > &RetOps, const SDLoc &DL, SelectionDAG &DAG)
static SDValue LowerEXTRACT_VECTOR_ELT_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue getInvertedARMCondCode(SDValue ARMcc, SelectionDAG &DAG)
static SDValue LowerSDIV_v4i8(SDValue X, SDValue Y, const SDLoc &dl, SelectionDAG &DAG)
static void expandf64Toi32(SDValue Op, SelectionDAG &DAG, SDValue &RetVal1, SDValue &RetVal2)
static SDValue LowerCONCAT_VECTORS_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerCTTZ(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVLDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static bool isSHL16(const SDValue &Op)
static bool isVEXTMask(ArrayRef< int > M, EVT VT, bool &ReverseVEXT, unsigned &Imm)
static SDValue PerformMVEVLDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
cl::opt< unsigned > ArmMaxBaseUpdatesToCheck("arm-max-base-updates-to-check", cl::Hidden, cl::desc("Maximum number of base-updates to check generating postindex."), cl::init(64))
static bool isTruncMask(ArrayRef< int > M, EVT VT, bool Top, bool SingleSource)
static SDValue PerformADDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2)
Return the load opcode for a given load size.
static SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG, unsigned Opcode, bool IsSigned)
static bool isLegalT2AddressImmediate(int64_t V, EVT VT, const ARMSubtarget *Subtarget)
static bool isLegalMVEShuffleOp(unsigned PFEntry)
static SDValue PerformSignExtendInregCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformShuffleVMOVNCombine(ShuffleVectorSDNode *N, SelectionDAG &DAG)
static SDValue PerformVECTOR_SHUFFLECombine(SDNode *N, SelectionDAG &DAG)
PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for ISD::VECTOR_SHUFFLE.
static SDValue SkipExtensionForVMULL(SDNode *N, SelectionDAG &DAG)
SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND, ANY_EXTEND,...
static int getNegationCost(SDValue Op)
static bool isVMOVNTruncMask(ArrayRef< int > M, EVT ToVT, bool rev)
static SDValue PerformVQMOVNCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static MachineBasicBlock * OtherSucc(MachineBasicBlock *MBB, MachineBasicBlock *Succ)
static SDValue LowerVecReduceMinMax(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformFPExtendCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformAddcSubcCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformVSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformVECREDUCE_ADDCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getZeroVector - Returns a vector of specified type with all zero elements.
static SDValue LowerAtomicLoadStore(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSplittingToNarrowingStores(StoreSDNode *St, SelectionDAG &DAG)
static bool getT2IndexedAddressParts(SDNode *Ptr, EVT VT, bool isSEXTLoad, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
static ARMCC::CondCodes getVCMPCondCode(SDValue N)
static cl::opt< bool > ARMInterworking("arm-interworking", cl::Hidden, cl::desc("Enable / disable ARM interworking (for debugging only)"), cl::init(true))
static void ReplaceREADCYCLECOUNTER(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformORCombineToBFI(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC, bool &Invert, SDValue &OtherOp, SelectionDAG &DAG)
static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVSetCCToVCTPCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerBUILD_VECTORToVIDUP(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isZeroVector(SDValue N)
static SDValue PerformAddeSubeCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static void ReplaceCMP_SWAP_64Results(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static bool isLowerSaturate(const SDValue LHS, const SDValue RHS, const SDValue TrueVal, const SDValue FalseVal, const ISD::CondCode CC, const SDValue K)
static bool isLegalLogicalImmediate(unsigned Imm, const ARMSubtarget *Subtarget)
static SDValue LowerPredicateLoad(SDValue Op, SelectionDAG &DAG)
static void emitPostSt(MachineBasicBlock *BB, MachineBasicBlock::iterator Pos, const TargetInstrInfo *TII, const DebugLoc &dl, unsigned StSize, unsigned Data, unsigned AddrIn, unsigned AddrOut, bool IsThumb1, bool IsThumb2)
Emit a post-increment store operation with given size.
static bool isVMOVNMask(ArrayRef< int > M, EVT VT, bool Top, bool SingleSource)
static SDValue CombineBaseUpdate(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
CombineBaseUpdate - Target-specific DAG combine function for VLDDUP, NEON load/store intrinsics,...
static SDValue LowerSaturatingConditional(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSubCSINCCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformVMOVRRDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVMOVRRDCombine - Target-specific dag combine xforms for ARMISD::VMOVRRD.
static SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformCSETCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformVMOVNCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue PerformInsertSubvectorCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerVectorExtend(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue WinDBZCheckDenominator(SelectionDAG &DAG, SDNode *N, SDValue InChain)
static SDValue LowerVECTOR_SHUFFLEv8i8(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static SDValue PerformVMULCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVMULCombine Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the special multi...
static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG)
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static SDValue PerformBFICombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformORCombine - Target-specific dag combine xforms for ISD::OR.
static SDValue LowerMLOAD(SDValue Op, SelectionDAG &DAG)
static SDValue PerformTruncatingStoreCombine(StoreSDNode *St, SelectionDAG &DAG)
static void emitPostLd(MachineBasicBlock *BB, MachineBasicBlock::iterator Pos, const TargetInstrInfo *TII, const DebugLoc &dl, unsigned LdSize, unsigned Data, unsigned AddrIn, unsigned AddrOut, bool IsThumb1, bool IsThumb2)
Emit a post-increment load operation with given size.
static SDValue TryDistrubutionADDVecReduce(SDNode *N, SelectionDAG &DAG)
static bool isValidBaseUpdate(SDNode *N, SDNode *User)
static SDValue IsSingleInstrConstant(SDValue N, SelectionDAG &DAG, const ARMSubtarget *ST, const SDLoc &dl)
static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op)
static SDValue PerformMinMaxToSatCombine(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformXORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment, bool isSEXTLoad, bool IsMasked, bool isLE, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
std::pair< unsigned, const TargetRegisterClass * > RCPair
static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, TargetLowering::DAGCombinerInfo &DCI, bool AllOnes=false)
static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND, ISD::ZERO_EXTEND,...
static SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
cl::opt< unsigned > MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden, cl::desc("Maximum interleave factor for MVE VLDn to generate."), cl::init(2))
static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef, unsigned SplatBitSize, SelectionDAG &DAG, const SDLoc &dl, EVT &VT, EVT VectorVT, VMOVModImmType type)
isVMOVModifiedImm - Check if the specified splat value corresponds to a valid vector constant for a N...
static SDValue LowerBuildVectorOfFPExt(SDValue BV, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue CombineVMOVDRRCandidateWithVecOp(const SDNode *BC, SelectionDAG &DAG)
BC is a bitcast that is about to be turned into a VMOVDRR.
static SDValue promoteToConstantPool(const ARMTargetLowering *TLI, const GlobalValue *GV, SelectionDAG &DAG, EVT PtrVT, const SDLoc &dl)
static unsigned isNEONTwoResultShuffleMask(ArrayRef< int > ShuffleMask, EVT VT, unsigned &WhichResult, bool &isV_UNDEF)
Check if ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN), and return the corresponding AR...
static bool BitsProperlyConcatenate(const APInt &A, const APInt &B)
static bool getARMIndexedAddressParts(SDNode *Ptr, EVT VT, bool isSEXTLoad, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
static SDValue LowerVecReduce(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG)
static bool TryCombineBaseUpdate(struct BaseUpdateTarget &Target, struct BaseUpdateUser &User, bool SimpleConstIncOnly, TargetLowering::DAGCombinerInfo &DCI)
static bool allUsersAreInFunction(const Value *V, const Function *F)
Return true if all users of V are within function F, looking through ConstantExprs.
static bool isSingletonVEXTMask(ArrayRef< int > M, EVT VT, unsigned &Imm)
static SDValue PerformVMOVDRRCombine(SDNode *N, SelectionDAG &DAG)
PerformVMOVDRRCombine - Target-specific dag combine xforms for ARMISD::VMOVDRR.
static SDValue PerformLegalizedInterleavedStoreCombine(StoreSDNode *ST, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static bool isLowerSaturatingConditional(const SDValue &Op, SDValue &V, SDValue &SatK)
static bool isLegalAddressImmediate(int64_t V, EVT VT, const ARMSubtarget *Subtarget)
isLegalAddressImmediate - Return true if the integer value can be used as the offset of the target ad...
static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isLegalT1AddressImmediate(int64_t V, EVT VT)
static SDValue CombineANDShift(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSHLSimplify(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue PerformADDECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDECombine - Target-specific dag combine transform from ARMISD::ADDC, ARMISD::ADDE,...
static SDValue PerformReduceShuffleCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerTruncate(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformHWLoopCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue PerformORCombineToShiftInsert(SelectionDAG &DAG, SDValue AndOp, SDValue ShiftOp, EVT VT, SDLoc dl)
static SDValue PerformSplittingMVETruncToNarrowingStores(StoreSDNode *St, SelectionDAG &DAG)
static bool isHomogeneousAggregate(Type *Ty, HABaseType &Base, uint64_t &Members)
static SDValue PerformMULCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformFADDCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerReverse_VECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
static SDValue getShiftedLowMaskZeroTest(SDValue Value, SelectionDAG &DAG, const SDLoc &DL)
static SDValue PerformANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformADDVecReduce(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerPredicateStore(SDValue Op, SelectionDAG &DAG)
static SDValue SearchLoopIntrinsic(SDValue N, ISD::CondCode &CC, int &Imm, bool &Negate)
static bool canChangeToInt(SDValue Op, bool &SeenZero, const ARMSubtarget *Subtarget)
canChangeToInt - Given the fp compare operand, return true if it is suitable to morph to an integer c...
static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2)
Return the store opcode for a given store size.
static bool IsVUZPShuffleNode(SDNode *N)
static SDValue Expand64BitShift(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget, MachineInstr &MI, const SDNode *Node)
Attaches vregs to MEMCPY that it will use as scratch registers when it is expanded into LDM/STM.
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
static SDValue findMUL_LOHI(SDValue V)
static SDValue LowerVECTOR_SHUFFLE_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformORCombine_i1(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformSplittingMVEEXTToWideningLoad(SDNode *N, SelectionDAG &DAG)
static SDValue PerformSplittingToWideningLoad(SDNode *N, SelectionDAG &DAG)
static void genTPLoopBody(MachineBasicBlock *TpLoopBody, MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit, const TargetInstrInfo *TII, DebugLoc Dl, MachineRegisterInfo &MRI, Register OpSrcReg, Register OpDestReg, Register ElementCountReg, Register TotalIterationsReg, bool IsMemcpy)
Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and t2DoLoopEnd.
static SDValue PerformBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformBUILD_VECTORCombine - Target-specific dag combine xforms for ISD::BUILD_VECTOR.
static SDValue LowerVecReduceF(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformMinMaxCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
PerformMinMaxCombine - Target-specific DAG combining for creating truncating saturates.
arm ldst static false bool definesCPSR(const MachineInstr &MI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file a TargetTransformInfoImplBase conforming object specific to the ARM target machine.
Function Alias Analysis false
Function Alias Analysis Results
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void createLoadIntrinsic(IntrinsicInst *II, LoadInst *LI, dxil::ResourceTypeInfo &RTI)
static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI, dxil::ResourceTypeInfo &RTI)
This file defines the DenseMap class.
static bool isSigned(unsigned Opcode)
#define Check(C,...)
#define op(i)
#define im(i)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
std::pair< Value *, Value * > ShuffleOps
We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs.
static Value * LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctpop of V before the specified instruction IP.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LVOptions Options
Definition LVOptions.cpp:25
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
nvptx lower args
uint64_t High
uint64_t IntrinsicInst * II
R600 Clause Merge
SmallVector< MachineOperand, 4 > Cond
int64_t C1
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
int64_t C0
MachineInstr *& Lo
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Contains matchers for matching SelectionDAG nodes and values.
SI Lower i1 Copies
Func MI getDebugLoc()))
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This file describes how to lower LLVM code to machine code.
static X86::CondCode getSwappedCondition(X86::CondCode CC)
Assuming the flags are set by MI(a,b), return the condition code if we modify the instructions such t...
static constexpr int Concat[]
Value * RHS
Value * LHS
BinaryOperator * Mul
static bool isIntrinsic(const CallBase &Call, Intrinsic::ID ID)
The Input class is used to parse a yaml document into in-memory structs and vectors.
static constexpr roundingMode rmTowardZero
Definition APFloat.h:365
LLVM_ABI bool getExactInverse(APFloat *Inv) const
If this value is normal and has an exact, normal, multiplicative inverse, store it in inv and return ...
Definition APFloat.cpp:5986
APInt bitcastToAPInt() const
Definition APFloat.h:1475
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1436
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition APInt.h:419
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1690
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1532
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:970
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1350
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1205
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
unsigned countr_zero() const
Count the number of trailing zero bits.
Definition APInt.h:1659
unsigned countl_zero() const
The APInt version of std::countl_zero.
Definition APInt.h:1618
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
Definition APInt.cpp:648
unsigned logBase2() const
Definition APInt.h:1781
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Definition APInt.h:471
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition APInt.h:1261
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:436
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
Definition APInt.h:860
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:853
unsigned countr_one() const
Count the number of trailing one bits.
Definition APInt.h:1676
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1225
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
const ARMBaseRegisterInfo & getRegisterInfo() const
const uint32_t * getSjLjDispatchPreservedMask(const MachineFunction &MF) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Register getFrameRegister(const MachineFunction &MF) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const uint32_t * getTLSCallPreservedMask(const MachineFunction &MF) const
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
static ARMConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *mbb, unsigned ID, unsigned char PCAdj)
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj, ARMCP::ARMCPModifier Modifier=ARMCP::no_modifier, bool AddCurrentAddress=false)
ARMConstantPoolValue - ARM specific constantpool value.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
SmallVectorImpl< ForwardedRegister > & getForwardedMustTailRegParms()
SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()
void setArgumentStackToRestore(unsigned v)
void setArgRegsSaveSize(unsigned s)
void setReturnRegsCount(unsigned s)
unsigned getArgRegsSaveSize() const
void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV)
Indicate to the backend that GV has had its storage changed to inside a constant pool.
void setArgumentStackSize(unsigned size)
unsigned getArgumentStackSize() const
const Triple & getTargetTriple() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
bool useFPVFMx() const
bool isThumb2() const
bool hasBaseDSP() const
const ARMTargetLowering * getTargetLowering() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
bool hasVFP2Base() const
bool useFPVFMx64() const
bool isLittle() const
bool useFPVFMx16() const
bool isMClass() const
bool useMulOps() const
bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X, SDValue Y) const override
Return true if pulling a binary operation into a select with an identity constant is profitable.
bool isReadOnly(const GlobalValue *GV) const
unsigned getMaxSupportedInterleaveFactor() const override
Get the maximum supported factor for interleaved memory accesses.
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be expanded by the IR-level AtomicExpand pass.
unsigned getNumInterleavedAccesses(VectorType *VecTy, const DataLayout &DL) const
Returns the number of interleaved accesses that will be generated when lowering accesses of the given...
bool shouldInsertFencesForAtomic(const Instruction *I) const override
Whether AtomicExpandPass should automatically insert fences and reduce ordering for this atomic.
Align getABIAlignmentForCallingConv(Type *ArgTy, const DataLayout &DL) const override
Return the correct alignment for the current calling convention.
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
const ARMSubtarget * getSubtarget() const
bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const
bool isLegalT1ScaledAddressingMode(const AddrMode &AM, EVT VT) const
Returns true if the addressing mode representing by AM is legal for the Thumb1 target,...
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
MachineInstr * EmitKCFICheck(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MBBI, const TargetInstrInfo *TII) const override
bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize, Align &PrefAlign) const override
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
getTgtMemIntrinsic - Represent NEON load and store intrinsics as MemIntrinsicNodes.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
void emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override
bool isMulAddWithConstProfitable(SDValue AddNode, SDValue ConstNode) const override
Return true if it may be profitable to transform (mul (add x, c1), c2) -> (add (mul x,...
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
void finalizeLowering(MachineFunction &MF) const override
Execute target specific actions to finalize target lowering.
SDValue PerformMVETruncCombine(SDNode *N, DAGCombinerInfo &DCI) const
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint letter, return the type of constraint it is for this target.
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize=false) const override
Returns how to materialize the specified FP immediate.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
SDValue PerformIntrinsicCombine(SDNode *N, DAGCombinerInfo &DCI) const
PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override
Return true if it is profitable to fold a pair of shifts into a mask.
bool isDesirableToCommuteXorWithShift(const SDNode *N) const override
Return true if it is profitable to combine an XOR of a logical shift to create a logical shift of NOT...
SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const
PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Value * createComplexDeinterleavingIR(IRBuilderBase &B, ComplexDeinterleavingOperation OperationType, ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB, Value *Accumulator=nullptr) const override
Create the IR node for the given complex deinterleaving operation.
bool isComplexDeinterleavingSupported() const override
Does this target support complex deinterleaving.
SDValue PerformMVEExtCombine(SDNode *N, DAGCombinerInfo &DCI) const
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering) const override
createFastISel - This method returns a target specific FastISel object, or null if the target does no...
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Inserts necessary declarations for SSP (stack protection) purpose.
bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &OriginalDemandedBits, const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth) const override
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the value type to use for ISD::SETCC.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
bool isShuffleMaskLegal(ArrayRef< int > M, EVT VT) const override
isShuffleMaskLegal - Targets can use this to indicate that they only support some VECTOR_SHUFFLE oper...
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
bool lowerInterleavedStore(Instruction *Store, Value *Mask, ShuffleVectorInst *SVI, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved store into a vstN intrinsic.
const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const override
getRegClassFor - Return the register class that should be used for the specified value type.
bool useLoadStackGuardNode(const Module &M) const override
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
bool lowerInterleavedLoad(Instruction *Load, Value *Mask, ArrayRef< ShuffleVectorInst * > Shuffles, ArrayRef< unsigned > Indices, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved load into a vldN intrinsic.
std::pair< const TargetRegisterClass *, uint8_t > findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const override
Return the largest legal super-reg register class of the register class for the specified type and it...
bool preferSelectsOverBooleanArithmetic(EVT VT) const override
Should we prefer selects to doing arithmetic on boolean types.
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const override
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
ExtractSubvectorCost getExtractSubvectorCost(EVT ResVT, EVT SrcVT, unsigned Index) const override
Return the cost of EXTRACT_SUBVECTOR for this result type with this index.
CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC, bool isVarArg) const
getEffectiveCallingConv - Get the effective calling convention, taking into account presence of float...
ARMTargetLowering(const TargetMachine &TM, const ARMSubtarget &STI)
bool isComplexDeinterleavingOperationSupported(ComplexDeinterleavingOperation Operation, Type *Ty) const override
Does this target support complex deinterleaving with the given operation and type.
bool supportKCFIBundles() const override
Return true if the target supports kcfi operand bundles.
SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const
PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const override
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
Instruction * makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
const char * LowerXConstraint(EVT ConstraintVT) const override
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const override
Return true if it is profitable for dag combiner to transform a floating point op of specified opcode...
CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
allowsMisalignedMemoryAccesses - Returns true if the target allows unaligned memory accesses of the s...
bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy, Align Alignment, const DataLayout &DL) const
Returns true if VecTy is a legal interleaved access type.
bool isVectorLoadExtDesirable(SDValue ExtVal) const override
Return true if folding a vector load into ExtVal (a sign, zero, or any extend node) is profitable.
bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const override
Return true if the target can combine store(extractelement VectorTy,Idx).
bool useSoftFloat() const override
bool alignLoopsWithOptSize() const override
Should loops be aligned even when the function is marked OptSize (but not MinSize).
SDValue PerformCMOVToBFICombine(SDNode *N, SelectionDAG &DAG) const
bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool hasAndNotCompare(SDValue V) const override
Return true if the target should transform: (X & Y) == Y ---> (~X & Y) == 0 (X & Y) !...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override
Should we generate fp_to_si_sat and fp_to_ui_sat from type FPVT to type VT.
bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg, const DataLayout &DL) const override
Returns true if an argument of type Ty needs to be passed in a contiguous block of registers in calli...
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
const ARMBaseTargetMachine & getTM() const
bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override
Return if the target supports combining a chain like:
ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const override
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPostIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mo...
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override
Return true if Op can create undef or poison from non-undef & non-poison operands.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
bool isFloatingPointOperation() const
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static LLVM_ABI BaseIndexOffset match(const SDNode *N, const SelectionDAG &DAG)
Parses tree in N for base, index, offset addresses.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
The address of a basic block.
Definition Constants.h:1088
static constexpr BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements, uint32_t BitWidth) const
If this is a constant FP splat and the splatted constant FP is an exact power or 2,...
CCState - This class holds information needed while lowering arguments and return values.
void getInRegsParamInfo(unsigned InRegsParamRecordIndex, unsigned &BeginReg, unsigned &EndReg) const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
LLVM_ABI void analyzeMustTailForwardedRegisters(SmallVectorImpl< ForwardedRegister > &Forwards, ArrayRef< MVT > RegParmTypes, CCAssignFn Fn)
Compute the set of registers that need to be preserved and forwarded to any musttail calls.
static LLVM_ABI bool resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC, MachineFunction &MF, LLVMContext &C, const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn CalleeFn, CCAssignFn CallerFn)
Returns true if the results of the two calling conventions are compatible.
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
unsigned getInRegsParamsProcessed() const
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd)
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
unsigned getInRegsParamsCount() const
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
int64_t getLocMemOffset() const
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
This class represents a function call, abstracting a target machine's calling convention.
bool isTailCall() const
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
Definition Constants.h:878
const APFloat & getValueAPF() const
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
This is the shared class of boolean and integer constants.
Definition Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
MachineConstantPoolValue * getMachineCPVal() const
const Constant * getConstVal() const
LLVM_ABI Type * getType() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
Definition Constant.h:44
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
bool isLittleEndian() const
Layout endianness...
Definition DataLayout.h:217
bool isBigEndian() const
Definition DataLayout.h:218
MaybeAlign getStackAlignment() const
Returns the natural stack alignment, or MaybeAlign() if one wasn't specified.
Definition DataLayout.h:250
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
StringRef getInternalSymbolPrefix() const
Definition DataLayout.h:308
LLVM_ABI Align getPreferredAlign(const GlobalVariable *GV) const
Returns the preferred alignment of the specified global.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
A debug info location.
Definition DebugLoc.h:126
bool empty() const
Definition DenseMap.h:716
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
unsigned size() const
Definition DenseMap.h:717
iterator begin()
Definition DenseMap.h:682
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition FastISel.h:67
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Type * getParamType(unsigned i) const
Parameter type accessors.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:212
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:696
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
arg_iterator arg_begin()
Definition Function.h:853
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:673
const Argument * const_arg_iterator
Definition Function.h:74
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
const GlobalValue * getGlobal() const
bool isDSOLocal() const
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
LLVM_ABI bool hasAtomicStore() const LLVM_READONLY
Return true if this atomic instruction stores to memory.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
Tracks which library functions to use for a particular subtarget or function.
const RTLIB::RuntimeLibcallsInfo & getRuntimeLibcallsInfo() const
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
Describe properties that are true of each instruction in the target description file.
Machine Value Type.
static MVT getFloatingPointVT(unsigned BitWidth)
static auto integer_fixedlen_vector_valuetypes()
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isInteger() const
Return true if this is an integer or a vector integer type.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
bool is64BitVector() const
Return true if this is a 64-bit vector type.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
bool hasMustTailInVarArgFunc() const
Returns true if the function is variadic and contains a musttail call.
void setReturnAddressIsTaken(bool s)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
int getFunctionContextIndex() const
Return the index for the function context object.
Properties which a MachineFunction may have at a given point in time.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_Inline
EK_Inline - Jump table entries are emitted inline at their point of use.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
This class is used to represent an MLOAD node.
This class is used to represent an MSTORE node.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
Align getAlign() const
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition Module.h:328
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
LLVM_ABI bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
const APInt & getConstantOperandAPInt(unsigned Num) const
Helper method returns the APInt of a ConstantSDNode operand.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
LLVM_ABI bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void setCFIType(uint32_t Type)
bool isUndef() const
Returns true if the node type is UNDEF or POISON.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
op_iterator op_end() const
op_iterator op_begin() const
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getSplatValue(SDValue V, bool LegalTypes=false)
If V is a splat vector, return its scalar source operand by extracting that element from the source v...
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * getNodeIfExists(unsigned Opcode, SDVTList VTList, ArrayRef< SDValue > Ops, const SDNodeFlags Flags, bool AllowCommute=false)
Get the specified node if it's already available, or else return NULL.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI bool haveNoCommonBitsSet(SDValue A, SDValue B) const
Return true if A and B have no common bits set.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
std::pair< SDValue, SDValue > SplitVectorOperand(const SDNode *N, unsigned OpNo)
Split the node's operand with EXTRACT_SUBVECTOR and return the low/high part.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getNegative(SDValue Val, const SDLoc &DL, EVT VT)
Create negative operation as (SUB 0, Val).
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provided VTs and return the low/high part.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI MaybeAlign InferPtrAlign(SDValue Ptr) const
Infer alignment of a load / store address.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI OverflowKind computeOverflowForSignedAdd(SDValue N0, SDValue N1) const
Determine if the result of the signed addition of 2 nodes can overflow.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)
Set CallSiteInfo to be associated with Node.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base, SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexedMode AM, ISD::LoadExtType, bool IsExpanding=false)
DenormalMode getDenormalMode(EVT VT) const
Return the current function's default denormal handling kind for the given floating point type.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI bool areNonVolatileConsecutiveStores(StoreSDNode *ST, StoreSDNode *Base, unsigned Bytes, int Dist) const
Return true if stores are next to each other and can be merged.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
This instruction constructs a fixed permutation of two input vectors.
VectorType * getType() const
Overload to return most specific vector type.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
static LLVM_ABI bool isSplatMask(ArrayRef< int > Mask)
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
bool empty() const
Definition SmallSet.h:169
bool erase(const T &V)
Definition SmallSet.h:200
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
const unsigned char * bytes_end() const
Definition StringRef.h:125
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
const unsigned char * bytes_begin() const
Definition StringRef.h:122
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual void finalizeLowering(MachineFunction &MF) const
Execute target specific actions to finalize target lowering.
void setMaxDivRemBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum div/rem the backend supports.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
ShiftLegalizationStrategy
Return the preferred strategy to legalize tihs SHIFT instruction, with ExpansionFactor being the recu...
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
const TargetMachine & getTargetMachine() const
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize=false) const
Returns true if the specified FP immediate can be materialized without a load from the constant pool.
void setIndexedMaskedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed masked load does or does not work with the specified type and ind...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
ExtractSubvectorCost
Enum that specifies how expensive lowering an EXTRACT_SUBVECTOR is.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
virtual unsigned getMaxSupportedInterleaveFactor() const
Get the maximum supported factor for interleaved memory accesses.
void setIndexedMaskedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed masked store does or does not work with the specified type and in...
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
@ Bitcast
Build the immediate as a bitcast of an integer constant with the same bits.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
virtual ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
virtual bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
virtual std::pair< const TargetRegisterClass *, uint8_t > findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const
Return the largest legal super-reg register class of the register class for the specified type and it...
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Get the libcall impl routine name for the specified libcall.
static StringRef getLibcallImplName(RTLIB::LibcallImpl Call)
Get the libcall routine name for the specified libcall implementation.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool SimplifyDemandedVectorElts(SDValue Op, const APInt &DemandedEltMask, APInt &KnownUndef, APInt &KnownZero, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Vector Op.
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
bool parametersInCSRMatch(const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask, const SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< SDValue > &OutVals) const
Check whether parameters to a call that are passed in callee saved registers are the same as from the...
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool expandDIVREMByConstant(SDNode *N, SmallVectorImpl< SDValue > &Result, EVT HiLoVT, SelectionDAG &DAG, SDValue LL=SDValue(), SDValue LH=SDValue()) const
Attempt to expand an n-bit div/rem/divrem by constant using an n/2-bit algorithm.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
SDValue buildLegalVectorShuffle(EVT VT, const SDLoc &DL, SDValue N0, SDValue N1, MutableArrayRef< int > Mask, SelectionDAG &DAG) const
Tries to build a legal vector shuffle using the provided parameters or equivalent variations.
static ArgListTy getArgListForFunctionType(FunctionType *FuncTy, const AttributeList &FuncAttrs, ArrayRef< SDValue > Ops)
Build a call argument list for FuncTy, taking the argument node values from Ops and the parameter typ...
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
virtual bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0) const
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
TargetLowering(const TargetLowering &)=delete
bool isConstTrueVal(SDValue N) const
Return if the N is a constant or constant vector equal to the true value from getBooleanContents().
virtual ArrayRef< MCPhysReg > getRoundingControlRegisters() const
Returns a 0 terminated array of rounding control registers that can be attached into strict FP call.
virtual bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const
Return true if Op can create undef or poison from non-undef & non-poison operands.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
void setTypeIdForCallsiteInfo(const CallBase *CB, MachineFunction &MF, MachineFunction::CallSiteInfo &CSInfo) const
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const Triple & getTargetTriple() const
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
TargetOptions Options
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition Triple.h:539
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:352
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:298
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition Use.cpp:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
Base class of all SIMD vector types.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
IteratorT end() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static CondCodes getOppositeCondition(CondCodes CC)
Definition ARMBaseInfo.h:49
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
Definition ARMBaseInfo.h:72
@ SECREL
Thread Pointer Offset.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
TOF
Target Operand Flag enum.
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
static ShiftOpc getShiftOpcForNode(unsigned Opcode)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
uint64_t decodeVMOVModImm(unsigned ModImm, unsigned &EltBits)
decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the element value and the element ...
unsigned getAM2Offset(unsigned AM2Opc)
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned createVMOVModImm(unsigned OpCmode, unsigned Val)
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
int getFP16Imm(const APInt &Imm)
getFP16Imm - Return an 8-bit floating-point version of the 16-bit floating-point value.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
int getFP32FP16Imm(const APInt &Imm)
If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding for it.
AddrOpc getAM2Op(unsigned AM2Opc)
bool isBitFieldInvertedMask(unsigned v)
const unsigned FPStatusBits
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
const unsigned FPReservedBits
const unsigned RoundingBitsPos
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ ARM_APCS
ARM Procedure Calling Standard (obsolete, but still used on some targets).
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ ARM_AAPCS
ARM Architecture Procedure Calling Standard calling convention (aka EABI).
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:43
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:263
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition ISDOpcodes.h:516
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:238
@ SET_FPENV
Sets the current floating-point environment.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition ISDOpcodes.h:170
@ FGETSIGN
INT = FGETSIGN(FP) - Return the sign bit of the specified floating point value as an integer 0/1 valu...
Definition ISDOpcodes.h:543
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:605
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ RESET_FPENV
Set floating-point environment to default state.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SET_FPMODE
Sets the current dynamic floating-point control modes.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:523
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:222
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition ISDOpcodes.h:174
@ GlobalAddress
Definition ISDOpcodes.h:90
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:906
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:589
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:765
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ RESET_FPMODE
Sets default dynamic floating-point control modes.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:256
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:441
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:91
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:814
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:725
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:490
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:675
@ BR
Control flow instructions. These all have token chains.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
Definition ISDOpcodes.h:853
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:355
@ BR_JT
BR_JT - Jumptable branch.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
Definition ISDOpcodes.h:640
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:377
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:235
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition ISDOpcodes.h:249
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition ISDOpcodes.h:232
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:351
@ CTLS
Count leading redundant sign bits.
Definition ISDOpcodes.h:818
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
Definition ISDOpcodes.h:996
@ STRICT_FP_TO_FP16
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ GET_FPMODE
Reads the current dynamic floating-point control modes.
@ STRICT_FP16_TO_FP
@ GET_FPENV
Gets the current floating-point environment.
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:659
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:619
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
Definition ISDOpcodes.h:141
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:226
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:359
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:831
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:331
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:489
@ STRICT_FROUNDEVEN
Definition ISDOpcodes.h:469
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:112
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:483
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:505
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:482
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:952
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:510
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:207
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:753
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:720
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:430
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:570
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:985
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
Definition ISDOpcodes.h:124
@ STRICT_FNEARBYINT
Definition ISDOpcodes.h:461
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition ISDOpcodes.h:971
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition ISDOpcodes.h:164
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:539
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:368
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
Definition ISDOpcodes.h:629
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
Definition ISDOpcodes.h:740
@ SADDO_CARRY
Carry-using overflow-aware nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:341
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:215
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:561
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
static const int LAST_INDEXED_MODE
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
bool isIntEqualitySetCC(CondCode Code)
Return true if this is a setcc instruction that performs an equality comparison when used with intege...
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
constexpr MCPhysReg SP
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
bool sd_match(SDValue N, Pattern &&P)
ConstantInt_match m_ConstInt()
Match any integer constants or splat of an integer constant.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:63
initializer< Ty > init(const Ty &Val)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool RetFastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
bool isVTRN_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of "vector_shuffle v,...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns true if Val1 has a lower Constant Materialization Cost than Val2.
bool isVZIPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
InstructionCost Cost
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
@ Known
Known to have no common set bits.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Kill
The last use of a register.
@ Define
Register definition.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
Definition bit.h:315
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool CC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition MathExtras.h:256
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
bool RetCC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
bool RetCC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI Value * concatenateVectors(IRBuilderBase &Builder, ArrayRef< Value * > Vecs)
Concatenate a list of vectors.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
void shuffle(Iterator first, Iterator last, RNG &&g)
Definition STLExtras.h:1546
bool CC_ARM_APCS_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
Definition MathExtras.h:268
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool FastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool CC_ARM_Win32_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isVUZPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
bool isVTRNMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
CombineLevel
Definition DAGCombine.h:15
@ BeforeLegalizeTypes
Definition DAGCombine.h:16
@ AfterLegalizeTypes
Definition DAGCombine.h:17
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
@ Add
Sum of integers.
@ FAdd
Sum of floats.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
@ Fast
Assign the register banks as fast as possible (default).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
bool isVUZP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of "vector_shuffle v,...
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr U AbsoluteValue(T X)
Return the absolute value of a signed integer, converted to the corresponding unsigned integer type.
Definition MathExtras.h:592
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr unsigned BitWidth
ExceptionHandling
Definition CodeGen.h:54
@ SjLj
setjmp/longjmp based exceptions
Definition CodeGen.h:58
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
bool isVREVMask(ArrayRef< int > M, EVT VT, unsigned BlockSize)
isVREVMask - Check if a vector shuffle corresponds to a VREV instruction with the specified blocksize...
unsigned gettBLXrOpcode(const MachineFunction &MF)
bool CC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
bool CC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI llvm::SmallVector< int, 16 > createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs)
Create a sequential shuffle mask.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
bool isVZIP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of "vector_shuffle v,...
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Load/store instruction that can be merged with a base address update.
SDNode * N
Instruction that updates a pointer.
unsigned ConstInc
Pointer increment value if it is a constant, or 0 otherwise.
SDValue Inc
Pointer increment operand.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition Metadata.h:774
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
static constexpr Align fromLog2(unsigned Log2Value)
Returns an alignment of 1 << Log2Value bytes.
Definition Alignment.h:73
static constexpr DenormalMode getIEEE()
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition ValueTypes.h:307
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition ValueTypes.h:323
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:494
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
Definition ValueTypes.h:382
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
Definition ValueTypes.h:501
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
Definition ValueTypes.h:98
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition ValueTypes.h:230
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:404
bool isFixedLengthVector() const
Definition ValueTypes.h:199
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
Definition ValueTypes.h:55
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:165
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition ValueTypes.h:331
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:484
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
bool is64BitVector() const
Return true if this is a 64-bit vector type.
Definition ValueTypes.h:225
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
EVT ArgVT
Usually the non-legalized type of the argument, which is the EVT corresponding to the OrigTy IR type.
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:315
unsigned getBitWidth() const
Get the bit width of this value.
Definition KnownBits.h:44
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
Definition KnownBits.h:176
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false, bool SelfAdd=false)
Compute knownbits resulting from addition of LHS and RHS.
Definition KnownBits.h:361
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition KnownBits.h:325
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
Definition KnownBits.h:136
Matching combinators.
SmallVector< ArgRegPair, 1 > ArgRegPairs
Vector of call argument and its forwarding register.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:111
LLVM_ABI std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
These are IR-level optimization flags that may be propagated to SDNodes.
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setInRegister(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
LLVM_ABI void AddToWorklist(SDNode *N)
LLVM_ABI bool recursivelyDeleteUnusedNodes(SDNode *N)
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...