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"
66#include "llvm/IR/Attributes.h"
67#include "llvm/IR/CallingConv.h"
68#include "llvm/IR/Constant.h"
69#include "llvm/IR/Constants.h"
70#include "llvm/IR/DataLayout.h"
71#include "llvm/IR/DebugLoc.h"
73#include "llvm/IR/Function.h"
74#include "llvm/IR/GlobalAlias.h"
75#include "llvm/IR/GlobalValue.h"
77#include "llvm/IR/IRBuilder.h"
78#include "llvm/IR/InlineAsm.h"
79#include "llvm/IR/Instruction.h"
82#include "llvm/IR/Intrinsics.h"
83#include "llvm/IR/IntrinsicsARM.h"
84#include "llvm/IR/Module.h"
85#include "llvm/IR/Type.h"
86#include "llvm/IR/User.h"
87#include "llvm/IR/Value.h"
88#include "llvm/MC/MCInstrDesc.h"
90#include "llvm/MC/MCSchedule.h"
97#include "llvm/Support/Debug.h"
105#include <algorithm>
106#include <cassert>
107#include <cstdint>
108#include <iterator>
109#include <limits>
110#include <optional>
111#include <tuple>
112#include <utility>
113#include <vector>
114
115using namespace llvm;
116
117#define DEBUG_TYPE "arm-isel"
118
119STATISTIC(NumTailCalls, "Number of tail calls");
120STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
121STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
122STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
123STATISTIC(NumConstpoolPromoted,
124 "Number of constants with their storage promoted into constant pools");
125
126static cl::opt<bool>
127ARMInterworking("arm-interworking", cl::Hidden,
128 cl::desc("Enable / disable ARM interworking (for debugging only)"),
129 cl::init(true));
130
132 "arm-promote-constant", cl::Hidden,
133 cl::desc("Enable / disable promotion of unnamed_addr constants into "
134 "constant pools"),
135 cl::init(false)); // FIXME: set to true by default once PR32780 is fixed
137 "arm-promote-constant-max-size", cl::Hidden,
138 cl::desc("Maximum size of constant to promote into a constant pool"),
139 cl::init(64));
141 "arm-promote-constant-max-total", cl::Hidden,
142 cl::desc("Maximum size of ALL constants to promote into a constant pool"),
143 cl::init(128));
144
146MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden,
147 cl::desc("Maximum interleave factor for MVE VLDn to generate."),
148 cl::init(2));
149
151 "arm-max-base-updates-to-check", cl::Hidden,
152 cl::desc("Maximum number of base-updates to check generating postindex."),
153 cl::init(64));
154
155/// Value type used for "flags" operands / results (either CPSR or FPSCR_NZCV).
156constexpr MVT FlagsVT = MVT::i32;
157
158// The APCS parameter registers.
159static const MCPhysReg GPRArgRegs[] = {
160 ARM::R0, ARM::R1, ARM::R2, ARM::R3
161};
162
164 SelectionDAG &DAG, const SDLoc &DL) {
166 assert(Arg.ArgVT.bitsLT(MVT::i32));
167 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
168 SDValue Ext =
170 MVT::i32, Trunc);
171 return Ext;
172}
173
174void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
175 if (VT != PromotedLdStVT) {
177 AddPromotedToType (ISD::LOAD, VT, PromotedLdStVT);
178
180 AddPromotedToType (ISD::STORE, VT, PromotedLdStVT);
181 }
182
183 MVT ElemTy = VT.getVectorElementType();
184 if (ElemTy != MVT::f64)
188 if (ElemTy == MVT::i32) {
193 } else {
198 }
207 if (VT.isInteger()) {
211 }
212
213 // Neon does not support vector divide/remainder operations.
222
223 if (!VT.isFloatingPoint() && VT != MVT::v2i64 && VT != MVT::v1i64)
224 for (auto Opcode : {ISD::ABS, ISD::ABDS, ISD::ABDU, ISD::SMIN, ISD::SMAX,
226 setOperationAction(Opcode, VT, Legal);
227 if (!VT.isFloatingPoint())
228 for (auto Opcode : {ISD::SADDSAT, ISD::UADDSAT, ISD::SSUBSAT, ISD::USUBSAT})
229 setOperationAction(Opcode, VT, Legal);
230}
231
232void ARMTargetLowering::addDRTypeForNEON(MVT VT) {
233 addRegisterClass(VT, &ARM::DPRRegClass);
234 addTypeForNEON(VT, MVT::f64);
235}
236
237void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
238 addRegisterClass(VT, &ARM::DPairRegClass);
239 addTypeForNEON(VT, MVT::v2f64);
240}
241
242void ARMTargetLowering::setAllExpand(MVT VT) {
243 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
245
246 // We support these really simple operations even on types where all
247 // the actual arithmetic has to be broken down into simpler
248 // operations or turned into library calls.
253}
254
255void ARMTargetLowering::addAllExtLoads(const MVT From, const MVT To,
256 LegalizeAction Action) {
257 setLoadExtAction(ISD::EXTLOAD, From, To, Action);
258 setLoadExtAction(ISD::ZEXTLOAD, From, To, Action);
259 setLoadExtAction(ISD::SEXTLOAD, From, To, Action);
260}
261
262void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
263 const MVT IntTypes[] = { MVT::v16i8, MVT::v8i16, MVT::v4i32 };
264
265 for (auto VT : IntTypes) {
266 addRegisterClass(VT, &ARM::MQPRRegClass);
297
298 // No native support for these.
308
309 // Vector reductions
319
320 if (!HasMVEFP) {
325 } else {
328 }
329
330 // Pre and Post inc are supported on loads and stores
331 for (unsigned im = (unsigned)ISD::PRE_INC;
332 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
337 }
338 }
339
340 const MVT FloatTypes[] = { MVT::v8f16, MVT::v4f32 };
341 for (auto VT : FloatTypes) {
342 addRegisterClass(VT, &ARM::MQPRRegClass);
343 if (!HasMVEFP)
344 setAllExpand(VT);
345
346 // These are legal or custom whether we have MVE.fp or not
359
360 // Pre and Post inc are supported on loads and stores
361 for (unsigned im = (unsigned)ISD::PRE_INC;
362 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
367 }
368
369 if (HasMVEFP) {
377 }
382
383 // No native support for these.
398 }
399 }
400
401 // Custom Expand smaller than legal vector reductions to prevent false zero
402 // items being added.
411
412 // We 'support' these types up to bitcast/load/store level, regardless of
413 // MVE integer-only / float support. Only doing FP data processing on the FP
414 // vector types is inhibited at integer-only level.
415 const MVT LongTypes[] = { MVT::v2i64, MVT::v2f64 };
416 for (auto VT : LongTypes) {
417 addRegisterClass(VT, &ARM::MQPRRegClass);
418 setAllExpand(VT);
424 }
426
427 // We can do bitwise operations on v2i64 vectors
428 setOperationAction(ISD::AND, MVT::v2i64, Legal);
429 setOperationAction(ISD::OR, MVT::v2i64, Legal);
430 setOperationAction(ISD::XOR, MVT::v2i64, Legal);
431
432 // It is legal to extload from v4i8 to v4i16 or v4i32.
433 addAllExtLoads(MVT::v8i16, MVT::v8i8, Legal);
434 addAllExtLoads(MVT::v4i32, MVT::v4i16, Legal);
435 addAllExtLoads(MVT::v4i32, MVT::v4i8, Legal);
436
437 // It is legal to sign extend from v4i8/v4i16 to v4i32 or v8i8 to v8i16.
443
444 // Some truncating stores are legal too.
445 setTruncStoreAction(MVT::v4i32, MVT::v4i16, Legal);
446 setTruncStoreAction(MVT::v4i32, MVT::v4i8, Legal);
447 setTruncStoreAction(MVT::v8i16, MVT::v8i8, Legal);
448
449 // Pre and Post inc on these are legal, given the correct extends
450 for (unsigned im = (unsigned)ISD::PRE_INC;
451 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
452 for (auto VT : {MVT::v8i8, MVT::v4i8, MVT::v4i16}) {
457 }
458 }
459
460 // Predicate types
461 const MVT pTypes[] = {MVT::v16i1, MVT::v8i1, MVT::v4i1, MVT::v2i1};
462 for (auto VT : pTypes) {
463 addRegisterClass(VT, &ARM::VCCRRegClass);
478
479 if (!HasMVEFP) {
484 }
485 }
489 setOperationAction(ISD::OR, MVT::v2i1, Expand);
495
504}
505
507 return static_cast<const ARMBaseTargetMachine &>(getTargetMachine());
508}
509
511 const ARMSubtarget &STI)
512 : TargetLowering(TM_, STI), Subtarget(&STI),
513 RegInfo(Subtarget->getRegisterInfo()),
514 Itins(Subtarget->getInstrItineraryData()) {
515 const auto &TM = static_cast<const ARMBaseTargetMachine &>(TM_);
516
519
520 const Triple &TT = TM.getTargetTriple();
521
522 if (Subtarget->isThumb1Only())
523 addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
524 else
525 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
526
527 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only() &&
528 Subtarget->hasFPRegs()) {
529 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
530 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
531
532 if (!Subtarget->hasVFP2Base()) {
533 setAllExpand(MVT::f32);
534 } else {
537
540 setOperationAction(Op, MVT::f32, Legal);
541 }
542 if (!Subtarget->hasFP64()) {
543 setAllExpand(MVT::f64);
544 } else {
547 setOperationAction(Op, MVT::f64, Legal);
548
550 }
551 }
552
553 if (Subtarget->hasFullFP16()) {
556 setOperationAction(Op, MVT::f16, Legal);
557
558 addRegisterClass(MVT::f16, &ARM::HPRRegClass);
561
566 }
567
568 if (Subtarget->hasBF16()) {
569 addRegisterClass(MVT::bf16, &ARM::HPRRegClass);
570 setAllExpand(MVT::bf16);
571 if (!Subtarget->hasFullFP16())
575 } else {
580 }
581
583 for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
584 setTruncStoreAction(VT, InnerVT, Expand);
585 addAllExtLoads(VT, InnerVT, Expand);
586 }
587
590
592 }
593
594 if (!Subtarget->isThumb1Only() && !Subtarget->hasV8_1MMainlineOps())
596
597 if (!Subtarget->hasV8_1MMainlineOps())
599
600 if (!Subtarget->isThumb1Only())
602
605
608
609 if (Subtarget->hasMVEIntegerOps())
610 addMVEVectorTypes(Subtarget->hasMVEFloatOps());
611
612 // Combine low-overhead loop intrinsics so that we can lower i1 types.
613 if (Subtarget->hasLOB()) {
615 }
616
617 if (Subtarget->hasNEON()) {
618 addDRTypeForNEON(MVT::v2f32);
619 addDRTypeForNEON(MVT::v8i8);
620 addDRTypeForNEON(MVT::v4i16);
621 addDRTypeForNEON(MVT::v2i32);
622 addDRTypeForNEON(MVT::v1i64);
623
624 addQRTypeForNEON(MVT::v4f32);
625 addQRTypeForNEON(MVT::v2f64);
626 addQRTypeForNEON(MVT::v16i8);
627 addQRTypeForNEON(MVT::v8i16);
628 addQRTypeForNEON(MVT::v4i32);
629 addQRTypeForNEON(MVT::v2i64);
630
631 if (Subtarget->hasFullFP16()) {
632 addQRTypeForNEON(MVT::v8f16);
633 addDRTypeForNEON(MVT::v4f16);
634 }
635
636 if (Subtarget->hasBF16()) {
637 addQRTypeForNEON(MVT::v8bf16);
638 addDRTypeForNEON(MVT::v4bf16);
639 }
640 }
641
642 if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) {
643 // v2f64 is legal so that QR subregs can be extracted as f64 elements, but
644 // none of Neon, MVE or VFP supports any arithmetic operations on it.
645 setOperationAction(ISD::FADD, MVT::v2f64, Expand);
646 setOperationAction(ISD::FSUB, MVT::v2f64, Expand);
647 setOperationAction(ISD::FMUL, MVT::v2f64, Expand);
648 // FIXME: Code duplication: FDIV and FREM are expanded always, see
649 // ARMTargetLowering::addTypeForNEON method for details.
650 setOperationAction(ISD::FDIV, MVT::v2f64, Expand);
651 setOperationAction(ISD::FREM, MVT::v2f64, Expand);
652 // FIXME: Create unittest.
653 // In another words, find a way when "copysign" appears in DAG with vector
654 // operands.
656 // FIXME: Code duplication: SETCC has custom operation action, see
657 // ARMTargetLowering::addTypeForNEON method for details.
659 // FIXME: Create unittest for FNEG and for FABS.
660 setOperationAction(ISD::FNEG, MVT::v2f64, Expand);
661 setOperationAction(ISD::FABS, MVT::v2f64, Expand);
663 setOperationAction(ISD::FSIN, MVT::v2f64, Expand);
664 setOperationAction(ISD::FCOS, MVT::v2f64, Expand);
665 setOperationAction(ISD::FTAN, MVT::v2f64, Expand);
666 setOperationAction(ISD::FPOW, MVT::v2f64, Expand);
667 setOperationAction(ISD::FLOG, MVT::v2f64, Expand);
670 setOperationAction(ISD::FEXP, MVT::v2f64, Expand);
679 setOperationAction(ISD::FMA, MVT::v2f64, Expand);
680 }
681
682 if (Subtarget->hasNEON()) {
683 // The same with v4f32. But keep in mind that vadd, vsub, vmul are natively
684 // supported for v4f32.
686 setOperationAction(ISD::FSIN, MVT::v4f32, Expand);
687 setOperationAction(ISD::FCOS, MVT::v4f32, Expand);
688 setOperationAction(ISD::FTAN, MVT::v4f32, Expand);
689 setOperationAction(ISD::FPOW, MVT::v4f32, Expand);
690 setOperationAction(ISD::FLOG, MVT::v4f32, Expand);
693 setOperationAction(ISD::FEXP, MVT::v4f32, Expand);
702
703 // Mark v2f32 intrinsics.
705 setOperationAction(ISD::FSIN, MVT::v2f32, Expand);
706 setOperationAction(ISD::FCOS, MVT::v2f32, Expand);
707 setOperationAction(ISD::FTAN, MVT::v2f32, Expand);
708 setOperationAction(ISD::FPOW, MVT::v2f32, Expand);
709 setOperationAction(ISD::FLOG, MVT::v2f32, Expand);
712 setOperationAction(ISD::FEXP, MVT::v2f32, Expand);
721
724 setOperationAction(Op, MVT::v4f16, Expand);
725 setOperationAction(Op, MVT::v8f16, Expand);
726 }
727
728 // Neon does not support some operations on v1i64 and v2i64 types.
729 setOperationAction(ISD::MUL, MVT::v1i64, Expand);
730 // Custom handling for some quad-vector types to detect VMULL.
731 setOperationAction(ISD::MUL, MVT::v8i16, Custom);
732 setOperationAction(ISD::MUL, MVT::v4i32, Custom);
733 setOperationAction(ISD::MUL, MVT::v2i64, Custom);
734 // Custom handling for some vector types to avoid expensive expansions
735 setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
737 setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
739 // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
740 // a destination type that is wider than the source, and nor does
741 // it have a FP_TO_[SU]INT instruction with a narrower destination than
742 // source.
751
754
755 // NEON does not have single instruction CTPOP for vectors with element
756 // types wider than 8-bits. However, custom lowering can leverage the
757 // v8i8/v16i8 vcnt instruction.
764
765 setOperationAction(ISD::CTLZ, MVT::v1i64, Expand);
766 setOperationAction(ISD::CTLZ, MVT::v2i64, Expand);
767
768 // NEON does not have single instruction CTTZ for vectors.
770 setOperationAction(ISD::CTTZ, MVT::v4i16, Custom);
771 setOperationAction(ISD::CTTZ, MVT::v2i32, Custom);
772 setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
773
774 setOperationAction(ISD::CTTZ, MVT::v16i8, Custom);
775 setOperationAction(ISD::CTTZ, MVT::v8i16, Custom);
776 setOperationAction(ISD::CTTZ, MVT::v4i32, Custom);
777 setOperationAction(ISD::CTTZ, MVT::v2i64, Custom);
778
783
788
792 }
793
794 // NEON only has FMA instructions as of VFP4.
795 if (!Subtarget->hasVFP4Base()) {
796 setOperationAction(ISD::FMA, MVT::v2f32, Expand);
797 setOperationAction(ISD::FMA, MVT::v4f32, Expand);
798 }
799
802
803 // It is legal to extload from v4i8 to v4i16 or v4i32.
804 for (MVT Ty : {MVT::v8i8, MVT::v4i8, MVT::v2i8, MVT::v4i16, MVT::v2i16,
805 MVT::v2i32}) {
810 }
811 }
812
813 for (auto VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v16i8, MVT::v8i16,
814 MVT::v4i32}) {
819 }
820 }
821
822 if (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) {
829 }
830 if (Subtarget->hasMVEIntegerOps()) {
833 ISD::SETCC});
834 }
835 if (Subtarget->hasMVEFloatOps()) {
837 }
838
839 if (!Subtarget->hasFP64()) {
840 // When targeting a floating-point unit with only single-precision
841 // operations, f64 is legal for the few double-precision instructions which
842 // are present However, no double-precision operations other than moves,
843 // loads and stores are provided by the hardware.
880 }
881
882 // STRICT_(U/S)INT_TO_FP specifically use the input MVT to register with
883 // setOperationAction() as opposed to other opcodes that use the output MVT
884 // All inputs should be i32 due to type legalization
887
890
891 if (!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) {
894 if (Subtarget->hasFullFP16()) {
897 }
898 } else {
900 }
901
902 if (!Subtarget->hasFP16()) {
905 } else {
908 }
909
910 computeRegisterProperties(Subtarget->getRegisterInfo());
911
912 // ARM does not have floating-point extending loads.
913 for (MVT VT : MVT::fp_valuetypes()) {
914 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
915 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
916 setLoadExtAction(ISD::EXTLOAD, VT, MVT::bf16, Expand);
917 }
918
919 // ... or truncating stores
920 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
921 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
922 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
923 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
924 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
925
926 // ARM does not have i1 sign extending load.
927 for (MVT VT : MVT::integer_valuetypes())
929
930 // ARM supports all 4 flavors of integer indexed load / store.
931 if (!Subtarget->isThumb1Only()) {
932 for (unsigned im = (unsigned)ISD::PRE_INC;
934 setIndexedLoadAction(im, MVT::i1, Legal);
935 setIndexedLoadAction(im, MVT::i8, Legal);
936 setIndexedLoadAction(im, MVT::i16, Legal);
937 setIndexedLoadAction(im, MVT::i32, Legal);
938 setIndexedStoreAction(im, MVT::i1, Legal);
939 setIndexedStoreAction(im, MVT::i8, Legal);
940 setIndexedStoreAction(im, MVT::i16, Legal);
941 setIndexedStoreAction(im, MVT::i32, Legal);
942 }
943 } else {
944 // Thumb-1 has limited post-inc load/store support - LDM r0!, {r1}.
947 }
948
949 // Custom loads/stores to possible use __aeabi_uread/write*
950 if (TT.isTargetAEABI() && !Subtarget->allowsUnalignedMem()) {
955 }
956
961
962 if (!Subtarget->isThumb1Only()) {
965 }
966
971 if (Subtarget->hasDSP()) {
980 }
981 if (Subtarget->hasBaseDSP()) {
984 }
985
986 // i64 operation support.
989 if (Subtarget->isThumb1Only()) {
992 }
993 if (Subtarget->isThumb1Only() || !Subtarget->hasV6Ops()
994 || (Subtarget->isThumb2() && !Subtarget->hasDSP()))
996
1006
1007 // MVE lowers 64 bit shifts to lsll and lsrl
1008 // assuming that ISD::SRL and SRA of i64 are already marked custom
1009 if (Subtarget->hasMVEIntegerOps())
1011
1012 // Expand to __aeabi_l{lsl,lsr,asr} calls for Thumb1.
1013 if (Subtarget->isThumb1Only()) {
1017 }
1018
1019 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops())
1021
1022 // ARM does not have ROTL.
1027 }
1029 // TODO: These two should be set to LibCall, but this currently breaks
1030 // the Linux kernel build. See #101786.
1033 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
1036 }
1037
1038 // @llvm.readcyclecounter requires the Performance Monitors extension.
1039 // Default to the 0 expansion on unsupported platforms.
1040 // FIXME: Technically there are older ARM CPUs that have
1041 // implementation-specific ways of obtaining this information.
1042 if (Subtarget->hasPerfMon())
1044
1045 // Only ARMv6 has BSWAP.
1046 if (!Subtarget->hasV6Ops())
1048
1049 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
1050 : Subtarget->hasDivideInARMMode();
1051 if (!hasDivide) {
1052 // These are expanded into libcalls if the cpu doesn't have HW divider.
1055 }
1056
1057 if (TT.isOSWindows() && !Subtarget->hasDivideInThumbMode()) {
1060
1063 }
1064
1067
1068 // Register based DivRem for AEABI (RTABI 4.2)
1069 if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
1070 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isOSWindows()) {
1073 HasStandaloneRem = false;
1074
1079 } else {
1082 }
1083
1088
1089 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1091
1092 // Use the default implementation.
1094 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1096 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1099
1100 if (TT.isOSWindows())
1102 else
1104
1105 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
1106 // the default expansion.
1107 InsertFencesForAtomic = false;
1108 if (Subtarget->hasAnyDataBarrier() &&
1109 (!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps())) {
1110 // ATOMIC_FENCE needs custom lowering; the others should have been expanded
1111 // to ldrex/strex loops already.
1113 if (!Subtarget->isThumb() || !Subtarget->isMClass())
1115
1116 // On v8, we have particularly efficient implementations of atomic fences
1117 // if they can be combined with nearby atomic loads and stores.
1118 if (!Subtarget->hasAcquireRelease() ||
1119 getTargetMachine().getOptLevel() == CodeGenOptLevel::None) {
1120 // Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
1121 InsertFencesForAtomic = true;
1122 }
1123 } else {
1124 // If there's anything we can use as a barrier, go through custom lowering
1125 // for ATOMIC_FENCE.
1126 // If target has DMB in thumb, Fences can be inserted.
1127 if (Subtarget->hasDataBarrier())
1128 InsertFencesForAtomic = true;
1129
1131 Subtarget->hasAnyDataBarrier() ? Custom : Expand);
1132
1133 // Set them all for libcall, which will force libcalls.
1146 // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the
1147 // Unordered/Monotonic case.
1148 if (!InsertFencesForAtomic) {
1151 }
1152 }
1153
1154 // Compute supported atomic widths.
1155 if (TT.isOSLinux() || (!Subtarget->isMClass() && Subtarget->hasV6Ops())) {
1156 // For targets where __sync_* routines are reliably available, we use them
1157 // if necessary.
1158 //
1159 // ARM Linux always supports 64-bit atomics through kernel-assisted atomic
1160 // routines (kernel 3.1 or later). FIXME: Not with compiler-rt?
1161 //
1162 // ARMv6 targets have native instructions in ARM mode. For Thumb mode,
1163 // such targets should provide __sync_* routines, which use the ARM mode
1164 // instructions. (ARMv6 doesn't have dmb, but it has an equivalent
1165 // encoding; see ARMISD::MEMBARRIER_MCR.)
1167 } else if ((Subtarget->isMClass() && Subtarget->hasV8MBaselineOps()) ||
1168 Subtarget->hasForced32BitAtomics()) {
1169 // Cortex-M (besides Cortex-M0) have 32-bit atomics.
1171 } else {
1172 // We can't assume anything about other targets; just use libatomic
1173 // routines.
1175 }
1176
1178
1180
1181 // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
1182 if (!Subtarget->hasV6Ops()) {
1185 }
1187
1188 if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() &&
1189 !Subtarget->isThumb1Only()) {
1190 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
1191 // iff target supports vfp2.
1201 }
1202
1203 // We want to custom lower some of our intrinsics.
1208
1218 if (Subtarget->hasFullFP16()) {
1222 }
1223
1225
1228 if (Subtarget->hasFullFP16())
1232 setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1233
1234 // We don't support sin/cos/fmod/copysign/pow
1243 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
1244 !Subtarget->isThumb1Only()) {
1247 }
1250
1251 if (!Subtarget->hasVFP4Base()) {
1254 }
1255
1256 // Various VFP goodness
1257 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
1258 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1259 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
1264 }
1265
1266 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
1267 if (!Subtarget->hasFP16()) {
1272 }
1273
1274 // Strict floating-point comparisons need custom lowering.
1281 }
1282
1283 // FP-ARMv8 implements a lot of rounding-like FP operations.
1284 if (Subtarget->hasFPARMv8Base()) {
1285 for (auto Op :
1292 setOperationAction(Op, MVT::f32, Legal);
1293
1294 if (Subtarget->hasFP64())
1295 setOperationAction(Op, MVT::f64, Legal);
1296 }
1297
1298 if (Subtarget->hasNEON()) {
1303 }
1304 }
1305
1306 // FP16 often need to be promoted to call lib functions
1307 // clang-format off
1308 if (Subtarget->hasFullFP16()) {
1312
1313 for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1327 setOperationAction(Op, MVT::f16, Promote);
1328 }
1329
1330 // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1331 // because the result type is integer.
1333 setOperationAction(Op, MVT::f16, Custom);
1334
1340 setOperationAction(Op, MVT::f16, Legal);
1341 }
1342 // clang-format on
1343 }
1344
1345 if (Subtarget->hasNEON()) {
1346 // vmin and vmax aren't available in a scalar form, so we can use
1347 // a NEON instruction with an undef lane instead.
1356
1357 if (Subtarget->hasV8Ops()) {
1362 setOperationAction(Op, MVT::v2f32, Legal);
1363 setOperationAction(Op, MVT::v4f32, Legal);
1364 }
1365 }
1366
1367 if (Subtarget->hasFullFP16()) {
1372
1377
1382 setOperationAction(Op, MVT::v4f16, Legal);
1383 setOperationAction(Op, MVT::v8f16, Legal);
1384 }
1385 }
1386 }
1387
1388 // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined. MinGW has
1389 // it, but it's just a wrapper around ldexp.
1390 if (TT.isOSWindows()) {
1392 if (isOperationExpand(Op, MVT::f32))
1393 setOperationAction(Op, MVT::f32, Promote);
1394 }
1395
1396 // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
1397 // isn't legal.
1399 if (isOperationExpand(Op, MVT::f16))
1400 setOperationAction(Op, MVT::f16, Promote);
1401
1402 // We have target-specific dag combine patterns for the following nodes:
1403 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
1406
1407 if (Subtarget->hasMVEIntegerOps())
1409
1410 if (Subtarget->hasV6Ops())
1412 if (Subtarget->isThumb1Only())
1414 // Attempt to lower smin/smax to ssat/usat
1415 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) ||
1416 Subtarget->isThumb2()) {
1418 }
1419
1421
1422 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1423 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
1425 else
1427
1428 //// temporary - rewrite interface to use type
1431 MaxStoresPerMemcpy = 4; // For @llvm.memcpy -> sequence of stores
1433 MaxStoresPerMemmove = 4; // For @llvm.memmove -> sequence of stores
1435
1436 // On ARM arguments smaller than 4 bytes are extended, so all arguments
1437 // are at least 4 bytes aligned.
1439
1440 // Prefer likely predicted branches to selects on out-of-order cores.
1441 PredictableSelectIsExpensive = Subtarget->getSchedModel().isOutOfOrder();
1442
1443 setPrefLoopAlignment(Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1445 Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1446
1447 setMinFunctionAlignment(Subtarget->isThumb() ? Align(2) : Align(4));
1448
1449 IsStrictFPEnabled = true;
1450}
1451
1453 return Subtarget->useSoftFloat();
1454}
1455
1457 return !Subtarget->isThumb1Only() && VT.getSizeInBits() <= 32;
1458}
1459
1460// FIXME: It might make sense to define the representative register class as the
1461// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
1462// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
1463// SPR's representative would be DPR_VFP2. This should work well if register
1464// pressure tracking were modified such that a register use would increment the
1465// pressure of the register class's representative and all of it's super
1466// classes' representatives transitively. We have not implemented this because
1467// of the difficulty prior to coalescing of modeling operand register classes
1468// due to the common occurrence of cross class copies and subregister insertions
1469// and extractions.
1470std::pair<const TargetRegisterClass *, uint8_t>
1472 MVT VT) const {
1473 const TargetRegisterClass *RRC = nullptr;
1474 uint8_t Cost = 1;
1475 switch (VT.SimpleTy) {
1476 default:
1478 // Use DPR as representative register class for all floating point
1479 // and vector types. Since there are 32 SPR registers and 32 DPR registers so
1480 // the cost is 1 for both f32 and f64.
1481 case MVT::f32: case MVT::f64: case MVT::v8i8: case MVT::v4i16:
1482 case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
1483 RRC = &ARM::DPRRegClass;
1484 // When NEON is used for SP, only half of the register file is available
1485 // because operations that define both SP and DP results will be constrained
1486 // to the VFP2 class (D0-D15). We currently model this constraint prior to
1487 // coalescing by double-counting the SP regs. See the FIXME above.
1488 if (Subtarget->useNEONForSinglePrecisionFP())
1489 Cost = 2;
1490 break;
1491 case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
1492 case MVT::v4f32: case MVT::v2f64:
1493 RRC = &ARM::DPRRegClass;
1494 Cost = 2;
1495 break;
1496 case MVT::v4i64:
1497 RRC = &ARM::DPRRegClass;
1498 Cost = 4;
1499 break;
1500 case MVT::v8i64:
1501 RRC = &ARM::DPRRegClass;
1502 Cost = 8;
1503 break;
1504 }
1505 return std::make_pair(RRC, Cost);
1506}
1507
1509 EVT VT) const {
1510 if (!VT.isVector())
1511 return getPointerTy(DL);
1512
1513 // MVE has a predicate register.
1514 if (Subtarget->hasMVEIntegerOps())
1515 return EVT::getVectorVT(C, MVT::i1, VT.getVectorElementCount());
1516
1518}
1519
1520/// getRegClassFor - Return the register class that should be used for the
1521/// specified value type.
1522const TargetRegisterClass *
1523ARMTargetLowering::getRegClassFor(MVT VT, bool isDivergent) const {
1524 (void)isDivergent;
1525 // Map v4i64 to QQ registers but do not make the type legal. Similarly map
1526 // v8i64 to QQQQ registers. v4i64 and v8i64 are only used for REG_SEQUENCE to
1527 // load / store 4 to 8 consecutive NEON D registers, or 2 to 4 consecutive
1528 // MVE Q registers.
1529 if (Subtarget->hasNEON()) {
1530 if (VT == MVT::v4i64)
1531 return &ARM::QQPRRegClass;
1532 if (VT == MVT::v8i64)
1533 return &ARM::QQQQPRRegClass;
1534 }
1535 if (Subtarget->hasMVEIntegerOps()) {
1536 if (VT == MVT::v4i64)
1537 return &ARM::MQQPRRegClass;
1538 if (VT == MVT::v8i64)
1539 return &ARM::MQQQQPRRegClass;
1540 }
1542}
1543
1544// memcpy, and other memory intrinsics, typically tries to use LDM/STM if the
1545// source/dest is aligned and the copy size is large enough. We therefore want
1546// to align such objects passed to memory intrinsics.
1548 Align &PrefAlign) const {
1549 if (!isa<MemIntrinsic>(CI))
1550 return false;
1551 MinSize = 8;
1552 // On ARM11 onwards (excluding M class) 8-byte aligned LDM is typically 1
1553 // cycle faster than 4-byte aligned LDM.
1554 PrefAlign =
1555 (Subtarget->hasV6Ops() && !Subtarget->isMClass() ? Align(8) : Align(4));
1556 return true;
1557}
1558
1559// Create a fast isel object.
1561 FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo,
1562 const LibcallLoweringInfo *libcallLowering) const {
1563 return ARM::createFastISel(funcInfo, libInfo, libcallLowering);
1564}
1565
1567 unsigned NumVals = N->getNumValues();
1568 if (!NumVals)
1569 return Sched::RegPressure;
1570
1571 for (unsigned i = 0; i != NumVals; ++i) {
1572 EVT VT = N->getValueType(i);
1573 if (VT == MVT::Glue || VT == MVT::Other)
1574 continue;
1575 if (VT.isFloatingPoint() || VT.isVector())
1576 return Sched::ILP;
1577 }
1578
1579 if (!N->isMachineOpcode())
1580 return Sched::RegPressure;
1581
1582 // Load are scheduled for latency even if there instruction itinerary
1583 // is not available.
1584 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
1585 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1586
1587 if (MCID.getNumDefs() == 0)
1588 return Sched::RegPressure;
1589 if (!Itins->isEmpty() &&
1590 Itins->getOperandCycle(MCID.getSchedClass(), 0) > 2U)
1591 return Sched::ILP;
1592
1593 return Sched::RegPressure;
1594}
1595
1596//===----------------------------------------------------------------------===//
1597// Lowering Code
1598//===----------------------------------------------------------------------===//
1599
1600static bool isSRL16(const SDValue &Op) {
1601 if (Op.getOpcode() != ISD::SRL)
1602 return false;
1603 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1604 return Const->getZExtValue() == 16;
1605 return false;
1606}
1607
1608static bool isSRA16(const SDValue &Op) {
1609 if (Op.getOpcode() != ISD::SRA)
1610 return false;
1611 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1612 return Const->getZExtValue() == 16;
1613 return false;
1614}
1615
1616static bool isSHL16(const SDValue &Op) {
1617 if (Op.getOpcode() != ISD::SHL)
1618 return false;
1619 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1620 return Const->getZExtValue() == 16;
1621 return false;
1622}
1623
1624// Check for a signed 16-bit value. We special case SRA because it makes it
1625// more simple when also looking for SRAs that aren't sign extending a
1626// smaller value. Without the check, we'd need to take extra care with
1627// checking order for some operations.
1628static bool isS16(const SDValue &Op, SelectionDAG &DAG) {
1629 if (isSRA16(Op))
1630 return isSHL16(Op.getOperand(0));
1631 return DAG.ComputeNumSignBits(Op) == 17;
1632}
1633
1634/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
1636 switch (CC) {
1637 default: llvm_unreachable("Unknown condition code!");
1638 case ISD::SETNE: return ARMCC::NE;
1639 case ISD::SETEQ: return ARMCC::EQ;
1640 case ISD::SETGT: return ARMCC::GT;
1641 case ISD::SETGE: return ARMCC::GE;
1642 case ISD::SETLT: return ARMCC::LT;
1643 case ISD::SETLE: return ARMCC::LE;
1644 case ISD::SETUGT: return ARMCC::HI;
1645 case ISD::SETUGE: return ARMCC::HS;
1646 case ISD::SETULT: return ARMCC::LO;
1647 case ISD::SETULE: return ARMCC::LS;
1648 }
1649}
1650
1651/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
1653 ARMCC::CondCodes &CondCode2) {
1654 CondCode2 = ARMCC::AL;
1655 switch (CC) {
1656 default: llvm_unreachable("Unknown FP condition!");
1657 case ISD::SETEQ:
1658 case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
1659 case ISD::SETGT:
1660 case ISD::SETOGT: CondCode = ARMCC::GT; break;
1661 case ISD::SETGE:
1662 case ISD::SETOGE: CondCode = ARMCC::GE; break;
1663 case ISD::SETOLT: CondCode = ARMCC::MI; break;
1664 case ISD::SETOLE: CondCode = ARMCC::LS; break;
1665 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
1666 case ISD::SETO: CondCode = ARMCC::VC; break;
1667 case ISD::SETUO: CondCode = ARMCC::VS; break;
1668 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
1669 case ISD::SETUGT: CondCode = ARMCC::HI; break;
1670 case ISD::SETUGE: CondCode = ARMCC::PL; break;
1671 case ISD::SETLT:
1672 case ISD::SETULT: CondCode = ARMCC::LT; break;
1673 case ISD::SETLE:
1674 case ISD::SETULE: CondCode = ARMCC::LE; break;
1675 case ISD::SETNE:
1676 case ISD::SETUNE: CondCode = ARMCC::NE; break;
1677 }
1678}
1679
1680//===----------------------------------------------------------------------===//
1681// Calling Convention Implementation
1682//===----------------------------------------------------------------------===//
1683
1684/// getEffectiveCallingConv - Get the effective calling convention, taking into
1685/// account presence of floating point hardware and calling convention
1686/// limitations, such as support for variadic functions.
1689 bool isVarArg) const {
1690 switch (CC) {
1691 default:
1692 // Unknown CCs are rejected when calling convention lowering is required.
1695 case CallingConv::GHC:
1697 return CC;
1703 case CallingConv::Swift:
1706 case CallingConv::C:
1707 case CallingConv::Tail:
1708 if (!Subtarget->isAAPCS_ABI())
1709 return CallingConv::ARM_APCS;
1710 else if (Subtarget->isTargetHardFloat() && !isVarArg)
1712 else
1714 case CallingConv::Fast:
1716 if (!Subtarget->isAAPCS_ABI()) {
1717 if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() && !isVarArg)
1718 return CallingConv::Fast;
1719 return CallingConv::ARM_APCS;
1720 } else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1721 !isVarArg)
1723 else
1725 }
1726}
1727
1729 bool isVarArg) const {
1730 return CCAssignFnForNode(CC, false, isVarArg);
1731}
1732
1734 bool isVarArg) const {
1735 return CCAssignFnForNode(CC, true, isVarArg);
1736}
1737
1738/// CCAssignFnForNode - Selects the correct CCAssignFn for the given
1739/// CallingConvention.
1740CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
1741 bool Return,
1742 bool isVarArg) const {
1743 switch (getEffectiveCallingConv(CC, isVarArg)) {
1744 default:
1745 report_fatal_error("Unsupported calling convention");
1747 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1749 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1751 return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1752 case CallingConv::Fast:
1753 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1754 case CallingConv::GHC:
1755 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1757 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1759 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1761 return (Return ? RetCC_ARM_AAPCS : CC_ARM_Win32_CFGuard_Check);
1762 }
1763}
1764
1765SDValue ARMTargetLowering::MoveToHPR(const SDLoc &dl, SelectionDAG &DAG,
1766 MVT LocVT, MVT ValVT, SDValue Val) const {
1767 Val = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocVT.getSizeInBits()),
1768 Val);
1769 if (Subtarget->hasFullFP16()) {
1770 Val = DAG.getNode(ARMISD::VMOVhr, dl, ValVT, Val);
1771 } else {
1772 Val = DAG.getNode(ISD::TRUNCATE, dl,
1773 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1774 Val = DAG.getNode(ISD::BITCAST, dl, ValVT, Val);
1775 }
1776 return Val;
1777}
1778
1779SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
1780 MVT LocVT, MVT ValVT,
1781 SDValue Val) const {
1782 if (Subtarget->hasFullFP16()) {
1783 Val = DAG.getNode(ARMISD::VMOVrh, dl,
1784 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1785 } else {
1786 Val = DAG.getNode(ISD::BITCAST, dl,
1787 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1788 Val = DAG.getNode(ISD::ZERO_EXTEND, dl,
1789 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1790 }
1791 return DAG.getNode(ISD::BITCAST, dl, LocVT, Val);
1792}
1793
1794/// LowerCallResult - Lower the result values of a call into the
1795/// appropriate copies out of appropriate physical registers.
1796SDValue ARMTargetLowering::LowerCallResult(
1797 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
1798 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1799 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
1800 SDValue ThisVal, bool isCmseNSCall) const {
1801 // Assign locations to each value returned by this call.
1803 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1804 *DAG.getContext());
1805 CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, isVarArg));
1806
1807 // Copy all of the result registers out of their specified physreg.
1808 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1809 CCValAssign VA = RVLocs[i];
1810
1811 // Pass 'this' value directly from the argument to return value, to avoid
1812 // reg unit interference
1813 if (i == 0 && isThisReturn) {
1814 assert(!VA.needsCustom() && VA.getLocVT() == MVT::i32 &&
1815 "unexpected return calling convention register assignment");
1816 InVals.push_back(ThisVal);
1817 continue;
1818 }
1819
1820 SDValue Val;
1821 if (VA.needsCustom() &&
1822 (VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2f64)) {
1823 // Handle f64 or half of a v2f64.
1824 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1825 InGlue);
1826 Chain = Lo.getValue(1);
1827 InGlue = Lo.getValue(2);
1828 VA = RVLocs[++i]; // skip ahead to next loc
1829 SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1830 InGlue);
1831 Chain = Hi.getValue(1);
1832 InGlue = Hi.getValue(2);
1833 if (!Subtarget->isLittle())
1834 std::swap (Lo, Hi);
1835 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1836
1837 if (VA.getLocVT() == MVT::v2f64) {
1838 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
1839 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1840 DAG.getConstant(0, dl, MVT::i32));
1841
1842 VA = RVLocs[++i]; // skip ahead to next loc
1843 Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1844 Chain = Lo.getValue(1);
1845 InGlue = Lo.getValue(2);
1846 VA = RVLocs[++i]; // skip ahead to next loc
1847 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1848 Chain = Hi.getValue(1);
1849 InGlue = Hi.getValue(2);
1850 if (!Subtarget->isLittle())
1851 std::swap (Lo, Hi);
1852 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1853 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1854 DAG.getConstant(1, dl, MVT::i32));
1855 }
1856 } else {
1857 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(),
1858 InGlue);
1859 Chain = Val.getValue(1);
1860 InGlue = Val.getValue(2);
1861 }
1862
1863 switch (VA.getLocInfo()) {
1864 default: llvm_unreachable("Unknown loc info!");
1865 case CCValAssign::Full: break;
1866 case CCValAssign::BCvt:
1867 Val = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), Val);
1868 break;
1869 }
1870
1871 // f16 arguments have their size extended to 4 bytes and passed as if they
1872 // had been copied to the LSBs of a 32-bit register.
1873 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
1874 if (VA.needsCustom() &&
1875 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
1876 Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
1877
1878 // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
1879 // is less than 32 bits must be sign- or zero-extended after the call for
1880 // security reasons. Although the ABI mandates an extension done by the
1881 // callee, the latter cannot be trusted to follow the rules of the ABI.
1882 const ISD::InputArg &Arg = Ins[VA.getValNo()];
1883 if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
1884 VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
1885 Val = handleCMSEValue(Val, Arg, DAG, dl);
1886
1887 InVals.push_back(Val);
1888 }
1889
1890 return Chain;
1891}
1892
1893std::pair<SDValue, MachinePointerInfo> ARMTargetLowering::computeAddrForCallArg(
1894 const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA, SDValue StackPtr,
1895 bool IsTailCall, int SPDiff) const {
1896 SDValue DstAddr;
1897 MachinePointerInfo DstInfo;
1898 int32_t Offset = VA.getLocMemOffset();
1900
1901 if (IsTailCall) {
1902 Offset += SPDiff;
1903 auto PtrVT = getPointerTy(DAG.getDataLayout());
1904 int Size = VA.getLocVT().getFixedSizeInBits() / 8;
1905 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
1906 DstAddr = DAG.getFrameIndex(FI, PtrVT);
1907 DstInfo =
1909 } else {
1910 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1911 DstAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
1912 StackPtr, PtrOff);
1913 DstInfo =
1915 }
1916
1917 return std::make_pair(DstAddr, DstInfo);
1918}
1919
1920// Returns the type of copying which is required to set up a byval argument to
1921// a tail-called function. This isn't needed for non-tail calls, because they
1922// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
1923// avoid clobbering another argument (CopyViaTemp), and sometimes can be
1924// optimised to zero copies when forwarding an argument from the caller's
1925// caller (NoCopy).
1926ARMTargetLowering::ByValCopyKind ARMTargetLowering::ByValNeedsCopyForTailCall(
1927 SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
1928 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1929 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
1930
1931 // Globals are always safe to copy from.
1933 return CopyOnce;
1934
1935 // Can only analyse frame index nodes, conservatively assume we need a
1936 // temporary.
1937 auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
1938 auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
1939 if (!SrcFrameIdxNode || !DstFrameIdxNode)
1940 return CopyViaTemp;
1941
1942 int SrcFI = SrcFrameIdxNode->getIndex();
1943 int DstFI = DstFrameIdxNode->getIndex();
1944 assert(MFI.isFixedObjectIndex(DstFI) &&
1945 "byval passed in non-fixed stack slot");
1946
1947 int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
1948 int64_t DstOffset = MFI.getObjectOffset(DstFI);
1949
1950 // If the source is in the local frame, then the copy to the argument memory
1951 // is always valid.
1952 bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
1953 if (!FixedSrc ||
1954 (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
1955 return CopyOnce;
1956
1957 // In the case of byval arguments split between registers and the stack,
1958 // computeAddrForCallArg returns a FrameIndex which corresponds only to the
1959 // stack portion, but the Src SDValue will refer to the full value, including
1960 // the local stack memory that the register portion gets stored into. We only
1961 // need to compare them for equality, so normalise on the full value version.
1962 uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
1963 DstOffset -= RegSize;
1964
1965 // If the value is already in the correct location, then no copying is
1966 // needed. If not, then we need to copy via a temporary.
1967 if (SrcOffset == DstOffset)
1968 return NoCopy;
1969 else
1970 return CopyViaTemp;
1971}
1972
1973void ARMTargetLowering::PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG,
1974 SDValue Chain, SDValue &Arg,
1975 RegsToPassVector &RegsToPass,
1976 CCValAssign &VA, CCValAssign &NextVA,
1977 SDValue &StackPtr,
1978 SmallVectorImpl<SDValue> &MemOpChains,
1979 bool IsTailCall,
1980 int SPDiff) const {
1981 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
1982 DAG.getVTList(MVT::i32, MVT::i32), Arg);
1983 unsigned id = Subtarget->isLittle() ? 0 : 1;
1984 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
1985
1986 if (NextVA.isRegLoc())
1987 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
1988 else {
1989 assert(NextVA.isMemLoc());
1990 if (!StackPtr.getNode())
1991 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP,
1993
1994 SDValue DstAddr;
1995 MachinePointerInfo DstInfo;
1996 std::tie(DstAddr, DstInfo) =
1997 computeAddrForCallArg(dl, DAG, NextVA, StackPtr, IsTailCall, SPDiff);
1998 MemOpChains.push_back(
1999 DAG.getStore(Chain, dl, fmrrd.getValue(1 - id), DstAddr, DstInfo));
2000 }
2001}
2002
2003static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
2004 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
2006}
2007
2008/// LowerCall - Lowering a call into a callseq_start <-
2009/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
2010/// nodes.
2011SDValue
2012ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2013 SmallVectorImpl<SDValue> &InVals) const {
2014 SelectionDAG &DAG = CLI.DAG;
2015 SDLoc &dl = CLI.DL;
2016 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2017 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2018 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2019 SDValue Chain = CLI.Chain;
2020 SDValue Callee = CLI.Callee;
2021 bool &isTailCall = CLI.IsTailCall;
2022 CallingConv::ID CallConv = CLI.CallConv;
2023 bool doesNotRet = CLI.DoesNotReturn;
2024 bool isVarArg = CLI.IsVarArg;
2025 const CallBase *CB = CLI.CB;
2026
2028 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2029 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2030 MachineFunction::CallSiteInfo CSInfo;
2031 bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
2032 bool isThisReturn = false;
2033 bool isCmseNSCall = false;
2034 bool isSibCall = false;
2035 bool PreferIndirect = false;
2036 bool GuardWithBTI = false;
2037
2038 // Analyze operands of the call, assigning locations to each operand.
2040 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
2041 *DAG.getContext());
2042 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, isVarArg));
2043
2044 // Lower 'returns_twice' calls to a pseudo-instruction.
2045 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) &&
2046 !Subtarget->noBTIAtReturnTwice())
2047 GuardWithBTI = AFI->branchTargetEnforcement();
2048
2049 // Set type id for call site info.
2050 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
2051
2052 // Determine whether this is a non-secure function call.
2053 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
2054 isCmseNSCall = true;
2055
2056 // Disable tail calls if they're not supported.
2057 if (!Subtarget->supportsTailCall())
2058 isTailCall = false;
2059
2060 // For both the non-secure calls and the returns from a CMSE entry function,
2061 // the function needs to do some extra work after the call, or before the
2062 // return, respectively, thus it cannot end with a tail call
2063 if (isCmseNSCall || AFI->isCmseNSEntryFunction())
2064 isTailCall = false;
2065
2066 if (isa<GlobalAddressSDNode>(Callee)) {
2067 // If we're optimizing for minimum size and the function is called three or
2068 // more times in this block, we can improve codesize by calling indirectly
2069 // as BLXr has a 16-bit encoding.
2070 auto *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
2071 if (CLI.CB) {
2072 auto *BB = CLI.CB->getParent();
2073 PreferIndirect = Subtarget->isThumb() && Subtarget->hasMinSize() &&
2074 count_if(GV->users(), [&BB](const User *U) {
2075 return isa<Instruction>(U) &&
2076 cast<Instruction>(U)->getParent() == BB;
2077 }) > 2;
2078 }
2079 }
2080 if (isTailCall) {
2081 // Check if it's really possible to do a tail call.
2082 isTailCall =
2083 IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
2084
2085 if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
2086 CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
2087 isSibCall = true;
2088
2089 // We don't support GuaranteedTailCallOpt for ARM, only automatically
2090 // detected sibcalls.
2091 if (isTailCall)
2092 ++NumTailCalls;
2093 }
2094
2095 if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
2096 report_fatal_error("failed to perform tail call elimination on a call "
2097 "site marked musttail");
2098
2099 // Get a count of how many bytes are to be pushed on the stack.
2100 unsigned NumBytes = CCInfo.getStackSize();
2101
2102 // SPDiff is the byte offset of the call's argument area from the callee's.
2103 // Stores to callee stack arguments will be placed in FixedStackSlots offset
2104 // by this amount for a tail call. In a sibling call it must be 0 because the
2105 // caller will deallocate the entire stack and the callee still expects its
2106 // arguments to begin at SP+0. Completely unused for non-tail calls.
2107 int SPDiff = 0;
2108
2109 if (isTailCall && !isSibCall) {
2110 auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
2111 unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
2112
2113 // Since callee will pop argument stack as a tail call, we must keep the
2114 // popped size 16-byte aligned.
2115 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
2116 assert(StackAlign && "data layout string is missing stack alignment");
2117 NumBytes = alignTo(NumBytes, *StackAlign);
2118
2119 // SPDiff will be negative if this tail call requires more space than we
2120 // would automatically have in our incoming argument space. Positive if we
2121 // can actually shrink the stack.
2122 SPDiff = NumReusableBytes - NumBytes;
2123
2124 // If this call requires more stack than we have available from
2125 // LowerFormalArguments, tell FrameLowering to reserve space for it.
2126 if (SPDiff < 0 && AFI->getArgRegsSaveSize() < (unsigned)-SPDiff)
2127 AFI->setArgRegsSaveSize(-SPDiff);
2128 }
2129
2130 if (isSibCall) {
2131 // For sibling tail calls, memory operands are available in our caller's stack.
2132 NumBytes = 0;
2133 } else {
2134 // Adjust the stack pointer for the new arguments...
2135 // These operations are automatically eliminated by the prolog/epilog pass
2136 Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
2137 }
2138
2139 SDValue StackPtr =
2140 DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy(DAG.getDataLayout()));
2141
2142 RegsToPassVector RegsToPass;
2143 SmallVector<SDValue, 8> MemOpChains;
2144
2145 // If we are doing a tail-call, any byval arguments will be written to stack
2146 // space which was used for incoming arguments. If any the values being used
2147 // are incoming byval arguments to this function, then they might be
2148 // overwritten by the stores of the outgoing arguments. To avoid this, we
2149 // need to make a temporary copy of them in local stack space, then copy back
2150 // to the argument area.
2151 DenseMap<unsigned, SDValue> ByValTemporaries;
2152 SDValue ByValTempChain;
2153 if (isTailCall) {
2154 SmallVector<SDValue, 8> ByValCopyChains;
2155 for (const CCValAssign &VA : ArgLocs) {
2156 unsigned ArgIdx = VA.getValNo();
2157 SDValue Src = OutVals[ArgIdx];
2158 ISD::ArgFlagsTy Flags = Outs[ArgIdx].Flags;
2159
2160 if (!Flags.isByVal())
2161 continue;
2162
2163 SDValue Dst;
2164 MachinePointerInfo DstInfo;
2165 std::tie(Dst, DstInfo) =
2166 computeAddrForCallArg(dl, DAG, VA, SDValue(), true, SPDiff);
2167 ByValCopyKind Copy = ByValNeedsCopyForTailCall(DAG, Src, Dst, Flags);
2168
2169 if (Copy == NoCopy) {
2170 // If the argument is already at the correct offset on the stack
2171 // (because we are forwarding a byval argument from our caller), we
2172 // don't need any copying.
2173 continue;
2174 } else if (Copy == CopyOnce) {
2175 // If the argument is in our local stack frame, no other argument
2176 // preparation can clobber it, so we can copy it to the final location
2177 // later.
2178 ByValTemporaries[ArgIdx] = Src;
2179 } else {
2180 assert(Copy == CopyViaTemp && "unexpected enum value");
2181 // If we might be copying this argument from the outgoing argument
2182 // stack area, we need to copy via a temporary in the local stack
2183 // frame.
2184 int TempFrameIdx = MFI.CreateStackObject(
2185 Flags.getByValSize(), Flags.getNonZeroByValAlign(), false);
2186 SDValue Temp =
2187 DAG.getFrameIndex(TempFrameIdx, getPointerTy(DAG.getDataLayout()));
2188
2189 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
2190 SDValue AlignNode =
2191 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2192
2193 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2194 SDValue Ops[] = {Chain, Temp, Src, SizeNode, AlignNode};
2195 ByValCopyChains.push_back(
2196 DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs, Ops));
2197 ByValTemporaries[ArgIdx] = Temp;
2198 }
2199 }
2200 if (!ByValCopyChains.empty())
2201 ByValTempChain =
2202 DAG.getNode(ISD::TokenFactor, dl, MVT::Other, ByValCopyChains);
2203 }
2204
2205 // During a tail call, stores to the argument area must happen after all of
2206 // the function's incoming arguments have been loaded because they may alias.
2207 // This is done by folding in a TokenFactor from LowerFormalArguments, but
2208 // there's no point in doing so repeatedly so this tracks whether that's
2209 // happened yet.
2210 bool AfterFormalArgLoads = false;
2211
2212 // Walk the register/memloc assignments, inserting copies/loads. In the case
2213 // of tail call optimization, arguments are handled later.
2214 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size();
2215 i != e;
2216 ++i, ++realArgIdx) {
2217 CCValAssign &VA = ArgLocs[i];
2218 SDValue Arg = OutVals[realArgIdx];
2219 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
2220 bool isByVal = Flags.isByVal();
2221
2222 // Promote the value if needed.
2223 switch (VA.getLocInfo()) {
2224 default: llvm_unreachable("Unknown loc info!");
2225 case CCValAssign::Full: break;
2226 case CCValAssign::SExt:
2227 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
2228 break;
2229 case CCValAssign::ZExt:
2230 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
2231 break;
2232 case CCValAssign::AExt:
2233 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
2234 break;
2235 case CCValAssign::BCvt:
2236 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2237 break;
2238 }
2239
2240 if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
2241 Chain = DAG.getStackArgumentTokenFactor(Chain);
2242 if (ByValTempChain) {
2243 // In case of large byval copies, re-using the stackframe for tail-calls
2244 // can lead to overwriting incoming arguments on the stack. Force
2245 // loading these stack arguments before the copy to avoid that.
2246 SmallVector<SDValue, 8> IncomingLoad;
2247 for (unsigned I = 0; I < OutVals.size(); ++I) {
2248 if (Outs[I].Flags.isByVal())
2249 continue;
2250
2251 SDValue OutVal = OutVals[I];
2252 LoadSDNode *OutLN = dyn_cast_or_null<LoadSDNode>(OutVal);
2253 if (!OutLN)
2254 continue;
2255
2256 FrameIndexSDNode *FIN =
2258 if (!FIN)
2259 continue;
2260
2261 if (!MFI.isFixedObjectIndex(FIN->getIndex()))
2262 continue;
2263
2264 for (const CCValAssign &VA : ArgLocs) {
2265 if (VA.isMemLoc())
2266 IncomingLoad.push_back(OutVal.getValue(1));
2267 }
2268 }
2269
2270 // Update the chain to force loads for potentially clobbered argument
2271 // loads to happen before the byval copy.
2272 if (!IncomingLoad.empty()) {
2273 IncomingLoad.push_back(Chain);
2274 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, IncomingLoad);
2275 }
2276
2277 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chain,
2278 ByValTempChain);
2279 }
2280 AfterFormalArgLoads = true;
2281 }
2282
2283 // f16 arguments have their size extended to 4 bytes and passed as if they
2284 // had been copied to the LSBs of a 32-bit register.
2285 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
2286 if (VA.needsCustom() &&
2287 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16)) {
2288 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2289 } else {
2290 // f16 arguments could have been extended prior to argument lowering.
2291 // Mask them arguments if this is a CMSE nonsecure call.
2292 auto ArgVT = Outs[realArgIdx].ArgVT;
2293 if (isCmseNSCall && (ArgVT == MVT::f16)) {
2294 auto LocBits = VA.getLocVT().getSizeInBits();
2295 auto MaskValue = APInt::getLowBitsSet(LocBits, ArgVT.getSizeInBits());
2296 SDValue Mask =
2297 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2298 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2299 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2300 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2301 }
2302 }
2303
2304 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
2305 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
2306 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2307 DAG.getConstant(0, dl, MVT::i32));
2308 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2309 DAG.getConstant(1, dl, MVT::i32));
2310
2311 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
2312 StackPtr, MemOpChains, isTailCall, SPDiff);
2313
2314 VA = ArgLocs[++i]; // skip ahead to next loc
2315 if (VA.isRegLoc()) {
2316 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
2317 StackPtr, MemOpChains, isTailCall, SPDiff);
2318 } else {
2319 assert(VA.isMemLoc());
2320 SDValue DstAddr;
2321 MachinePointerInfo DstInfo;
2322 std::tie(DstAddr, DstInfo) =
2323 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2324 MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
2325 }
2326 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
2327 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
2328 StackPtr, MemOpChains, isTailCall, SPDiff);
2329 } else if (VA.isRegLoc()) {
2330 if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
2331 Outs[0].VT == MVT::i32) {
2332 assert(VA.getLocVT() == MVT::i32 &&
2333 "unexpected calling convention register assignment");
2334 assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
2335 "unexpected use of 'returned'");
2336 isThisReturn = true;
2337 }
2338 const TargetOptions &Options = DAG.getTarget().Options;
2339 if (Options.EmitCallSiteInfo)
2340 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
2341 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2342 } else if (isByVal) {
2343 assert(VA.isMemLoc());
2344 unsigned offset = 0;
2345
2346 // True if this byval aggregate will be split between registers
2347 // and memory.
2348 unsigned ByValArgsCount = CCInfo.getInRegsParamsCount();
2349 unsigned CurByValIdx = CCInfo.getInRegsParamsProcessed();
2350
2351 SDValue ByValSrc;
2352 bool NeedsStackCopy;
2353 if (auto It = ByValTemporaries.find(realArgIdx);
2354 It != ByValTemporaries.end()) {
2355 ByValSrc = It->second;
2356 NeedsStackCopy = true;
2357 } else {
2358 ByValSrc = Arg;
2359 NeedsStackCopy = !isTailCall;
2360 }
2361
2362 // If part of the argument is in registers, load them.
2363 if (CurByValIdx < ByValArgsCount) {
2364 unsigned RegBegin, RegEnd;
2365 CCInfo.getInRegsParamInfo(CurByValIdx, RegBegin, RegEnd);
2366
2367 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2368 unsigned int i, j;
2369 for (i = 0, j = RegBegin; j < RegEnd; i++, j++) {
2370 SDValue Const = DAG.getConstant(4*i, dl, MVT::i32);
2371 SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, Const);
2372 SDValue Load =
2373 DAG.getLoad(PtrVT, dl, Chain, AddArg, MachinePointerInfo(),
2374 DAG.InferPtrAlign(AddArg));
2375 MemOpChains.push_back(Load.getValue(1));
2376 RegsToPass.push_back(std::make_pair(j, Load));
2377 }
2378
2379 // If parameter size outsides register area, "offset" value
2380 // helps us to calculate stack slot for remained part properly.
2381 offset = RegEnd - RegBegin;
2382
2383 CCInfo.nextInRegsParam();
2384 }
2385
2386 // If the memory part of the argument isn't already in the correct place
2387 // (which can happen with tail calls), copy it into the argument area.
2388 if (NeedsStackCopy && Flags.getByValSize() > 4 * offset) {
2389 auto PtrVT = getPointerTy(DAG.getDataLayout());
2390 SDValue Dst;
2391 MachinePointerInfo DstInfo;
2392 std::tie(Dst, DstInfo) =
2393 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2394 SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
2395 SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
2396 SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
2397 MVT::i32);
2398 SDValue AlignNode =
2399 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2400
2401 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2402 SDValue Ops[] = { Chain, Dst, Src, SizeNode, AlignNode};
2403 MemOpChains.push_back(DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs,
2404 Ops));
2405 }
2406 } else {
2407 assert(VA.isMemLoc());
2408 SDValue DstAddr;
2409 MachinePointerInfo DstInfo;
2410 std::tie(DstAddr, DstInfo) =
2411 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2412
2413 SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
2414 MemOpChains.push_back(Store);
2415 }
2416 }
2417
2418 if (!MemOpChains.empty())
2419 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
2420
2421 // Build a sequence of copy-to-reg nodes chained together with token chain
2422 // and flag operands which copy the outgoing args into the appropriate regs.
2423 SDValue InGlue;
2424 for (const auto &[Reg, N] : RegsToPass) {
2425 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
2426 InGlue = Chain.getValue(1);
2427 }
2428
2429 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2430 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2431 // node so that legalize doesn't hack it.
2432 bool isDirect = false;
2433
2434 const TargetMachine &TM = getTargetMachine();
2435 const Triple &TT = TM.getTargetTriple();
2436 const GlobalValue *GVal = nullptr;
2437 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
2438 GVal = G->getGlobal();
2439 bool isStub = !TM.shouldAssumeDSOLocal(GVal) && TT.isOSBinFormatMachO();
2440
2441 bool isARMFunc = !Subtarget->isThumb() || (isStub && !Subtarget->isMClass());
2442 bool isLocalARMFunc = false;
2443 auto PtrVt = getPointerTy(DAG.getDataLayout());
2444
2445 if (Subtarget->genLongCalls()) {
2446 bool isPIC = isPositionIndependent() && !TT.isOSWindows();
2447 if (isPIC && Subtarget->genExecuteOnly())
2448 reportFatalUsageError("long-calls with execute-only and "
2449 "position-independent code is not supported");
2450 if (Subtarget->isROPI())
2451 reportFatalUsageError("long-calls with ROPI is not currently supported");
2452
2453 // Handle a global address or an external symbol. If it's not one of
2454 // those, the target's already in a register, so we don't need to do
2455 // anything extra.
2456 if (isa<GlobalAddressSDNode>(Callee)) {
2457 if (Subtarget->genExecuteOnly()) {
2458 // Execute-only forbids constant pools in .text, so use movw/movt.
2459 // fPIC is not supported with execute-only.
2460 if (Subtarget->useMovt())
2461 ++NumMovwMovt;
2462 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2463 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2464 } else if (isPIC) {
2465 // PIC without execute-only: use GOT-based addressing.
2466 // DSO-local symbols use a plain PC-relative WrapperPIC;
2467 // non-DSO-local symbols additionally load the address from the GOT.
2468 SDValue G = DAG.getTargetGlobalAddress(
2469 GVal, dl, PtrVt, 0, GVal->isDSOLocal() ? 0 : ARMII::MO_GOT);
2470 Callee = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVt, G);
2471 if (!GVal->isDSOLocal())
2472 Callee =
2473 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2475 } else {
2476 // Neither execute-only nor PIC: load the address from a constant pool.
2477 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2478 ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(
2479 GVal, ARMPCLabelIndex, ARMCP::CPValue, 0);
2480
2481 // Get the address of the callee into a register
2482 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2483 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2484 Callee = DAG.getLoad(
2485 PtrVt, dl, DAG.getEntryNode(), Addr,
2487 }
2488 } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
2489 const char *Sym = S->getSymbol();
2490
2491 if (Subtarget->genExecuteOnly()) {
2492 // Execute-only forbids constant pools in .text, so use movw/movt.
2493 // fPIC is not supported with execute-only.
2494 if (Subtarget->useMovt())
2495 ++NumMovwMovt;
2496 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2497 DAG.getTargetExternalSymbol(Sym, PtrVt, 0));
2498 } else if (isPIC) {
2499 // PIC without execute-only: load the symbol's address from the GOT via
2500 // a GOT_PREL constant pool entry consumed by a PICLDR.
2501 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
2502 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2503 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2504 *DAG.getContext(), Sym, ARMPCLabelIndex, PCAdj, ARMCP::GOT_PREL,
2505 /*AddCurrentAddress=*/true);
2506 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2507 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2508 SDValue GOTOffset = DAG.getLoad(
2509 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2511 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2512 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, GOTOffset, PICLabel);
2513 Callee =
2514 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2516 } else {
2517 // Neither execute-only nor PIC: load the address from a constant pool.
2518 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2519 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2520 *DAG.getContext(), Sym, ARMPCLabelIndex, 0);
2521
2522 // Get the address of the callee into a register
2523 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2524 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2525 Callee = DAG.getLoad(
2526 PtrVt, dl, DAG.getEntryNode(), Addr,
2528 }
2529 }
2530 } else if (isa<GlobalAddressSDNode>(Callee)) {
2531 if (!PreferIndirect) {
2532 isDirect = true;
2533 bool isDef = GVal->isStrongDefinitionForLinker();
2534
2535 // ARM call to a local ARM function is predicable.
2536 isLocalARMFunc = !Subtarget->isThumb() && (isDef || !ARMInterworking);
2537 // tBX takes a register source operand.
2538 if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2539 assert(TT.isOSBinFormatMachO() && "WrapperPIC use on non-MachO?");
2540 Callee = DAG.getNode(
2541 ARMISD::WrapperPIC, dl, PtrVt,
2542 DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, ARMII::MO_NONLAZY));
2543 Callee = DAG.getLoad(
2544 PtrVt, dl, DAG.getEntryNode(), Callee,
2548 } else if (Subtarget->isTargetCOFF()) {
2549 assert(Subtarget->isTargetWindows() &&
2550 "Windows is the only supported COFF target");
2551 unsigned TargetFlags = ARMII::MO_NO_FLAG;
2552 if (GVal->hasDLLImportStorageClass())
2553 TargetFlags = ARMII::MO_DLLIMPORT;
2554 else if (!TM.shouldAssumeDSOLocal(GVal))
2555 TargetFlags = ARMII::MO_COFFSTUB;
2556 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, /*offset=*/0,
2557 TargetFlags);
2558 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
2559 Callee =
2560 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
2561 DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
2563 } else {
2564 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, 0);
2565 }
2566 }
2567 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2568 isDirect = true;
2569 // tBX takes a register source operand.
2570 const char *Sym = S->getSymbol();
2571 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2572 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2573 ARMConstantPoolValue *CPV =
2575 ARMPCLabelIndex, 4);
2576 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2577 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2578 Callee = DAG.getLoad(
2579 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2581 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2582 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, Callee, PICLabel);
2583 } else {
2584 Callee = DAG.getTargetExternalSymbol(Sym, PtrVt, 0);
2585 }
2586 }
2587
2588 if (isCmseNSCall) {
2589 assert(!isARMFunc && !isDirect &&
2590 "Cannot handle call to ARM function or direct call");
2591 if (NumBytes > 0) {
2592 DAG.getContext()->diagnose(
2593 DiagnosticInfoUnsupported(DAG.getMachineFunction().getFunction(),
2594 "call to non-secure function would require "
2595 "passing arguments on stack",
2596 dl.getDebugLoc()));
2597 }
2598 if (isStructRet) {
2599 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2601 "call to non-secure function would return value through pointer",
2602 dl.getDebugLoc()));
2603 }
2604 }
2605
2606 // FIXME: handle tail calls differently.
2607 unsigned CallOpc;
2608 if (Subtarget->isThumb()) {
2609 if (GuardWithBTI)
2610 CallOpc = ARMISD::t2CALL_BTI;
2611 else if (isCmseNSCall)
2612 CallOpc = ARMISD::tSECALL;
2613 else if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
2614 CallOpc = ARMISD::CALL_NOLINK;
2615 else
2616 CallOpc = ARMISD::CALL;
2617 } else {
2618 if (!isDirect && !Subtarget->hasV5TOps())
2619 CallOpc = ARMISD::CALL_NOLINK;
2620 else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
2621 // Emit regular call when code size is the priority
2622 !Subtarget->hasMinSize())
2623 // "mov lr, pc; b _foo" to avoid confusing the RSP
2624 CallOpc = ARMISD::CALL_NOLINK;
2625 else
2626 CallOpc = isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL;
2627 }
2628
2629 // We don't usually want to end the call-sequence here because we would tidy
2630 // the frame up *after* the call, however in the ABI-changing tail-call case
2631 // we've carefully laid out the parameters so that when sp is reset they'll be
2632 // in the correct location.
2633 if (isTailCall && !isSibCall) {
2634 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
2635 InGlue = Chain.getValue(1);
2636 }
2637
2638 std::vector<SDValue> Ops;
2639 Ops.push_back(Chain);
2640 Ops.push_back(Callee);
2641
2642 if (isTailCall) {
2643 Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
2644 }
2645
2646 // Add argument registers to the end of the list so that they are known live
2647 // into the call.
2648 for (const auto &[Reg, N] : RegsToPass)
2649 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2650
2651 // Add a register mask operand representing the call-preserved registers.
2652 const uint32_t *Mask;
2653 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
2654 if (isThisReturn) {
2655 // For 'this' returns, use the R0-preserving mask if applicable
2656 Mask = ARI->getThisReturnPreservedMask(MF, CallConv);
2657 if (!Mask) {
2658 // Set isThisReturn to false if the calling convention is not one that
2659 // allows 'returned' to be modeled in this way, so LowerCallResult does
2660 // not try to pass 'this' straight through
2661 isThisReturn = false;
2662 Mask = ARI->getCallPreservedMask(MF, CallConv);
2663 }
2664 } else
2665 Mask = ARI->getCallPreservedMask(MF, CallConv);
2666
2667 assert(Mask && "Missing call preserved mask for calling convention");
2668 Ops.push_back(DAG.getRegisterMask(Mask));
2669
2670 if (InGlue.getNode())
2671 Ops.push_back(InGlue);
2672
2673 if (isTailCall) {
2675 SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
2676 if (CLI.CFIType)
2677 Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2678 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2679 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2680 return Ret;
2681 }
2682
2683 // Returns a chain and a flag for retval copy to use.
2684 Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
2685 if (CLI.CFIType)
2686 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2687 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2688 InGlue = Chain.getValue(1);
2689 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
2690
2691 // If we're guaranteeing tail-calls will be honoured, the callee must
2692 // pop its own argument stack on return. But this call is *not* a tail call so
2693 // we need to undo that after it returns to restore the status-quo.
2694 bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
2695 uint64_t CalleePopBytes =
2696 canGuaranteeTCO(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : -1U;
2697
2698 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, CalleePopBytes, InGlue, dl);
2699 if (!Ins.empty())
2700 InGlue = Chain.getValue(1);
2701
2702 // Handle result values, copying them out of physregs into vregs that we
2703 // return.
2704 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2705 InVals, isThisReturn,
2706 isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
2707}
2708
2709/// HandleByVal - Every parameter *after* a byval parameter is passed
2710/// on the stack. Remember the next parameter register to allocate,
2711/// and then confiscate the rest of the parameter registers to insure
2712/// this.
2713void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size,
2714 Align Alignment) const {
2715 // Byval (as with any stack) slots are always at least 4 byte aligned.
2716 Alignment = std::max(Alignment, Align(4));
2717
2718 MCRegister Reg = State->AllocateReg(GPRArgRegs);
2719 if (!Reg)
2720 return;
2721
2722 unsigned AlignInRegs = Alignment.value() / 4;
2723 unsigned Waste = (ARM::R4 - Reg) % AlignInRegs;
2724 for (unsigned i = 0; i < Waste; ++i)
2725 Reg = State->AllocateReg(GPRArgRegs);
2726
2727 if (!Reg)
2728 return;
2729
2730 unsigned Excess = 4 * (ARM::R4 - Reg);
2731
2732 // Special case when NSAA != SP and parameter size greater than size of
2733 // all remained GPR regs. In that case we can't split parameter, we must
2734 // send it to stack. We also must set NCRN to R4, so waste all
2735 // remained registers.
2736 const unsigned NSAAOffset = State->getStackSize();
2737 if (NSAAOffset != 0 && Size > Excess) {
2738 while (State->AllocateReg(GPRArgRegs))
2739 ;
2740 return;
2741 }
2742
2743 // First register for byval parameter is the first register that wasn't
2744 // allocated before this method call, so it would be "reg".
2745 // If parameter is small enough to be saved in range [reg, r4), then
2746 // the end (first after last) register would be reg + param-size-in-regs,
2747 // else parameter would be splitted between registers and stack,
2748 // end register would be r4 in this case.
2749 unsigned ByValRegBegin = Reg;
2750 unsigned ByValRegEnd = std::min<unsigned>(Reg + Size / 4, ARM::R4);
2751 State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd);
2752 // Note, first register is allocated in the beginning of function already,
2753 // allocate remained amount of registers we need.
2754 for (unsigned i = Reg + 1; i != ByValRegEnd; ++i)
2755 State->AllocateReg(GPRArgRegs);
2756 // A byval parameter that is split between registers and memory needs its
2757 // size truncated here.
2758 // In the case where the entire structure fits in registers, we set the
2759 // size in memory to zero.
2760 Size = std::max<int>(Size - Excess, 0);
2761}
2762
2763/// IsEligibleForTailCallOptimization - Check whether the call is eligible
2764/// for tail call optimization. Targets which want to do tail call
2765/// optimization should implement this function. Note that this function also
2766/// processes musttail calls, so when this function returns false on a valid
2767/// musttail call, a fatal backend error occurs.
2768bool ARMTargetLowering::IsEligibleForTailCallOptimization(
2770 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
2771 CallingConv::ID CalleeCC = CLI.CallConv;
2772 SDValue Callee = CLI.Callee;
2773 bool isVarArg = CLI.IsVarArg;
2774 const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2775 const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2776 const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2777 const SelectionDAG &DAG = CLI.DAG;
2779 const Function &CallerF = MF.getFunction();
2780 CallingConv::ID CallerCC = CallerF.getCallingConv();
2781
2782 assert(Subtarget->supportsTailCall());
2783
2784 // Indirect tail-calls require a register to hold the target address. That
2785 // register must be:
2786 // * Allocatable (i.e. r0-r7 if the target is Thumb1).
2787 // * Not callee-saved, so must be one of r0-r3 or r12.
2788 // * Not used to hold an argument to the tail-called function, which might be
2789 // in r0-r3.
2790 // * Not used to hold the return address authentication code, which is in r12
2791 // if enabled.
2792 // Sometimes, no register matches all of these conditions, so we can't do a
2793 // tail-call.
2794 if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) {
2795 SmallSet<MCPhysReg, 5> AddressRegisters = {ARM::R0, ARM::R1, ARM::R2,
2796 ARM::R3};
2797 if (!(Subtarget->isThumb1Only() ||
2798 MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)))
2799 AddressRegisters.insert(ARM::R12);
2800 for (const CCValAssign &AL : ArgLocs)
2801 if (AL.isRegLoc())
2802 AddressRegisters.erase(AL.getLocReg());
2803 if (AddressRegisters.empty()) {
2804 LLVM_DEBUG(dbgs() << "false (no reg to hold function pointer)\n");
2805 return false;
2806 }
2807 }
2808
2809 // Look for obvious safe cases to perform tail call optimization that do not
2810 // require ABI changes. This is what gcc calls sibcall.
2811
2812 // Exception-handling functions need a special set of instructions to indicate
2813 // a return to the hardware. Tail-calling another function would probably
2814 // break this.
2815 if (CallerF.hasFnAttribute("interrupt")) {
2816 LLVM_DEBUG(dbgs() << "false (interrupt attribute)\n");
2817 return false;
2818 }
2819
2820 if (canGuaranteeTCO(CalleeCC,
2821 getTargetMachine().Options.GuaranteedTailCallOpt)) {
2822 LLVM_DEBUG(dbgs() << (CalleeCC == CallerCC ? "true" : "false")
2823 << " (guaranteed tail-call CC)\n");
2824 return CalleeCC == CallerCC;
2825 }
2826
2827 // Also avoid sibcall optimization if either caller or callee uses struct
2828 // return semantics.
2829 bool isCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
2830 bool isCallerStructRet = MF.getFunction().hasStructRetAttr();
2831 if (isCalleeStructRet != isCallerStructRet) {
2832 LLVM_DEBUG(dbgs() << "false (struct-ret)\n");
2833 return false;
2834 }
2835
2836 // Externally-defined functions with weak linkage should not be
2837 // tail-called on ARM when the OS does not support dynamic
2838 // pre-emption of symbols, as the AAELF spec requires normal calls
2839 // to undefined weak functions to be replaced with a NOP or jump to the
2840 // next instruction. The behaviour of branch instructions in this
2841 // situation (as used for tail calls) is implementation-defined, so we
2842 // cannot rely on the linker replacing the tail call with a return.
2843 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2844 const GlobalValue *GV = G->getGlobal();
2845 const Triple &TT = getTargetMachine().getTargetTriple();
2846 if (GV->hasExternalWeakLinkage() &&
2847 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
2848 TT.isOSBinFormatMachO())) {
2849 LLVM_DEBUG(dbgs() << "false (external weak linkage)\n");
2850 return false;
2851 }
2852 }
2853
2854 // Check that the call results are passed in the same way.
2855 LLVMContext &C = *DAG.getContext();
2857 getEffectiveCallingConv(CalleeCC, isVarArg),
2858 getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
2859 CCAssignFnForReturn(CalleeCC, isVarArg),
2860 CCAssignFnForReturn(CallerCC, CallerF.isVarArg()))) {
2861 LLVM_DEBUG(dbgs() << "false (incompatible results)\n");
2862 return false;
2863 }
2864 // The callee has to preserve all registers the caller needs to preserve.
2865 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
2866 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
2867 if (CalleeCC != CallerCC) {
2868 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
2869 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) {
2870 LLVM_DEBUG(dbgs() << "false (not all registers preserved)\n");
2871 return false;
2872 }
2873 }
2874
2875 // If Caller's vararg argument has been split between registers and stack, do
2876 // not perform tail call, since part of the argument is in caller's local
2877 // frame.
2878 const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
2879 if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
2880 LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
2881 return false;
2882 }
2883
2884 // If the callee takes no arguments then go on to check the results of the
2885 // call.
2886 const MachineRegisterInfo &MRI = MF.getRegInfo();
2887 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals)) {
2888 LLVM_DEBUG(dbgs() << "false (parameters in CSRs do not match)\n");
2889 return false;
2890 }
2891
2892 // If the stack arguments for this call do not fit into our own save area then
2893 // the call cannot be made tail.
2894 if (CCInfo.getStackSize() > AFI_Caller->getArgumentStackSize())
2895 return false;
2896
2897 LLVM_DEBUG(dbgs() << "true\n");
2898 return true;
2899}
2900
2901bool
2902ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2903 MachineFunction &MF, bool isVarArg,
2905 LLVMContext &Context, const Type *RetTy) const {
2907 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
2908 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2909}
2910
2912 const SDLoc &DL, SelectionDAG &DAG) {
2913 const MachineFunction &MF = DAG.getMachineFunction();
2914 const Function &F = MF.getFunction();
2915
2916 StringRef IntKind = F.getFnAttribute("interrupt").getValueAsString();
2917
2918 // See ARM ARM v7 B1.8.3. On exception entry LR is set to a possibly offset
2919 // version of the "preferred return address". These offsets affect the return
2920 // instruction if this is a return from PL1 without hypervisor extensions.
2921 // IRQ/FIQ: +4 "subs pc, lr, #4"
2922 // SWI: 0 "subs pc, lr, #0"
2923 // ABORT: +4 "subs pc, lr, #4"
2924 // UNDEF: +4/+2 "subs pc, lr, #0"
2925 // UNDEF varies depending on where the exception came from ARM or Thumb
2926 // mode. Alongside GCC, we throw our hands up in disgust and pretend it's 0.
2927
2928 int64_t LROffset;
2929 if (IntKind == "" || IntKind == "IRQ" || IntKind == "FIQ" ||
2930 IntKind == "ABORT")
2931 LROffset = 4;
2932 else if (IntKind == "SWI" || IntKind == "UNDEF")
2933 LROffset = 0;
2934 else
2935 report_fatal_error("Unsupported interrupt attribute. If present, value "
2936 "must be one of: IRQ, FIQ, SWI, ABORT or UNDEF");
2937
2938 RetOps.insert(RetOps.begin() + 1,
2939 DAG.getConstant(LROffset, DL, MVT::i32, false));
2940
2941 return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
2942}
2943
2944SDValue
2945ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2946 bool isVarArg,
2948 const SmallVectorImpl<SDValue> &OutVals,
2949 const SDLoc &dl, SelectionDAG &DAG) const {
2950 // CCValAssign - represent the assignment of the return value to a location.
2952
2953 // CCState - Info about the registers and stack slots.
2954 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
2955 *DAG.getContext());
2956
2957 // Analyze outgoing return values.
2958 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2959
2960 SDValue Glue;
2962 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
2963 bool isLittleEndian = Subtarget->isLittle();
2964
2966 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2967 AFI->setReturnRegsCount(RVLocs.size());
2968
2969 // Report error if cmse entry function returns structure through first ptr arg.
2970 if (AFI->isCmseNSEntryFunction() && MF.getFunction().hasStructRetAttr()) {
2971 // Note: using an empty SDLoc(), as the first line of the function is a
2972 // better place to report than the last line.
2973 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2975 "secure entry function would return value through pointer",
2976 SDLoc().getDebugLoc()));
2977 }
2978
2979 // Copy the result values into the output registers.
2980 for (unsigned i = 0, realRVLocIdx = 0;
2981 i != RVLocs.size();
2982 ++i, ++realRVLocIdx) {
2983 CCValAssign &VA = RVLocs[i];
2984 assert(VA.isRegLoc() && "Can only return in registers!");
2985
2986 SDValue Arg = OutVals[realRVLocIdx];
2987 bool ReturnF16 = false;
2988
2989 if (Subtarget->hasFullFP16() && Subtarget->isTargetHardFloat()) {
2990 // Half-precision return values can be returned like this:
2991 //
2992 // t11 f16 = fadd ...
2993 // t12: i16 = bitcast t11
2994 // t13: i32 = zero_extend t12
2995 // t14: f32 = bitcast t13 <~~~~~~~ Arg
2996 //
2997 // to avoid code generation for bitcasts, we simply set Arg to the node
2998 // that produces the f16 value, t11 in this case.
2999 //
3000 if (Arg.getValueType() == MVT::f32 && Arg.getOpcode() == ISD::BITCAST) {
3001 SDValue ZE = Arg.getOperand(0);
3002 if (ZE.getOpcode() == ISD::ZERO_EXTEND && ZE.getValueType() == MVT::i32) {
3003 SDValue BC = ZE.getOperand(0);
3004 if (BC.getOpcode() == ISD::BITCAST && BC.getValueType() == MVT::i16) {
3005 Arg = BC.getOperand(0);
3006 ReturnF16 = true;
3007 }
3008 }
3009 }
3010 }
3011
3012 switch (VA.getLocInfo()) {
3013 default: llvm_unreachable("Unknown loc info!");
3014 case CCValAssign::Full: break;
3015 case CCValAssign::BCvt:
3016 if (!ReturnF16)
3017 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3018 break;
3019 }
3020
3021 // Mask f16 arguments if this is a CMSE nonsecure entry.
3022 auto RetVT = Outs[realRVLocIdx].ArgVT;
3023 if (AFI->isCmseNSEntryFunction() && (RetVT == MVT::f16)) {
3024 if (VA.needsCustom() && VA.getValVT() == MVT::f16) {
3025 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
3026 } else {
3027 auto LocBits = VA.getLocVT().getSizeInBits();
3028 auto MaskValue = APInt::getLowBitsSet(LocBits, RetVT.getSizeInBits());
3029 SDValue Mask =
3030 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
3031 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
3032 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
3033 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3034 }
3035 }
3036
3037 if (VA.needsCustom() &&
3038 (VA.getLocVT() == MVT::v2f64 || VA.getLocVT() == MVT::f64)) {
3039 if (VA.getLocVT() == MVT::v2f64) {
3040 // Extract the first half and return it in two registers.
3041 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3042 DAG.getConstant(0, dl, MVT::i32));
3043 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
3044 DAG.getVTList(MVT::i32, MVT::i32), Half);
3045
3046 Chain =
3047 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3048 HalfGPRs.getValue(isLittleEndian ? 0 : 1), Glue);
3049 Glue = Chain.getValue(1);
3050 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3051 VA = RVLocs[++i]; // skip ahead to next loc
3052 Chain =
3053 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3054 HalfGPRs.getValue(isLittleEndian ? 1 : 0), Glue);
3055 Glue = Chain.getValue(1);
3056 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3057 VA = RVLocs[++i]; // skip ahead to next loc
3058
3059 // Extract the 2nd half and fall through to handle it as an f64 value.
3060 Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3061 DAG.getConstant(1, dl, MVT::i32));
3062 }
3063 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
3064 // available.
3065 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
3066 DAG.getVTList(MVT::i32, MVT::i32), Arg);
3067 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3068 fmrrd.getValue(isLittleEndian ? 0 : 1), 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 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3073 fmrrd.getValue(isLittleEndian ? 1 : 0), Glue);
3074 } else
3075 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
3076
3077 // Guarantee that all emitted copies are
3078 // stuck together, avoiding something bad.
3079 Glue = Chain.getValue(1);
3080 RetOps.push_back(DAG.getRegister(
3081 VA.getLocReg(), ReturnF16 ? Arg.getValueType() : VA.getLocVT()));
3082 }
3083 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
3084 const MCPhysReg *I =
3085 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3086 if (I) {
3087 for (; *I; ++I) {
3088 if (ARM::GPRRegClass.contains(*I))
3089 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3090 else if (ARM::DPRRegClass.contains(*I))
3092 else
3093 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3094 }
3095 }
3096
3097 // Update chain and glue.
3098 RetOps[0] = Chain;
3099 if (Glue.getNode())
3100 RetOps.push_back(Glue);
3101
3102 // CPUs which aren't M-class use a special sequence to return from
3103 // exceptions (roughly, any instruction setting pc and cpsr simultaneously,
3104 // though we use "subs pc, lr, #N").
3105 //
3106 // M-class CPUs actually use a normal return sequence with a special
3107 // (hardware-provided) value in LR, so the normal code path works.
3108 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt") &&
3109 !Subtarget->isMClass()) {
3110 if (Subtarget->isThumb1Only())
3111 report_fatal_error("interrupt attribute is not supported in Thumb1");
3112 return LowerInterruptReturn(RetOps, dl, DAG);
3113 }
3114
3115 unsigned RetNode =
3116 AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
3117 return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
3118}
3119
3120bool ARMTargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
3121 if (N->getNumValues() != 1)
3122 return false;
3123 if (!N->hasNUsesOfValue(1, 0))
3124 return false;
3125
3126 SDValue TCChain = Chain;
3127 SDNode *Copy = *N->user_begin();
3128 if (Copy->getOpcode() == ISD::CopyToReg) {
3129 // If the copy has a glue operand, we conservatively assume it isn't safe to
3130 // perform a tail call.
3131 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3132 return false;
3133 TCChain = Copy->getOperand(0);
3134 } else if (Copy->getOpcode() == ARMISD::VMOVRRD) {
3135 SDNode *VMov = Copy;
3136 // f64 returned in a pair of GPRs.
3137 SmallPtrSet<SDNode*, 2> Copies;
3138 for (SDNode *U : VMov->users()) {
3139 if (U->getOpcode() != ISD::CopyToReg)
3140 return false;
3141 Copies.insert(U);
3142 }
3143 if (Copies.size() > 2)
3144 return false;
3145
3146 for (SDNode *U : VMov->users()) {
3147 SDValue UseChain = U->getOperand(0);
3148 if (Copies.count(UseChain.getNode()))
3149 // Second CopyToReg
3150 Copy = U;
3151 else {
3152 // We are at the top of this chain.
3153 // If the copy has a glue operand, we conservatively assume it
3154 // isn't safe to perform a tail call.
3155 if (U->getOperand(U->getNumOperands() - 1).getValueType() == MVT::Glue)
3156 return false;
3157 // First CopyToReg
3158 TCChain = UseChain;
3159 }
3160 }
3161 } else if (Copy->getOpcode() == ISD::BITCAST) {
3162 // f32 returned in a single GPR.
3163 if (!Copy->hasOneUse())
3164 return false;
3165 Copy = *Copy->user_begin();
3166 if (Copy->getOpcode() != ISD::CopyToReg || !Copy->hasNUsesOfValue(1, 0))
3167 return false;
3168 // If the copy has a glue operand, we conservatively assume it isn't safe to
3169 // perform a tail call.
3170 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3171 return false;
3172 TCChain = Copy->getOperand(0);
3173 } else {
3174 return false;
3175 }
3176
3177 bool HasRet = false;
3178 for (const SDNode *U : Copy->users()) {
3179 if (U->getOpcode() != ARMISD::RET_GLUE &&
3180 U->getOpcode() != ARMISD::INTRET_GLUE)
3181 return false;
3182 HasRet = true;
3183 }
3184
3185 if (!HasRet)
3186 return false;
3187
3188 Chain = TCChain;
3189 return true;
3190}
3191
3192bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
3193 if (!Subtarget->supportsTailCall())
3194 return false;
3195
3196 if (!CI->isTailCall())
3197 return false;
3198
3199 return true;
3200}
3201
3202// Trying to write a 64 bit value so need to split into two 32 bit values first,
3203// and pass the lower and high parts through.
3205 SDLoc DL(Op);
3206 SDValue WriteValue = Op->getOperand(2);
3207
3208 // This function is only supposed to be called for i64 type argument.
3209 assert(WriteValue.getValueType() == MVT::i64
3210 && "LowerWRITE_REGISTER called for non-i64 type argument.");
3211
3212 SDValue Lo, Hi;
3213 std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32);
3214 SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi };
3215 return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops);
3216}
3217
3218// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3219// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
3220// one of the above mentioned nodes. It has to be wrapped because otherwise
3221// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3222// be used to form addressing mode. These wrapped nodes will be selected
3223// into MOVi.
3224SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
3225 SelectionDAG &DAG) const {
3226 EVT PtrVT = Op.getValueType();
3227 // FIXME there is no actual debug info here
3228 SDLoc dl(Op);
3229 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3230 SDValue Res;
3231
3232 // When generating execute-only code Constant Pools must be promoted to the
3233 // global data section. It's a bit ugly that we can't share them across basic
3234 // blocks, but this way we guarantee that execute-only behaves correct with
3235 // position-independent addressing modes.
3236 if (Subtarget->genExecuteOnly()) {
3237 auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
3238 auto *T = CP->getType();
3239 auto C = const_cast<Constant*>(CP->getConstVal());
3240 auto M = DAG.getMachineFunction().getFunction().getParent();
3241 auto GV = new GlobalVariable(
3242 *M, T, /*isConstant=*/true, GlobalVariable::InternalLinkage, C,
3243 Twine(DAG.getDataLayout().getInternalSymbolPrefix()) + "CP" +
3244 Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
3245 Twine(AFI->createPICLabelUId()));
3246 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3247 return LowerGlobalAddress(GA, DAG);
3248 }
3249
3250 // The 16-bit ADR instruction can only encode offsets that are multiples of 4,
3251 // so we need to align to at least 4 bytes when we don't have 32-bit ADR.
3252 Align CPAlign = CP->getAlign();
3253 if (Subtarget->isThumb1Only())
3254 CPAlign = std::max(CPAlign, Align(4));
3256 Res =
3257 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CPAlign);
3258 else
3259 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CPAlign);
3260 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
3261}
3262
3264 // If we don't have a 32-bit pc-relative branch instruction then the jump
3265 // table consists of block addresses. Usually this is inline, but for
3266 // execute-only it must be placed out-of-line.
3267 if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
3270}
3271
3272SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
3273 SelectionDAG &DAG) const {
3276 unsigned ARMPCLabelIndex = 0;
3277 SDLoc DL(Op);
3278 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3279 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
3280 SDValue CPAddr;
3281 bool IsPositionIndependent = isPositionIndependent() || Subtarget->isROPI();
3282 if (!IsPositionIndependent) {
3283 CPAddr = DAG.getTargetConstantPool(BA, PtrVT, Align(4));
3284 } else {
3285 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3286 ARMPCLabelIndex = AFI->createPICLabelUId();
3288 ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex,
3289 ARMCP::CPBlockAddress, PCAdj);
3290 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3291 }
3292 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
3293 SDValue Result = DAG.getLoad(
3294 PtrVT, DL, DAG.getEntryNode(), CPAddr,
3296 if (!IsPositionIndependent)
3297 return Result;
3298 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, DL, MVT::i32);
3299 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
3300}
3301
3302/// Convert a TLS address reference into the correct sequence of loads
3303/// and calls to compute the variable's address for Darwin, and return an
3304/// SDValue containing the final node.
3305
3306/// Darwin only has one TLS scheme which must be capable of dealing with the
3307/// fully general situation, in the worst case. This means:
3308/// + "extern __thread" declaration.
3309/// + Defined in a possibly unknown dynamic library.
3310///
3311/// The general system is that each __thread variable has a [3 x i32] descriptor
3312/// which contains information used by the runtime to calculate the address. The
3313/// only part of this the compiler needs to know about is the first word, which
3314/// contains a function pointer that must be called with the address of the
3315/// entire descriptor in "r0".
3316///
3317/// Since this descriptor may be in a different unit, in general access must
3318/// proceed along the usual ARM rules. A common sequence to produce is:
3319///
3320/// movw rT1, :lower16:_var$non_lazy_ptr
3321/// movt rT1, :upper16:_var$non_lazy_ptr
3322/// ldr r0, [rT1]
3323/// ldr rT2, [r0]
3324/// blx rT2
3325/// [...address now in r0...]
3326SDValue
3327ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
3328 SelectionDAG &DAG) const {
3329 assert(getTargetMachine().getTargetTriple().isOSDarwin() &&
3330 "This function expects a Darwin target");
3331 SDLoc DL(Op);
3332
3333 // First step is to get the address of the actua global symbol. This is where
3334 // the TLS descriptor lives.
3335 SDValue DescAddr = LowerGlobalAddressDarwin(Op, DAG);
3336
3337 // The first entry in the descriptor is a function pointer that we must call
3338 // to obtain the address of the variable.
3339 SDValue Chain = DAG.getEntryNode();
3340 SDValue FuncTLVGet = DAG.getLoad(
3341 MVT::i32, DL, Chain, DescAddr,
3345 Chain = FuncTLVGet.getValue(1);
3346
3348 MachineFrameInfo &MFI = F.getFrameInfo();
3349 MFI.setAdjustsStack(true);
3350
3351 // TLS calls preserve all registers except those that absolutely must be
3352 // trashed: R0 (it takes an argument), LR (it's a call) and CPSR (let's not be
3353 // silly).
3354 auto TRI =
3356 auto ARI = static_cast<const ARMRegisterInfo *>(TRI);
3357 const uint32_t *Mask = ARI->getTLSCallPreservedMask(DAG.getMachineFunction());
3358
3359 // Finally, we can make the call. This is just a degenerate version of a
3360 // normal AArch64 call node: r0 takes the address of the descriptor, and
3361 // returns the address of the variable in this thread.
3362 Chain = DAG.getCopyToReg(Chain, DL, ARM::R0, DescAddr, SDValue());
3363 Chain =
3364 DAG.getNode(ARMISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
3365 Chain, FuncTLVGet, DAG.getRegister(ARM::R0, MVT::i32),
3366 DAG.getRegisterMask(Mask), Chain.getValue(1));
3367 return DAG.getCopyFromReg(Chain, DL, ARM::R0, MVT::i32, Chain.getValue(1));
3368}
3369
3370SDValue
3371ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
3372 SelectionDAG &DAG) const {
3373 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3374 "Windows specific TLS lowering");
3375
3376 SDValue Chain = DAG.getEntryNode();
3377 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3378 SDLoc DL(Op);
3379
3380 // Load the current TEB (thread environment block)
3381 SDValue Ops[] = {Chain,
3382 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
3383 DAG.getTargetConstant(15, DL, MVT::i32),
3384 DAG.getTargetConstant(0, DL, MVT::i32),
3385 DAG.getTargetConstant(13, DL, MVT::i32),
3386 DAG.getTargetConstant(0, DL, MVT::i32),
3387 DAG.getTargetConstant(2, DL, MVT::i32)};
3388 SDValue CurrentTEB = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
3389 DAG.getVTList(MVT::i32, MVT::Other), Ops);
3390
3391 SDValue TEB = CurrentTEB.getValue(0);
3392 Chain = CurrentTEB.getValue(1);
3393
3394 // Load the ThreadLocalStoragePointer from the TEB
3395 // A pointer to the TLS array is located at offset 0x2c from the TEB.
3396 SDValue TLSArray =
3397 DAG.getNode(ISD::ADD, DL, PtrVT, TEB, DAG.getIntPtrConstant(0x2c, DL));
3398 TLSArray = DAG.getLoad(PtrVT, DL, Chain, TLSArray, MachinePointerInfo());
3399
3400 // The pointer to the thread's TLS data area is at the TLS Index scaled by 4
3401 // offset into the TLSArray.
3402
3403 // Load the TLS index from the C runtime
3404 SDValue TLSIndex =
3405 DAG.getTargetExternalSymbol("_tls_index", PtrVT, ARMII::MO_NO_FLAG);
3406 TLSIndex = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, TLSIndex);
3407 TLSIndex = DAG.getLoad(PtrVT, DL, Chain, TLSIndex, MachinePointerInfo());
3408
3409 SDValue Slot = DAG.getNode(ISD::SHL, DL, PtrVT, TLSIndex,
3410 DAG.getConstant(2, DL, MVT::i32));
3411 SDValue TLS = DAG.getLoad(PtrVT, DL, Chain,
3412 DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
3413 MachinePointerInfo());
3414
3415 // Get the offset of the start of the .tls section (section base)
3416 const auto *GA = cast<GlobalAddressSDNode>(Op);
3417 auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
3418 SDValue Offset = DAG.getLoad(
3419 PtrVT, DL, Chain,
3420 DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
3421 DAG.getTargetConstantPool(CPV, PtrVT, Align(4))),
3423
3424 return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
3425}
3426
3427// Lower ISD::GlobalTLSAddress using the "general dynamic" model
3428SDValue
3429ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
3430 SelectionDAG &DAG) const {
3431 SDLoc dl(GA);
3432 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3433 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3435 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3436 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3437 ARMConstantPoolValue *CPV =
3438 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3439 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
3440 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3441 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
3442 Argument = DAG.getLoad(
3443 PtrVT, dl, DAG.getEntryNode(), Argument,
3445 SDValue Chain = Argument.getValue(1);
3446
3447 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3448 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
3449
3450 // call __tls_get_addr.
3452 Args.emplace_back(Argument, Type::getInt32Ty(*DAG.getContext()));
3453
3454 // FIXME: is there useful debug info available here?
3455 TargetLowering::CallLoweringInfo CLI(DAG);
3456 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3458 DAG.getExternalSymbol("__tls_get_addr", PtrVT), std::move(Args));
3459
3460 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3461 return CallResult.first;
3462}
3463
3464// Lower ISD::GlobalTLSAddress using the "initial exec" or
3465// "local exec" model.
3466SDValue
3467ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
3468 SelectionDAG &DAG,
3469 TLSModel::Model model) const {
3470 const GlobalValue *GV = GA->getGlobal();
3471 SDLoc dl(GA);
3472 SDValue Offset;
3473 SDValue Chain = DAG.getEntryNode();
3474 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3475 // Get the Thread Pointer
3476 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3477
3478 if (model == TLSModel::InitialExec) {
3480 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3481 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3482 // Initial exec model.
3483 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3484 ARMConstantPoolValue *CPV =
3485 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3487 true);
3488 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3489 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3490 Offset = DAG.getLoad(
3491 PtrVT, dl, Chain, Offset,
3493 Chain = Offset.getValue(1);
3494
3495 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3496 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
3497
3498 Offset = DAG.getLoad(
3499 PtrVT, dl, Chain, Offset,
3501 } else {
3502 // local exec model
3503 assert(model == TLSModel::LocalExec);
3504 ARMConstantPoolValue *CPV =
3506 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3507 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3508 Offset = DAG.getLoad(
3509 PtrVT, dl, Chain, Offset,
3511 }
3512
3513 // The address of the thread local variable is the add of the thread
3514 // pointer with the offset of the variable.
3515 return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
3516}
3517
3518SDValue
3519ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
3520 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
3521 if (DAG.getTarget().useEmulatedTLS())
3522 return LowerToTLSEmulatedModel(GA, DAG);
3523
3524 const Triple &TT = getTargetMachine().getTargetTriple();
3525 if (TT.isOSDarwin())
3526 return LowerGlobalTLSAddressDarwin(Op, DAG);
3527
3528 if (TT.isOSWindows())
3529 return LowerGlobalTLSAddressWindows(Op, DAG);
3530
3531 // TODO: implement the "local dynamic" model
3532 assert(TT.isOSBinFormatELF() && "Only ELF implemented here");
3534
3535 switch (model) {
3538 return LowerToTLSGeneralDynamicModel(GA, DAG);
3541 return LowerToTLSExecModels(GA, DAG, model);
3542 }
3543 llvm_unreachable("bogus TLS model");
3544}
3545
3546/// Return true if all users of V are within function F, looking through
3547/// ConstantExprs.
3548static bool allUsersAreInFunction(const Value *V, const Function *F) {
3549 SmallVector<const User*,4> Worklist(V->users());
3550 while (!Worklist.empty()) {
3551 auto *U = Worklist.pop_back_val();
3552 if (isa<ConstantExpr>(U)) {
3553 append_range(Worklist, U->users());
3554 continue;
3555 }
3556
3557 auto *I = dyn_cast<Instruction>(U);
3558 if (!I || I->getParent()->getParent() != F)
3559 return false;
3560 }
3561 return true;
3562}
3563
3565 const GlobalValue *GV, SelectionDAG &DAG,
3566 EVT PtrVT, const SDLoc &dl) {
3567 // If we're creating a pool entry for a constant global with unnamed address,
3568 // and the global is small enough, we can emit it inline into the constant pool
3569 // to save ourselves an indirection.
3570 //
3571 // This is a win if the constant is only used in one function (so it doesn't
3572 // need to be duplicated) or duplicating the constant wouldn't increase code
3573 // size (implying the constant is no larger than 4 bytes).
3574 const Function &F = DAG.getMachineFunction().getFunction();
3575
3576 // We rely on this decision to inline being idempotent and unrelated to the
3577 // use-site. We know that if we inline a variable at one use site, we'll
3578 // inline it elsewhere too (and reuse the constant pool entry). Fast-isel
3579 // doesn't know about this optimization, so bail out if it's enabled else
3580 // we could decide to inline here (and thus never emit the GV) but require
3581 // the GV from fast-isel generated code.
3584 return SDValue();
3585
3586 auto *GVar = dyn_cast<GlobalVariable>(GV);
3587 if (!GVar || !GVar->hasInitializer() ||
3588 !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
3589 !GVar->hasLocalLinkage())
3590 return SDValue();
3591
3592 // If we inline a value that contains relocations, we move the relocations
3593 // from .data to .text. This is not allowed in position-independent code.
3594 auto *Init = GVar->getInitializer();
3595 if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3596 Init->needsDynamicRelocation())
3597 return SDValue();
3598
3599 // The constant islands pass can only really deal with alignment requests
3600 // <= 4 bytes and cannot pad constants itself. Therefore we cannot promote
3601 // any type wanting greater alignment requirements than 4 bytes. We also
3602 // can only promote constants that are multiples of 4 bytes in size or
3603 // are paddable to a multiple of 4. Currently we only try and pad constants
3604 // that are strings for simplicity.
3605 auto *CDAInit = dyn_cast<ConstantDataArray>(Init);
3606 unsigned Size = DAG.getDataLayout().getTypeAllocSize(Init->getType());
3607 Align PrefAlign = DAG.getDataLayout().getPreferredAlign(GVar);
3608 unsigned RequiredPadding = 4 - (Size % 4);
3609 bool PaddingPossible =
3610 RequiredPadding == 4 || (CDAInit && CDAInit->isString());
3611 if (!PaddingPossible || PrefAlign > 4 || Size > ConstpoolPromotionMaxSize ||
3612 Size == 0)
3613 return SDValue();
3614
3615 unsigned PaddedSize = Size + ((RequiredPadding == 4) ? 0 : RequiredPadding);
3617 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3618
3619 // We can't bloat the constant pool too much, else the ConstantIslands pass
3620 // may fail to converge. If we haven't promoted this global yet (it may have
3621 // multiple uses), and promoting it would increase the constant pool size (Sz
3622 // > 4), ensure we have space to do so up to MaxTotal.
3623 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar) && Size > 4)
3624 if (AFI->getPromotedConstpoolIncrease() + PaddedSize - 4 >=
3626 return SDValue();
3627
3628 // This is only valid if all users are in a single function; we can't clone
3629 // the constant in general. The LLVM IR unnamed_addr allows merging
3630 // constants, but not cloning them.
3631 //
3632 // We could potentially allow cloning if we could prove all uses of the
3633 // constant in the current function don't care about the address, like
3634 // printf format strings. But that isn't implemented for now.
3635 if (!allUsersAreInFunction(GVar, &F))
3636 return SDValue();
3637
3638 // We're going to inline this global. Pad it out if needed.
3639 if (RequiredPadding != 4) {
3640 StringRef S = CDAInit->getAsString();
3641
3643 std::copy(S.bytes_begin(), S.bytes_end(), V.begin());
3644 while (RequiredPadding--)
3645 V.push_back(0);
3647 }
3648
3649 auto CPVal = ARMConstantPoolConstant::Create(GVar, Init);
3650 SDValue CPAddr = DAG.getTargetConstantPool(CPVal, PtrVT, Align(4));
3651 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar)) {
3654 PaddedSize - 4);
3655 }
3656 ++NumConstpoolPromoted;
3657 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3658}
3659
3661 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
3662 if (!(GV = GA->getAliaseeObject()))
3663 return false;
3664 if (const auto *V = dyn_cast<GlobalVariable>(GV))
3665 return V->isConstant();
3666 return isa<Function>(GV);
3667}
3668
3669SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3670 SelectionDAG &DAG) const {
3671 switch (Subtarget->getTargetTriple().getObjectFormat()) {
3672 default: llvm_unreachable("unknown object format");
3673 case Triple::COFF:
3674 return LowerGlobalAddressWindows(Op, DAG);
3675 case Triple::ELF:
3676 return LowerGlobalAddressELF(Op, DAG);
3677 case Triple::MachO:
3678 return LowerGlobalAddressDarwin(Op, DAG);
3679 }
3680}
3681
3682SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
3683 SelectionDAG &DAG) const {
3684 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3685 SDLoc dl(Op);
3686 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3687 bool IsRO = isReadOnly(GV);
3688
3689 // promoteToConstantPool only if not generating XO text section
3690 if (GV->isDSOLocal() && !Subtarget->genExecuteOnly())
3691 if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
3692 return V;
3693
3694 if (isPositionIndependent()) {
3695 SDValue G = DAG.getTargetGlobalAddress(
3696 GV, dl, PtrVT, 0, GV->isDSOLocal() ? 0 : ARMII::MO_GOT);
3697 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3698 if (!GV->isDSOLocal())
3699 Result =
3700 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3702 return Result;
3703 } else if (Subtarget->isROPI() && IsRO) {
3704 // PC-relative.
3705 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3706 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3707 return Result;
3708 } else if (Subtarget->isRWPI() && !IsRO) {
3709 // SB-relative.
3710 SDValue RelAddr;
3711 if (Subtarget->useMovt()) {
3712 ++NumMovwMovt;
3713 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_SBREL);
3714 RelAddr = DAG.getNode(ARMISD::Wrapper, dl, PtrVT, G);
3715 } else { // use literal pool for address constant
3716 ARMConstantPoolValue *CPV =
3718 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3719 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3720 RelAddr = DAG.getLoad(
3721 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3723 }
3724 SDValue SB = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::R9, PtrVT);
3725 SDValue Result = DAG.getNode(ISD::ADD, dl, PtrVT, SB, RelAddr);
3726 return Result;
3727 }
3728
3729 // If we have T2 ops, we can materialize the address directly via movt/movw
3730 // pair. This is always cheaper. If need to generate Execute Only code, and we
3731 // only have Thumb1 available, we can't use a constant pool and are forced to
3732 // use immediate relocations.
3733 if (Subtarget->useMovt() || Subtarget->genExecuteOnly()) {
3734 if (Subtarget->useMovt())
3735 ++NumMovwMovt;
3736 // FIXME: Once remat is capable of dealing with instructions with register
3737 // operands, expand this into two nodes.
3738 return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
3739 DAG.getTargetGlobalAddress(GV, dl, PtrVT));
3740 } else {
3741 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
3742 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3743 return DAG.getLoad(
3744 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3746 }
3747}
3748
3749SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3750 SelectionDAG &DAG) const {
3751 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3752 "ROPI/RWPI not currently supported for Darwin");
3753 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3754 SDLoc dl(Op);
3755 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3756
3757 if (Subtarget->useMovt())
3758 ++NumMovwMovt;
3759
3760 // FIXME: Once remat is capable of dealing with instructions with register
3761 // operands, expand this into multiple nodes
3762 unsigned Wrapper =
3763 isPositionIndependent() ? ARMISD::WrapperPIC : ARMISD::Wrapper;
3764
3765 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
3766 SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
3767
3768 if (Subtarget->isGVIndirectSymbol(GV))
3769 Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3771 return Result;
3772}
3773
3774SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op,
3775 SelectionDAG &DAG) const {
3776 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3777 "non-Windows COFF is not supported");
3778 assert(Subtarget->useMovt() &&
3779 "Windows on ARM expects to use movw/movt");
3780 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3781 "ROPI/RWPI not currently supported for Windows");
3782
3783 const TargetMachine &TM = getTargetMachine();
3784 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3785 ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG;
3786 if (GV->hasDLLImportStorageClass())
3787 TargetFlags = ARMII::MO_DLLIMPORT;
3788 else if (!TM.shouldAssumeDSOLocal(GV))
3789 TargetFlags = ARMII::MO_COFFSTUB;
3790 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3791 SDValue Result;
3792 SDLoc DL(Op);
3793
3794 ++NumMovwMovt;
3795
3796 // FIXME: Once remat is capable of dealing with instructions with register
3797 // operands, expand this into two nodes.
3798 Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT,
3799 DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*offset=*/0,
3800 TargetFlags));
3801 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
3802 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
3804 return Result;
3805}
3806
3807SDValue
3808ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const {
3809 SDLoc dl(Op);
3810 SDValue Val = DAG.getConstant(0, dl, MVT::i32);
3811 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl,
3812 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
3813 Op.getOperand(1), Val);
3814}
3815
3816SDValue
3817ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
3818 SDLoc dl(Op);
3819 return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
3820 Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
3821}
3822
3823SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
3824 SelectionDAG &DAG) const {
3825 SDLoc dl(Op);
3826 return DAG.getNode(ARMISD::EH_SJLJ_SETUP_DISPATCH, dl, MVT::Other,
3827 Op.getOperand(0));
3828}
3829
3830SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3831 SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3832 unsigned IntNo =
3833 Op.getConstantOperandVal(Op.getOperand(0).getValueType() == MVT::Other);
3834 switch (IntNo) {
3835 default:
3836 return SDValue(); // Don't custom lower most intrinsics.
3837 case Intrinsic::arm_gnu_eabi_mcount: {
3839 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3840 SDLoc dl(Op);
3841 SDValue Chain = Op.getOperand(0);
3842 // call "\01__gnu_mcount_nc"
3843 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3844 const uint32_t *Mask =
3846 assert(Mask && "Missing call preserved mask for calling convention");
3847 // Mark LR an implicit live-in.
3848 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3849 SDValue ReturnAddress =
3850 DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3851 constexpr EVT ResultTys[] = {MVT::Other, MVT::Glue};
3852 SDValue Callee =
3853 DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3854 SDValue RegisterMask = DAG.getRegisterMask(Mask);
3855 if (Subtarget->isThumb())
3856 return SDValue(
3857 DAG.getMachineNode(
3858 ARM::tBL_PUSHLR, dl, ResultTys,
3859 {ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3860 DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3861 0);
3862 return SDValue(
3863 DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3864 {ReturnAddress, Callee, RegisterMask, Chain}),
3865 0);
3866 }
3867 }
3868}
3869
3870SDValue
3871ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
3872 const ARMSubtarget *Subtarget) const {
3873 unsigned IntNo = Op.getConstantOperandVal(0);
3874 SDLoc dl(Op);
3875 switch (IntNo) {
3876 default: return SDValue(); // Don't custom lower most intrinsics.
3877 case Intrinsic::localaddress: {
3878 const MachineFunction &MF = DAG.getMachineFunction();
3879 const auto *RegInfo = Subtarget->getRegisterInfo();
3880 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
3881 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
3882 Op.getSimpleValueType());
3883 }
3884 case Intrinsic::eh_recoverfp: {
3885 SDValue FnOp = Op.getOperand(1);
3886 GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
3887 auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
3888 if (!Fn)
3890 "llvm.eh.recoverfp must take a function as the first argument");
3891 const auto *RegInfo = Subtarget->getRegisterInfo();
3892 Register BaseReg = RegInfo->getBaseRegister();
3894 MachineBasicBlock &MBB = *MF.begin();
3895 if (!MBB.isLiveIn(BaseReg))
3896 MBB.addLiveIn(BaseReg);
3897 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3898 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, BaseReg, PtrVT);
3899 }
3900 case Intrinsic::thread_pointer: {
3901 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3902 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3903 }
3904 case Intrinsic::arm_cls: {
3905 // Note: arm_cls and arm_cls64 intrinsics are expanded directly here
3906 // in LowerINTRINSIC_WO_CHAIN since there's no native scalar CLS
3907 // instruction.
3908 const SDValue &Operand = Op.getOperand(1);
3909 const EVT VTy = Op.getValueType();
3910 return DAG.getNode(ISD::CTLS, dl, VTy, Operand);
3911 }
3912 case Intrinsic::arm_cls64: {
3913 // arm_cls64 returns i32 but takes i64 input.
3914 // Use ISD::CTLS for i64 and truncate the result.
3915 SDValue CTLS64 = DAG.getNode(ISD::CTLS, dl, MVT::i64, Op.getOperand(1));
3916 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, CTLS64);
3917 }
3918 case Intrinsic::arm_neon_vcls:
3919 case Intrinsic::arm_mve_vcls: {
3920 // Lower vector CLS intrinsics to ISD::CTLS.
3921 // Vector CTLS is Legal when NEON/MVE is available (set elsewhere).
3922 const EVT VTy = Op.getValueType();
3923 return DAG.getNode(ISD::CTLS, dl, VTy, Op.getOperand(1));
3924 }
3925 case Intrinsic::eh_sjlj_lsda: {
3927 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3928 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3929 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3930 SDValue CPAddr;
3931 bool IsPositionIndependent = isPositionIndependent();
3932 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
3933 ARMConstantPoolValue *CPV =
3934 ARMConstantPoolConstant::Create(&MF.getFunction(), ARMPCLabelIndex,
3935 ARMCP::CPLSDA, PCAdj);
3936 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3937 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3938 SDValue Result = DAG.getLoad(
3939 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3941
3942 if (IsPositionIndependent) {
3943 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3944 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
3945 }
3946 return Result;
3947 }
3948 case Intrinsic::arm_neon_vabs:
3949 return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(),
3950 Op.getOperand(1));
3951 case Intrinsic::arm_neon_vabds:
3952 if (Op.getValueType().isInteger())
3953 return DAG.getNode(ISD::ABDS, SDLoc(Op), Op.getValueType(),
3954 Op.getOperand(1), Op.getOperand(2));
3955 return SDValue();
3956 case Intrinsic::arm_neon_vabdu:
3957 return DAG.getNode(ISD::ABDU, SDLoc(Op), Op.getValueType(),
3958 Op.getOperand(1), Op.getOperand(2));
3959 case Intrinsic::arm_neon_vmulls:
3960 case Intrinsic::arm_neon_vmullu: {
3961 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
3962 ? ARMISD::VMULLs : ARMISD::VMULLu;
3963 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3964 Op.getOperand(1), Op.getOperand(2));
3965 }
3966 case Intrinsic::arm_neon_vminnm:
3967 case Intrinsic::arm_neon_vmaxnm: {
3968 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminnm)
3969 ? ISD::FMINNUM : ISD::FMAXNUM;
3970 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3971 Op.getOperand(1), Op.getOperand(2));
3972 }
3973 case Intrinsic::arm_neon_vminu:
3974 case Intrinsic::arm_neon_vmaxu: {
3975 if (Op.getValueType().isFloatingPoint())
3976 return SDValue();
3977 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminu)
3978 ? ISD::UMIN : ISD::UMAX;
3979 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3980 Op.getOperand(1), Op.getOperand(2));
3981 }
3982 case Intrinsic::arm_neon_vmins:
3983 case Intrinsic::arm_neon_vmaxs: {
3984 // v{min,max}s is overloaded between signed integers and floats.
3985 if (!Op.getValueType().isFloatingPoint()) {
3986 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3987 ? ISD::SMIN : ISD::SMAX;
3988 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3989 Op.getOperand(1), Op.getOperand(2));
3990 }
3991 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3992 ? ISD::FMINIMUM : ISD::FMAXIMUM;
3993 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3994 Op.getOperand(1), Op.getOperand(2));
3995 }
3996 case Intrinsic::arm_neon_vtbl1:
3997 return DAG.getNode(ARMISD::VTBL1, SDLoc(Op), Op.getValueType(),
3998 Op.getOperand(1), Op.getOperand(2));
3999 case Intrinsic::arm_neon_vtbl2:
4000 return DAG.getNode(ARMISD::VTBL2, SDLoc(Op), Op.getValueType(),
4001 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4002 case Intrinsic::arm_mve_pred_i2v:
4003 case Intrinsic::arm_mve_pred_v2i:
4004 return DAG.getNode(ARMISD::PREDICATE_CAST, SDLoc(Op), Op.getValueType(),
4005 Op.getOperand(1));
4006 case Intrinsic::arm_mve_vreinterpretq:
4007 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(Op), Op.getValueType(),
4008 Op.getOperand(1));
4009 case Intrinsic::arm_mve_lsll:
4010 return DAG.getNode(ARMISD::LSLL, SDLoc(Op), Op->getVTList(),
4011 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4012 case Intrinsic::arm_mve_asrl:
4013 return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
4014 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4015 case Intrinsic::arm_mve_vsli:
4016 return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
4017 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4018 case Intrinsic::arm_mve_vsri:
4019 return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
4020 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4021 }
4022}
4023
4025 const ARMSubtarget *Subtarget) {
4026 SDLoc dl(Op);
4027 auto SSID = static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
4028 if (SSID == SyncScope::SingleThread)
4029 return Op;
4030
4031 if (!Subtarget->hasDataBarrier()) {
4032 // Some ARMv6 cpus can support data barriers with an mcr instruction.
4033 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
4034 // here.
4035 assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() &&
4036 "Unexpected ISD::ATOMIC_FENCE encountered. Should be libcall!");
4037 return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0),
4038 DAG.getConstant(0, dl, MVT::i32));
4039 }
4040
4041 AtomicOrdering Ord =
4042 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
4044 if (Subtarget->isMClass()) {
4045 // Only a full system barrier exists in the M-class architectures.
4047 } else if (Subtarget->preferISHSTBarriers() &&
4048 Ord == AtomicOrdering::Release) {
4049 // Swift happens to implement ISHST barriers in a way that's compatible with
4050 // Release semantics but weaker than ISH so we'd be fools not to use
4051 // it. Beware: other processors probably don't!
4053 }
4054
4055 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
4056 DAG.getConstant(Intrinsic::arm_dmb, dl, MVT::i32),
4057 DAG.getConstant(Domain, dl, MVT::i32));
4058}
4059
4061 const ARMSubtarget *Subtarget) {
4062 // ARM pre v5TE and Thumb1 does not have preload instructions.
4063 if (!(Subtarget->isThumb2() ||
4064 (!Subtarget->isThumb1Only() && Subtarget->hasV5TEOps())))
4065 // Just preserve the chain.
4066 return Op.getOperand(0);
4067
4068 SDLoc dl(Op);
4069 unsigned isRead = ~Op.getConstantOperandVal(2) & 1;
4070 if (!isRead &&
4071 (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
4072 // ARMv7 with MP extension has PLDW.
4073 return Op.getOperand(0);
4074
4075 unsigned isData = Op.getConstantOperandVal(4);
4076 if (Subtarget->isThumb()) {
4077 // Invert the bits.
4078 isRead = ~isRead & 1;
4079 isData = ~isData & 1;
4080 }
4081
4082 return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
4083 Op.getOperand(1), DAG.getConstant(isRead, dl, MVT::i32),
4084 DAG.getConstant(isData, dl, MVT::i32));
4085}
4086
4089 ARMFunctionInfo *FuncInfo = MF.getInfo<ARMFunctionInfo>();
4090
4091 // vastart just stores the address of the VarArgsFrameIndex slot into the
4092 // memory location argument.
4093 SDLoc dl(Op);
4095 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4096 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4097 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
4098 MachinePointerInfo(SV));
4099}
4100
4101SDValue ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA,
4102 CCValAssign &NextVA,
4103 SDValue &Root,
4104 SelectionDAG &DAG,
4105 const SDLoc &dl) const {
4107 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4108
4109 const TargetRegisterClass *RC;
4110 if (AFI->isThumb1OnlyFunction())
4111 RC = &ARM::tGPRRegClass;
4112 else
4113 RC = &ARM::GPRRegClass;
4114
4115 // Transform the arguments stored in physical registers into virtual ones.
4116 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4117 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4118
4119 SDValue ArgValue2;
4120 if (NextVA.isMemLoc()) {
4121 MachineFrameInfo &MFI = MF.getFrameInfo();
4122 int FI = MFI.CreateFixedObject(4, NextVA.getLocMemOffset(), true);
4123
4124 // Create load node to retrieve arguments from the stack.
4125 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4126 ArgValue2 = DAG.getLoad(
4127 MVT::i32, dl, Root, FIN,
4129 } else {
4130 Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
4131 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4132 }
4133 if (!Subtarget->isLittle())
4134 std::swap (ArgValue, ArgValue2);
4135 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
4136}
4137
4138// The remaining GPRs hold either the beginning of variable-argument
4139// data, or the beginning of an aggregate passed by value (usually
4140// byval). Either way, we allocate stack slots adjacent to the data
4141// provided by our caller, and store the unallocated registers there.
4142// If this is a variadic function, the va_list pointer will begin with
4143// these values; otherwise, this reassembles a (byval) structure that
4144// was split between registers and memory.
4145// Return: The frame index registers were stored into.
4146int ARMTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG,
4147 const SDLoc &dl, SDValue &Chain,
4148 const Value *OrigArg,
4149 unsigned InRegsParamRecordIdx,
4150 int ArgOffset, unsigned ArgSize) const {
4151 // Currently, two use-cases possible:
4152 // Case #1. Non-var-args function, and we meet first byval parameter.
4153 // Setup first unallocated register as first byval register;
4154 // eat all remained registers
4155 // (these two actions are performed by HandleByVal method).
4156 // Then, here, we initialize stack frame with
4157 // "store-reg" instructions.
4158 // Case #2. Var-args function, that doesn't contain byval parameters.
4159 // The same: eat all remained unallocated registers,
4160 // initialize stack frame.
4161
4163 MachineFrameInfo &MFI = MF.getFrameInfo();
4164 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4165 unsigned RBegin, REnd;
4166 if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) {
4167 CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, RBegin, REnd);
4168 } else {
4169 unsigned RBeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4170 RBegin = RBeginIdx == 4 ? (unsigned)ARM::R4 : GPRArgRegs[RBeginIdx];
4171 REnd = ARM::R4;
4172 }
4173
4174 if (REnd != RBegin)
4175 ArgOffset = -4 * (ARM::R4 - RBegin);
4176
4177 auto PtrVT = getPointerTy(DAG.getDataLayout());
4178 int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, false);
4179 SDValue FIN = DAG.getFrameIndex(FrameIndex, PtrVT);
4180
4182 const TargetRegisterClass *RC =
4183 AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
4184
4185 for (unsigned Reg = RBegin, i = 0; Reg < REnd; ++Reg, ++i) {
4186 Register VReg = MF.addLiveIn(Reg, RC);
4187 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
4188 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
4189 MachinePointerInfo(OrigArg, 4 * i));
4190 MemOps.push_back(Store);
4191 FIN = DAG.getNode(ISD::ADD, dl, PtrVT, FIN, DAG.getConstant(4, dl, PtrVT));
4192 }
4193
4194 if (!MemOps.empty())
4195 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
4196 return FrameIndex;
4197}
4198
4199// Setup stack frame, the va_list pointer will start from.
4200void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
4201 const SDLoc &dl, SDValue &Chain,
4202 unsigned ArgOffset,
4203 unsigned TotalArgRegsSaveSize,
4204 bool ForceMutable) const {
4206 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4207
4208 // Try to store any remaining integer argument regs
4209 // to their spots on the stack so that they may be loaded by dereferencing
4210 // the result of va_next.
4211 // If there is no regs to be stored, just point address after last
4212 // argument passed via stack.
4213 int FrameIndex = StoreByValRegs(
4214 CCInfo, DAG, dl, Chain, nullptr, CCInfo.getInRegsParamsCount(),
4215 CCInfo.getStackSize(), std::max(4U, TotalArgRegsSaveSize));
4216 AFI->setVarArgsFrameIndex(FrameIndex);
4217}
4218
4219bool ARMTargetLowering::splitValueIntoRegisterParts(
4220 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
4221 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
4222 EVT ValueVT = Val.getValueType();
4223 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4224 unsigned ValueBits = ValueVT.getSizeInBits();
4225 unsigned PartBits = PartVT.getSizeInBits();
4226 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(ValueBits), Val);
4227 Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::getIntegerVT(PartBits), Val);
4228 Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
4229 Parts[0] = Val;
4230 return true;
4231 }
4232 return false;
4233}
4234
4235SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
4236 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
4237 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
4238 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4239 unsigned ValueBits = ValueVT.getSizeInBits();
4240 unsigned PartBits = PartVT.getSizeInBits();
4241 SDValue Val = Parts[0];
4242
4243 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(PartBits), Val);
4244 Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::getIntegerVT(ValueBits), Val);
4245 Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
4246 return Val;
4247 }
4248 return SDValue();
4249}
4250
4251SDValue ARMTargetLowering::LowerFormalArguments(
4252 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
4253 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
4254 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
4256 MachineFrameInfo &MFI = MF.getFrameInfo();
4257
4258 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4259
4260 // Assign locations to all of the incoming arguments.
4262 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
4263 *DAG.getContext());
4264 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4265
4267 unsigned CurArgIdx = 0;
4268
4269 // Initially ArgRegsSaveSize is zero.
4270 // Then we increase this value each time we meet byval parameter.
4271 // We also increase this value in case of varargs function.
4272 AFI->setArgRegsSaveSize(0);
4273
4274 // Calculate the amount of stack space that we need to allocate to store
4275 // byval and variadic arguments that are passed in registers.
4276 // We need to know this before we allocate the first byval or variadic
4277 // argument, as they will be allocated a stack slot below the CFA (Canonical
4278 // Frame Address, the stack pointer at entry to the function).
4279 unsigned ArgRegBegin = ARM::R4;
4280 for (const CCValAssign &VA : ArgLocs) {
4281 if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
4282 break;
4283
4284 unsigned Index = VA.getValNo();
4285 ISD::ArgFlagsTy Flags = Ins[Index].Flags;
4286 if (!Flags.isByVal())
4287 continue;
4288
4289 assert(VA.isMemLoc() && "unexpected byval pointer in reg");
4290 unsigned RBegin, REnd;
4291 CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
4292 ArgRegBegin = std::min(ArgRegBegin, RBegin);
4293
4294 CCInfo.nextInRegsParam();
4295 }
4296 CCInfo.rewindByValRegsInfo();
4297
4298 int lastInsIndex = -1;
4299 if (isVarArg && MFI.hasVAStart()) {
4300 unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4301 if (RegIdx != std::size(GPRArgRegs))
4302 ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
4303 }
4304
4305 unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
4306 AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
4307 auto PtrVT = getPointerTy(DAG.getDataLayout());
4308
4309 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4310 CCValAssign &VA = ArgLocs[i];
4311 if (Ins[VA.getValNo()].isOrigArg()) {
4312 std::advance(CurOrigArg,
4313 Ins[VA.getValNo()].getOrigArgIndex() - CurArgIdx);
4314 CurArgIdx = Ins[VA.getValNo()].getOrigArgIndex();
4315 }
4316 // Arguments stored in registers.
4317 if (VA.isRegLoc()) {
4318 EVT RegVT = VA.getLocVT();
4319 SDValue ArgValue;
4320
4321 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4322 // f64 and vector types are split up into multiple registers or
4323 // combinations of registers and stack slots.
4324 SDValue ArgValue1 =
4325 GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4326 VA = ArgLocs[++i]; // skip ahead to next loc
4327 SDValue ArgValue2;
4328 if (VA.isMemLoc()) {
4329 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), true);
4330 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4331 ArgValue2 = DAG.getLoad(
4332 MVT::f64, dl, Chain, FIN,
4334 } else {
4335 ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4336 }
4337 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
4338 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4339 ArgValue1, DAG.getIntPtrConstant(0, dl));
4340 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4341 ArgValue2, DAG.getIntPtrConstant(1, dl));
4342 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
4343 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4344 } else {
4345 const TargetRegisterClass *RC;
4346
4347 if (RegVT == MVT::f16 || RegVT == MVT::bf16)
4348 RC = &ARM::HPRRegClass;
4349 else if (RegVT == MVT::f32)
4350 RC = &ARM::SPRRegClass;
4351 else if (RegVT == MVT::f64 || RegVT == MVT::v4f16 ||
4352 RegVT == MVT::v4bf16)
4353 RC = &ARM::DPRRegClass;
4354 else if (RegVT == MVT::v2f64 || RegVT == MVT::v8f16 ||
4355 RegVT == MVT::v8bf16)
4356 RC = &ARM::QPRRegClass;
4357 else if (RegVT == MVT::i32)
4358 RC = AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass
4359 : &ARM::GPRRegClass;
4360 else
4361 llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
4362
4363 // Transform the arguments in physical registers into virtual ones.
4364 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4365 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
4366
4367 // If this value is passed in r0 and has the returned attribute (e.g.
4368 // C++ 'structors), record this fact for later use.
4369 if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
4370 AFI->setPreservesR0();
4371 }
4372 }
4373
4374 // If this is an 8 or 16-bit value, it is really passed promoted
4375 // to 32 bits. Insert an assert[sz]ext to capture this, then
4376 // truncate to the right size.
4377 switch (VA.getLocInfo()) {
4378 default: llvm_unreachable("Unknown loc info!");
4379 case CCValAssign::Full: break;
4380 case CCValAssign::BCvt:
4381 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4382 break;
4383 }
4384
4385 // f16 arguments have their size extended to 4 bytes and passed as if they
4386 // had been copied to the LSBs of a 32-bit register.
4387 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
4388 if (VA.needsCustom() &&
4389 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4390 ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4391
4392 // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4393 // less than 32 bits must be sign- or zero-extended in the callee for
4394 // security reasons. Although the ABI mandates an extension done by the
4395 // caller, the latter cannot be trusted to follow the rules of the ABI.
4396 const ISD::InputArg &Arg = Ins[VA.getValNo()];
4397 if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4398 RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4399 ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4400
4401 InVals.push_back(ArgValue);
4402 } else { // VA.isRegLoc()
4403 // Only arguments passed on the stack should make it here.
4404 assert(VA.isMemLoc());
4405 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
4406
4407 int index = VA.getValNo();
4408
4409 // Some Ins[] entries become multiple ArgLoc[] entries.
4410 // Process them only once.
4411 if (index != lastInsIndex)
4412 {
4413 ISD::ArgFlagsTy Flags = Ins[index].Flags;
4414 // FIXME: For now, all byval parameter objects are marked mutable.
4415 // This can be changed with more analysis.
4416 // In case of tail call optimization mark all arguments mutable.
4417 // Since they could be overwritten by lowering of arguments in case of
4418 // a tail call.
4419 if (Flags.isByVal()) {
4420 assert(Ins[index].isOrigArg() &&
4421 "Byval arguments cannot be implicit");
4422 unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed();
4423
4424 int FrameIndex = StoreByValRegs(
4425 CCInfo, DAG, dl, Chain, &*CurOrigArg, CurByValIndex,
4426 VA.getLocMemOffset(), Flags.getByValSize());
4427 InVals.push_back(DAG.getFrameIndex(FrameIndex, PtrVT));
4428 CCInfo.nextInRegsParam();
4429 } else if (VA.needsCustom() && (VA.getValVT() == MVT::f16 ||
4430 VA.getValVT() == MVT::bf16)) {
4431 // f16 and bf16 values are passed in the least-significant half of
4432 // a 4 byte stack slot. This is done as-if the extension was done
4433 // in a 32-bit register, so the actual bytes used for the value
4434 // differ between little and big endian.
4435 assert(VA.getLocVT().getSizeInBits() == 32);
4436 unsigned FIOffset = VA.getLocMemOffset();
4437 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits() / 8,
4438 FIOffset, true);
4439
4440 SDValue Addr = DAG.getFrameIndex(FI, PtrVT);
4441 if (DAG.getDataLayout().isBigEndian())
4442 Addr = DAG.getObjectPtrOffset(dl, Addr, TypeSize::getFixed(2));
4443
4444 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, Addr,
4446 DAG.getMachineFunction(), FI)));
4447
4448 } else {
4449 unsigned FIOffset = VA.getLocMemOffset();
4450 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
4451 FIOffset, true);
4452
4453 // Create load nodes to retrieve arguments from the stack.
4454 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4455 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
4457 DAG.getMachineFunction(), FI)));
4458 }
4459 lastInsIndex = index;
4460 }
4461 }
4462 }
4463
4464 // varargs
4465 if (isVarArg && MFI.hasVAStart()) {
4466 VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getStackSize(),
4467 TotalArgRegsSaveSize);
4468 if (AFI->isCmseNSEntryFunction()) {
4469 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4471 "secure entry function must not be variadic", dl.getDebugLoc()));
4472 }
4473 }
4474
4475 unsigned StackArgSize = CCInfo.getStackSize();
4476 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4477 if (canGuaranteeTCO(CallConv, TailCallOpt)) {
4478 // The only way to guarantee a tail call is if the callee restores its
4479 // argument area, but it must also keep the stack aligned when doing so.
4480 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
4481 assert(StackAlign && "data layout string is missing stack alignment");
4482 StackArgSize = alignTo(StackArgSize, *StackAlign);
4483
4484 AFI->setArgumentStackToRestore(StackArgSize);
4485 }
4486 AFI->setArgumentStackSize(StackArgSize);
4487
4488 if (CCInfo.getStackSize() > 0 && AFI->isCmseNSEntryFunction()) {
4489 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4491 "secure entry function requires arguments on stack", dl.getDebugLoc()));
4492 }
4493
4494 return Chain;
4495}
4496
4497/// isFloatingPointZero - Return true if this is +0.0.
4500 return CFP->getValueAPF().isPosZero();
4501 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
4502 // Maybe this has already been legalized into the constant pool?
4503 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
4504 SDValue WrapperOp = Op.getOperand(1).getOperand(0);
4506 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
4507 return CFP->getValueAPF().isPosZero();
4508 }
4509 } else if (Op->getOpcode() == ISD::BITCAST &&
4510 Op->getValueType(0) == MVT::f64) {
4511 // Handle (ISD::BITCAST (ARMISD::VMOVIMM (ISD::TargetConstant 0)) MVT::f64)
4512 // created by LowerConstantFP().
4513 SDValue BitcastOp = Op->getOperand(0);
4514 if (BitcastOp->getOpcode() == ARMISD::VMOVIMM &&
4515 isNullConstant(BitcastOp->getOperand(0)))
4516 return true;
4517 }
4518 return false;
4519}
4520
4522 // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
4523 if (Op->getFlags().hasNoSignedWrap())
4524 return true;
4525
4526 // We can still figure out if the second operand is safe to use
4527 // in a CMN instruction by checking if it is known to be not the minimum
4528 // signed value. If it is not, then we can safely use CMN.
4529 // Note: We can eventually remove this check and simply rely on
4530 // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
4531 // consistently sets them appropriately when making said nodes.
4532
4533 KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
4534 return !KnownSrc.getSignedMinValue().isMinSignedValue();
4535}
4536
4538 return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
4539 (isIntEqualitySetCC(CC) ||
4540 (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
4541 (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
4542}
4543
4544/// Returns how profitable it is to fold a comparison's operand's shift and/or
4545/// extension operations into the comparison instruction's second operand
4546/// (so_reg_imm / so_reg_reg for ARM, t2_so_reg for Thumb-2).
4548 // Thumb-1 CMP does not support shifted second operands.
4549 if (ST.isThumb1Only() || !Op.hasOneUse())
4550 return 0;
4551
4552 unsigned Opc = Op.getOpcode();
4553 if (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) {
4554 if (auto *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
4555 return ShiftAmt->getZExtValue() <= 31 ? 1 : 0;
4556 // Register-controlled shift: only ARM-mode CMP/CMN (so_reg_reg) supports
4557 // this; Thumb-2 t2_so_reg requires an immediate shift amount.
4558 return ST.isThumb() ? 0 : 1;
4559 }
4560
4561 if (Opc == ISD::ROTR) {
4562 // Rotr constants will be normalized via mod 32, or & 31,
4563 // so we do not have to bounds check.
4564 if (isa<ConstantSDNode>(Op.getOperand(1)))
4565 return 1;
4566 return ST.isThumb() ? 0 : 1;
4567 }
4568
4569 return 0;
4570}
4571
4572/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4573/// the given operands.
4574SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4575 SDValue &ARMcc, SelectionDAG &DAG,
4576 const SDLoc &dl) const {
4577 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4578 unsigned C = RHSC->getZExtValue();
4579 if (!isLegalICmpImmediate((int32_t)C)) {
4580 // Constant does not fit, try adjusting it by one.
4581 switch (CC) {
4582 default: break;
4583 case ISD::SETLT:
4584 case ISD::SETGE:
4585 if (C != 0x80000000 && isLegalICmpImmediate(C-1)) {
4586 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4587 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4588 }
4589 break;
4590 case ISD::SETULT:
4591 case ISD::SETUGE:
4592 if (C != 0 && isLegalICmpImmediate(C-1)) {
4593 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4594 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4595 }
4596 break;
4597 case ISD::SETLE:
4598 case ISD::SETGT:
4599 if (C != 0x7fffffff && isLegalICmpImmediate(C+1)) {
4600 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4601 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4602 }
4603 break;
4604 case ISD::SETULE:
4605 case ISD::SETUGT:
4606 if (C != 0xffffffff && isLegalICmpImmediate(C+1)) {
4607 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4608 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4609 }
4610 break;
4611 }
4612 }
4613 }
4614
4615 // Thumb1 has very limited immediate modes, so turning an "and" into a
4616 // shift can save multiple instructions.
4617 //
4618 // If we have (x & C1), and C1 is an appropriate mask, we can transform it
4619 // into "((x << n) >> n)". But that isn't necessarily profitable on its
4620 // own. If it's the operand to an unsigned comparison with an immediate,
4621 // we can eliminate one of the shifts: we transform
4622 // "((x << n) >> n) == C2" to "(x << n) == (C2 << n)".
4623 //
4624 // We avoid transforming cases which aren't profitable due to encoding
4625 // details:
4626 //
4627 // 1. C2 fits into the immediate field of a cmp, and the transformed version
4628 // would not; in that case, we're essentially trading one immediate load for
4629 // another.
4630 // 2. C1 is 255 or 65535, so we can use uxtb or uxth.
4631 // 3. C2 is zero; we have other code for this special case.
4632 //
4633 // FIXME: Figure out profitability for Thumb2; we usually can't save an
4634 // instruction, since the AND is always one instruction anyway, but we could
4635 // use narrow instructions in some cases.
4636 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::AND &&
4637 LHS->hasOneUse() && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4638 LHS.getValueType() == MVT::i32 && isa<ConstantSDNode>(RHS) &&
4639 !isSignedIntSetCC(CC)) {
4640 unsigned Mask = LHS.getConstantOperandVal(1);
4641 auto *RHSC = cast<ConstantSDNode>(RHS.getNode());
4642 uint64_t RHSV = RHSC->getZExtValue();
4643 if (isMask_32(Mask) && (RHSV & ~Mask) == 0 && Mask != 255 && Mask != 65535) {
4644 unsigned ShiftBits = llvm::countl_zero(Mask);
4645 if (RHSV && (RHSV > 255 || (RHSV << ShiftBits) <= 255)) {
4646 SDValue ShiftAmt = DAG.getConstant(ShiftBits, dl, MVT::i32);
4647 LHS = DAG.getNode(ISD::SHL, dl, MVT::i32, LHS.getOperand(0), ShiftAmt);
4648 RHS = DAG.getConstant(RHSV << ShiftBits, dl, MVT::i32);
4649 }
4650 }
4651 }
4652
4653 // The specific comparison "(x<<c) > 0x80000000U" can be optimized to a
4654 // single "lsls x, c+1". The shift sets the "C" and "Z" flags the same
4655 // way a cmp would.
4656 // FIXME: Add support for ARM/Thumb2; this would need isel patterns, and
4657 // some tweaks to the heuristics for the previous and->shift transform.
4658 // FIXME: Optimize cases where the LHS isn't a shift.
4659 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::SHL &&
4660 isa<ConstantSDNode>(RHS) && RHS->getAsZExtVal() == 0x80000000U &&
4661 CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4662 LHS.getConstantOperandVal(1) < 31) {
4663 unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
4664 SDValue Shift =
4665 DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
4666 LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
4667 ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
4668 return Shift.getValue(1);
4669 }
4670
4672
4673 unsigned CompareType;
4674 switch (CondCode) {
4675 default:
4676 CompareType = ARMISD::CMP;
4677 break;
4678 case ARMCC::EQ:
4679 case ARMCC::NE:
4680 // Uses only Z Flag
4681 CompareType = ARMISD::CMPZ;
4682 break;
4683 }
4684
4685 // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
4686 // the codebase.
4687
4688 // TODO: When we have a solution to the vselect predicate not allowing pl/mi
4689 // all the time, allow those cases to be cmn too no matter what.
4690 if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
4691 CompareType = ARMISD::CMN;
4692 RHS = RHS.getOperand(1);
4693 } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
4694 CompareType = ARMISD::CMN;
4695 LHS = LHS.getOperand(1);
4697 }
4698
4699 // Prefer folding shifts / CMN into the cmp/cmn second operand (so_reg /
4700 // t2_so_reg). When both sides compete, pick the higher
4701 // getCmpOperandFoldingProfit. Only when RHS is not a legal icmp
4702 // immediate: otherwise keep the canonical (reg, imm) form.
4703 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getNode());
4704 if (!C || !isLegalICmpImmediate(C->getSExtValue())) {
4705 if (getCmpOperandFoldingProfit(LHS, *Subtarget) >
4706 getCmpOperandFoldingProfit(RHS, *Subtarget)) {
4707 std::swap(LHS, RHS);
4708 if (CompareType == ARMISD::CMP)
4710 }
4711 }
4712
4713 // If the RHS is a constant zero then the V (overflow) flag will never be
4714 // set. This can allow us to simplify GE to PL or LT to MI, which can be
4715 // simpler for other passes (like the peephole optimiser) to deal with.
4716 if (isNullConstant(RHS)) {
4717 switch (CondCode) {
4718 default:
4719 break;
4720 case ARMCC::GE:
4722 break;
4723 case ARMCC::LT:
4725 break;
4726 }
4727 }
4728
4729 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
4730 return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
4731}
4732
4733/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
4734SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4735 SelectionDAG &DAG, const SDLoc &dl,
4736 bool Signaling) const {
4737 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
4738 SDValue Flags;
4740 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP, dl, FlagsVT,
4741 LHS, RHS);
4742 else
4743 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
4744 FlagsVT, LHS);
4745 return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
4746}
4747
4748// This function returns three things: the arithmetic computation itself
4749// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4750// comparison and the condition code define the case in which the arithmetic
4751// computation *does not* overflow.
4752std::pair<SDValue, SDValue>
4753ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4754 SDValue &ARMcc) const {
4755 assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4756
4757 SDValue Value, OverflowCmp;
4758 SDValue LHS = Op.getOperand(0);
4759 SDValue RHS = Op.getOperand(1);
4760 SDLoc dl(Op);
4761
4762 // FIXME: We are currently always generating CMPs because we don't support
4763 // generating CMN through the backend. This is not as good as the natural
4764 // CMP case because it causes a register dependency and cannot be folded
4765 // later.
4766
4767 switch (Op.getOpcode()) {
4768 default:
4769 llvm_unreachable("Unknown overflow instruction!");
4770 case ISD::SADDO:
4771 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4772 Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4773 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4774 break;
4775 case ISD::UADDO:
4776 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4777 // We use ADDC here to correspond to its use in LowerALUO.
4778 // We do not use it in the USUBO case as Value may not be used.
4779 Value = DAG.getNode(ARMISD::ADDC, dl,
4780 DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4781 .getValue(0);
4782 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4783 break;
4784 case ISD::SSUBO:
4785 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4786 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4787 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4788 break;
4789 case ISD::USUBO:
4790 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4791 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4792 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4793 break;
4794 case ISD::UMULO:
4795 // We generate a UMUL_LOHI and then check if the high word is 0.
4796 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4797 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4798 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4799 LHS, RHS);
4800 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4801 DAG.getConstant(0, dl, MVT::i32));
4802 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4803 break;
4804 case ISD::SMULO:
4805 // We generate a SMUL_LOHI and then check if all the bits of the high word
4806 // are the same as the sign bit of the low word.
4807 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4808 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4809 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4810 LHS, RHS);
4811 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4812 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4813 Value.getValue(0),
4814 DAG.getConstant(31, dl, MVT::i32)));
4815 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4816 break;
4817 } // switch (...)
4818
4819 return std::make_pair(Value, OverflowCmp);
4820}
4821
4823 SDLoc DL(Value);
4824 EVT VT = Value.getValueType();
4825
4826 if (Invert)
4827 Value = DAG.getNode(ISD::SUB, DL, MVT::i32,
4828 DAG.getConstant(1, DL, MVT::i32), Value);
4829
4830 SDValue Cmp = DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(VT, MVT::i32),
4831 Value, DAG.getConstant(1, DL, VT));
4832 return Cmp.getValue(1);
4833}
4834
4836 bool Invert) {
4837 SDLoc DL(Flags);
4838
4839 if (Invert) {
4840 // Convert flags to boolean with ADDE 0,0,Carry then compute 1 - bool.
4841 SDValue BoolCarry = DAG.getNode(
4842 ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4843 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT), Flags);
4844 return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, VT), BoolCarry);
4845 }
4846
4847 // Now convert the carry flag into a boolean carry. We do this
4848 // using ARMISD::ADDE 0, 0, Carry
4849 return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4850 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT),
4851 Flags);
4852}
4853
4854// Value is 1 if 'V' bit is 1, else 0
4856 SDLoc DL(Flags);
4857 SDValue Zero = DAG.getConstant(0, DL, VT);
4858 SDValue One = DAG.getConstant(1, DL, VT);
4859 SDValue ARMcc = DAG.getConstant(ARMCC::VS, DL, MVT::i32);
4860 return DAG.getNode(ARMISD::CMOV, DL, VT, Zero, One, ARMcc, Flags);
4861}
4862
4863SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
4864 // Let legalize expand this if it isn't a legal type yet.
4865 if (!isTypeLegal(Op.getValueType()))
4866 return SDValue();
4867
4868 SDValue LHS = Op.getOperand(0);
4869 SDValue RHS = Op.getOperand(1);
4870 SDLoc dl(Op);
4871
4872 EVT VT = Op.getValueType();
4873 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4874 SDValue Value;
4875 SDValue Overflow;
4876 switch (Op.getOpcode()) {
4877 case ISD::UADDO:
4878 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4879 // Convert the carry flag into a boolean value.
4880 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, false);
4881 break;
4882 case ISD::USUBO:
4883 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4884 // Convert the carry flag into a boolean value.
4885 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, true);
4886 break;
4887 default: {
4888 // Handle other operations with getARMXALUOOp
4889 SDValue OverflowCmp, ARMcc;
4890 std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4891 // We use 0 and 1 as false and true values.
4892 // ARMcc represents the "no overflow" condition (e.g., VC for signed ops).
4893 // CMOV operand order is (FalseVal, TrueVal), so we put 1 in FalseVal
4894 // position to get Overflow=1 when the "no overflow" condition is false.
4895 Overflow =
4896 DAG.getNode(ARMISD::CMOV, dl, MVT::i32,
4897 DAG.getConstant(1, dl, MVT::i32), // FalseVal: overflow
4898 DAG.getConstant(0, dl, MVT::i32), // TrueVal: no overflow
4899 ARMcc, OverflowCmp);
4900 break;
4901 }
4902 }
4903
4904 return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4905}
4906
4908 const ARMSubtarget *Subtarget) {
4909 EVT VT = Op.getValueType();
4910 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || Subtarget->isThumb1Only())
4911 return SDValue();
4912 if (!VT.isSimple())
4913 return SDValue();
4914
4915 unsigned NewOpcode;
4916 switch (VT.getSimpleVT().SimpleTy) {
4917 default:
4918 return SDValue();
4919 case MVT::i8:
4920 switch (Op->getOpcode()) {
4921 case ISD::UADDSAT:
4922 NewOpcode = ARMISD::UQADD8b;
4923 break;
4924 case ISD::SADDSAT:
4925 NewOpcode = ARMISD::QADD8b;
4926 break;
4927 case ISD::USUBSAT:
4928 NewOpcode = ARMISD::UQSUB8b;
4929 break;
4930 case ISD::SSUBSAT:
4931 NewOpcode = ARMISD::QSUB8b;
4932 break;
4933 }
4934 break;
4935 case MVT::i16:
4936 switch (Op->getOpcode()) {
4937 case ISD::UADDSAT:
4938 NewOpcode = ARMISD::UQADD16b;
4939 break;
4940 case ISD::SADDSAT:
4941 NewOpcode = ARMISD::QADD16b;
4942 break;
4943 case ISD::USUBSAT:
4944 NewOpcode = ARMISD::UQSUB16b;
4945 break;
4946 case ISD::SSUBSAT:
4947 NewOpcode = ARMISD::QSUB16b;
4948 break;
4949 }
4950 break;
4951 }
4952
4953 SDLoc dl(Op);
4954 SDValue Add =
4955 DAG.getNode(NewOpcode, dl, MVT::i32,
4956 DAG.getSExtOrTrunc(Op->getOperand(0), dl, MVT::i32),
4957 DAG.getSExtOrTrunc(Op->getOperand(1), dl, MVT::i32));
4958 return DAG.getNode(ISD::TRUNCATE, dl, VT, Add);
4959}
4960
4961SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
4962 SDValue Cond = Op.getOperand(0);
4963 SDValue SelectTrue = Op.getOperand(1);
4964 SDValue SelectFalse = Op.getOperand(2);
4965 SDLoc dl(Op);
4966 unsigned Opc = Cond.getOpcode();
4967
4968 if (Cond.getResNo() == 1 &&
4969 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
4970 Opc == ISD::USUBO)) {
4971 if (!isTypeLegal(Cond->getValueType(0)))
4972 return SDValue();
4973
4974 SDValue Value, OverflowCmp;
4975 SDValue ARMcc;
4976 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
4977 EVT VT = Op.getValueType();
4978
4979 return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
4980 }
4981
4982 // Convert:
4983 //
4984 // (select (cmov 1, 0, cond), t, f) -> (cmov t, f, cond)
4985 // (select (cmov 0, 1, cond), t, f) -> (cmov f, t, cond)
4986 //
4987 if (Cond.getOpcode() == ARMISD::CMOV && Cond.hasOneUse()) {
4988 const ConstantSDNode *CMOVTrue =
4989 dyn_cast<ConstantSDNode>(Cond.getOperand(0));
4990 const ConstantSDNode *CMOVFalse =
4991 dyn_cast<ConstantSDNode>(Cond.getOperand(1));
4992
4993 if (CMOVTrue && CMOVFalse) {
4994 unsigned CMOVTrueVal = CMOVTrue->getZExtValue();
4995 unsigned CMOVFalseVal = CMOVFalse->getZExtValue();
4996
4997 SDValue True;
4998 SDValue False;
4999 if (CMOVTrueVal == 1 && CMOVFalseVal == 0) {
5000 True = SelectTrue;
5001 False = SelectFalse;
5002 } else if (CMOVTrueVal == 0 && CMOVFalseVal == 1) {
5003 True = SelectFalse;
5004 False = SelectTrue;
5005 }
5006
5007 if (True.getNode() && False.getNode())
5008 return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
5009 Cond.getOperand(3), DAG);
5010 }
5011 }
5012
5013 return DAG.getSelectCC(dl, Cond,
5014 DAG.getConstant(0, dl, Cond.getValueType()),
5015 SelectTrue, SelectFalse, ISD::SETNE);
5016}
5017
5019 bool &swpCmpOps, bool &swpVselOps) {
5020 // Start by selecting the GE condition code for opcodes that return true for
5021 // 'equality'
5022 if (CC == ISD::SETUGE || CC == ISD::SETOGE || CC == ISD::SETOLE ||
5023 CC == ISD::SETULE || CC == ISD::SETGE || CC == ISD::SETLE)
5024 CondCode = ARMCC::GE;
5025
5026 // and GT for opcodes that return false for 'equality'.
5027 else if (CC == ISD::SETUGT || CC == ISD::SETOGT || CC == ISD::SETOLT ||
5028 CC == ISD::SETULT || CC == ISD::SETGT || CC == ISD::SETLT)
5029 CondCode = ARMCC::GT;
5030
5031 // Since we are constrained to GE/GT, if the opcode contains 'less', we need
5032 // to swap the compare operands.
5033 if (CC == ISD::SETOLE || CC == ISD::SETULE || CC == ISD::SETOLT ||
5034 CC == ISD::SETULT || CC == ISD::SETLE || CC == ISD::SETLT)
5035 swpCmpOps = true;
5036
5037 // Both GT and GE are ordered comparisons, and return false for 'unordered'.
5038 // If we have an unordered opcode, we need to swap the operands to the VSEL
5039 // instruction (effectively negating the condition).
5040 //
5041 // This also has the effect of swapping which one of 'less' or 'greater'
5042 // returns true, so we also swap the compare operands. It also switches
5043 // whether we return true for 'equality', so we compensate by picking the
5044 // opposite condition code to our original choice.
5045 if (CC == ISD::SETULE || CC == ISD::SETULT || CC == ISD::SETUGE ||
5046 CC == ISD::SETUGT) {
5047 swpCmpOps = !swpCmpOps;
5048 swpVselOps = !swpVselOps;
5049 CondCode = CondCode == ARMCC::GT ? ARMCC::GE : ARMCC::GT;
5050 }
5051
5052 // 'ordered' is 'anything but unordered', so use the VS condition code and
5053 // swap the VSEL operands.
5054 if (CC == ISD::SETO) {
5055 CondCode = ARMCC::VS;
5056 swpVselOps = true;
5057 }
5058
5059 // 'unordered or not equal' is 'anything but equal', so use the EQ condition
5060 // code and swap the VSEL operands. Also do this if we don't care about the
5061 // unordered case.
5062 if (CC == ISD::SETUNE || CC == ISD::SETNE) {
5063 CondCode = ARMCC::EQ;
5064 swpVselOps = true;
5065 }
5066}
5067
5068SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
5069 SDValue TrueVal, SDValue ARMcc,
5070 SDValue Flags, SelectionDAG &DAG) const {
5071 if (!Subtarget->hasFP64() && VT == MVT::f64) {
5072 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5073 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
5074 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5075 DAG.getVTList(MVT::i32, MVT::i32), TrueVal);
5076
5077 SDValue TrueLow = TrueVal.getValue(0);
5078 SDValue TrueHigh = TrueVal.getValue(1);
5079 SDValue FalseLow = FalseVal.getValue(0);
5080 SDValue FalseHigh = FalseVal.getValue(1);
5081
5082 SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
5083 ARMcc, Flags);
5084 SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
5085 ARMcc, Flags);
5086
5087 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
5088 }
5089 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
5090}
5091
5092static bool isGTorGE(ISD::CondCode CC) {
5093 return CC == ISD::SETGT || CC == ISD::SETGE;
5094}
5095
5096static bool isLTorLE(ISD::CondCode CC) {
5097 return CC == ISD::SETLT || CC == ISD::SETLE;
5098}
5099
5100// See if a conditional (LHS CC RHS ? TrueVal : FalseVal) is lower-saturating.
5101// All of these conditions (and their <= and >= counterparts) will do:
5102// x < k ? k : x
5103// x > k ? x : k
5104// k < x ? x : k
5105// k > x ? k : x
5106static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
5107 const SDValue TrueVal, const SDValue FalseVal,
5108 const ISD::CondCode CC, const SDValue K) {
5109 return (isGTorGE(CC) &&
5110 ((K == LHS && K == TrueVal) || (K == RHS && K == FalseVal))) ||
5111 (isLTorLE(CC) &&
5112 ((K == RHS && K == TrueVal) || (K == LHS && K == FalseVal)));
5113}
5114
5115// Check if two chained conditionals could be converted into SSAT or USAT.
5116//
5117// SSAT can replace a set of two conditional selectors that bound a number to an
5118// interval of type [k, ~k] when k + 1 is a power of 2. Here are some examples:
5119//
5120// x < -k ? -k : (x > k ? k : x)
5121// x < -k ? -k : (x < k ? x : k)
5122// x > -k ? (x > k ? k : x) : -k
5123// x < k ? (x < -k ? -k : x) : k
5124// etc.
5125//
5126// LLVM canonicalizes these to either a min(max()) or a max(min())
5127// pattern. This function tries to match one of these and will return a SSAT
5128// node if successful.
5129//
5130// USAT works similarly to SSAT but bounds on the interval [0, k] where k + 1
5131// is a power of 2.
5133 EVT VT = Op.getValueType();
5134 SDValue V1 = Op.getOperand(0);
5135 SDValue K1 = Op.getOperand(1);
5136 SDValue TrueVal1 = Op.getOperand(2);
5137 SDValue FalseVal1 = Op.getOperand(3);
5138 ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5139
5140 const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
5141 if (Op2.getOpcode() != ISD::SELECT_CC)
5142 return SDValue();
5143
5144 SDValue V2 = Op2.getOperand(0);
5145 SDValue K2 = Op2.getOperand(1);
5146 SDValue TrueVal2 = Op2.getOperand(2);
5147 SDValue FalseVal2 = Op2.getOperand(3);
5148 ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
5149
5150 SDValue V1Tmp = V1;
5151 SDValue V2Tmp = V2;
5152
5153 // Check that the registers and the constants match a max(min()) or min(max())
5154 // pattern
5155 if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
5156 K2 != FalseVal2 ||
5157 !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
5158 return SDValue();
5159
5160 // Check that the constant in the lower-bound check is
5161 // the opposite of the constant in the upper-bound check
5162 // in 1's complement.
5164 return SDValue();
5165
5166 int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
5167 int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
5168 int64_t PosVal = std::max(Val1, Val2);
5169 int64_t NegVal = std::min(Val1, Val2);
5170
5171 if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
5172 !isPowerOf2_64(PosVal + 1))
5173 return SDValue();
5174
5175 // Handle the difference between USAT (unsigned) and SSAT (signed)
5176 // saturation
5177 // At this point, PosVal is guaranteed to be positive
5178 uint64_t K = PosVal;
5179 SDLoc dl(Op);
5180 if (Val1 == ~Val2)
5181 return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
5182 DAG.getConstant(llvm::countr_one(K), dl, VT));
5183 if (NegVal == 0)
5184 return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
5185 DAG.getConstant(llvm::countr_one(K), dl, VT));
5186
5187 return SDValue();
5188}
5189
5190// Check if a condition of the type x < k ? k : x can be converted into a
5191// bit operation instead of conditional moves.
5192// Currently this is allowed given:
5193// - The conditions and values match up
5194// - k is 0 or -1 (all ones)
5195// This function will not check the last condition, thats up to the caller
5196// It returns true if the transformation can be made, and in such case
5197// returns x in V, and k in SatK.
5199 SDValue &SatK)
5200{
5201 SDValue LHS = Op.getOperand(0);
5202 SDValue RHS = Op.getOperand(1);
5203 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5204 SDValue TrueVal = Op.getOperand(2);
5205 SDValue FalseVal = Op.getOperand(3);
5206
5208 ? &RHS
5209 : nullptr;
5210
5211 // No constant operation in comparison, early out
5212 if (!K)
5213 return false;
5214
5215 SDValue KTmp = isa<ConstantSDNode>(TrueVal) ? TrueVal : FalseVal;
5216 V = (KTmp == TrueVal) ? FalseVal : TrueVal;
5217 SDValue VTmp = (K && *K == LHS) ? RHS : LHS;
5218
5219 // If the constant on left and right side, or variable on left and right,
5220 // does not match, early out
5221 if (*K != KTmp || V != VTmp)
5222 return false;
5223
5224 if (isLowerSaturate(LHS, RHS, TrueVal, FalseVal, CC, *K)) {
5225 SatK = *K;
5226 return true;
5227 }
5228
5229 return false;
5230}
5231
5232bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
5233 if (VT == MVT::f32)
5234 return !Subtarget->hasVFP2Base();
5235 if (VT == MVT::f64)
5236 return !Subtarget->hasFP64();
5237 if (VT == MVT::f16)
5238 return !Subtarget->hasFullFP16();
5239 return false;
5240}
5241
5242static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
5243 SDValue FalseVal, const ARMSubtarget *Subtarget) {
5244 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5245 ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
5246 if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
5247 return SDValue();
5248
5249 unsigned TVal = CTVal->getZExtValue();
5250 unsigned FVal = CFVal->getZExtValue();
5251
5252 Opcode = 0;
5253 InvertCond = false;
5254 if (TVal == ~FVal) {
5255 Opcode = ARMISD::CSINV;
5256 } else if (TVal == ~FVal + 1) {
5257 Opcode = ARMISD::CSNEG;
5258 } else if (TVal + 1 == FVal) {
5259 Opcode = ARMISD::CSINC;
5260 } else if (TVal == FVal + 1) {
5261 Opcode = ARMISD::CSINC;
5262 std::swap(TrueVal, FalseVal);
5263 std::swap(TVal, FVal);
5264 InvertCond = !InvertCond;
5265 } else {
5266 return SDValue();
5267 }
5268
5269 // If one of the constants is cheaper than another, materialise the
5270 // cheaper one and let the csel generate the other.
5271 if (Opcode != ARMISD::CSINC &&
5272 HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
5273 std::swap(TrueVal, FalseVal);
5274 std::swap(TVal, FVal);
5275 InvertCond = !InvertCond;
5276 }
5277
5278 // Attempt to use ZR checking TVal is 0, possibly inverting the condition
5279 // to get there. CSINC not is invertable like the other two (~(~a) == a,
5280 // -(-a) == a, but (a+1)+1 != a).
5281 if (FVal == 0 && Opcode != ARMISD::CSINC) {
5282 std::swap(TrueVal, FalseVal);
5283 std::swap(TVal, FVal);
5284 InvertCond = !InvertCond;
5285 }
5286
5287 return TrueVal;
5288}
5289
5290SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
5291 EVT VT = Op.getValueType();
5292 SDLoc dl(Op);
5293
5294 // Try to convert two saturating conditional selects into a single SSAT
5295 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
5296 if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
5297 return SatValue;
5298
5299 // Try to convert expressions of the form x < k ? k : x (and similar forms)
5300 // into more efficient bit operations, which is possible when k is 0 or -1
5301 // On ARM and Thumb-2 which have flexible operand 2 this will result in
5302 // single instructions. On Thumb the shift and the bit operation will be two
5303 // instructions.
5304 // Only allow this transformation on full-width (32-bit) operations
5305 SDValue LowerSatConstant;
5306 SDValue SatValue;
5307 if (VT == MVT::i32 &&
5308 isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
5309 SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
5310 DAG.getConstant(31, dl, VT));
5311 if (isNullConstant(LowerSatConstant)) {
5312 SDValue NotShiftV = DAG.getNode(ISD::XOR, dl, VT, ShiftV,
5313 DAG.getAllOnesConstant(dl, VT));
5314 return DAG.getNode(ISD::AND, dl, VT, SatValue, NotShiftV);
5315 } else if (isAllOnesConstant(LowerSatConstant))
5316 return DAG.getNode(ISD::OR, dl, VT, SatValue, ShiftV);
5317 }
5318
5319 SDValue LHS = Op.getOperand(0);
5320 SDValue RHS = Op.getOperand(1);
5321 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5322 SDValue TrueVal = Op.getOperand(2);
5323 SDValue FalseVal = Op.getOperand(3);
5324 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5325 ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
5326 if (Op.getValueType().isInteger()) {
5327
5328 // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
5329 // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
5330 // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
5331 // Both require less instructions than compare and conditional select.
5332 if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
5333 RHSC->isZero() && CFVal && CFVal->isZero() &&
5334 LHS.getValueType() == RHS.getValueType()) {
5335 EVT VT = LHS.getValueType();
5336 SDValue Shift =
5337 DAG.getNode(ISD::SRA, dl, VT, LHS,
5338 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5339
5340 if (CC == ISD::SETGT)
5341 Shift = DAG.getNOT(dl, Shift, VT);
5342
5343 return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
5344 }
5345
5346 // (SELECT_CC setlt, x, 0, 1, 0) -> SRL(x, bw-1)
5347 if (CC == ISD::SETLT && isNullConstant(RHS) && isOneConstant(TrueVal) &&
5348 isNullConstant(FalseVal) && LHS.getValueType() == VT)
5349 return DAG.getNode(ISD::SRL, dl, VT, LHS,
5350 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5351 }
5352
5353 if (LHS.getValueType() == MVT::i32) {
5354 unsigned Opcode;
5355 bool InvertCond;
5356 if (SDValue Op =
5357 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
5358 if (InvertCond)
5359 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5360
5361 SDValue ARMcc;
5362 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5363 EVT VT = Op.getValueType();
5364 return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
5365 }
5366 }
5367
5368 if (isUnsupportedFloatingType(LHS.getValueType())) {
5369 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5370
5371 // If softenSetCCOperands only returned one value, we should compare it to
5372 // zero.
5373 if (!RHS.getNode()) {
5374 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5375 CC = ISD::SETNE;
5376 }
5377 }
5378
5379 if (LHS.getValueType() == MVT::i32) {
5380 // Try to generate VSEL on ARMv8.
5381 // The VSEL instruction can't use all the usual ARM condition
5382 // codes: it only has two bits to select the condition code, so it's
5383 // constrained to use only GE, GT, VS and EQ.
5384 //
5385 // To implement all the various ISD::SETXXX opcodes, we sometimes need to
5386 // swap the operands of the previous compare instruction (effectively
5387 // inverting the compare condition, swapping 'less' and 'greater') and
5388 // sometimes need to swap the operands to the VSEL (which inverts the
5389 // condition in the sense of firing whenever the previous condition didn't)
5390 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
5391 TrueVal.getValueType() == MVT::f32 ||
5392 TrueVal.getValueType() == MVT::f64)) {
5394 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
5395 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
5396 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5397 std::swap(TrueVal, FalseVal);
5398 }
5399 }
5400
5401 SDValue ARMcc;
5402 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5403 // Choose GE over PL, which vsel does now support
5404 if (ARMcc->getAsZExtVal() == ARMCC::PL)
5405 ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
5406 return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5407 }
5408
5409 ARMCC::CondCodes CondCode, CondCode2;
5410 FPCCToARMCC(CC, CondCode, CondCode2);
5411
5412 // Normalize the fp compare. If RHS is zero we prefer to keep it there so we
5413 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
5414 // must use VSEL (limited condition codes), due to not having conditional f16
5415 // moves.
5416 if (Subtarget->hasFPARMv8Base() &&
5417 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
5418 (TrueVal.getValueType() == MVT::f16 ||
5419 TrueVal.getValueType() == MVT::f32 ||
5420 TrueVal.getValueType() == MVT::f64)) {
5421 bool swpCmpOps = false;
5422 bool swpVselOps = false;
5423 checkVSELConstraints(CC, CondCode, swpCmpOps, swpVselOps);
5424
5425 if (CondCode == ARMCC::GT || CondCode == ARMCC::GE ||
5426 CondCode == ARMCC::VS || CondCode == ARMCC::EQ) {
5427 if (swpCmpOps)
5428 std::swap(LHS, RHS);
5429 if (swpVselOps)
5430 std::swap(TrueVal, FalseVal);
5431 }
5432 }
5433
5434 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5435 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5436 SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5437 if (CondCode2 != ARMCC::AL) {
5438 SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
5439 Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
5440 }
5441 return Result;
5442}
5443
5444/// canChangeToInt - Given the fp compare operand, return true if it is suitable
5445/// to morph to an integer compare sequence.
5446static bool canChangeToInt(SDValue Op, bool &SeenZero,
5447 const ARMSubtarget *Subtarget) {
5448 SDNode *N = Op.getNode();
5449 if (!N->hasOneUse())
5450 // Otherwise it requires moving the value from fp to integer registers.
5451 return false;
5452 if (!N->getNumValues())
5453 return false;
5454 EVT VT = Op.getValueType();
5455 if (VT != MVT::f32 && !Subtarget->isFPBrccSlow())
5456 // f32 case is generally profitable. f64 case only makes sense when vcmpe +
5457 // vmrs are very slow, e.g. cortex-a8.
5458 return false;
5459
5460 if (isFloatingPointZero(Op)) {
5461 SeenZero = true;
5462 return true;
5463 }
5464 return ISD::isNormalLoad(N);
5465}
5466
5469 return DAG.getConstant(0, SDLoc(Op), MVT::i32);
5470
5472 return DAG.getLoad(MVT::i32, SDLoc(Op), Ld->getChain(), Ld->getBasePtr(),
5473 Ld->getPointerInfo(), Ld->getAlign(),
5474 Ld->getMemOperand()->getFlags());
5475
5476 llvm_unreachable("Unknown VFP cmp argument!");
5477}
5478
5480 SDValue &RetVal1, SDValue &RetVal2) {
5481 SDLoc dl(Op);
5482
5483 if (isFloatingPointZero(Op)) {
5484 RetVal1 = DAG.getConstant(0, dl, MVT::i32);
5485 RetVal2 = DAG.getConstant(0, dl, MVT::i32);
5486 return;
5487 }
5488
5489 if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Op)) {
5490 SDValue Ptr = Ld->getBasePtr();
5491 RetVal1 =
5492 DAG.getLoad(MVT::i32, dl, Ld->getChain(), Ptr, Ld->getPointerInfo(),
5493 Ld->getAlign(), Ld->getMemOperand()->getFlags());
5494
5495 EVT PtrType = Ptr.getValueType();
5496 SDValue NewPtr = DAG.getNode(ISD::ADD, dl,
5497 PtrType, Ptr, DAG.getConstant(4, dl, PtrType));
5498 RetVal2 = DAG.getLoad(MVT::i32, dl, Ld->getChain(), NewPtr,
5499 Ld->getPointerInfo().getWithOffset(4),
5500 commonAlignment(Ld->getAlign(), 4),
5501 Ld->getMemOperand()->getFlags());
5502 return;
5503 }
5504
5505 llvm_unreachable("Unknown VFP cmp argument!");
5506}
5507
5508/// OptimizeVFPBrcond - With nnan and without daz, it's legal to optimize some
5509/// f32 and even f64 comparisons to integer ones.
5510SDValue
5511ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
5512 SDValue Chain = Op.getOperand(0);
5513 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5514 SDValue LHS = Op.getOperand(2);
5515 SDValue RHS = Op.getOperand(3);
5516 SDValue Dest = Op.getOperand(4);
5517 SDLoc dl(Op);
5518
5519 bool LHSSeenZero = false;
5520 bool LHSOk = canChangeToInt(LHS, LHSSeenZero, Subtarget);
5521 bool RHSSeenZero = false;
5522 bool RHSOk = canChangeToInt(RHS, RHSSeenZero, Subtarget);
5523 if (LHSOk && RHSOk && (LHSSeenZero || RHSSeenZero)) {
5524 // If unsafe fp math optimization is enabled and there are no other uses of
5525 // the CMP operands, and the condition code is EQ or NE, we can optimize it
5526 // to an integer comparison.
5527 if (CC == ISD::SETOEQ)
5528 CC = ISD::SETEQ;
5529 else if (CC == ISD::SETUNE)
5530 CC = ISD::SETNE;
5531
5532 SDValue Mask = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5533 SDValue ARMcc;
5534 if (LHS.getValueType() == MVT::f32) {
5535 LHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5536 bitcastf32Toi32(LHS, DAG), Mask);
5537 RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5538 bitcastf32Toi32(RHS, DAG), Mask);
5539 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5540 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5541 Cmp);
5542 }
5543
5544 SDValue LHS1, LHS2;
5545 SDValue RHS1, RHS2;
5546 expandf64Toi32(LHS, DAG, LHS1, LHS2);
5547 expandf64Toi32(RHS, DAG, RHS1, RHS2);
5548 LHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, LHS2, Mask);
5549 RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
5551 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5552 SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
5553 return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
5554 }
5555
5556 return SDValue();
5557}
5558
5559// Generate CMP + CMOV for integer abs.
5560SDValue ARMTargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
5561 SDLoc DL(Op);
5562
5563 SDValue Neg = DAG.getNegative(Op.getOperand(0), DL, MVT::i32);
5564
5565 // Generate CMP & CMOV.
5566 SDValue Cmp = DAG.getNode(ARMISD::CMP, DL, FlagsVT, Op.getOperand(0),
5567 DAG.getConstant(0, DL, MVT::i32));
5568 return DAG.getNode(ARMISD::CMOV, DL, MVT::i32, Op.getOperand(0), Neg,
5569 DAG.getConstant(ARMCC::MI, DL, MVT::i32), Cmp);
5570}
5571
5573 ARMCC::CondCodes CondCode =
5574 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();
5575 CondCode = ARMCC::getOppositeCondition(CondCode);
5576 return DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5577}
5578
5579SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5580 SDValue Chain = Op.getOperand(0);
5581 SDValue Cond = Op.getOperand(1);
5582 SDValue Dest = Op.getOperand(2);
5583 SDLoc dl(Op);
5584
5585 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5586 // instruction.
5587 unsigned Opc = Cond.getOpcode();
5588 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5589 !Subtarget->isThumb1Only();
5590 if (Cond.getResNo() == 1 &&
5591 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5592 Opc == ISD::USUBO || OptimizeMul)) {
5593 // Only lower legal XALUO ops.
5594 if (!isTypeLegal(Cond->getValueType(0)))
5595 return SDValue();
5596
5597 // The actual operation with overflow check.
5598 SDValue Value, OverflowCmp;
5599 SDValue ARMcc;
5600 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5601
5602 // Reverse the condition code.
5603 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5604
5605 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5606 OverflowCmp);
5607 }
5608
5609 return SDValue();
5610}
5611
5612SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5613 SDValue Chain = Op.getOperand(0);
5614 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5615 SDValue LHS = Op.getOperand(2);
5616 SDValue RHS = Op.getOperand(3);
5617 SDValue Dest = Op.getOperand(4);
5618 SDLoc dl(Op);
5619
5620 if (isUnsupportedFloatingType(LHS.getValueType())) {
5621 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5622
5623 // If softenSetCCOperands only returned one value, we should compare it to
5624 // zero.
5625 if (!RHS.getNode()) {
5626 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5627 CC = ISD::SETNE;
5628 }
5629 }
5630
5631 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5632 // instruction.
5633 unsigned Opc = LHS.getOpcode();
5634 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5635 !Subtarget->isThumb1Only();
5636 if (LHS.getResNo() == 1 && (isOneConstant(RHS) || isNullConstant(RHS)) &&
5637 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5638 Opc == ISD::USUBO || OptimizeMul) &&
5639 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5640 // Only lower legal XALUO ops.
5641 if (!isTypeLegal(LHS->getValueType(0)))
5642 return SDValue();
5643
5644 // The actual operation with overflow check.
5645 SDValue Value, OverflowCmp;
5646 SDValue ARMcc;
5647 std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5648
5649 if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5650 // Reverse the condition code.
5651 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5652 }
5653
5654 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5655 OverflowCmp);
5656 }
5657
5658 if (LHS.getValueType() == MVT::i32) {
5659 SDValue ARMcc;
5660 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5661 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
5662 }
5663
5664 SDNodeFlags Flags = Op->getFlags();
5665 if (Flags.hasNoNaNs() &&
5666 DAG.getDenormalMode(MVT::f32) == DenormalMode::getIEEE() &&
5667 DAG.getDenormalMode(MVT::f64) == DenormalMode::getIEEE() &&
5668 (CC == ISD::SETEQ || CC == ISD::SETOEQ || CC == ISD::SETNE ||
5669 CC == ISD::SETUNE)) {
5670 if (SDValue Result = OptimizeVFPBrcond(Op, DAG))
5671 return Result;
5672 }
5673
5674 ARMCC::CondCodes CondCode, CondCode2;
5675 FPCCToARMCC(CC, CondCode, CondCode2);
5676
5677 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5678 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5679 SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
5680 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5681 if (CondCode2 != ARMCC::AL) {
5682 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
5683 SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
5684 Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5685 }
5686 return Res;
5687}
5688
5689SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
5690 SDValue Chain = Op.getOperand(0);
5691 SDValue Table = Op.getOperand(1);
5692 SDValue Index = Op.getOperand(2);
5693 SDLoc dl(Op);
5694
5695 EVT PTy = getPointerTy(DAG.getDataLayout());
5696 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
5697 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
5698 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
5699 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
5700 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
5701 if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
5702 // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
5703 // which does another jump to the destination. This also makes it easier
5704 // to translate it to TBB / TBH later (Thumb2 only).
5705 // FIXME: This might not work if the function is extremely large.
5706 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,
5707 Addr, Op.getOperand(2), JTI);
5708 }
5709 if (isPositionIndependent() || Subtarget->isROPI()) {
5710 Addr =
5711 DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
5713 Chain = Addr.getValue(1);
5714 Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
5715 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5716 } else {
5717 Addr =
5718 DAG.getLoad(PTy, dl, Chain, Addr,
5720 Chain = Addr.getValue(1);
5721 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5722 }
5723}
5724
5726 EVT VT = Op.getValueType();
5727 SDLoc dl(Op);
5728
5729 if (Op.getValueType().getVectorElementType() == MVT::i32) {
5730 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::f32)
5731 return Op;
5732 return DAG.UnrollVectorOp(Op.getNode());
5733 }
5734
5735 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5736
5737 EVT NewTy;
5738 const EVT OpTy = Op.getOperand(0).getValueType();
5739 if (OpTy == MVT::v4f32)
5740 NewTy = MVT::v4i32;
5741 else if (OpTy == MVT::v4f16 && HasFullFP16)
5742 NewTy = MVT::v4i16;
5743 else if (OpTy == MVT::v8f16 && HasFullFP16)
5744 NewTy = MVT::v8i16;
5745 else
5746 llvm_unreachable("Invalid type for custom lowering!");
5747
5748 if (VT != MVT::v4i16 && VT != MVT::v8i16)
5749 return DAG.UnrollVectorOp(Op.getNode());
5750
5751 Op = DAG.getNode(Op.getOpcode(), dl, NewTy, Op.getOperand(0));
5752 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
5753}
5754
5755SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
5756 EVT VT = Op.getValueType();
5757 if (VT.isVector())
5758 return LowerVectorFP_TO_INT(Op, DAG);
5759
5760 bool IsStrict = Op->isStrictFPOpcode();
5761 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5762
5763 if (isUnsupportedFloatingType(SrcVal.getValueType())) {
5764 RTLIB::Libcall LC;
5765 if (Op.getOpcode() == ISD::FP_TO_SINT ||
5766 Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
5767 LC = RTLIB::getFPTOSINT(SrcVal.getValueType(),
5768 Op.getValueType());
5769 else
5770 LC = RTLIB::getFPTOUINT(SrcVal.getValueType(),
5771 Op.getValueType());
5772 SDLoc Loc(Op);
5773 MakeLibCallOptions CallOptions;
5774 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5775 SDValue Result;
5776 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5777 CallOptions, Loc, Chain);
5778 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5779 }
5780
5781 return Op;
5782}
5783
5785 const ARMSubtarget *Subtarget) {
5786 EVT VT = Op.getValueType();
5787 EVT ToVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
5788 EVT FromVT = Op.getOperand(0).getValueType();
5789
5790 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f32)
5791 return Op;
5792 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f64 &&
5793 Subtarget->hasFP64())
5794 return Op;
5795 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f16 &&
5796 Subtarget->hasFullFP16())
5797 return Op;
5798 if (VT == MVT::v4i32 && ToVT == MVT::i32 && FromVT == MVT::v4f32 &&
5799 Subtarget->hasMVEFloatOps())
5800 return Op;
5801 if (VT == MVT::v8i16 && ToVT == MVT::i16 && FromVT == MVT::v8f16 &&
5802 Subtarget->hasMVEFloatOps())
5803 return Op;
5804
5805 if (FromVT != MVT::v4f32 && FromVT != MVT::v8f16)
5806 return SDValue();
5807
5808 SDLoc DL(Op);
5809 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
5810 unsigned BW = ToVT.getScalarSizeInBits() - IsSigned;
5811 SDValue CVT = DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
5812 DAG.getValueType(VT.getScalarType()));
5813 SDValue Max = DAG.getNode(IsSigned ? ISD::SMIN : ISD::UMIN, DL, VT, CVT,
5814 DAG.getConstant((1 << BW) - 1, DL, VT));
5815 if (IsSigned)
5816 Max = DAG.getNode(ISD::SMAX, DL, VT, Max,
5817 DAG.getSignedConstant(-(1 << BW), DL, VT));
5818 return Max;
5819}
5820
5822 EVT VT = Op.getValueType();
5823 SDLoc dl(Op);
5824
5825 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::i32) {
5826 if (VT.getVectorElementType() == MVT::f32)
5827 return Op;
5828 return DAG.UnrollVectorOp(Op.getNode());
5829 }
5830
5831 assert((Op.getOperand(0).getValueType() == MVT::v4i16 ||
5832 Op.getOperand(0).getValueType() == MVT::v8i16) &&
5833 "Invalid type for custom lowering!");
5834
5835 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5836
5837 EVT DestVecType;
5838 if (VT == MVT::v4f32)
5839 DestVecType = MVT::v4i32;
5840 else if (VT == MVT::v4f16 && HasFullFP16)
5841 DestVecType = MVT::v4i16;
5842 else if (VT == MVT::v8f16 && HasFullFP16)
5843 DestVecType = MVT::v8i16;
5844 else
5845 return DAG.UnrollVectorOp(Op.getNode());
5846
5847 unsigned CastOpc;
5848 unsigned Opc;
5849 switch (Op.getOpcode()) {
5850 default: llvm_unreachable("Invalid opcode!");
5851 case ISD::SINT_TO_FP:
5852 CastOpc = ISD::SIGN_EXTEND;
5854 break;
5855 case ISD::UINT_TO_FP:
5856 CastOpc = ISD::ZERO_EXTEND;
5858 break;
5859 }
5860
5861 Op = DAG.getNode(CastOpc, dl, DestVecType, Op.getOperand(0));
5862 return DAG.getNode(Opc, dl, VT, Op);
5863}
5864
5865SDValue ARMTargetLowering::LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const {
5866 EVT VT = Op.getValueType();
5867 if (VT.isVector())
5868 return LowerVectorINT_TO_FP(Op, DAG);
5869
5870 bool IsStrict = Op->isStrictFPOpcode();
5871 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5872
5873 if (isUnsupportedFloatingType(VT)) {
5874 RTLIB::Libcall LC;
5875 if (Op.getOpcode() == ISD::SINT_TO_FP ||
5876 Op.getOpcode() == ISD::STRICT_SINT_TO_FP)
5877 LC = RTLIB::getSINTTOFP(SrcVal.getValueType(), Op.getValueType());
5878 else
5879 LC = RTLIB::getUINTTOFP(SrcVal.getValueType(), Op.getValueType());
5880 SDLoc Loc(Op);
5881 MakeLibCallOptions CallOptions;
5882 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5883 SDValue Result;
5884 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5885 CallOptions, Loc, Chain);
5886 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5887 }
5888
5889 return Op;
5890}
5891
5892SDValue ARMTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
5893 // Implement fcopysign with a fabs and a conditional fneg.
5894 SDValue Tmp0 = Op.getOperand(0);
5895 SDValue Tmp1 = Op.getOperand(1);
5896 SDLoc dl(Op);
5897 EVT VT = Op.getValueType();
5898 EVT SrcVT = Tmp1.getValueType();
5899 bool InGPR = Tmp0.getOpcode() == ISD::BITCAST ||
5900 Tmp0.getOpcode() == ARMISD::VMOVDRR;
5901 bool UseNEON = !InGPR && Subtarget->hasNEON();
5902
5903 if (UseNEON) {
5904 // Use VBSL to copy the sign bit.
5905 unsigned EncodedVal = ARM_AM::createVMOVModImm(0x6, 0x80);
5906 SDValue Mask = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v2i32,
5907 DAG.getTargetConstant(EncodedVal, dl, MVT::i32));
5908 EVT OpVT = (VT == MVT::f32) ? MVT::v2i32 : MVT::v1i64;
5909 if (VT == MVT::f64)
5910 Mask = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5911 DAG.getNode(ISD::BITCAST, dl, OpVT, Mask),
5912 DAG.getConstant(32, dl, MVT::i32));
5913 else /*if (VT == MVT::f32)*/
5914 Tmp0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp0);
5915 if (SrcVT == MVT::f32) {
5916 Tmp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp1);
5917 if (VT == MVT::f64)
5918 Tmp1 = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5919 DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1),
5920 DAG.getConstant(32, dl, MVT::i32));
5921 } else if (VT == MVT::f32)
5922 Tmp1 = DAG.getNode(ARMISD::VSHRuIMM, dl, MVT::v1i64,
5923 DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, Tmp1),
5924 DAG.getConstant(32, dl, MVT::i32));
5925 Tmp0 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp0);
5926 Tmp1 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1);
5927
5928 SDValue AllOnes = DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff),
5929 dl, MVT::i32);
5930 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v8i8, AllOnes);
5931 SDValue MaskNot = DAG.getNode(ISD::XOR, dl, OpVT, Mask,
5932 DAG.getNode(ISD::BITCAST, dl, OpVT, AllOnes));
5933
5934 SDValue Res = DAG.getNode(ISD::OR, dl, OpVT,
5935 DAG.getNode(ISD::AND, dl, OpVT, Tmp1, Mask),
5936 DAG.getNode(ISD::AND, dl, OpVT, Tmp0, MaskNot));
5937 if (VT == MVT::f32) {
5938 Res = DAG.getNode(ISD::BITCAST, dl, MVT::v2f32, Res);
5939 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
5940 DAG.getConstant(0, dl, MVT::i32));
5941 } else {
5942 Res = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Res);
5943 }
5944
5945 return Res;
5946 }
5947
5948 // Bitcast operand 1 to i32.
5949 if (SrcVT == MVT::f64)
5950 Tmp1 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5951 Tmp1).getValue(1);
5952 Tmp1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp1);
5953
5954 // Or in the signbit with integer operations.
5955 SDValue Mask1 = DAG.getConstant(0x80000000, dl, MVT::i32);
5956 SDValue Mask2 = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5957 Tmp1 = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp1, Mask1);
5958 if (VT == MVT::f32) {
5959 Tmp0 = DAG.getNode(ISD::AND, dl, MVT::i32,
5960 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp0), Mask2);
5961 return DAG.getNode(ISD::BITCAST, dl, MVT::f32,
5962 DAG.getNode(ISD::OR, dl, MVT::i32, Tmp0, Tmp1));
5963 }
5964
5965 // f64: Or the high part with signbit and then combine two parts.
5966 Tmp0 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5967 Tmp0);
5968 SDValue Lo = Tmp0.getValue(0);
5969 SDValue Hi = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp0.getValue(1), Mask2);
5970 Hi = DAG.getNode(ISD::OR, dl, MVT::i32, Hi, Tmp1);
5971 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
5972}
5973
5974SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
5976 MachineFrameInfo &MFI = MF.getFrameInfo();
5977 MFI.setReturnAddressIsTaken(true);
5978
5979 EVT VT = Op.getValueType();
5980 SDLoc dl(Op);
5981 unsigned Depth = Op.getConstantOperandVal(0);
5982 if (Depth) {
5983 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
5984 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
5985 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
5986 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
5987 MachinePointerInfo());
5988 }
5989
5990 // Return LR, which contains the return address. Mark it an implicit live-in.
5991 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
5992 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
5993}
5994
5995SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
5996 const ARMBaseRegisterInfo &ARI =
5997 *static_cast<const ARMBaseRegisterInfo*>(RegInfo);
5999 MachineFrameInfo &MFI = MF.getFrameInfo();
6000 MFI.setFrameAddressIsTaken(true);
6001
6002 EVT VT = Op.getValueType();
6003 SDLoc dl(Op); // FIXME probably not meaningful
6004 unsigned Depth = Op.getConstantOperandVal(0);
6005 Register FrameReg = ARI.getFrameRegister(MF);
6006 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
6007 while (Depth--)
6008 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
6009 MachinePointerInfo());
6010 return FrameAddr;
6011}
6012
6013// FIXME? Maybe this could be a TableGen attribute on some registers and
6014// this table could be generated automatically from RegInfo.
6015Register ARMTargetLowering::getRegisterByName(const char* RegName, LLT VT,
6016 const MachineFunction &MF) const {
6017 return StringSwitch<Register>(RegName)
6018 .Case("sp", ARM::SP)
6019 .Default(Register());
6020}
6021
6022// Result is 64 bit value so split into two 32 bit values and return as a
6023// pair of values.
6025 SelectionDAG &DAG) {
6026 SDLoc DL(N);
6027
6028 // This function is only supposed to be called for i64 type destination.
6029 assert(N->getValueType(0) == MVT::i64
6030 && "ExpandREAD_REGISTER called for non-i64 type result.");
6031
6033 DAG.getVTList(MVT::i32, MVT::i32, MVT::Other),
6034 N->getOperand(0),
6035 N->getOperand(1));
6036
6037 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0),
6038 Read.getValue(1)));
6039 Results.push_back(Read.getValue(2)); // Chain
6040}
6041
6042/// \p BC is a bitcast that is about to be turned into a VMOVDRR.
6043/// When \p DstVT, the destination type of \p BC, is on the vector
6044/// register bank and the source of bitcast, \p Op, operates on the same bank,
6045/// it might be possible to combine them, such that everything stays on the
6046/// vector register bank.
6047/// \p return The node that would replace \p BT, if the combine
6048/// is possible.
6050 SelectionDAG &DAG) {
6051 SDValue Op = BC->getOperand(0);
6052 EVT DstVT = BC->getValueType(0);
6053
6054 // The only vector instruction that can produce a scalar (remember,
6055 // since the bitcast was about to be turned into VMOVDRR, the source
6056 // type is i64) from a vector is EXTRACT_VECTOR_ELT.
6057 // Moreover, we can do this combine only if there is one use.
6058 // Finally, if the destination type is not a vector, there is not
6059 // much point on forcing everything on the vector bank.
6060 if (!DstVT.isVector() || Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
6061 !Op.hasOneUse())
6062 return SDValue();
6063
6064 // If the index is not constant, we will introduce an additional
6065 // multiply that will stick.
6066 // Give up in that case.
6067 ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Op.getOperand(1));
6068 if (!Index)
6069 return SDValue();
6070 unsigned DstNumElt = DstVT.getVectorNumElements();
6071
6072 // Compute the new index.
6073 const APInt &APIntIndex = Index->getAPIntValue();
6074 APInt NewIndex(APIntIndex.getBitWidth(), DstNumElt);
6075 NewIndex *= APIntIndex;
6076 // Check if the new constant index fits into i32.
6077 if (NewIndex.getBitWidth() > 32)
6078 return SDValue();
6079
6080 // vMTy bitcast(i64 extractelt vNi64 src, i32 index) ->
6081 // vMTy extractsubvector vNxMTy (bitcast vNi64 src), i32 index*M)
6082 SDLoc dl(Op);
6083 SDValue ExtractSrc = Op.getOperand(0);
6084 EVT VecVT = EVT::getVectorVT(
6085 *DAG.getContext(), DstVT.getScalarType(),
6086 ExtractSrc.getValueType().getVectorNumElements() * DstNumElt);
6087 SDValue BitCast = DAG.getNode(ISD::BITCAST, dl, VecVT, ExtractSrc);
6088 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, BitCast,
6089 DAG.getConstant(NewIndex.getZExtValue(), dl, MVT::i32));
6090}
6091
6092/// ExpandBITCAST - If the target supports VFP, this function is called to
6093/// expand a bit convert where either the source or destination type is i64 to
6094/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
6095/// operand type is illegal (e.g., v2f32 for a target that doesn't support
6096/// vectors), since the legalizer won't know what to do with that.
6097SDValue ARMTargetLowering::ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
6098 const ARMSubtarget *Subtarget) const {
6099 SDLoc dl(N);
6100 SDValue Op = N->getOperand(0);
6101
6102 // This function is only supposed to be called for i16 and i64 types, either
6103 // as the source or destination of the bit convert.
6104 EVT SrcVT = Op.getValueType();
6105 EVT DstVT = N->getValueType(0);
6106
6107 if ((SrcVT == MVT::i16 || SrcVT == MVT::i32) &&
6108 (DstVT == MVT::f16 || DstVT == MVT::bf16))
6109 return MoveToHPR(SDLoc(N), DAG, MVT::i32, DstVT.getSimpleVT(),
6110 DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i32, Op));
6111
6112 if ((DstVT == MVT::i16 || DstVT == MVT::i32) &&
6113 (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
6114 if (Subtarget->hasFullFP16() && !Subtarget->hasBF16())
6115 Op = DAG.getBitcast(MVT::f16, Op);
6116 return DAG.getNode(
6117 ISD::TRUNCATE, SDLoc(N), DstVT,
6118 MoveFromHPR(SDLoc(N), DAG, MVT::i32, SrcVT.getSimpleVT(), Op));
6119 }
6120
6121 if (!(SrcVT == MVT::i64 || DstVT == MVT::i64))
6122 return SDValue();
6123
6124 // Turn i64->f64 into VMOVDRR.
6125 if (SrcVT == MVT::i64 && isTypeLegal(DstVT)) {
6126 // Do not force values to GPRs (this is what VMOVDRR does for the inputs)
6127 // if we can combine the bitcast with its source.
6128 if (SDValue Val = CombineVMOVDRRCandidateWithVecOp(N, DAG))
6129 return Val;
6130 SDValue Lo, Hi;
6131 std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32);
6132 return DAG.getNode(ISD::BITCAST, dl, DstVT,
6133 DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi));
6134 }
6135
6136 // Turn f64->i64 into VMOVRRD.
6137 if (DstVT == MVT::i64 && isTypeLegal(SrcVT)) {
6138 SDValue Cvt;
6139 if (DAG.getDataLayout().isBigEndian() && SrcVT.isVector() &&
6140 SrcVT.getVectorNumElements() > 1)
6141 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6142 DAG.getVTList(MVT::i32, MVT::i32),
6143 DAG.getNode(ARMISD::VREV64, dl, SrcVT, Op));
6144 else
6145 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6146 DAG.getVTList(MVT::i32, MVT::i32), Op);
6147 // Merge the pieces into a single i64 value.
6148 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1));
6149 }
6150
6151 return SDValue();
6152}
6153
6154/// getZeroVector - Returns a vector of specified type with all zero elements.
6155/// Zero vectors are used to represent vector negation and in those cases
6156/// will be implemented with the NEON VNEG instruction. However, VNEG does
6157/// not support i64 elements, so sometimes the zero vectors will need to be
6158/// explicitly constructed. Regardless, use a canonical VMOV to create the
6159/// zero vector.
6160static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
6161 assert(VT.isVector() && "Expected a vector type");
6162 // The canonical modified immediate encoding of a zero vector is....0!
6163 SDValue EncodedVal = DAG.getTargetConstant(0, dl, MVT::i32);
6164 EVT VmovVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
6165 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, EncodedVal);
6166 return DAG.getNode(ISD::BITCAST, dl, VT, Vmov);
6167}
6168
6169/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
6170/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6171SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
6172 SelectionDAG &DAG) const {
6173 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6174 EVT VT = Op.getValueType();
6175 unsigned VTBits = VT.getSizeInBits();
6176 SDLoc dl(Op);
6177 SDValue ShOpLo = Op.getOperand(0);
6178 SDValue ShOpHi = Op.getOperand(1);
6179 SDValue ShAmt = Op.getOperand(2);
6180 SDValue ARMcc;
6181 unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
6182
6183 assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
6184
6185 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6186 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6187 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt);
6188 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6189 DAG.getConstant(VTBits, dl, MVT::i32));
6190 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt);
6191 SDValue LoSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6192 SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
6193 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6194 ISD::SETGE, ARMcc, DAG, dl);
6195 SDValue Lo =
6196 DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
6197
6198 SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
6199 SDValue HiBigShift = Opc == ISD::SRA
6200 ? DAG.getNode(Opc, dl, VT, ShOpHi,
6201 DAG.getConstant(VTBits - 1, dl, VT))
6202 : DAG.getConstant(0, dl, VT);
6203 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6204 ISD::SETGE, ARMcc, DAG, dl);
6205 SDValue Hi =
6206 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6207
6208 SDValue Ops[2] = { Lo, Hi };
6209 return DAG.getMergeValues(Ops, dl);
6210}
6211
6212/// LowerShiftLeftParts - Lower SHL_PARTS, which returns two
6213/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6214SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op,
6215 SelectionDAG &DAG) const {
6216 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6217 EVT VT = Op.getValueType();
6218 unsigned VTBits = VT.getSizeInBits();
6219 SDLoc dl(Op);
6220 SDValue ShOpLo = Op.getOperand(0);
6221 SDValue ShOpHi = Op.getOperand(1);
6222 SDValue ShAmt = Op.getOperand(2);
6223 SDValue ARMcc;
6224
6225 assert(Op.getOpcode() == ISD::SHL_PARTS);
6226 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6227 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6228 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
6229 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
6230 SDValue HiSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6231
6232 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6233 DAG.getConstant(VTBits, dl, MVT::i32));
6234 SDValue HiBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
6235 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6236 ISD::SETGE, ARMcc, DAG, dl);
6237 SDValue Hi =
6238 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6239
6240 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6241 ISD::SETGE, ARMcc, DAG, dl);
6242 SDValue LoSmallShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
6243 SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift,
6244 DAG.getConstant(0, dl, VT), ARMcc, CmpLo);
6245
6246 SDValue Ops[2] = { Lo, Hi };
6247 return DAG.getMergeValues(Ops, dl);
6248}
6249
6250SDValue ARMTargetLowering::LowerGET_ROUNDING(SDValue Op,
6251 SelectionDAG &DAG) const {
6252 // The rounding mode is in bits 23:22 of the FPSCR.
6253 // The ARM rounding mode value to FLT_ROUNDS mapping is 0->1, 1->2, 2->3, 3->0
6254 // The formula we use to implement this is (((FPSCR + 1 << 22) >> 22) & 3)
6255 // so that the shift + and get folded into a bitfield extract.
6256 SDLoc dl(Op);
6257 SDValue Chain = Op.getOperand(0);
6258 SDValue Ops[] = {Chain,
6259 DAG.getConstant(Intrinsic::arm_get_fpscr, dl, MVT::i32)};
6260
6261 SDValue FPSCR =
6262 DAG.getNode(ISD::INTRINSIC_W_CHAIN, dl, {MVT::i32, MVT::Other}, Ops);
6263 Chain = FPSCR.getValue(1);
6264 SDValue FltRounds = DAG.getNode(ISD::ADD, dl, MVT::i32, FPSCR,
6265 DAG.getConstant(1U << 22, dl, MVT::i32));
6266 SDValue RMODE = DAG.getNode(ISD::SRL, dl, MVT::i32, FltRounds,
6267 DAG.getConstant(22, dl, MVT::i32));
6268 SDValue And = DAG.getNode(ISD::AND, dl, MVT::i32, RMODE,
6269 DAG.getConstant(3, dl, MVT::i32));
6270 return DAG.getMergeValues({And, Chain}, dl);
6271}
6272
6273SDValue ARMTargetLowering::LowerSET_ROUNDING(SDValue Op,
6274 SelectionDAG &DAG) const {
6275 SDLoc DL(Op);
6276 SDValue Chain = Op->getOperand(0);
6277 SDValue RMValue = Op->getOperand(1);
6278
6279 // The rounding mode is in bits 23:22 of the FPSCR.
6280 // The llvm.set.rounding argument value to ARM rounding mode value mapping
6281 // is 0->3, 1->0, 2->1, 3->2. The formula we use to implement this is
6282 // ((arg - 1) & 3) << 22).
6283 //
6284 // It is expected that the argument of llvm.set.rounding is within the
6285 // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
6286 // responsibility of the code generated llvm.set.rounding to ensure this
6287 // condition.
6288
6289 // Calculate new value of FPSCR[23:22].
6290 RMValue = DAG.getNode(ISD::SUB, DL, MVT::i32, RMValue,
6291 DAG.getConstant(1, DL, MVT::i32));
6292 RMValue = DAG.getNode(ISD::AND, DL, MVT::i32, RMValue,
6293 DAG.getConstant(0x3, DL, MVT::i32));
6294 RMValue = DAG.getNode(ISD::SHL, DL, MVT::i32, RMValue,
6295 DAG.getConstant(ARM::RoundingBitsPos, DL, MVT::i32));
6296
6297 // Get current value of FPSCR.
6298 SDValue Ops[] = {Chain,
6299 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6300 SDValue FPSCR =
6301 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6302 Chain = FPSCR.getValue(1);
6303 FPSCR = FPSCR.getValue(0);
6304
6305 // Put new rounding mode into FPSCR[23:22].
6306 const unsigned RMMask = ~(ARM::Rounding::rmMask << ARM::RoundingBitsPos);
6307 FPSCR = DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6308 DAG.getConstant(RMMask, DL, MVT::i32));
6309 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCR, RMValue);
6310 SDValue Ops2[] = {
6311 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6312 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6313}
6314
6315SDValue ARMTargetLowering::LowerSET_FPMODE(SDValue Op,
6316 SelectionDAG &DAG) const {
6317 SDLoc DL(Op);
6318 SDValue Chain = Op->getOperand(0);
6319 SDValue Mode = Op->getOperand(1);
6320
6321 // Generate nodes to build:
6322 // FPSCR = (FPSCR & FPStatusBits) | (Mode & ~FPStatusBits)
6323 SDValue Ops[] = {Chain,
6324 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6325 SDValue FPSCR =
6326 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6327 Chain = FPSCR.getValue(1);
6328 FPSCR = FPSCR.getValue(0);
6329
6330 SDValue FPSCRMasked =
6331 DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6332 DAG.getConstant(ARM::FPStatusBits, DL, MVT::i32));
6333 SDValue InputMasked =
6334 DAG.getNode(ISD::AND, DL, MVT::i32, Mode,
6335 DAG.getConstant(~ARM::FPStatusBits, DL, MVT::i32));
6336 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCRMasked, InputMasked);
6337
6338 SDValue Ops2[] = {
6339 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6340 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6341}
6342
6343SDValue ARMTargetLowering::LowerRESET_FPMODE(SDValue Op,
6344 SelectionDAG &DAG) const {
6345 SDLoc DL(Op);
6346 SDValue Chain = Op->getOperand(0);
6347
6348 // To get the default FP mode all control bits are cleared:
6349 // FPSCR = FPSCR & (FPStatusBits | FPReservedBits)
6350 SDValue Ops[] = {Chain,
6351 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6352 SDValue FPSCR =
6353 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6354 Chain = FPSCR.getValue(1);
6355 FPSCR = FPSCR.getValue(0);
6356
6357 SDValue FPSCRMasked = DAG.getNode(
6358 ISD::AND, DL, MVT::i32, FPSCR,
6360 SDValue Ops2[] = {Chain,
6361 DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32),
6362 FPSCRMasked};
6363 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6364}
6365
6367 const ARMSubtarget *ST) {
6368 SDLoc dl(N);
6369 EVT VT = N->getValueType(0);
6370 if (VT.isVector() && ST->hasNEON()) {
6371
6372 // Compute the least significant set bit: LSB = X & -X
6373 SDValue X = N->getOperand(0);
6374 SDValue NX = DAG.getNode(ISD::SUB, dl, VT, getZeroVector(VT, DAG, dl), X);
6375 SDValue LSB = DAG.getNode(ISD::AND, dl, VT, X, NX);
6376
6378
6379 if (ElemTy == MVT::i8) {
6380 // Compute with: cttz(x) = ctpop(lsb - 1)
6381 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6382 DAG.getTargetConstant(1, dl, ElemTy));
6383 SDValue Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6384 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6385 }
6386
6387 if ((ElemTy == MVT::i16 || ElemTy == MVT::i32) &&
6388 (N->getOpcode() == ISD::CTTZ_ZERO_POISON)) {
6389 // Compute with: cttz(x) = (width - 1) - ctlz(lsb), if x != 0
6390 unsigned NumBits = ElemTy.getSizeInBits();
6391 SDValue WidthMinus1 =
6392 DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6393 DAG.getTargetConstant(NumBits - 1, dl, ElemTy));
6394 SDValue CTLZ = DAG.getNode(ISD::CTLZ, dl, VT, LSB);
6395 return DAG.getNode(ISD::SUB, dl, VT, WidthMinus1, CTLZ);
6396 }
6397
6398 // Compute with: cttz(x) = ctpop(lsb - 1)
6399
6400 // Compute LSB - 1.
6401 SDValue Bits;
6402 if (ElemTy == MVT::i64) {
6403 // Load constant 0xffff'ffff'ffff'ffff to register.
6404 SDValue FF = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6405 DAG.getTargetConstant(0x1eff, dl, MVT::i32));
6406 Bits = DAG.getNode(ISD::ADD, dl, VT, LSB, FF);
6407 } else {
6408 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6409 DAG.getTargetConstant(1, dl, ElemTy));
6410 Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6411 }
6412 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6413 }
6414
6415 if (!ST->hasV6T2Ops())
6416 return SDValue();
6417
6418 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, VT, N->getOperand(0));
6419 return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
6420}
6421
6423 const ARMSubtarget *ST) {
6424 EVT VT = N->getValueType(0);
6425 SDLoc DL(N);
6426
6427 assert(ST->hasNEON() && "Custom ctpop lowering requires NEON.");
6428 assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
6429 VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
6430 "Unexpected type for custom ctpop lowering");
6431
6432 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6433 EVT VT8Bit = VT.is64BitVector() ? MVT::v8i8 : MVT::v16i8;
6434 SDValue Res = DAG.getBitcast(VT8Bit, N->getOperand(0));
6435 Res = DAG.getNode(ISD::CTPOP, DL, VT8Bit, Res);
6436
6437 // Widen v8i8/v16i8 CTPOP result to VT by repeatedly widening pairwise adds.
6438 unsigned EltSize = 8;
6439 unsigned NumElts = VT.is64BitVector() ? 8 : 16;
6440 while (EltSize != VT.getScalarSizeInBits()) {
6442 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddlu, DL,
6443 TLI.getPointerTy(DAG.getDataLayout())));
6444 Ops.push_back(Res);
6445
6446 EltSize *= 2;
6447 NumElts /= 2;
6448 MVT WidenVT = MVT::getVectorVT(MVT::getIntegerVT(EltSize), NumElts);
6449 Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, WidenVT, Ops);
6450 }
6451
6452 return Res;
6453}
6454
6455/// Getvshiftimm - Check if this is a valid build_vector for the immediate
6456/// operand of a vector shift operation, where all the elements of the
6457/// build_vector must have the same constant integer value.
6458static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) {
6459 // Ignore bit_converts.
6460 while (Op.getOpcode() == ISD::BITCAST)
6461 Op = Op.getOperand(0);
6463 APInt SplatBits, SplatUndef;
6464 unsigned SplatBitSize;
6465 bool HasAnyUndefs;
6466 if (!BVN ||
6467 !BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6468 ElementBits) ||
6469 SplatBitSize > ElementBits)
6470 return false;
6471 Cnt = SplatBits.getSExtValue();
6472 return true;
6473}
6474
6475/// isVShiftLImm - Check if this is a valid build_vector for the immediate
6476/// operand of a vector shift left operation. That value must be in the range:
6477/// 0 <= Value < ElementBits for a left shift; or
6478/// 0 <= Value <= ElementBits for a long left shift.
6479static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) {
6480 assert(VT.isVector() && "vector shift count is not a vector type");
6481 int64_t ElementBits = VT.getScalarSizeInBits();
6482 if (!getVShiftImm(Op, ElementBits, Cnt))
6483 return false;
6484 return (Cnt >= 0 && (isLong ? Cnt - 1 : Cnt) < ElementBits);
6485}
6486
6487/// isVShiftRImm - Check if this is a valid build_vector for the immediate
6488/// operand of a vector shift right operation. For a shift opcode, the value
6489/// is positive, but for an intrinsic the value count must be negative. The
6490/// absolute value must be in the range:
6491/// 1 <= |Value| <= ElementBits for a right shift; or
6492/// 1 <= |Value| <= ElementBits/2 for a narrow right shift.
6493static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic,
6494 int64_t &Cnt) {
6495 assert(VT.isVector() && "vector shift count is not a vector type");
6496 int64_t ElementBits = VT.getScalarSizeInBits();
6497 if (!getVShiftImm(Op, ElementBits, Cnt))
6498 return false;
6499 if (!isIntrinsic)
6500 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits / 2 : ElementBits));
6501 if (Cnt >= -(isNarrow ? ElementBits / 2 : ElementBits) && Cnt <= -1) {
6502 Cnt = -Cnt;
6503 return true;
6504 }
6505 return false;
6506}
6507
6509 const ARMSubtarget *ST) {
6510 EVT VT = N->getValueType(0);
6511 SDLoc dl(N);
6512 int64_t Cnt;
6513
6514 if (!VT.isVector())
6515 return SDValue();
6516
6517 // We essentially have two forms here. Shift by an immediate and shift by a
6518 // vector register (there are also shift by a gpr, but that is just handled
6519 // with a tablegen pattern). We cannot easily match shift by an immediate in
6520 // tablegen so we do that here and generate a VSHLIMM/VSHRsIMM/VSHRuIMM.
6521 // For shifting by a vector, we don't have VSHR, only VSHL (which can be
6522 // signed or unsigned, and a negative shift indicates a shift right).
6523 if (N->getOpcode() == ISD::SHL) {
6524 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt))
6525 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
6526 DAG.getConstant(Cnt, dl, MVT::i32));
6527 return DAG.getNode(ARMISD::VSHLu, dl, VT, N->getOperand(0),
6528 N->getOperand(1));
6529 }
6530
6531 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
6532 "unexpected vector shift opcode");
6533
6534 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
6535 unsigned VShiftOpc =
6536 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
6537 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
6538 DAG.getConstant(Cnt, dl, MVT::i32));
6539 }
6540
6541 // Other right shifts we don't have operations for (we use a shift left by a
6542 // negative number).
6543 EVT ShiftVT = N->getOperand(1).getValueType();
6544 SDValue NegatedCount = DAG.getNode(
6545 ISD::SUB, dl, ShiftVT, getZeroVector(ShiftVT, DAG, dl), N->getOperand(1));
6546 unsigned VShiftOpc =
6547 (N->getOpcode() == ISD::SRA ? ARMISD::VSHLs : ARMISD::VSHLu);
6548 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0), NegatedCount);
6549}
6550
6552 const ARMSubtarget *ST) {
6553 EVT VT = N->getValueType(0);
6554 SDLoc dl(N);
6555
6556 // We can get here for a node like i32 = ISD::SHL i32, i64
6557 if (VT != MVT::i64)
6558 return SDValue();
6559
6560 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA ||
6561 N->getOpcode() == ISD::SHL) &&
6562 "Unknown shift to lower!");
6563
6564 unsigned ShOpc = N->getOpcode();
6565 if (ST->hasMVEIntegerOps()) {
6566 SDValue ShAmt = N->getOperand(1);
6567 unsigned ShPartsOpc = ARMISD::LSLL;
6569
6570 // If the shift amount is greater than 32 or has a greater bitwidth than 64
6571 // then do the default optimisation
6572 if ((!Con && ShAmt->getValueType(0).getSizeInBits() > 64) ||
6573 (Con && (Con->getAPIntValue() == 0 || Con->getAPIntValue().uge(32))))
6574 return SDValue();
6575
6576 // Extract the lower 32 bits of the shift amount if it's not an i32
6577 if (ShAmt->getValueType(0) != MVT::i32)
6578 ShAmt = DAG.getZExtOrTrunc(ShAmt, dl, MVT::i32);
6579
6580 if (ShOpc == ISD::SRL) {
6581 if (!Con)
6582 // There is no t2LSRLr instruction so negate and perform an lsll if the
6583 // shift amount is in a register, emulating a right shift.
6584 ShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6585 DAG.getConstant(0, dl, MVT::i32), ShAmt);
6586 else
6587 // Else generate an lsrl on the immediate shift amount
6588 ShPartsOpc = ARMISD::LSRL;
6589 } else if (ShOpc == ISD::SRA)
6590 ShPartsOpc = ARMISD::ASRL;
6591
6592 // Split Lower/Upper 32 bits of the destination/source
6593 SDValue Lo, Hi;
6594 std::tie(Lo, Hi) =
6595 DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6596 // Generate the shift operation as computed above
6597 Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi,
6598 ShAmt);
6599 // The upper 32 bits come from the second return value of lsll
6600 Hi = SDValue(Lo.getNode(), 1);
6601 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6602 }
6603
6604 // We only lower SRA, SRL of 1 here, all others use generic lowering.
6605 if (!isOneConstant(N->getOperand(1)) || N->getOpcode() == ISD::SHL)
6606 return SDValue();
6607
6608 // If we are in thumb mode, we don't have RRX.
6609 if (ST->isThumb1Only())
6610 return SDValue();
6611
6612 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr.
6613 SDValue Lo, Hi;
6614 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6615
6616 // First, build a LSRS1/ASRS1 op, which shifts the top part by one and
6617 // captures the shifted out bit into a carry flag.
6618 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::LSRS1 : ARMISD::ASRS1;
6619 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, FlagsVT), Hi);
6620
6621 // The low part is an ARMISD::RRX operand, which shifts the carry in.
6622 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1));
6623
6624 // Merge the pieces into a single i64 value.
6625 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6626}
6627
6629 const ARMSubtarget *ST) {
6630 bool Invert = false;
6631 bool Swap = false;
6632 unsigned Opc = ARMCC::AL;
6633
6634 SDValue Op0 = Op.getOperand(0);
6635 SDValue Op1 = Op.getOperand(1);
6636 SDValue CC = Op.getOperand(2);
6637 EVT VT = Op.getValueType();
6638 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
6639 SDLoc dl(Op);
6640
6641 EVT CmpVT;
6642 if (ST->hasNEON())
6644 else {
6645 assert(ST->hasMVEIntegerOps() &&
6646 "No hardware support for integer vector comparison!");
6647
6648 if (Op.getValueType().getVectorElementType() != MVT::i1)
6649 return SDValue();
6650
6651 // Make sure we expand floating point setcc to scalar if we do not have
6652 // mve.fp, so that we can handle them from there.
6653 if (Op0.getValueType().isFloatingPoint() && !ST->hasMVEFloatOps())
6654 return SDValue();
6655
6656 CmpVT = VT;
6657 }
6658
6659 if (Op0.getValueType().getVectorElementType() == MVT::i64 &&
6660 (SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE)) {
6661 // Special-case integer 64-bit equality comparisons. They aren't legal,
6662 // but they can be lowered with a few vector instructions.
6663 unsigned CmpElements = CmpVT.getVectorNumElements() * 2;
6664 EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, CmpElements);
6665 SDValue CastOp0 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op0);
6666 SDValue CastOp1 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op1);
6667 SDValue Cmp = DAG.getNode(ISD::SETCC, dl, SplitVT, CastOp0, CastOp1,
6668 DAG.getCondCode(ISD::SETEQ));
6669 SDValue Reversed = DAG.getNode(ARMISD::VREV64, dl, SplitVT, Cmp);
6670 SDValue Merged = DAG.getNode(ISD::AND, dl, SplitVT, Cmp, Reversed);
6671 Merged = DAG.getNode(ISD::BITCAST, dl, CmpVT, Merged);
6672 if (SetCCOpcode == ISD::SETNE)
6673 Merged = DAG.getNOT(dl, Merged, CmpVT);
6674 Merged = DAG.getSExtOrTrunc(Merged, dl, VT);
6675 return Merged;
6676 }
6677
6678 if (CmpVT.getVectorElementType() == MVT::i64)
6679 // 64-bit comparisons are not legal in general.
6680 return SDValue();
6681
6682 if (Op1.getValueType().isFloatingPoint()) {
6683 switch (SetCCOpcode) {
6684 default: llvm_unreachable("Illegal FP comparison");
6685 case ISD::SETUNE:
6686 case ISD::SETNE:
6687 if (ST->hasMVEFloatOps()) {
6688 Opc = ARMCC::NE; break;
6689 } else {
6690 Invert = true; [[fallthrough]];
6691 }
6692 case ISD::SETOEQ:
6693 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6694 case ISD::SETOLT:
6695 case ISD::SETLT: Swap = true; [[fallthrough]];
6696 case ISD::SETOGT:
6697 case ISD::SETGT: Opc = ARMCC::GT; break;
6698 case ISD::SETOLE:
6699 case ISD::SETLE: Swap = true; [[fallthrough]];
6700 case ISD::SETOGE:
6701 case ISD::SETGE: Opc = ARMCC::GE; break;
6702 case ISD::SETUGE: Swap = true; [[fallthrough]];
6703 case ISD::SETULE: Invert = true; Opc = ARMCC::GT; break;
6704 case ISD::SETUGT: Swap = true; [[fallthrough]];
6705 case ISD::SETULT: Invert = true; Opc = ARMCC::GE; break;
6706 case ISD::SETUEQ: Invert = true; [[fallthrough]];
6707 case ISD::SETONE: {
6708 // Expand this to (OLT | OGT).
6709 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6710 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6711 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6712 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6713 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6714 if (Invert)
6715 Result = DAG.getNOT(dl, Result, VT);
6716 return Result;
6717 }
6718 case ISD::SETUO: Invert = true; [[fallthrough]];
6719 case ISD::SETO: {
6720 // Expand this to (OLT | OGE).
6721 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6722 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6723 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6724 DAG.getConstant(ARMCC::GE, dl, MVT::i32));
6725 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6726 if (Invert)
6727 Result = DAG.getNOT(dl, Result, VT);
6728 return Result;
6729 }
6730 }
6731 } else {
6732 // Integer comparisons.
6733 switch (SetCCOpcode) {
6734 default: llvm_unreachable("Illegal integer comparison");
6735 case ISD::SETNE:
6736 if (ST->hasMVEIntegerOps()) {
6737 Opc = ARMCC::NE; break;
6738 } else {
6739 Invert = true; [[fallthrough]];
6740 }
6741 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6742 case ISD::SETLT: Swap = true; [[fallthrough]];
6743 case ISD::SETGT: Opc = ARMCC::GT; break;
6744 case ISD::SETLE: Swap = true; [[fallthrough]];
6745 case ISD::SETGE: Opc = ARMCC::GE; break;
6746 case ISD::SETULT: Swap = true; [[fallthrough]];
6747 case ISD::SETUGT: Opc = ARMCC::HI; break;
6748 case ISD::SETULE: Swap = true; [[fallthrough]];
6749 case ISD::SETUGE: Opc = ARMCC::HS; break;
6750 }
6751
6752 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero).
6753 if (ST->hasNEON() && Opc == ARMCC::EQ) {
6754 SDValue AndOp;
6756 AndOp = Op0;
6757 else if (ISD::isBuildVectorAllZeros(Op0.getNode()))
6758 AndOp = Op1;
6759
6760 // Ignore bitconvert.
6761 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BITCAST)
6762 AndOp = AndOp.getOperand(0);
6763
6764 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
6765 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
6766 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
6767 SDValue Result = DAG.getNode(ARMISD::VTST, dl, CmpVT, Op0, Op1);
6768 if (!Invert)
6769 Result = DAG.getNOT(dl, Result, VT);
6770 return Result;
6771 }
6772 }
6773 }
6774
6775 if (Swap)
6776 std::swap(Op0, Op1);
6777
6778 // If one of the operands is a constant vector zero, attempt to fold the
6779 // comparison to a specialized compare-against-zero form.
6781 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::EQ ||
6782 Opc == ARMCC::NE)) {
6783 if (Opc == ARMCC::GE)
6784 Opc = ARMCC::LE;
6785 else if (Opc == ARMCC::GT)
6786 Opc = ARMCC::LT;
6787 std::swap(Op0, Op1);
6788 }
6789
6790 SDValue Result;
6792 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::LE ||
6793 Opc == ARMCC::LT || Opc == ARMCC::NE || Opc == ARMCC::EQ))
6794 Result = DAG.getNode(ARMISD::VCMPZ, dl, CmpVT, Op0,
6795 DAG.getConstant(Opc, dl, MVT::i32));
6796 else
6797 Result = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6798 DAG.getConstant(Opc, dl, MVT::i32));
6799
6800 Result = DAG.getSExtOrTrunc(Result, dl, VT);
6801
6802 if (Invert)
6803 Result = DAG.getNOT(dl, Result, VT);
6804
6805 return Result;
6806}
6807
6809 SDValue LHS = Op.getOperand(0);
6810 SDValue RHS = Op.getOperand(1);
6811
6812 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
6813
6814 SDValue Carry = Op.getOperand(2);
6815 SDValue Cond = Op.getOperand(3);
6816 SDLoc DL(Op);
6817
6818 // ARMISD::SUBE expects a carry not a borrow like ISD::USUBO_CARRY so we
6819 // have to invert the carry first.
6820 SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
6821
6822 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
6823 SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, InvCarry);
6824
6825 SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
6826 SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
6827 SDValue ARMcc = DAG.getConstant(
6828 IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
6829 return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
6830 Cmp.getValue(1));
6831}
6832
6833/// isVMOVModifiedImm - Check if the specified splat value corresponds to a
6834/// valid vector constant for a NEON or MVE instruction with a "modified
6835/// immediate" operand (e.g., VMOV). If so, return the encoded value.
6836static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
6837 unsigned SplatBitSize, SelectionDAG &DAG,
6838 const SDLoc &dl, EVT &VT, EVT VectorVT,
6839 VMOVModImmType type) {
6840 unsigned OpCmode, Imm;
6841 bool is128Bits = VectorVT.is128BitVector();
6842
6843 // SplatBitSize is set to the smallest size that splats the vector, so a
6844 // zero vector will always have SplatBitSize == 8. However, NEON modified
6845 // immediate instructions others than VMOV do not support the 8-bit encoding
6846 // of a zero vector, and the default encoding of zero is supposed to be the
6847 // 32-bit version.
6848 if (SplatBits == 0)
6849 SplatBitSize = 32;
6850
6851 switch (SplatBitSize) {
6852 case 8:
6853 if (type != VMOVModImm)
6854 return SDValue();
6855 // Any 1-byte value is OK. Op=0, Cmode=1110.
6856 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
6857 OpCmode = 0xe;
6858 Imm = SplatBits;
6859 VT = is128Bits ? MVT::v16i8 : MVT::v8i8;
6860 break;
6861
6862 case 16:
6863 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero.
6864 VT = is128Bits ? MVT::v8i16 : MVT::v4i16;
6865 if ((SplatBits & ~0xff) == 0) {
6866 // Value = 0x00nn: Op=x, Cmode=100x.
6867 OpCmode = 0x8;
6868 Imm = SplatBits;
6869 break;
6870 }
6871 if ((SplatBits & ~0xff00) == 0) {
6872 // Value = 0xnn00: Op=x, Cmode=101x.
6873 OpCmode = 0xa;
6874 Imm = SplatBits >> 8;
6875 break;
6876 }
6877 return SDValue();
6878
6879 case 32:
6880 // NEON's 32-bit VMOV supports splat values where:
6881 // * only one byte is nonzero, or
6882 // * the least significant byte is 0xff and the second byte is nonzero, or
6883 // * the least significant 2 bytes are 0xff and the third is nonzero.
6884 VT = is128Bits ? MVT::v4i32 : MVT::v2i32;
6885 if ((SplatBits & ~0xff) == 0) {
6886 // Value = 0x000000nn: Op=x, Cmode=000x.
6887 OpCmode = 0;
6888 Imm = SplatBits;
6889 break;
6890 }
6891 if ((SplatBits & ~0xff00) == 0) {
6892 // Value = 0x0000nn00: Op=x, Cmode=001x.
6893 OpCmode = 0x2;
6894 Imm = SplatBits >> 8;
6895 break;
6896 }
6897 if ((SplatBits & ~0xff0000) == 0) {
6898 // Value = 0x00nn0000: Op=x, Cmode=010x.
6899 OpCmode = 0x4;
6900 Imm = SplatBits >> 16;
6901 break;
6902 }
6903 if ((SplatBits & ~0xff000000) == 0) {
6904 // Value = 0xnn000000: Op=x, Cmode=011x.
6905 OpCmode = 0x6;
6906 Imm = SplatBits >> 24;
6907 break;
6908 }
6909
6910 // cmode == 0b1100 and cmode == 0b1101 are not supported for VORR or VBIC
6911 if (type == OtherModImm) return SDValue();
6912
6913 if ((SplatBits & ~0xffff) == 0 &&
6914 ((SplatBits | SplatUndef) & 0xff) == 0xff) {
6915 // Value = 0x0000nnff: Op=x, Cmode=1100.
6916 OpCmode = 0xc;
6917 Imm = SplatBits >> 8;
6918 break;
6919 }
6920
6921 // cmode == 0b1101 is not supported for MVE VMVN
6922 if (type == MVEVMVNModImm)
6923 return SDValue();
6924
6925 if ((SplatBits & ~0xffffff) == 0 &&
6926 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
6927 // Value = 0x00nnffff: Op=x, Cmode=1101.
6928 OpCmode = 0xd;
6929 Imm = SplatBits >> 16;
6930 break;
6931 }
6932
6933 // Note: there are a few 32-bit splat values (specifically: 00ffff00,
6934 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not
6935 // VMOV.I32. A (very) minor optimization would be to replicate the value
6936 // and fall through here to test for a valid 64-bit splat. But, then the
6937 // caller would also need to check and handle the change in size.
6938 return SDValue();
6939
6940 case 64: {
6941 if (type != VMOVModImm)
6942 return SDValue();
6943 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
6944 uint64_t BitMask = 0xff;
6945 unsigned ImmMask = 1;
6946 Imm = 0;
6947 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) {
6948 if (((SplatBits | SplatUndef) & BitMask) == BitMask) {
6949 Imm |= ImmMask;
6950 } else if ((SplatBits & BitMask) != 0) {
6951 return SDValue();
6952 }
6953 BitMask <<= 8;
6954 ImmMask <<= 1;
6955 }
6956
6957 // Op=1, Cmode=1110.
6958 OpCmode = 0x1e;
6959 VT = is128Bits ? MVT::v2i64 : MVT::v1i64;
6960 break;
6961 }
6962
6963 default:
6964 llvm_unreachable("unexpected size for isVMOVModifiedImm");
6965 }
6966
6967 unsigned EncodedVal = ARM_AM::createVMOVModImm(OpCmode, Imm);
6968 return DAG.getTargetConstant(EncodedVal, dl, MVT::i32);
6969}
6970
6971SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
6972 const ARMSubtarget *ST) const {
6973 EVT VT = Op.getValueType();
6974 bool IsDouble = (VT == MVT::f64);
6975 ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
6976 const APFloat &FPVal = CFP->getValueAPF();
6977
6978 // Prevent floating-point constants from using literal loads
6979 // when execute-only is enabled.
6980 if (ST->genExecuteOnly()) {
6981 // We shouldn't trigger this for v6m execute-only
6982 assert((!ST->isThumb1Only() || ST->hasV8MBaselineOps()) &&
6983 "Unexpected architecture");
6984
6985 // If we can represent the constant as an immediate, don't lower it
6986 if (isFPImmLegal(FPVal, VT))
6987 return Op;
6988 // Otherwise, construct as integer, and move to float register
6989 APInt INTVal = FPVal.bitcastToAPInt();
6990 SDLoc DL(CFP);
6991 switch (VT.getSimpleVT().SimpleTy) {
6992 default:
6993 llvm_unreachable("Unknown floating point type!");
6994 break;
6995 case MVT::f64: {
6996 SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);
6997 SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);
6998 return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);
6999 }
7000 case MVT::f32:
7001 return DAG.getNode(ARMISD::VMOVSR, DL, VT,
7002 DAG.getConstant(INTVal, DL, MVT::i32));
7003 }
7004 }
7005
7006 if (!ST->hasVFP3Base())
7007 return SDValue();
7008
7009 // Use the default (constant pool) lowering for double constants when we have
7010 // an SP-only FPU
7011 if (IsDouble && !Subtarget->hasFP64())
7012 return SDValue();
7013
7014 // Try splatting with a VMOV.f32...
7015 int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);
7016
7017 if (ImmVal != -1) {
7018 if (IsDouble || !ST->useNEONForSinglePrecisionFP()) {
7019 // We have code in place to select a valid ConstantFP already, no need to
7020 // do any mangling.
7021 return Op;
7022 }
7023
7024 // It's a float and we are trying to use NEON operations where
7025 // possible. Lower it to a splat followed by an extract.
7026 SDLoc DL(Op);
7027 SDValue NewVal = DAG.getTargetConstant(ImmVal, DL, MVT::i32);
7028 SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
7029 NewVal);
7030 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
7031 DAG.getConstant(0, DL, MVT::i32));
7032 }
7033
7034 // The rest of our options are NEON only, make sure that's allowed before
7035 // proceeding..
7036 if (!ST->hasNEON() || (!IsDouble && !ST->useNEONForSinglePrecisionFP()))
7037 return SDValue();
7038
7039 EVT VMovVT;
7040 uint64_t iVal = FPVal.bitcastToAPInt().getZExtValue();
7041
7042 // It wouldn't really be worth bothering for doubles except for one very
7043 // important value, which does happen to match: 0.0. So make sure we don't do
7044 // anything stupid.
7045 if (IsDouble && (iVal & 0xffffffff) != (iVal >> 32))
7046 return SDValue();
7047
7048 // Try a VMOV.i32 (FIXME: i8, i16, or i64 could work too).
7049 SDValue NewVal = isVMOVModifiedImm(iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op),
7050 VMovVT, VT, VMOVModImm);
7051 if (NewVal != SDValue()) {
7052 SDLoc DL(Op);
7053 SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
7054 NewVal);
7055 if (IsDouble)
7056 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7057
7058 // It's a float: cast and extract a vector element.
7059 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7060 VecConstant);
7061 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7062 DAG.getConstant(0, DL, MVT::i32));
7063 }
7064
7065 // Finally, try a VMVN.i32
7066 NewVal = isVMOVModifiedImm(~iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op), VMovVT,
7067 VT, VMVNModImm);
7068 if (NewVal != SDValue()) {
7069 SDLoc DL(Op);
7070 SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
7071
7072 if (IsDouble)
7073 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7074
7075 // It's a float: cast and extract a vector element.
7076 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7077 VecConstant);
7078 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7079 DAG.getConstant(0, DL, MVT::i32));
7080 }
7081
7082 return SDValue();
7083}
7084
7085// check if an VEXT instruction can handle the shuffle mask when the
7086// vector sources of the shuffle are the same.
7087static bool isSingletonVEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
7088 unsigned NumElts = VT.getVectorNumElements();
7089
7090 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7091 if (M[0] < 0)
7092 return false;
7093
7094 Imm = M[0];
7095
7096 // If this is a VEXT shuffle, the immediate value is the index of the first
7097 // element. The other shuffle indices must be the successive elements after
7098 // the first one.
7099 unsigned ExpectedElt = Imm;
7100 for (unsigned i = 1; i < NumElts; ++i) {
7101 // Increment the expected index. If it wraps around, just follow it
7102 // back to index zero and keep going.
7103 ++ExpectedElt;
7104 if (ExpectedElt == NumElts)
7105 ExpectedElt = 0;
7106
7107 if (M[i] < 0) continue; // ignore UNDEF indices
7108 if (ExpectedElt != static_cast<unsigned>(M[i]))
7109 return false;
7110 }
7111
7112 return true;
7113}
7114
7115static bool isVEXTMask(ArrayRef<int> M, EVT VT,
7116 bool &ReverseVEXT, unsigned &Imm) {
7117 unsigned NumElts = VT.getVectorNumElements();
7118 ReverseVEXT = false;
7119
7120 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7121 if (M[0] < 0)
7122 return false;
7123
7124 Imm = M[0];
7125
7126 // If this is a VEXT shuffle, the immediate value is the index of the first
7127 // element. The other shuffle indices must be the successive elements after
7128 // the first one.
7129 unsigned ExpectedElt = Imm;
7130 for (unsigned i = 1; i < NumElts; ++i) {
7131 // Increment the expected index. If it wraps around, it may still be
7132 // a VEXT but the source vectors must be swapped.
7133 ExpectedElt += 1;
7134 if (ExpectedElt == NumElts * 2) {
7135 ExpectedElt = 0;
7136 ReverseVEXT = true;
7137 }
7138
7139 if (M[i] < 0) continue; // ignore UNDEF indices
7140 if (ExpectedElt != static_cast<unsigned>(M[i]))
7141 return false;
7142 }
7143
7144 // Adjust the index value if the source operands will be swapped.
7145 if (ReverseVEXT)
7146 Imm -= NumElts;
7147
7148 return true;
7149}
7150
7151static bool isVTBLMask(ArrayRef<int> M, EVT VT) {
7152 // We can handle <8 x i8> vector shuffles. If the index in the mask is out of
7153 // range, then 0 is placed into the resulting vector. So pretty much any mask
7154 // of 8 elements can work here.
7155 return VT == MVT::v8i8 && M.size() == 8;
7156}
7157
7158static unsigned SelectPairHalf(unsigned Elements, ArrayRef<int> Mask,
7159 unsigned Index) {
7160 if (Mask.size() == Elements * 2)
7161 return Index / Elements;
7162 return Mask[Index] == 0 ? 0 : 1;
7163}
7164
7165// Checks whether the shuffle mask represents a vector transpose (VTRN) by
7166// checking that pairs of elements in the shuffle mask represent the same index
7167// in each vector, incrementing the expected index by 2 at each step.
7168// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 2, 6]
7169// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,c,g}
7170// v2={e,f,g,h}
7171// WhichResult gives the offset for each element in the mask based on which
7172// of the two results it belongs to.
7173//
7174// The transpose can be represented either as:
7175// result1 = shufflevector v1, v2, result1_shuffle_mask
7176// result2 = shufflevector v1, v2, result2_shuffle_mask
7177// where v1/v2 and the shuffle masks have the same number of elements
7178// (here WhichResult (see below) indicates which result is being checked)
7179//
7180// or as:
7181// results = shufflevector v1, v2, shuffle_mask
7182// where both results are returned in one vector and the shuffle mask has twice
7183// as many elements as v1/v2 (here WhichResult will always be 0 if true) here we
7184// want to check the low half and high half of the shuffle mask as if it were
7185// the other case
7186static bool isVTRNMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7187 unsigned EltSz = VT.getScalarSizeInBits();
7188 if (EltSz == 64)
7189 return false;
7190
7191 unsigned NumElts = VT.getVectorNumElements();
7192 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7193 return false;
7194
7195 // If the mask is twice as long as the input vector then we need to check the
7196 // upper and lower parts of the mask with a matching value for WhichResult
7197 // FIXME: A mask with only even values will be rejected in case the first
7198 // element is undefined, e.g. [-1, 4, 2, 6] will be rejected, because only
7199 // M[0] is used to determine WhichResult
7200 for (unsigned i = 0; i < M.size(); i += NumElts) {
7201 WhichResult = SelectPairHalf(NumElts, M, i);
7202 for (unsigned j = 0; j < NumElts; j += 2) {
7203 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7204 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + NumElts + WhichResult))
7205 return false;
7206 }
7207 }
7208
7209 if (M.size() == NumElts*2)
7210 WhichResult = 0;
7211
7212 return true;
7213}
7214
7215/// isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of
7216/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7217/// Mask is e.g., <0, 0, 2, 2> instead of <0, 4, 2, 6>.
7218static bool isVTRN_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7219 unsigned EltSz = VT.getScalarSizeInBits();
7220 if (EltSz == 64)
7221 return false;
7222
7223 unsigned NumElts = VT.getVectorNumElements();
7224 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7225 return false;
7226
7227 for (unsigned i = 0; i < M.size(); i += NumElts) {
7228 WhichResult = SelectPairHalf(NumElts, M, i);
7229 for (unsigned j = 0; j < NumElts; j += 2) {
7230 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7231 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + WhichResult))
7232 return false;
7233 }
7234 }
7235
7236 if (M.size() == NumElts*2)
7237 WhichResult = 0;
7238
7239 return true;
7240}
7241
7242// Checks whether the shuffle mask represents a vector unzip (VUZP) by checking
7243// that the mask elements are either all even and in steps of size 2 or all odd
7244// and in steps of size 2.
7245// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 2, 4, 6]
7246// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,c,e,g}
7247// v2={e,f,g,h}
7248// Requires similar checks to that of isVTRNMask with
7249// respect the how results are returned.
7250static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7251 unsigned EltSz = VT.getScalarSizeInBits();
7252 if (EltSz == 64)
7253 return false;
7254
7255 unsigned NumElts = VT.getVectorNumElements();
7256 if (M.size() != NumElts && M.size() != NumElts*2)
7257 return false;
7258
7259 for (unsigned i = 0; i < M.size(); i += NumElts) {
7260 WhichResult = SelectPairHalf(NumElts, M, i);
7261 for (unsigned j = 0; j < NumElts; ++j) {
7262 if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
7263 return false;
7264 }
7265 }
7266
7267 if (M.size() == NumElts*2)
7268 WhichResult = 0;
7269
7270 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7271 if (VT.is64BitVector() && EltSz == 32)
7272 return false;
7273
7274 return true;
7275}
7276
7277/// isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of
7278/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7279/// Mask is e.g., <0, 2, 0, 2> instead of <0, 2, 4, 6>,
7280static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7281 unsigned EltSz = VT.getScalarSizeInBits();
7282 if (EltSz == 64)
7283 return false;
7284
7285 unsigned NumElts = VT.getVectorNumElements();
7286 if (M.size() != NumElts && M.size() != NumElts*2)
7287 return false;
7288
7289 unsigned Half = NumElts / 2;
7290 for (unsigned i = 0; i < M.size(); i += NumElts) {
7291 WhichResult = SelectPairHalf(NumElts, M, i);
7292 for (unsigned j = 0; j < NumElts; j += Half) {
7293 unsigned Idx = WhichResult;
7294 for (unsigned k = 0; k < Half; ++k) {
7295 int MIdx = M[i + j + k];
7296 if (MIdx >= 0 && (unsigned) MIdx != Idx)
7297 return false;
7298 Idx += 2;
7299 }
7300 }
7301 }
7302
7303 if (M.size() == NumElts*2)
7304 WhichResult = 0;
7305
7306 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7307 if (VT.is64BitVector() && EltSz == 32)
7308 return false;
7309
7310 return true;
7311}
7312
7313// Checks whether the shuffle mask represents a vector zip (VZIP) by checking
7314// that pairs of elements of the shufflemask represent the same index in each
7315// vector incrementing sequentially through the vectors.
7316// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 1, 5]
7317// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,b,f}
7318// v2={e,f,g,h}
7319// Requires similar checks to that of isVTRNMask with respect the how results
7320// are returned.
7321static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7322 unsigned EltSz = VT.getScalarSizeInBits();
7323 if (EltSz == 64)
7324 return false;
7325
7326 unsigned NumElts = VT.getVectorNumElements();
7327 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7328 return false;
7329
7330 for (unsigned i = 0; i < M.size(); i += NumElts) {
7331 WhichResult = SelectPairHalf(NumElts, M, i);
7332 unsigned Idx = WhichResult * NumElts / 2;
7333 for (unsigned j = 0; j < NumElts; j += 2) {
7334 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7335 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx + NumElts))
7336 return false;
7337 Idx += 1;
7338 }
7339 }
7340
7341 if (M.size() == NumElts*2)
7342 WhichResult = 0;
7343
7344 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7345 if (VT.is64BitVector() && EltSz == 32)
7346 return false;
7347
7348 return true;
7349}
7350
7351/// isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of
7352/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7353/// Mask is e.g., <0, 0, 1, 1> instead of <0, 4, 1, 5>.
7354static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7355 unsigned EltSz = VT.getScalarSizeInBits();
7356 if (EltSz == 64)
7357 return false;
7358
7359 unsigned NumElts = VT.getVectorNumElements();
7360 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7361 return false;
7362
7363 for (unsigned i = 0; i < M.size(); i += NumElts) {
7364 WhichResult = SelectPairHalf(NumElts, M, i);
7365 unsigned Idx = WhichResult * NumElts / 2;
7366 for (unsigned j = 0; j < NumElts; j += 2) {
7367 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7368 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx))
7369 return false;
7370 Idx += 1;
7371 }
7372 }
7373
7374 if (M.size() == NumElts*2)
7375 WhichResult = 0;
7376
7377 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7378 if (VT.is64BitVector() && EltSz == 32)
7379 return false;
7380
7381 return true;
7382}
7383
7384/// Check if \p ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN),
7385/// and return the corresponding ARMISD opcode if it is, or 0 if it isn't.
7386static unsigned isNEONTwoResultShuffleMask(ArrayRef<int> ShuffleMask, EVT VT,
7387 unsigned &WhichResult,
7388 bool &isV_UNDEF) {
7389 isV_UNDEF = false;
7390 if (isVTRNMask(ShuffleMask, VT, WhichResult))
7391 return ARMISD::VTRN;
7392 if (isVUZPMask(ShuffleMask, VT, WhichResult))
7393 return ARMISD::VUZP;
7394 if (isVZIPMask(ShuffleMask, VT, WhichResult))
7395 return ARMISD::VZIP;
7396
7397 isV_UNDEF = true;
7398 if (isVTRN_v_undef_Mask(ShuffleMask, VT, WhichResult))
7399 return ARMISD::VTRN;
7400 if (isVUZP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7401 return ARMISD::VUZP;
7402 if (isVZIP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7403 return ARMISD::VZIP;
7404
7405 return 0;
7406}
7407
7408/// \return true if this is a reverse operation on an vector.
7409static bool isReverseMask(ArrayRef<int> M, EVT VT) {
7410 unsigned NumElts = VT.getVectorNumElements();
7411 // Make sure the mask has the right size.
7412 if (NumElts != M.size())
7413 return false;
7414
7415 // Look for <15, ..., 3, -1, 1, 0>.
7416 for (unsigned i = 0; i != NumElts; ++i)
7417 if (M[i] >= 0 && M[i] != (int) (NumElts - 1 - i))
7418 return false;
7419
7420 return true;
7421}
7422
7423static bool isTruncMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7424 unsigned NumElts = VT.getVectorNumElements();
7425 // Make sure the mask has the right size.
7426 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7427 return false;
7428
7429 // Half-width truncation patterns (e.g. v4i32 -> v8i16):
7430 // !Top && SingleSource: <0, 2, 4, 6, 0, 2, 4, 6>
7431 // !Top && !SingleSource: <0, 2, 4, 6, 8, 10, 12, 14>
7432 // Top && SingleSource: <1, 3, 5, 7, 1, 3, 5, 7>
7433 // Top && !SingleSource: <1, 3, 5, 7, 9, 11, 13, 15>
7434 int Ofs = Top ? 1 : 0;
7435 int Upper = SingleSource ? 0 : NumElts;
7436 for (int i = 0, e = NumElts / 2; i != e; ++i) {
7437 if (M[i] >= 0 && M[i] != (i * 2) + Ofs)
7438 return false;
7439 if (M[i + e] >= 0 && M[i + e] != (i * 2) + Ofs + Upper)
7440 return false;
7441 }
7442 return true;
7443}
7444
7445static bool isVMOVNMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7446 unsigned NumElts = VT.getVectorNumElements();
7447 // Make sure the mask has the right size.
7448 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7449 return false;
7450
7451 // If Top
7452 // Look for <0, N, 2, N+2, 4, N+4, ..>.
7453 // This inserts Input2 into Input1
7454 // else if not Top
7455 // Look for <0, N+1, 2, N+3, 4, N+5, ..>
7456 // This inserts Input1 into Input2
7457 unsigned Offset = Top ? 0 : 1;
7458 unsigned N = SingleSource ? 0 : NumElts;
7459 for (unsigned i = 0; i < NumElts; i += 2) {
7460 if (M[i] >= 0 && M[i] != (int)i)
7461 return false;
7462 if (M[i + 1] >= 0 && M[i + 1] != (int)(N + i + Offset))
7463 return false;
7464 }
7465
7466 return true;
7467}
7468
7469static bool isVMOVNTruncMask(ArrayRef<int> M, EVT ToVT, bool rev) {
7470 unsigned NumElts = ToVT.getVectorNumElements();
7471 if (NumElts != M.size())
7472 return false;
7473
7474 // Test if the Trunc can be convertible to a VMOVN with this shuffle. We are
7475 // looking for patterns of:
7476 // !rev: 0 N/2 1 N/2+1 2 N/2+2 ...
7477 // rev: N/2 0 N/2+1 1 N/2+2 2 ...
7478
7479 unsigned Off0 = rev ? NumElts / 2 : 0;
7480 unsigned Off1 = rev ? 0 : NumElts / 2;
7481 for (unsigned i = 0; i < NumElts; i += 2) {
7482 if (M[i] >= 0 && M[i] != (int)(Off0 + i / 2))
7483 return false;
7484 if (M[i + 1] >= 0 && M[i + 1] != (int)(Off1 + i / 2))
7485 return false;
7486 }
7487
7488 return true;
7489}
7490
7491// Reconstruct an MVE VCVT from a BuildVector of scalar fptrunc, all extracted
7492// from a pair of inputs. For example:
7493// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7494// FP_ROUND(EXTRACT_ELT(Y, 0),
7495// FP_ROUND(EXTRACT_ELT(X, 1),
7496// FP_ROUND(EXTRACT_ELT(Y, 1), ...)
7498 const ARMSubtarget *ST) {
7499 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7500 if (!ST->hasMVEFloatOps())
7501 return SDValue();
7502
7503 SDLoc dl(BV);
7504 EVT VT = BV.getValueType();
7505 if (VT != MVT::v8f16)
7506 return SDValue();
7507
7508 // We are looking for a buildvector of fptrunc elements, where all the
7509 // elements are interleavingly extracted from two sources. Check the first two
7510 // items are valid enough and extract some info from them (they are checked
7511 // properly in the loop below).
7512 if (BV.getOperand(0).getOpcode() != ISD::FP_ROUND ||
7515 return SDValue();
7516 if (BV.getOperand(1).getOpcode() != ISD::FP_ROUND ||
7519 return SDValue();
7520 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7521 SDValue Op1 = BV.getOperand(1).getOperand(0).getOperand(0);
7522 if (Op0.getValueType() != MVT::v4f32 || Op1.getValueType() != MVT::v4f32)
7523 return SDValue();
7524
7525 // Check all the values in the BuildVector line up with our expectations.
7526 for (unsigned i = 1; i < 4; i++) {
7527 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7528 return Trunc.getOpcode() == ISD::FP_ROUND &&
7530 Trunc.getOperand(0).getOperand(0) == Op &&
7531 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7532 };
7533 if (!Check(BV.getOperand(i * 2 + 0), Op0, i))
7534 return SDValue();
7535 if (!Check(BV.getOperand(i * 2 + 1), Op1, i))
7536 return SDValue();
7537 }
7538
7539 SDValue N1 = DAG.getNode(ARMISD::VCVTN, dl, VT, DAG.getUNDEF(VT), Op0,
7540 DAG.getConstant(0, dl, MVT::i32));
7541 return DAG.getNode(ARMISD::VCVTN, dl, VT, N1, Op1,
7542 DAG.getConstant(1, dl, MVT::i32));
7543}
7544
7545// Reconstruct an MVE VCVT from a BuildVector of scalar fpext, all extracted
7546// from a single input on alternating lanes. For example:
7547// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7548// FP_ROUND(EXTRACT_ELT(X, 2),
7549// FP_ROUND(EXTRACT_ELT(X, 4), ...)
7551 const ARMSubtarget *ST) {
7552 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7553 if (!ST->hasMVEFloatOps())
7554 return SDValue();
7555
7556 SDLoc dl(BV);
7557 EVT VT = BV.getValueType();
7558 if (VT != MVT::v4f32)
7559 return SDValue();
7560
7561 // We are looking for a buildvector of fptext elements, where all the
7562 // elements are alternating lanes from a single source. For example <0,2,4,6>
7563 // or <1,3,5,7>. Check the first two items are valid enough and extract some
7564 // info from them (they are checked properly in the loop below).
7565 if (BV.getOperand(0).getOpcode() != ISD::FP_EXTEND ||
7567 return SDValue();
7568 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7570 if (Op0.getValueType() != MVT::v8f16 || (Offset != 0 && Offset != 1))
7571 return SDValue();
7572
7573 // Check all the values in the BuildVector line up with our expectations.
7574 for (unsigned i = 1; i < 4; i++) {
7575 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7576 return Trunc.getOpcode() == ISD::FP_EXTEND &&
7578 Trunc.getOperand(0).getOperand(0) == Op &&
7579 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7580 };
7581 if (!Check(BV.getOperand(i), Op0, 2 * i + Offset))
7582 return SDValue();
7583 }
7584
7585 return DAG.getNode(ARMISD::VCVTL, dl, VT, Op0,
7586 DAG.getConstant(Offset, dl, MVT::i32));
7587}
7588
7589// If N is an integer constant that can be moved into a register in one
7590// instruction, return an SDValue of such a constant (will become a MOV
7591// instruction). Otherwise return null.
7593 const ARMSubtarget *ST, const SDLoc &dl) {
7594 uint64_t Val;
7595 if (!isa<ConstantSDNode>(N))
7596 return SDValue();
7597 Val = N->getAsZExtVal();
7598
7599 if (ST->isThumb1Only()) {
7600 if (Val <= 255 || ~Val <= 255)
7601 return DAG.getConstant(Val, dl, MVT::i32);
7602 } else {
7603 if (ARM_AM::getSOImmVal(Val) != -1 || ARM_AM::getSOImmVal(~Val) != -1)
7604 return DAG.getConstant(Val, dl, MVT::i32);
7605 }
7606 return SDValue();
7607}
7608
7610 const ARMSubtarget *ST) {
7611 SDLoc dl(Op);
7612 EVT VT = Op.getValueType();
7613
7614 assert(ST->hasMVEIntegerOps() && "LowerBUILD_VECTOR_i1 called without MVE!");
7615
7616 unsigned NumElts = VT.getVectorNumElements();
7617 unsigned BoolMask;
7618 unsigned BitsPerBool;
7619 if (NumElts == 2) {
7620 BitsPerBool = 8;
7621 BoolMask = 0xff;
7622 } else if (NumElts == 4) {
7623 BitsPerBool = 4;
7624 BoolMask = 0xf;
7625 } else if (NumElts == 8) {
7626 BitsPerBool = 2;
7627 BoolMask = 0x3;
7628 } else if (NumElts == 16) {
7629 BitsPerBool = 1;
7630 BoolMask = 0x1;
7631 } else
7632 return SDValue();
7633
7634 // If this is a single value copied into all lanes (a splat), we can just sign
7635 // extend that single value
7636 SDValue FirstOp = Op.getOperand(0);
7637 if (!isa<ConstantSDNode>(FirstOp) &&
7638 llvm::all_of(llvm::drop_begin(Op->ops()), [&FirstOp](const SDUse &U) {
7639 return U.get().isUndef() || U.get() == FirstOp;
7640 })) {
7641 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
7642 DAG.getValueType(MVT::i1));
7643 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
7644 }
7645
7646 // First create base with bits set where known
7647 unsigned Bits32 = 0;
7648 for (unsigned i = 0; i < NumElts; ++i) {
7649 SDValue V = Op.getOperand(i);
7650 if (!isa<ConstantSDNode>(V) && !V.isUndef())
7651 continue;
7652 bool BitSet = V.isUndef() ? false : V->getAsZExtVal();
7653 if (BitSet)
7654 Bits32 |= BoolMask << (i * BitsPerBool);
7655 }
7656
7657 // Add in unknown nodes
7658 SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
7659 DAG.getConstant(Bits32, dl, MVT::i32));
7660 for (unsigned i = 0; i < NumElts; ++i) {
7661 SDValue V = Op.getOperand(i);
7662 if (isa<ConstantSDNode>(V) || V.isUndef())
7663 continue;
7664 Base = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Base, V,
7665 DAG.getConstant(i, dl, MVT::i32));
7666 }
7667
7668 return Base;
7669}
7670
7672 const ARMSubtarget *ST) {
7673 if (!ST->hasMVEIntegerOps())
7674 return SDValue();
7675
7676 // We are looking for a buildvector where each element is Op[0] + i*N
7677 EVT VT = Op.getValueType();
7678 SDValue Op0 = Op.getOperand(0);
7679 unsigned NumElts = VT.getVectorNumElements();
7680
7681 // Get the increment value from operand 1
7682 SDValue Op1 = Op.getOperand(1);
7683 if (Op1.getOpcode() != ISD::ADD || Op1.getOperand(0) != Op0 ||
7685 return SDValue();
7686 unsigned N = Op1.getConstantOperandVal(1);
7687 if (N != 1 && N != 2 && N != 4 && N != 8)
7688 return SDValue();
7689
7690 // Check that each other operand matches
7691 for (unsigned I = 2; I < NumElts; I++) {
7692 SDValue OpI = Op.getOperand(I);
7693 if (OpI.getOpcode() != ISD::ADD || OpI.getOperand(0) != Op0 ||
7695 OpI.getConstantOperandVal(1) != I * N)
7696 return SDValue();
7697 }
7698
7699 SDLoc DL(Op);
7700 return DAG.getNode(ARMISD::VIDUP, DL, DAG.getVTList(VT, MVT::i32), Op0,
7701 DAG.getConstant(N, DL, MVT::i32));
7702}
7703
7704// Returns true if the operation N can be treated as qr instruction variant at
7705// operand Op.
7706static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op) {
7707 switch (N->getOpcode()) {
7708 case ISD::ADD:
7709 case ISD::MUL:
7710 case ISD::SADDSAT:
7711 case ISD::UADDSAT:
7712 case ISD::AVGFLOORS:
7713 case ISD::AVGFLOORU:
7714 return true;
7715 case ISD::SUB:
7716 case ISD::SSUBSAT:
7717 case ISD::USUBSAT:
7718 return N->getOperand(1).getNode() == Op;
7720 switch (N->getConstantOperandVal(0)) {
7721 case Intrinsic::arm_mve_add_predicated:
7722 case Intrinsic::arm_mve_mul_predicated:
7723 case Intrinsic::arm_mve_qadd_predicated:
7724 case Intrinsic::arm_mve_vhadd:
7725 case Intrinsic::arm_mve_hadd_predicated:
7726 case Intrinsic::arm_mve_vqdmulh:
7727 case Intrinsic::arm_mve_qdmulh_predicated:
7728 case Intrinsic::arm_mve_vqrdmulh:
7729 case Intrinsic::arm_mve_qrdmulh_predicated:
7730 case Intrinsic::arm_mve_vqdmull:
7731 case Intrinsic::arm_mve_vqdmull_predicated:
7732 return true;
7733 case Intrinsic::arm_mve_sub_predicated:
7734 case Intrinsic::arm_mve_qsub_predicated:
7735 case Intrinsic::arm_mve_vhsub:
7736 case Intrinsic::arm_mve_hsub_predicated:
7737 return N->getOperand(2).getNode() == Op;
7738 default:
7739 return false;
7740 }
7741 default:
7742 return false;
7743 }
7744}
7745
7746// If this is a case we can't handle, return null and let the default
7747// expansion code take care of it.
7748SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
7749 const ARMSubtarget *ST) const {
7750 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode());
7751 SDLoc dl(Op);
7752 EVT VT = Op.getValueType();
7753
7754 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
7755 return LowerBUILD_VECTOR_i1(Op, DAG, ST);
7756
7757 if (SDValue R = LowerBUILD_VECTORToVIDUP(Op, DAG, ST))
7758 return R;
7759
7760 APInt SplatBits, SplatUndef;
7761 unsigned SplatBitSize;
7762 bool HasAnyUndefs;
7763 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
7764 if (SplatUndef.isAllOnes())
7765 return DAG.getUNDEF(VT);
7766
7767 // If all the users of this constant splat are qr instruction variants,
7768 // generate a vdup of the constant.
7769 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == SplatBitSize &&
7770 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32) &&
7771 all_of(BVN->users(),
7772 [BVN](const SDNode *U) { return IsQRMVEInstruction(U, BVN); })) {
7773 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7774 : SplatBitSize == 16 ? MVT::v8i16
7775 : MVT::v16i8;
7776 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7777 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7778 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7779 }
7780
7781 if ((ST->hasNEON() && SplatBitSize <= 64) ||
7782 (ST->hasMVEIntegerOps() && SplatBitSize <= 64)) {
7783 // Check if an immediate VMOV works.
7784 EVT VmovVT;
7785 SDValue Val =
7786 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
7787 SplatBitSize, DAG, dl, VmovVT, VT, VMOVModImm);
7788
7789 if (Val.getNode()) {
7790 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, Val);
7791 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7792 }
7793
7794 // Try an immediate VMVN.
7795 uint64_t NegatedImm = (~SplatBits).getZExtValue();
7796 Val = isVMOVModifiedImm(
7797 NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, dl, VmovVT,
7798 VT, ST->hasMVEIntegerOps() ? MVEVMVNModImm : VMVNModImm);
7799 if (Val.getNode()) {
7800 SDValue Vmov = DAG.getNode(ARMISD::VMVNIMM, dl, VmovVT, Val);
7801 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7802 }
7803
7804 // Use vmov.f32 to materialize other v2f32 and v4f32 splats.
7805 if ((VT == MVT::v2f32 || VT == MVT::v4f32) && SplatBitSize == 32) {
7806 int ImmVal = ARM_AM::getFP32Imm(SplatBits);
7807 if (ImmVal != -1) {
7808 SDValue Val = DAG.getTargetConstant(ImmVal, dl, MVT::i32);
7809 return DAG.getNode(ARMISD::VMOVFPIMM, dl, VT, Val);
7810 }
7811 }
7812
7813 // If we are under MVE, generate a VDUP(constant), bitcast to the original
7814 // type.
7815 if (ST->hasMVEIntegerOps() &&
7816 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32)) {
7817 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7818 : SplatBitSize == 16 ? MVT::v8i16
7819 : MVT::v16i8;
7820 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7821 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7822 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7823 }
7824 }
7825 }
7826
7827 // Scan through the operands to see if only one value is used.
7828 //
7829 // As an optimisation, even if more than one value is used it may be more
7830 // profitable to splat with one value then change some lanes.
7831 //
7832 // Heuristically we decide to do this if the vector has a "dominant" value,
7833 // defined as splatted to more than half of the lanes.
7834 unsigned NumElts = VT.getVectorNumElements();
7835 bool isOnlyLowElement = true;
7836 bool usesOnlyOneValue = true;
7837 bool hasDominantValue = false;
7838 bool isConstant = true;
7839
7840 // Map of the number of times a particular SDValue appears in the
7841 // element list.
7842 DenseMap<SDValue, unsigned> ValueCounts;
7843 SDValue Value;
7844 for (unsigned i = 0; i < NumElts; ++i) {
7845 SDValue V = Op.getOperand(i);
7846 if (V.isUndef())
7847 continue;
7848 if (i > 0)
7849 isOnlyLowElement = false;
7851 isConstant = false;
7852
7853 unsigned &Count = ValueCounts[V];
7854
7855 // Is this value dominant? (takes up more than half of the lanes)
7856 if (++Count > (NumElts / 2)) {
7857 hasDominantValue = true;
7858 Value = V;
7859 }
7860 }
7861 if (ValueCounts.size() != 1)
7862 usesOnlyOneValue = false;
7863 if (!Value.getNode() && !ValueCounts.empty())
7864 Value = ValueCounts.begin()->first;
7865
7866 if (ValueCounts.empty())
7867 return DAG.getUNDEF(VT);
7868
7869 // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
7870 // Keep going if we are hitting this case.
7871 if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()) &&
7872 (VT != MVT::v8f16 || ST->hasFullFP16()))
7873 return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
7874
7875 unsigned EltSize = VT.getScalarSizeInBits();
7876
7877 // Use VDUP for non-constant splats. For f32 constant splats, reduce to
7878 // i32 and try again.
7879 if (hasDominantValue && EltSize <= 32) {
7880 if (!isConstant) {
7881 SDValue N;
7882
7883 // If we are VDUPing a value that comes directly from a vector, that will
7884 // cause an unnecessary move to and from a GPR, where instead we could
7885 // just use VDUPLANE. We can only do this if the lane being extracted
7886 // is at a constant index, as the VDUP from lane instructions only have
7887 // constant-index forms.
7888 ConstantSDNode *constIndex;
7889 if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7890 (constIndex = dyn_cast<ConstantSDNode>(Value->getOperand(1)))) {
7891 // We need to create a new undef vector to use for the VDUPLANE if the
7892 // size of the vector from which we get the value is different than the
7893 // size of the vector that we need to create. We will insert the element
7894 // such that the register coalescer will remove unnecessary copies.
7895 if (VT != Value->getOperand(0).getValueType()) {
7896 unsigned index = constIndex->getAPIntValue().getLimitedValue() %
7898 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7899 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DAG.getUNDEF(VT),
7900 Value, DAG.getConstant(index, dl, MVT::i32)),
7901 DAG.getConstant(index, dl, MVT::i32));
7902 } else
7903 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7904 Value->getOperand(0), Value->getOperand(1));
7905 } else
7906 N = DAG.getNode(ARMISD::VDUP, dl, VT, Value);
7907
7908 if (!usesOnlyOneValue) {
7909 // The dominant value was splatted as 'N', but we now have to insert
7910 // all differing elements.
7911 for (unsigned I = 0; I < NumElts; ++I) {
7912 if (Op.getOperand(I) == Value)
7913 continue;
7915 Ops.push_back(N);
7916 Ops.push_back(Op.getOperand(I));
7917 Ops.push_back(DAG.getConstant(I, dl, MVT::i32));
7918 N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ops);
7919 }
7920 }
7921 return N;
7922 }
7925 MVT FVT = VT.getVectorElementType().getSimpleVT();
7926 assert(FVT == MVT::f32 || FVT == MVT::f16);
7927 MVT IVT = (FVT == MVT::f32) ? MVT::i32 : MVT::i16;
7928 for (unsigned i = 0; i < NumElts; ++i)
7929 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, IVT,
7930 Op.getOperand(i)));
7931 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), IVT, NumElts);
7932 SDValue Val = DAG.getBuildVector(VecVT, dl, Ops);
7933 Val = LowerBUILD_VECTOR(Val, DAG, ST);
7934 if (Val.getNode())
7935 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7936 }
7937 if (usesOnlyOneValue) {
7938 SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl);
7939 if (isConstant && Val.getNode())
7940 return DAG.getNode(ARMISD::VDUP, dl, VT, Val);
7941 }
7942 }
7943
7944 // If all elements are constants and the case above didn't get hit, fall back
7945 // to the default expansion, which will generate a load from the constant
7946 // pool.
7947 if (isConstant)
7948 return SDValue();
7949
7950 // Reconstruct the BUILDVECTOR to one of the legal shuffles (such as vext and
7951 // vmovn). Empirical tests suggest this is rarely worth it for vectors of
7952 // length <= 2.
7953 if (NumElts >= 4)
7954 if (SDValue shuffle = ReconstructShuffle(Op, DAG))
7955 return shuffle;
7956
7957 // Attempt to turn a buildvector of scalar fptrunc's or fpext's back into
7958 // VCVT's
7959 if (SDValue VCVT = LowerBuildVectorOfFPTrunc(Op, DAG, Subtarget))
7960 return VCVT;
7961 if (SDValue VCVT = LowerBuildVectorOfFPExt(Op, DAG, Subtarget))
7962 return VCVT;
7963
7964 if (ST->hasNEON() && VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
7965 // If we haven't found an efficient lowering, try splitting a 128-bit vector
7966 // into two 64-bit vectors; we might discover a better way to lower it.
7967 SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
7968 EVT ExtVT = VT.getVectorElementType();
7969 EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
7970 SDValue Lower = DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[0], NumElts / 2));
7971 if (Lower.getOpcode() == ISD::BUILD_VECTOR)
7972 Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
7973 SDValue Upper =
7974 DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[NumElts / 2], NumElts / 2));
7975 if (Upper.getOpcode() == ISD::BUILD_VECTOR)
7976 Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
7977 if (Lower && Upper)
7978 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
7979 }
7980
7981 // Vectors with 32- or 64-bit elements can be built by directly assigning
7982 // the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
7983 // will be legalized.
7984 if (EltSize >= 32) {
7985 // Do the expansion with floating-point types, since that is what the VFP
7986 // registers are defined to use, and since i64 is not legal.
7987 EVT EltVT = EVT::getFloatingPointVT(EltSize);
7988 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
7990 for (unsigned i = 0; i < NumElts; ++i)
7991 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, EltVT, Op.getOperand(i)));
7992 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
7993 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7994 }
7995
7996 // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
7997 // know the default expansion would otherwise fall back on something even
7998 // worse. For a vector with one or two non-undef values, that's
7999 // scalar_to_vector for the elements followed by a shuffle (provided the
8000 // shuffle is valid for the target) and materialization element by element
8001 // on the stack followed by a load for everything else.
8002 if ((!isConstant && !usesOnlyOneValue) ||
8003 (VT == MVT::v8f16 && !ST->hasFullFP16())) {
8004 SDValue Vec = DAG.getUNDEF(VT);
8005 for (unsigned i = 0 ; i < NumElts; ++i) {
8006 SDValue V = Op.getOperand(i);
8007 if (V.isUndef())
8008 continue;
8009 SDValue LaneIdx = DAG.getConstant(i, dl, MVT::i32);
8010 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
8011 }
8012 return Vec;
8013 }
8014
8015 return SDValue();
8016}
8017
8018// Gather data to see if the operation can be modelled as a
8019// shuffle in combination with VEXTs.
8020SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
8021 SelectionDAG &DAG) const {
8022 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
8023 SDLoc dl(Op);
8024 EVT VT = Op.getValueType();
8025 unsigned NumElts = VT.getVectorNumElements();
8026
8027 struct ShuffleSourceInfo {
8028 SDValue Vec;
8029 unsigned MinElt = std::numeric_limits<unsigned>::max();
8030 unsigned MaxElt = 0;
8031
8032 // We may insert some combination of BITCASTs and VEXT nodes to force Vec to
8033 // be compatible with the shuffle we intend to construct. As a result
8034 // ShuffleVec will be some sliding window into the original Vec.
8035 SDValue ShuffleVec;
8036
8037 // Code should guarantee that element i in Vec starts at element "WindowBase
8038 // + i * WindowScale in ShuffleVec".
8039 int WindowBase = 0;
8040 int WindowScale = 1;
8041
8042 ShuffleSourceInfo(SDValue Vec) : Vec(Vec), ShuffleVec(Vec) {}
8043
8044 bool operator ==(SDValue OtherVec) { return Vec == OtherVec; }
8045 };
8046
8047 // First gather all vectors used as an immediate source for this BUILD_VECTOR
8048 // node.
8050 for (unsigned i = 0; i < NumElts; ++i) {
8051 SDValue V = Op.getOperand(i);
8052 if (V.isUndef())
8053 continue;
8054 else if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
8055 // A shuffle can only come from building a vector from various
8056 // elements of other vectors.
8057 return SDValue();
8058 } else if (!isa<ConstantSDNode>(V.getOperand(1))) {
8059 // Furthermore, shuffles require a constant mask, whereas extractelts
8060 // accept variable indices.
8061 return SDValue();
8062 }
8063
8064 // Add this element source to the list if it's not already there.
8065 SDValue SourceVec = V.getOperand(0);
8066 auto Source = llvm::find(Sources, SourceVec);
8067 if (Source == Sources.end())
8068 Source = Sources.insert(Sources.end(), ShuffleSourceInfo(SourceVec));
8069
8070 // Update the minimum and maximum lane number seen.
8071 unsigned EltNo = V.getConstantOperandVal(1);
8072 Source->MinElt = std::min(Source->MinElt, EltNo);
8073 Source->MaxElt = std::max(Source->MaxElt, EltNo);
8074 }
8075
8076 // Currently only do something sane when at most two source vectors
8077 // are involved.
8078 if (Sources.size() > 2)
8079 return SDValue();
8080
8081 // Find out the smallest element size among result and two sources, and use
8082 // it as element size to build the shuffle_vector.
8083 EVT SmallestEltTy = VT.getVectorElementType();
8084 for (auto &Source : Sources) {
8085 EVT SrcEltTy = Source.Vec.getValueType().getVectorElementType();
8086 if (SrcEltTy.bitsLT(SmallestEltTy))
8087 SmallestEltTy = SrcEltTy;
8088 }
8089 unsigned ResMultiplier =
8090 VT.getScalarSizeInBits() / SmallestEltTy.getSizeInBits();
8091 NumElts = VT.getSizeInBits() / SmallestEltTy.getSizeInBits();
8092 EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
8093
8094 // If the source vector is too wide or too narrow, we may nevertheless be able
8095 // to construct a compatible shuffle either by concatenating it with UNDEF or
8096 // extracting a suitable range of elements.
8097 for (auto &Src : Sources) {
8098 EVT SrcVT = Src.ShuffleVec.getValueType();
8099
8100 uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
8101 uint64_t VTSize = VT.getFixedSizeInBits();
8102 if (SrcVTSize == VTSize)
8103 continue;
8104
8105 // This stage of the search produces a source with the same element type as
8106 // the original, but with a total width matching the BUILD_VECTOR output.
8107 EVT EltVT = SrcVT.getVectorElementType();
8108 unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
8109 EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
8110
8111 if (SrcVTSize < VTSize) {
8112 if (2 * SrcVTSize != VTSize)
8113 return SDValue();
8114 // We can pad out the smaller vector for free, so if it's part of a
8115 // shuffle...
8116 Src.ShuffleVec =
8117 DAG.getNode(ISD::CONCAT_VECTORS, dl, DestVT, Src.ShuffleVec,
8118 DAG.getUNDEF(Src.ShuffleVec.getValueType()));
8119 continue;
8120 }
8121
8122 if (SrcVTSize != 2 * VTSize)
8123 return SDValue();
8124
8125 if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
8126 // Span too large for a VEXT to cope
8127 return SDValue();
8128 }
8129
8130 if (Src.MinElt >= NumSrcElts) {
8131 // The extraction can just take the second half
8132 Src.ShuffleVec =
8133 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8134 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8135 Src.WindowBase = -NumSrcElts;
8136 } else if (Src.MaxElt < NumSrcElts) {
8137 // The extraction can just take the first half
8138 Src.ShuffleVec =
8139 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8140 DAG.getConstant(0, dl, MVT::i32));
8141 } else {
8142 // An actual VEXT is needed
8143 SDValue VEXTSrc1 =
8144 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8145 DAG.getConstant(0, dl, MVT::i32));
8146 SDValue VEXTSrc2 =
8147 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8148 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8149
8150 Src.ShuffleVec = DAG.getNode(ARMISD::VEXT, dl, DestVT, VEXTSrc1,
8151 VEXTSrc2,
8152 DAG.getConstant(Src.MinElt, dl, MVT::i32));
8153 Src.WindowBase = -Src.MinElt;
8154 }
8155 }
8156
8157 // Another possible incompatibility occurs from the vector element types. We
8158 // can fix this by bitcasting the source vectors to the same type we intend
8159 // for the shuffle.
8160 for (auto &Src : Sources) {
8161 EVT SrcEltTy = Src.ShuffleVec.getValueType().getVectorElementType();
8162 if (SrcEltTy == SmallestEltTy)
8163 continue;
8164 assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
8165 Src.ShuffleVec = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, ShuffleVT, Src.ShuffleVec);
8166 Src.WindowScale = SrcEltTy.getSizeInBits() / SmallestEltTy.getSizeInBits();
8167 Src.WindowBase *= Src.WindowScale;
8168 }
8169
8170 // Final check before we try to actually produce a shuffle.
8171 LLVM_DEBUG({
8172 for (auto Src : Sources)
8173 assert(Src.ShuffleVec.getValueType() == ShuffleVT);
8174 });
8175
8176 // The stars all align, our next step is to produce the mask for the shuffle.
8177 SmallVector<int, 8> Mask(ShuffleVT.getVectorNumElements(), -1);
8178 int BitsPerShuffleLane = ShuffleVT.getScalarSizeInBits();
8179 for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
8180 SDValue Entry = Op.getOperand(i);
8181 if (Entry.isUndef())
8182 continue;
8183
8184 auto Src = llvm::find(Sources, Entry.getOperand(0));
8185 int EltNo = cast<ConstantSDNode>(Entry.getOperand(1))->getSExtValue();
8186
8187 // EXTRACT_VECTOR_ELT performs an implicit any_ext; BUILD_VECTOR an implicit
8188 // trunc. So only std::min(SrcBits, DestBits) actually get defined in this
8189 // segment.
8190 EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
8191 int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
8192 VT.getScalarSizeInBits());
8193 int LanesDefined = BitsDefined / BitsPerShuffleLane;
8194
8195 // This source is expected to fill ResMultiplier lanes of the final shuffle,
8196 // starting at the appropriate offset.
8197 int *LaneMask = &Mask[i * ResMultiplier];
8198
8199 int ExtractBase = EltNo * Src->WindowScale + Src->WindowBase;
8200 ExtractBase += NumElts * (Src - Sources.begin());
8201 for (int j = 0; j < LanesDefined; ++j)
8202 LaneMask[j] = ExtractBase + j;
8203 }
8204
8205
8206 // We can't handle more than two sources. This should have already
8207 // been checked before this point.
8208 assert(Sources.size() <= 2 && "Too many sources!");
8209
8210 SDValue ShuffleOps[] = { DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT) };
8211 for (unsigned i = 0; i < Sources.size(); ++i)
8212 ShuffleOps[i] = Sources[i].ShuffleVec;
8213
8214 SDValue Shuffle = buildLegalVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
8215 ShuffleOps[1], Mask, DAG);
8216 if (!Shuffle)
8217 return SDValue();
8218 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuffle);
8219}
8220
8222 OP_COPY = 0, // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
8231 OP_VUZPL, // VUZP, left result
8232 OP_VUZPR, // VUZP, right result
8233 OP_VZIPL, // VZIP, left result
8234 OP_VZIPR, // VZIP, right result
8235 OP_VTRNL, // VTRN, left result
8236 OP_VTRNR // VTRN, right result
8237};
8238
8239static bool isLegalMVEShuffleOp(unsigned PFEntry) {
8240 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8241 switch (OpNum) {
8242 case OP_COPY:
8243 case OP_VREV:
8244 case OP_VDUP0:
8245 case OP_VDUP1:
8246 case OP_VDUP2:
8247 case OP_VDUP3:
8248 return true;
8249 }
8250 return false;
8251}
8252
8253/// isShuffleMaskLegal - Targets can use this to indicate that they only
8254/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
8255/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
8256/// are assumed to be legal.
8258 if (VT.getVectorNumElements() == 4 &&
8259 (VT.is128BitVector() || VT.is64BitVector())) {
8260 unsigned PFIndexes[4];
8261 for (unsigned i = 0; i != 4; ++i) {
8262 if (M[i] < 0)
8263 PFIndexes[i] = 8;
8264 else
8265 PFIndexes[i] = M[i];
8266 }
8267
8268 // Compute the index in the perfect shuffle table.
8269 unsigned PFTableIndex =
8270 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8271 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8272 unsigned Cost = (PFEntry >> 30);
8273
8274 if (Cost <= 4 && (Subtarget->hasNEON() || isLegalMVEShuffleOp(PFEntry)))
8275 return true;
8276 }
8277
8278 bool ReverseVEXT, isV_UNDEF;
8279 unsigned Imm, WhichResult;
8280
8281 unsigned EltSize = VT.getScalarSizeInBits();
8282 if (EltSize >= 32 ||
8284 ShuffleVectorInst::isIdentityMask(M, M.size()) ||
8285 isVREVMask(M, VT, 64) ||
8286 isVREVMask(M, VT, 32) ||
8287 isVREVMask(M, VT, 16))
8288 return true;
8289 else if (Subtarget->hasNEON() &&
8290 (isVEXTMask(M, VT, ReverseVEXT, Imm) ||
8291 isVTBLMask(M, VT) ||
8292 isNEONTwoResultShuffleMask(M, VT, WhichResult, isV_UNDEF)))
8293 return true;
8294 else if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8295 isReverseMask(M, VT))
8296 return true;
8297 else if (Subtarget->hasMVEIntegerOps() &&
8298 (isVMOVNMask(M, VT, true, false) ||
8299 isVMOVNMask(M, VT, false, false) || isVMOVNMask(M, VT, true, true)))
8300 return true;
8301 else if (Subtarget->hasMVEIntegerOps() &&
8302 (isTruncMask(M, VT, false, false) ||
8303 isTruncMask(M, VT, false, true) ||
8304 isTruncMask(M, VT, true, false) || isTruncMask(M, VT, true, true)))
8305 return true;
8306 else
8307 return false;
8308}
8309
8310/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
8311/// the specified operations to build the shuffle.
8313 SDValue RHS, SelectionDAG &DAG,
8314 const SDLoc &dl) {
8315 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8316 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8317 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8318
8319 if (OpNum == OP_COPY) {
8320 if (LHSID == (1*9+2)*9+3) return LHS;
8321 assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
8322 return RHS;
8323 }
8324
8325 SDValue OpLHS, OpRHS;
8326 OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
8327 OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);
8328 EVT VT = OpLHS.getValueType();
8329
8330 switch (OpNum) {
8331 default: llvm_unreachable("Unknown shuffle opcode!");
8332 case OP_VREV:
8333 // VREV divides the vector in half and swaps within the half.
8334 if (VT.getScalarSizeInBits() == 32)
8335 return DAG.getNode(ARMISD::VREV64, dl, VT, OpLHS);
8336 // vrev <4 x i16> -> VREV32
8337 if (VT.getScalarSizeInBits() == 16)
8338 return DAG.getNode(ARMISD::VREV32, dl, VT, OpLHS);
8339 // vrev <4 x i8> -> VREV16
8340 assert(VT.getScalarSizeInBits() == 8);
8341 return DAG.getNode(ARMISD::VREV16, dl, VT, OpLHS);
8342 case OP_VDUP0:
8343 case OP_VDUP1:
8344 case OP_VDUP2:
8345 case OP_VDUP3:
8346 return DAG.getNode(ARMISD::VDUPLANE, dl, VT,
8347 OpLHS, DAG.getConstant(OpNum-OP_VDUP0, dl, MVT::i32));
8348 case OP_VEXT1:
8349 case OP_VEXT2:
8350 case OP_VEXT3:
8351 return DAG.getNode(ARMISD::VEXT, dl, VT,
8352 OpLHS, OpRHS,
8353 DAG.getConstant(OpNum - OP_VEXT1 + 1, dl, MVT::i32));
8354 case OP_VUZPL:
8355 case OP_VUZPR:
8356 return DAG.getNode(ARMISD::VUZP, dl, DAG.getVTList(VT, VT),
8357 OpLHS, OpRHS).getValue(OpNum-OP_VUZPL);
8358 case OP_VZIPL:
8359 case OP_VZIPR:
8360 return DAG.getNode(ARMISD::VZIP, dl, DAG.getVTList(VT, VT),
8361 OpLHS, OpRHS).getValue(OpNum-OP_VZIPL);
8362 case OP_VTRNL:
8363 case OP_VTRNR:
8364 return DAG.getNode(ARMISD::VTRN, dl, DAG.getVTList(VT, VT),
8365 OpLHS, OpRHS).getValue(OpNum-OP_VTRNL);
8366 }
8367}
8368
8370 ArrayRef<int> ShuffleMask,
8371 SelectionDAG &DAG) {
8372 // Check to see if we can use the VTBL instruction.
8373 SDValue V1 = Op.getOperand(0);
8374 SDValue V2 = Op.getOperand(1);
8375 SDLoc DL(Op);
8376
8377 SmallVector<SDValue, 8> VTBLMask;
8378 for (int I : ShuffleMask)
8379 VTBLMask.push_back(DAG.getSignedConstant(I, DL, MVT::i32));
8380
8381 if (V2.getNode()->isUndef())
8382 return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1,
8383 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8384
8385 return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2,
8386 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8387}
8388
8390 SDLoc DL(Op);
8391 EVT VT = Op.getValueType();
8392
8393 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8394 "Expect an v8i16/v16i8 type");
8395 SDValue OpLHS = DAG.getNode(ARMISD::VREV64, DL, VT, Op.getOperand(0));
8396 // For a v16i8 type: After the VREV, we have got <7, ..., 0, 15, ..., 8>. Now,
8397 // extract the first 8 bytes into the top double word and the last 8 bytes
8398 // into the bottom double word, through a new vector shuffle that will be
8399 // turned into a VEXT on Neon, or a couple of VMOVDs on MVE.
8400 std::vector<int> NewMask;
8401 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8402 NewMask.push_back(VT.getVectorNumElements() / 2 + i);
8403 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8404 NewMask.push_back(i);
8405 return DAG.getVectorShuffle(VT, DL, OpLHS, OpLHS, NewMask);
8406}
8407
8409 switch (VT.getSimpleVT().SimpleTy) {
8410 case MVT::v2i1:
8411 return MVT::v2f64;
8412 case MVT::v4i1:
8413 return MVT::v4i32;
8414 case MVT::v8i1:
8415 return MVT::v8i16;
8416 case MVT::v16i1:
8417 return MVT::v16i8;
8418 default:
8419 llvm_unreachable("Unexpected vector predicate type");
8420 }
8421}
8422
8424 SelectionDAG &DAG) {
8425 // Converting from boolean predicates to integers involves creating a vector
8426 // of all ones or all zeroes and selecting the lanes based upon the real
8427 // predicate.
8429 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff), dl, MVT::i32);
8430 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllOnes);
8431
8432 SDValue AllZeroes =
8433 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0x0), dl, MVT::i32);
8434 AllZeroes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllZeroes);
8435
8436 // Get full vector type from predicate type
8438
8439 SDValue RecastV1;
8440 // If the real predicate is an v8i1 or v4i1 (not v16i1) then we need to recast
8441 // this to a v16i1. This cannot be done with an ordinary bitcast because the
8442 // sizes are not the same. We have to use a MVE specific PREDICATE_CAST node,
8443 // since we know in hardware the sizes are really the same.
8444 if (VT != MVT::v16i1)
8445 RecastV1 = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Pred);
8446 else
8447 RecastV1 = Pred;
8448
8449 // Select either all ones or zeroes depending upon the real predicate bits.
8450 SDValue PredAsVector =
8451 DAG.getNode(ISD::VSELECT, dl, MVT::v16i8, RecastV1, AllOnes, AllZeroes);
8452
8453 // Recast our new predicate-as-integer v16i8 vector into something
8454 // appropriate for the shuffle, i.e. v4i32 for a real v4i1 predicate.
8455 return DAG.getNode(ISD::BITCAST, dl, NewVT, PredAsVector);
8456}
8457
8459 const ARMSubtarget *ST) {
8460 EVT VT = Op.getValueType();
8462 ArrayRef<int> ShuffleMask = SVN->getMask();
8463
8464 assert(ST->hasMVEIntegerOps() &&
8465 "No support for vector shuffle of boolean predicates");
8466
8467 SDValue V1 = Op.getOperand(0);
8468 SDValue V2 = Op.getOperand(1);
8469 SDLoc dl(Op);
8470 if (isReverseMask(ShuffleMask, VT)) {
8471 SDValue cast = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, V1);
8472 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, cast);
8473 SDValue srl = DAG.getNode(ISD::SRL, dl, MVT::i32, rbit,
8474 DAG.getConstant(16, dl, MVT::i32));
8475 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, srl);
8476 }
8477
8478 // Until we can come up with optimised cases for every single vector
8479 // shuffle in existence we have chosen the least painful strategy. This is
8480 // to essentially promote the boolean predicate to a 8-bit integer, where
8481 // each predicate represents a byte. Then we fall back on a normal integer
8482 // vector shuffle and convert the result back into a predicate vector. In
8483 // many cases the generated code might be even better than scalar code
8484 // operating on bits. Just imagine trying to shuffle 8 arbitrary 2-bit
8485 // fields in a register into 8 other arbitrary 2-bit fields!
8486 SDValue PredAsVector1 = PromoteMVEPredVector(dl, V1, VT, DAG);
8487 EVT NewVT = PredAsVector1.getValueType();
8488 SDValue PredAsVector2 = V2.isUndef() ? DAG.getUNDEF(NewVT)
8489 : PromoteMVEPredVector(dl, V2, VT, DAG);
8490 assert(PredAsVector2.getValueType() == NewVT &&
8491 "Expected identical vector type in expanded i1 shuffle!");
8492
8493 // Do the shuffle!
8494 SDValue Shuffled = DAG.getVectorShuffle(NewVT, dl, PredAsVector1,
8495 PredAsVector2, ShuffleMask);
8496
8497 // Now return the result of comparing the shuffled vector with zero,
8498 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1. For a v2i1
8499 // we convert to a v4i1 compare to fill in the two halves of the i64 as i32s.
8500 if (VT == MVT::v2i1) {
8501 SDValue BC = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Shuffled);
8502 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, BC,
8503 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8504 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8505 }
8506 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Shuffled,
8507 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8508}
8509
8511 ArrayRef<int> ShuffleMask,
8512 SelectionDAG &DAG) {
8513 // Attempt to lower the vector shuffle using as many whole register movs as
8514 // possible. This is useful for types smaller than 32bits, which would
8515 // often otherwise become a series for grp movs.
8516 SDLoc dl(Op);
8517 EVT VT = Op.getValueType();
8518 if (VT.getScalarSizeInBits() >= 32)
8519 return SDValue();
8520
8521 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8522 "Unexpected vector type");
8523 int NumElts = VT.getVectorNumElements();
8524 int QuarterSize = NumElts / 4;
8525 // The four final parts of the vector, as i32's
8526 SDValue Parts[4];
8527
8528 // Look for full lane vmovs like <0,1,2,3> or <u,5,6,7> etc, (but not
8529 // <u,u,u,u>), returning the vmov lane index
8530 auto getMovIdx = [](ArrayRef<int> ShuffleMask, int Start, int Length) {
8531 // Detect which mov lane this would be from the first non-undef element.
8532 int MovIdx = -1;
8533 for (int i = 0; i < Length; i++) {
8534 if (ShuffleMask[Start + i] >= 0) {
8535 if (ShuffleMask[Start + i] % Length != i)
8536 return -1;
8537 MovIdx = ShuffleMask[Start + i] / Length;
8538 break;
8539 }
8540 }
8541 // If all items are undef, leave this for other combines
8542 if (MovIdx == -1)
8543 return -1;
8544 // Check the remaining values are the correct part of the same mov
8545 for (int i = 1; i < Length; i++) {
8546 if (ShuffleMask[Start + i] >= 0 &&
8547 (ShuffleMask[Start + i] / Length != MovIdx ||
8548 ShuffleMask[Start + i] % Length != i))
8549 return -1;
8550 }
8551 return MovIdx;
8552 };
8553
8554 for (int Part = 0; Part < 4; ++Part) {
8555 // Does this part look like a mov
8556 int Elt = getMovIdx(ShuffleMask, Part * QuarterSize, QuarterSize);
8557 if (Elt != -1) {
8558 SDValue Input = Op->getOperand(0);
8559 if (Elt >= 4) {
8560 Input = Op->getOperand(1);
8561 Elt -= 4;
8562 }
8563 SDValue BitCast = DAG.getBitcast(MVT::v4f32, Input);
8564 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, BitCast,
8565 DAG.getConstant(Elt, dl, MVT::i32));
8566 }
8567 }
8568
8569 // Nothing interesting found, just return
8570 if (!Parts[0] && !Parts[1] && !Parts[2] && !Parts[3])
8571 return SDValue();
8572
8573 // The other parts need to be built with the old shuffle vector, cast to a
8574 // v4i32 and extract_vector_elts
8575 if (!Parts[0] || !Parts[1] || !Parts[2] || !Parts[3]) {
8576 SmallVector<int, 16> NewShuffleMask;
8577 for (int Part = 0; Part < 4; ++Part)
8578 for (int i = 0; i < QuarterSize; i++)
8579 NewShuffleMask.push_back(
8580 Parts[Part] ? -1 : ShuffleMask[Part * QuarterSize + i]);
8581 SDValue NewShuffle = DAG.getVectorShuffle(
8582 VT, dl, Op->getOperand(0), Op->getOperand(1), NewShuffleMask);
8583 SDValue BitCast = DAG.getBitcast(MVT::v4f32, NewShuffle);
8584
8585 for (int Part = 0; Part < 4; ++Part)
8586 if (!Parts[Part])
8587 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32,
8588 BitCast, DAG.getConstant(Part, dl, MVT::i32));
8589 }
8590 // Build a vector out of the various parts and bitcast it back to the original
8591 // type.
8592 SDValue NewVec = DAG.getNode(ARMISD::BUILD_VECTOR, dl, MVT::v4f32, Parts);
8593 return DAG.getBitcast(VT, NewVec);
8594}
8595
8597 ArrayRef<int> ShuffleMask,
8598 SelectionDAG &DAG) {
8599 SDValue V1 = Op.getOperand(0);
8600 SDValue V2 = Op.getOperand(1);
8601 EVT VT = Op.getValueType();
8602 unsigned NumElts = VT.getVectorNumElements();
8603
8604 // An One-Off Identity mask is one that is mostly an identity mask from as
8605 // single source but contains a single element out-of-place, either from a
8606 // different vector or from another position in the same vector. As opposed to
8607 // lowering this via a ARMISD::BUILD_VECTOR we can generate an extract/insert
8608 // pair directly.
8609 auto isOneOffIdentityMask = [](ArrayRef<int> Mask, EVT VT, int BaseOffset,
8610 int &OffElement) {
8611 OffElement = -1;
8612 int NonUndef = 0;
8613 for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
8614 if (Mask[i] == -1)
8615 continue;
8616 NonUndef++;
8617 if (Mask[i] != i + BaseOffset) {
8618 if (OffElement == -1)
8619 OffElement = i;
8620 else
8621 return false;
8622 }
8623 }
8624 return NonUndef > 2 && OffElement != -1;
8625 };
8626 int OffElement;
8627 SDValue VInput;
8628 if (isOneOffIdentityMask(ShuffleMask, VT, 0, OffElement))
8629 VInput = V1;
8630 else if (isOneOffIdentityMask(ShuffleMask, VT, NumElts, OffElement))
8631 VInput = V2;
8632 else
8633 return SDValue();
8634
8635 SDLoc dl(Op);
8636 EVT SVT = VT.getScalarType() == MVT::i8 || VT.getScalarType() == MVT::i16
8637 ? MVT::i32
8638 : VT.getScalarType();
8639 SDValue Elt = DAG.getNode(
8640 ISD::EXTRACT_VECTOR_ELT, dl, SVT,
8641 ShuffleMask[OffElement] < (int)NumElts ? V1 : V2,
8642 DAG.getVectorIdxConstant(ShuffleMask[OffElement] % NumElts, dl));
8643 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, VInput, Elt,
8644 DAG.getVectorIdxConstant(OffElement % NumElts, dl));
8645}
8646
8648 const ARMSubtarget *ST) {
8649 SDValue V1 = Op.getOperand(0);
8650 SDValue V2 = Op.getOperand(1);
8651 SDLoc dl(Op);
8652 EVT VT = Op.getValueType();
8654 unsigned EltSize = VT.getScalarSizeInBits();
8655
8656 if (ST->hasMVEIntegerOps() && EltSize == 1)
8657 return LowerVECTOR_SHUFFLE_i1(Op, DAG, ST);
8658
8659 // Convert shuffles that are directly supported on NEON to target-specific
8660 // DAG nodes, instead of keeping them as shuffles and matching them again
8661 // during code selection. This is more efficient and avoids the possibility
8662 // of inconsistencies between legalization and selection.
8663 // FIXME: floating-point vectors should be canonicalized to integer vectors
8664 // of the same time so that they get CSEd properly.
8665 ArrayRef<int> ShuffleMask = SVN->getMask();
8666
8667 if (EltSize <= 32) {
8668 if (SVN->isSplat()) {
8669 int Lane = SVN->getSplatIndex();
8670 // If this is undef splat, generate it via "just" vdup, if possible.
8671 if (Lane == -1) Lane = 0;
8672
8673 // Test if V1 is a SCALAR_TO_VECTOR.
8674 if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR) {
8675 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8676 }
8677 // Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
8678 // (and probably will turn into a SCALAR_TO_VECTOR once legalization
8679 // reaches it).
8680 if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
8681 !isa<ConstantSDNode>(V1.getOperand(0))) {
8682 bool IsScalarToVector = true;
8683 for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
8684 if (!V1.getOperand(i).isUndef()) {
8685 IsScalarToVector = false;
8686 break;
8687 }
8688 if (IsScalarToVector)
8689 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8690 }
8691 return DAG.getNode(ARMISD::VDUPLANE, dl, VT, V1,
8692 DAG.getConstant(Lane, dl, MVT::i32));
8693 }
8694
8695 bool ReverseVEXT = false;
8696 unsigned Imm = 0;
8697 if (ST->hasNEON() && isVEXTMask(ShuffleMask, VT, ReverseVEXT, Imm)) {
8698 if (ReverseVEXT)
8699 std::swap(V1, V2);
8700 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V2,
8701 DAG.getConstant(Imm, dl, MVT::i32));
8702 }
8703
8704 if (isVREVMask(ShuffleMask, VT, 64))
8705 return DAG.getNode(ARMISD::VREV64, dl, VT, V1);
8706 if (isVREVMask(ShuffleMask, VT, 32))
8707 return DAG.getNode(ARMISD::VREV32, dl, VT, V1);
8708 if (isVREVMask(ShuffleMask, VT, 16))
8709 return DAG.getNode(ARMISD::VREV16, dl, VT, V1);
8710
8711 if (ST->hasNEON() && V2->isUndef() && isSingletonVEXTMask(ShuffleMask, VT, Imm)) {
8712 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V1,
8713 DAG.getConstant(Imm, dl, MVT::i32));
8714 }
8715
8716 // Check for Neon shuffles that modify both input vectors in place.
8717 // If both results are used, i.e., if there are two shuffles with the same
8718 // source operands and with masks corresponding to both results of one of
8719 // these operations, DAG memoization will ensure that a single node is
8720 // used for both shuffles.
8721 unsigned WhichResult = 0;
8722 bool isV_UNDEF = false;
8723 if (ST->hasNEON()) {
8724 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8725 ShuffleMask, VT, WhichResult, isV_UNDEF)) {
8726 if (isV_UNDEF)
8727 V2 = V1;
8728 return DAG.getNode(ShuffleOpc, dl, DAG.getVTList(VT, VT), V1, V2)
8729 .getValue(WhichResult);
8730 }
8731 }
8732 if (ST->hasMVEIntegerOps()) {
8733 if (isVMOVNMask(ShuffleMask, VT, false, false))
8734 return DAG.getNode(ARMISD::VMOVN, dl, VT, V2, V1,
8735 DAG.getConstant(0, dl, MVT::i32));
8736 if (isVMOVNMask(ShuffleMask, VT, true, false))
8737 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V2,
8738 DAG.getConstant(1, dl, MVT::i32));
8739 if (isVMOVNMask(ShuffleMask, VT, true, true))
8740 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V1,
8741 DAG.getConstant(1, dl, MVT::i32));
8742 }
8743
8744 // Also check for these shuffles through CONCAT_VECTORS: we canonicalize
8745 // shuffles that produce a result larger than their operands with:
8746 // shuffle(concat(v1, undef), concat(v2, undef))
8747 // ->
8748 // shuffle(concat(v1, v2), undef)
8749 // because we can access quad vectors (see PerformVECTOR_SHUFFLECombine).
8750 //
8751 // This is useful in the general case, but there are special cases where
8752 // native shuffles produce larger results: the two-result ops.
8753 //
8754 // Look through the concat when lowering them:
8755 // shuffle(concat(v1, v2), undef)
8756 // ->
8757 // concat(VZIP(v1, v2):0, :1)
8758 //
8759 if (ST->hasNEON() && V1->getOpcode() == ISD::CONCAT_VECTORS && V2->isUndef()) {
8760 SDValue SubV1 = V1->getOperand(0);
8761 SDValue SubV2 = V1->getOperand(1);
8762 EVT SubVT = SubV1.getValueType();
8763
8764 // We expect these to have been canonicalized to -1.
8765 assert(llvm::all_of(ShuffleMask, [&](int i) {
8766 return i < (int)VT.getVectorNumElements();
8767 }) && "Unexpected shuffle index into UNDEF operand!");
8768
8769 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8770 ShuffleMask, SubVT, WhichResult, isV_UNDEF)) {
8771 if (isV_UNDEF)
8772 SubV2 = SubV1;
8773 assert((WhichResult == 0) &&
8774 "In-place shuffle of concat can only have one result!");
8775 SDValue Res = DAG.getNode(ShuffleOpc, dl, DAG.getVTList(SubVT, SubVT),
8776 SubV1, SubV2);
8777 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Res.getValue(0),
8778 Res.getValue(1));
8779 }
8780 }
8781 }
8782
8783 if (ST->hasMVEIntegerOps() && EltSize <= 32 &&
8784 (ST->hasFullFP16() || VT != MVT::v8f16)) {
8785 if (SDValue V = LowerVECTOR_SHUFFLEUsingOneOff(Op, ShuffleMask, DAG))
8786 return V;
8787
8788 for (bool Top : {false, true}) {
8789 for (bool SingleSource : {false, true}) {
8790 if (isTruncMask(ShuffleMask, VT, Top, SingleSource)) {
8791 MVT FromSVT = MVT::getIntegerVT(EltSize * 2);
8792 MVT FromVT = MVT::getVectorVT(FromSVT, ShuffleMask.size() / 2);
8793 SDValue Lo = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT, V1);
8794 SDValue Hi = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT,
8795 SingleSource ? V1 : V2);
8796 if (Top) {
8797 SDValue Amt = DAG.getConstant(EltSize, dl, FromVT);
8798 Lo = DAG.getNode(ISD::SRL, dl, FromVT, Lo, Amt);
8799 Hi = DAG.getNode(ISD::SRL, dl, FromVT, Hi, Amt);
8800 }
8801 return DAG.getNode(ARMISD::MVETRUNC, dl, VT, Lo, Hi);
8802 }
8803 }
8804 }
8805 }
8806
8807 // If the shuffle is not directly supported and it has 4 elements, use
8808 // the PerfectShuffle-generated table to synthesize it from other shuffles.
8809 unsigned NumElts = VT.getVectorNumElements();
8810 if (NumElts == 4) {
8811 unsigned PFIndexes[4];
8812 for (unsigned i = 0; i != 4; ++i) {
8813 if (ShuffleMask[i] < 0)
8814 PFIndexes[i] = 8;
8815 else
8816 PFIndexes[i] = ShuffleMask[i];
8817 }
8818
8819 // Compute the index in the perfect shuffle table.
8820 unsigned PFTableIndex =
8821 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8822 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8823 unsigned Cost = (PFEntry >> 30);
8824
8825 if (Cost <= 4) {
8826 if (ST->hasNEON())
8827 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8828 else if (isLegalMVEShuffleOp(PFEntry)) {
8829 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8830 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8831 unsigned PFEntryLHS = PerfectShuffleTable[LHSID];
8832 unsigned PFEntryRHS = PerfectShuffleTable[RHSID];
8833 if (isLegalMVEShuffleOp(PFEntryLHS) && isLegalMVEShuffleOp(PFEntryRHS))
8834 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8835 }
8836 }
8837 }
8838
8839 // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
8840 if (EltSize >= 32) {
8841 // Do the expansion with floating-point types, since that is what the VFP
8842 // registers are defined to use, and since i64 is not legal.
8843 EVT EltVT = EVT::getFloatingPointVT(EltSize);
8844 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
8845 V1 = DAG.getNode(ISD::BITCAST, dl, VecVT, V1);
8846 V2 = DAG.getNode(ISD::BITCAST, dl, VecVT, V2);
8848 for (unsigned i = 0; i < NumElts; ++i) {
8849 if (ShuffleMask[i] < 0)
8850 Ops.push_back(DAG.getUNDEF(EltVT));
8851 else
8852 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
8853 ShuffleMask[i] < (int)NumElts ? V1 : V2,
8854 DAG.getConstant(ShuffleMask[i] & (NumElts-1),
8855 dl, MVT::i32)));
8856 }
8857 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
8858 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
8859 }
8860
8861 if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8862 isReverseMask(ShuffleMask, VT))
8863 return LowerReverse_VECTOR_SHUFFLE(Op, DAG);
8864
8865 if (ST->hasNEON() && VT == MVT::v8i8)
8866 if (SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG))
8867 return NewOp;
8868
8869 if (ST->hasMVEIntegerOps())
8870 if (SDValue NewOp = LowerVECTOR_SHUFFLEUsingMovs(Op, ShuffleMask, DAG))
8871 return NewOp;
8872
8873 // Lower v8f16 via v8i16 to avoid invalid f16 nodes.
8874 if (VT == MVT::v8f16 && !ST->hasFullFP16()) {
8875 SDValue BC0 =
8876 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(0));
8877 SDValue BC1 =
8878 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(1));
8879 SDValue Shuf = DAG.getVectorShuffle(MVT::v8i16, dl, BC0, BC1, ShuffleMask);
8880 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuf);
8881 }
8882
8883 return SDValue();
8884}
8885
8887 const ARMSubtarget *ST) {
8888 EVT VecVT = Op.getOperand(0).getValueType();
8889 SDLoc dl(Op);
8890
8891 assert(ST->hasMVEIntegerOps() &&
8892 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8893
8894 SDValue Conv =
8895 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8896 unsigned Lane = Op.getConstantOperandVal(2);
8897 unsigned LaneWidth =
8899 unsigned Mask = ((1 << LaneWidth) - 1) << Lane * LaneWidth;
8900 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32,
8901 Op.getOperand(1), DAG.getValueType(MVT::i1));
8902 SDValue BFI = DAG.getNode(ARMISD::BFI, dl, MVT::i32, Conv, Ext,
8903 DAG.getConstant(~Mask, dl, MVT::i32));
8904 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), BFI);
8905}
8906
8907SDValue ARMTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
8908 SelectionDAG &DAG) const {
8909 // INSERT_VECTOR_ELT is legal only for immediate indexes.
8910 SDValue Lane = Op.getOperand(2);
8911 if (!isa<ConstantSDNode>(Lane))
8912 return SDValue();
8913
8914 SDValue Elt = Op.getOperand(1);
8915 EVT EltVT = Elt.getValueType();
8916
8917 if (Subtarget->hasMVEIntegerOps() &&
8918 Op.getValueType().getScalarSizeInBits() == 1)
8919 return LowerINSERT_VECTOR_ELT_i1(Op, DAG, Subtarget);
8920
8921 if (getTypeAction(*DAG.getContext(), EltVT) ==
8923 // INSERT_VECTOR_ELT doesn't want f16 operands promoting to f32,
8924 // but the type system will try to do that if we don't intervene.
8925 // Reinterpret any such vector-element insertion as one with the
8926 // corresponding integer types.
8927
8928 SDLoc dl(Op);
8929
8930 EVT IEltVT = MVT::getIntegerVT(EltVT.getScalarSizeInBits());
8931 assert(getTypeAction(*DAG.getContext(), IEltVT) !=
8933
8934 SDValue VecIn = Op.getOperand(0);
8935 EVT VecVT = VecIn.getValueType();
8936 EVT IVecVT = EVT::getVectorVT(*DAG.getContext(), IEltVT,
8937 VecVT.getVectorNumElements());
8938
8939 SDValue IElt = DAG.getNode(ISD::BITCAST, dl, IEltVT, Elt);
8940 SDValue IVecIn = DAG.getNode(ISD::BITCAST, dl, IVecVT, VecIn);
8941 SDValue IVecOut = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, IVecVT,
8942 IVecIn, IElt, Lane);
8943 return DAG.getNode(ISD::BITCAST, dl, VecVT, IVecOut);
8944 }
8945
8946 return Op;
8947}
8948
8950 const ARMSubtarget *ST) {
8951 EVT VecVT = Op.getOperand(0).getValueType();
8952 SDLoc dl(Op);
8953
8954 assert(ST->hasMVEIntegerOps() &&
8955 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8956
8957 SDValue Conv =
8958 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8959 unsigned Lane = Op.getConstantOperandVal(1);
8960 unsigned LaneWidth =
8962 SDValue Shift = DAG.getNode(ISD::SRL, dl, MVT::i32, Conv,
8963 DAG.getConstant(Lane * LaneWidth, dl, MVT::i32));
8964 return Shift;
8965}
8966
8968 const ARMSubtarget *ST) {
8969 // EXTRACT_VECTOR_ELT is legal only for immediate indexes.
8970 SDValue Lane = Op.getOperand(1);
8971 if (!isa<ConstantSDNode>(Lane))
8972 return SDValue();
8973
8974 SDValue Vec = Op.getOperand(0);
8975 EVT VT = Vec.getValueType();
8976
8977 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8978 return LowerEXTRACT_VECTOR_ELT_i1(Op, DAG, ST);
8979
8980 if (Op.getValueType() == MVT::i32 && Vec.getScalarValueSizeInBits() < 32) {
8981 SDLoc dl(Op);
8982 return DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane);
8983 }
8984
8985 return Op;
8986}
8987
8989 const ARMSubtarget *ST) {
8990 SDLoc dl(Op);
8991 assert(Op.getValueType().getScalarSizeInBits() == 1 &&
8992 "Unexpected custom CONCAT_VECTORS lowering");
8993 assert(isPowerOf2_32(Op.getNumOperands()) &&
8994 "Unexpected custom CONCAT_VECTORS lowering");
8995 assert(ST->hasMVEIntegerOps() &&
8996 "CONCAT_VECTORS lowering only supported for MVE");
8997
8998 auto ConcatPair = [&](SDValue V1, SDValue V2) {
8999 EVT Op1VT = V1.getValueType();
9000 EVT Op2VT = V2.getValueType();
9001 assert(Op1VT == Op2VT && "Operand types don't match!");
9002 assert((Op1VT == MVT::v2i1 || Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) &&
9003 "Unexpected i1 concat operations!");
9004 EVT VT = Op1VT.getDoubleNumVectorElementsVT(*DAG.getContext());
9005
9006 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9007 SDValue NewV2 = PromoteMVEPredVector(dl, V2, Op2VT, DAG);
9008
9009 // We now have Op1 + Op2 promoted to vectors of integers, where v8i1 gets
9010 // promoted to v8i16, etc.
9011 MVT ElType =
9013 unsigned NumElts = 2 * Op1VT.getVectorNumElements();
9014
9015 EVT ConcatVT = MVT::getVectorVT(ElType, NumElts);
9016 if (Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) {
9017 // Use MVETRUNC to truncate the combined NewV1::NewV2 into the smaller
9018 // ConcatVT.
9019 SDValue ConVec =
9020 DAG.getNode(ARMISD::MVETRUNC, dl, ConcatVT, NewV1, NewV2);
9021 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9022 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9023 }
9024
9025 // Extract the vector elements from Op1 and Op2 one by one and truncate them
9026 // to be the right size for the destination. For example, if Op1 is v4i1
9027 // then the promoted vector is v4i32. The result of concatenation gives a
9028 // v8i1, which when promoted is v8i16. That means each i32 element from Op1
9029 // needs truncating to i16 and inserting in the result.
9030 auto ExtractInto = [&DAG, &dl](SDValue NewV, SDValue ConVec, unsigned &j) {
9031 EVT NewVT = NewV.getValueType();
9032 EVT ConcatVT = ConVec.getValueType();
9033 unsigned ExtScale = 1;
9034 if (NewVT == MVT::v2f64) {
9035 NewV = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, NewV);
9036 ExtScale = 2;
9037 }
9038 for (unsigned i = 0, e = NewVT.getVectorNumElements(); i < e; i++, j++) {
9039 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV,
9040 DAG.getIntPtrConstant(i * ExtScale, dl));
9041 ConVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ConcatVT, ConVec, Elt,
9042 DAG.getConstant(j, dl, MVT::i32));
9043 }
9044 return ConVec;
9045 };
9046 unsigned j = 0;
9047 SDValue ConVec = DAG.getNode(ISD::UNDEF, dl, ConcatVT);
9048 ConVec = ExtractInto(NewV1, ConVec, j);
9049 ConVec = ExtractInto(NewV2, ConVec, j);
9050
9051 // Now return the result of comparing the subvector with zero, which will
9052 // generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9053 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9054 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9055 };
9056
9057 // Concat each pair of subvectors and pack into the lower half of the array.
9058 SmallVector<SDValue> ConcatOps(Op->ops());
9059 while (ConcatOps.size() > 1) {
9060 for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) {
9061 SDValue V1 = ConcatOps[I];
9062 SDValue V2 = ConcatOps[I + 1];
9063 ConcatOps[I / 2] = ConcatPair(V1, V2);
9064 }
9065 ConcatOps.resize(ConcatOps.size() / 2);
9066 }
9067 return ConcatOps[0];
9068}
9069
9071 const ARMSubtarget *ST) {
9072 EVT VT = Op->getValueType(0);
9073 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
9074 return LowerCONCAT_VECTORS_i1(Op, DAG, ST);
9075
9076 // The only time a CONCAT_VECTORS operation can have legal types is when
9077 // two 64-bit vectors are concatenated to a 128-bit vector.
9078 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
9079 "unexpected CONCAT_VECTORS");
9080 SDLoc dl(Op);
9081 SDValue Val = DAG.getUNDEF(MVT::v2f64);
9082 SDValue Op0 = Op.getOperand(0);
9083 SDValue Op1 = Op.getOperand(1);
9084 if (!Op0.isUndef())
9085 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9086 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op0),
9087 DAG.getIntPtrConstant(0, dl));
9088 if (!Op1.isUndef())
9089 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9090 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op1),
9091 DAG.getIntPtrConstant(1, dl));
9092 return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Val);
9093}
9094
9096 const ARMSubtarget *ST) {
9097 SDValue V1 = Op.getOperand(0);
9098 SDValue V2 = Op.getOperand(1);
9099 SDLoc dl(Op);
9100 EVT VT = Op.getValueType();
9101 EVT Op1VT = V1.getValueType();
9102 unsigned NumElts = VT.getVectorNumElements();
9103 unsigned Index = V2->getAsZExtVal();
9104
9105 assert(VT.getScalarSizeInBits() == 1 &&
9106 "Unexpected custom EXTRACT_SUBVECTOR lowering");
9107 assert(ST->hasMVEIntegerOps() &&
9108 "EXTRACT_SUBVECTOR lowering only supported for MVE");
9109
9110 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9111
9112 // We now have Op1 promoted to a vector of integers, where v8i1 gets
9113 // promoted to v8i16, etc.
9114
9116
9117 if (NumElts == 2) {
9118 EVT SubVT = MVT::v4i32;
9119 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9120 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j += 2) {
9121 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9122 DAG.getIntPtrConstant(i, dl));
9123 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9124 DAG.getConstant(j, dl, MVT::i32));
9125 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9126 DAG.getConstant(j + 1, dl, MVT::i32));
9127 }
9128 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, SubVec,
9129 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9130 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
9131 }
9132
9133 EVT SubVT = MVT::getVectorVT(ElType, NumElts);
9134 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9135 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j++) {
9136 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9137 DAG.getIntPtrConstant(i, dl));
9138 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9139 DAG.getConstant(j, dl, MVT::i32));
9140 }
9141
9142 // Now return the result of comparing the subvector with zero,
9143 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9144 return DAG.getNode(ARMISD::VCMPZ, dl, VT, SubVec,
9145 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9146}
9147
9148// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
9150 const ARMSubtarget *ST) {
9151 assert(ST->hasMVEIntegerOps() && "Expected MVE!");
9152 EVT VT = N->getValueType(0);
9153 assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
9154 "Expected a vector i1 type!");
9155 SDValue Op = N->getOperand(0);
9156 EVT FromVT = Op.getValueType();
9157 SDLoc DL(N);
9158
9159 SDValue And =
9160 DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
9161 return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
9162 DAG.getCondCode(ISD::SETNE));
9163}
9164
9166 const ARMSubtarget *Subtarget) {
9167 if (!Subtarget->hasMVEIntegerOps())
9168 return SDValue();
9169
9170 EVT ToVT = N->getValueType(0);
9171 if (ToVT.getScalarType() == MVT::i1)
9172 return LowerTruncatei1(N, DAG, Subtarget);
9173
9174 // MVE does not have a single instruction to perform the truncation of a v4i32
9175 // into the lower half of a v8i16, in the same way that a NEON vmovn would.
9176 // Most of the instructions in MVE follow the 'Beats' system, where moving
9177 // values from different lanes is usually something that the instructions
9178 // avoid.
9179 //
9180 // Instead it has top/bottom instructions such as VMOVLT/B and VMOVNT/B,
9181 // which take a the top/bottom half of a larger lane and extend it (or do the
9182 // opposite, truncating into the top/bottom lane from a larger lane). Note
9183 // that because of the way we widen lanes, a v4i16 is really a v4i32 using the
9184 // bottom 16bits from each vector lane. This works really well with T/B
9185 // instructions, but that doesn't extend to v8i32->v8i16 where the lanes need
9186 // to move order.
9187 //
9188 // But truncates and sext/zext are always going to be fairly common from llvm.
9189 // We have several options for how to deal with them:
9190 // - Wherever possible combine them into an instruction that makes them
9191 // "free". This includes loads/stores, which can perform the trunc as part
9192 // of the memory operation. Or certain shuffles that can be turned into
9193 // VMOVN/VMOVL.
9194 // - Lane Interleaving to transform blocks surrounded by ext/trunc. So
9195 // trunc(mul(sext(a), sext(b))) may become
9196 // VMOVNT(VMUL(VMOVLB(a), VMOVLB(b)), VMUL(VMOVLT(a), VMOVLT(b))). (Which in
9197 // this case can use VMULL). This is performed in the
9198 // MVELaneInterleavingPass.
9199 // - Otherwise we have an option. By default we would expand the
9200 // zext/sext/trunc into a series of lane extract/inserts going via GPR
9201 // registers. One for each vector lane in the vector. This can obviously be
9202 // very expensive.
9203 // - The other option is to use the fact that loads/store can extend/truncate
9204 // to turn a trunc into two truncating stack stores and a stack reload. This
9205 // becomes 3 back-to-back memory operations, but at least that is less than
9206 // all the insert/extracts.
9207 //
9208 // In order to do the last, we convert certain trunc's into MVETRUNC, which
9209 // are either optimized where they can be, or eventually lowered into stack
9210 // stores/loads. This prevents us from splitting a v8i16 trunc into two stores
9211 // two early, where other instructions would be better, and stops us from
9212 // having to reconstruct multiple buildvector shuffles into loads/stores.
9213 if (ToVT != MVT::v8i16 && ToVT != MVT::v16i8)
9214 return SDValue();
9215 EVT FromVT = N->getOperand(0).getValueType();
9216 if (FromVT != MVT::v8i32 && FromVT != MVT::v16i16)
9217 return SDValue();
9218
9219 SDValue Lo, Hi;
9220 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
9221 SDLoc DL(N);
9222 return DAG.getNode(ARMISD::MVETRUNC, DL, ToVT, Lo, Hi);
9223}
9224
9226 const ARMSubtarget *Subtarget) {
9227 if (!Subtarget->hasMVEIntegerOps())
9228 return SDValue();
9229
9230 // See LowerTruncate above for an explanation of MVEEXT/MVETRUNC.
9231
9232 EVT ToVT = N->getValueType(0);
9233 if (ToVT != MVT::v16i32 && ToVT != MVT::v8i32 && ToVT != MVT::v16i16)
9234 return SDValue();
9235 SDValue Op = N->getOperand(0);
9236 EVT FromVT = Op.getValueType();
9237 if (FromVT != MVT::v8i16 && FromVT != MVT::v16i8)
9238 return SDValue();
9239
9240 SDLoc DL(N);
9241 EVT ExtVT = ToVT.getHalfNumVectorElementsVT(*DAG.getContext());
9242 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8)
9243 ExtVT = MVT::v8i16;
9244
9245 unsigned Opcode =
9247 SDValue Ext = DAG.getNode(Opcode, DL, DAG.getVTList(ExtVT, ExtVT), Op);
9248 SDValue Ext1 = Ext.getValue(1);
9249
9250 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8) {
9251 Ext = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext);
9252 Ext1 = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext1);
9253 }
9254
9255 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Ext, Ext1);
9256}
9257
9258/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
9259/// element has been zero/sign-extended, depending on the isSigned parameter,
9260/// from an integer type half its size.
9262 bool isSigned) {
9263 // A v2i64 BUILD_VECTOR will have been legalized to a BITCAST from v4i32.
9264 EVT VT = N->getValueType(0);
9265 if (VT == MVT::v2i64 && N->getOpcode() == ISD::BITCAST) {
9266 SDNode *BVN = N->getOperand(0).getNode();
9267 if (BVN->getValueType(0) != MVT::v4i32 ||
9268 BVN->getOpcode() != ISD::BUILD_VECTOR)
9269 return false;
9270 unsigned LoElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9271 unsigned HiElt = 1 - LoElt;
9276 if (!Lo0 || !Hi0 || !Lo1 || !Hi1)
9277 return false;
9278 if (isSigned) {
9279 if (Hi0->getSExtValue() == Lo0->getSExtValue() >> 32 &&
9280 Hi1->getSExtValue() == Lo1->getSExtValue() >> 32)
9281 return true;
9282 } else {
9283 if (Hi0->isZero() && Hi1->isZero())
9284 return true;
9285 }
9286 return false;
9287 }
9288
9289 if (N->getOpcode() != ISD::BUILD_VECTOR)
9290 return false;
9291
9292 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
9293 SDNode *Elt = N->getOperand(i).getNode();
9295 unsigned EltSize = VT.getScalarSizeInBits();
9296 unsigned HalfSize = EltSize / 2;
9297 if (isSigned) {
9298 if (!isIntN(HalfSize, C->getSExtValue()))
9299 return false;
9300 } else {
9301 if (!isUIntN(HalfSize, C->getZExtValue()))
9302 return false;
9303 }
9304 continue;
9305 }
9306 return false;
9307 }
9308
9309 return true;
9310}
9311
9312/// isSignExtended - Check if a node is a vector value that is sign-extended
9313/// or a constant BUILD_VECTOR with sign-extended elements.
9315 if (N->getOpcode() == ISD::SIGN_EXTEND || ISD::isSEXTLoad(N))
9316 return true;
9317 if (isExtendedBUILD_VECTOR(N, DAG, true))
9318 return true;
9319 return false;
9320}
9321
9322/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
9323/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
9325 if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
9327 return true;
9328 if (isExtendedBUILD_VECTOR(N, DAG, false))
9329 return true;
9330 return false;
9331}
9332
9333static EVT getExtensionTo64Bits(const EVT &OrigVT) {
9334 if (OrigVT.getSizeInBits() >= 64)
9335 return OrigVT;
9336
9337 assert(OrigVT.isSimple() && "Expecting a simple value type");
9338
9339 MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
9340 switch (OrigSimpleTy) {
9341 default: llvm_unreachable("Unexpected Vector Type");
9342 case MVT::v2i8:
9343 case MVT::v2i16:
9344 return MVT::v2i32;
9345 case MVT::v4i8:
9346 return MVT::v4i16;
9347 }
9348}
9349
9350/// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
9351/// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
9352/// We insert the required extension here to get the vector to fill a D register.
9354 const EVT &OrigTy,
9355 const EVT &ExtTy,
9356 unsigned ExtOpcode) {
9357 // The vector originally had a size of OrigTy. It was then extended to ExtTy.
9358 // We expect the ExtTy to be 128-bits total. If the OrigTy is less than
9359 // 64-bits we need to insert a new extension so that it will be 64-bits.
9360 assert(ExtTy.is128BitVector() && "Unexpected extension size");
9361 if (OrigTy.getSizeInBits() >= 64)
9362 return N;
9363
9364 // Must extend size to at least 64 bits to be used as an operand for VMULL.
9365 EVT NewVT = getExtensionTo64Bits(OrigTy);
9366
9367 return DAG.getNode(ExtOpcode, SDLoc(N), NewVT, N);
9368}
9369
9370/// SkipLoadExtensionForVMULL - return a load of the original vector size that
9371/// does not do any sign/zero extension. If the original vector is less
9372/// than 64 bits, an appropriate extension will be added after the load to
9373/// reach a total size of 64 bits. We have to add the extension separately
9374/// because ARM does not have a sign/zero extending load for vectors.
9376 EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
9377
9378 // The load already has the right type.
9379 if (ExtendedTy == LD->getMemoryVT())
9380 return DAG.getLoad(LD->getMemoryVT(), SDLoc(LD), LD->getChain(),
9381 LD->getBasePtr(), LD->getPointerInfo(), LD->getAlign(),
9382 LD->getMemOperand()->getFlags());
9383
9384 // We need to create a zextload/sextload. We cannot just create a load
9385 // followed by a zext/zext node because LowerMUL is also run during normal
9386 // operation legalization where we can't create illegal types.
9387 return DAG.getExtLoad(LD->getExtensionType(), SDLoc(LD), ExtendedTy,
9388 LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
9389 LD->getMemoryVT(), LD->getAlign(),
9390 LD->getMemOperand()->getFlags());
9391}
9392
9393/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
9394/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
9395/// the unextended value. The unextended vector should be 64 bits so that it can
9396/// be used as an operand to a VMULL instruction. If the original vector size
9397/// before extension is less than 64 bits we add a an extension to resize
9398/// the vector to 64 bits.
9400 if (N->getOpcode() == ISD::SIGN_EXTEND ||
9401 N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
9402 return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
9403 N->getOperand(0)->getValueType(0),
9404 N->getValueType(0),
9405 N->getOpcode());
9406
9407 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
9408 assert((ISD::isSEXTLoad(LD) || ISD::isZEXTLoad(LD)) &&
9409 "Expected extending load");
9410
9411 SDValue newLoad = SkipLoadExtensionForVMULL(LD, DAG);
9412 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), newLoad.getValue(1));
9413 unsigned Opcode = ISD::isSEXTLoad(LD) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
9414 SDValue extLoad =
9415 DAG.getNode(Opcode, SDLoc(newLoad), LD->getValueType(0), newLoad);
9416 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 0), extLoad);
9417
9418 return newLoad;
9419 }
9420
9421 // Otherwise, the value must be a BUILD_VECTOR. For v2i64, it will
9422 // have been legalized as a BITCAST from v4i32.
9423 if (N->getOpcode() == ISD::BITCAST) {
9424 SDNode *BVN = N->getOperand(0).getNode();
9426 BVN->getValueType(0) == MVT::v4i32 && "expected v4i32 BUILD_VECTOR");
9427 unsigned LowElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9428 return DAG.getBuildVector(
9429 MVT::v2i32, SDLoc(N),
9430 {BVN->getOperand(LowElt), BVN->getOperand(LowElt + 2)});
9431 }
9432 // Construct a new BUILD_VECTOR with elements truncated to half the size.
9433 assert(N->getOpcode() == ISD::BUILD_VECTOR && "expected BUILD_VECTOR");
9434 EVT VT = N->getValueType(0);
9435 unsigned EltSize = VT.getScalarSizeInBits() / 2;
9436 unsigned NumElts = VT.getVectorNumElements();
9437 MVT TruncVT = MVT::getIntegerVT(EltSize);
9439 SDLoc dl(N);
9440 for (unsigned i = 0; i != NumElts; ++i) {
9441 const APInt &CInt = N->getConstantOperandAPInt(i);
9442 // Element types smaller than 32 bits are not legal, so use i32 elements.
9443 // The values are implicitly truncated so sext vs. zext doesn't matter.
9444 Ops.push_back(DAG.getConstant(CInt.zextOrTrunc(32), dl, MVT::i32));
9445 }
9446 return DAG.getBuildVector(MVT::getVectorVT(TruncVT, NumElts), dl, Ops);
9447}
9448
9449static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
9450 unsigned Opcode = N->getOpcode();
9451 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9452 SDNode *N0 = N->getOperand(0).getNode();
9453 SDNode *N1 = N->getOperand(1).getNode();
9454 return N0->hasOneUse() && N1->hasOneUse() &&
9455 isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
9456 }
9457 return false;
9458}
9459
9460static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
9461 unsigned Opcode = N->getOpcode();
9462 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9463 SDNode *N0 = N->getOperand(0).getNode();
9464 SDNode *N1 = N->getOperand(1).getNode();
9465 return N0->hasOneUse() && N1->hasOneUse() &&
9466 isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
9467 }
9468 return false;
9469}
9470
9472 // Multiplications are only custom-lowered for 128-bit vectors so that
9473 // VMULL can be detected. Otherwise v2i64 multiplications are not legal.
9474 EVT VT = Op.getValueType();
9475 assert(VT.is128BitVector() && VT.isInteger() &&
9476 "unexpected type for custom-lowering ISD::MUL");
9477 SDNode *N0 = Op.getOperand(0).getNode();
9478 SDNode *N1 = Op.getOperand(1).getNode();
9479 unsigned NewOpc = 0;
9480 bool isMLA = false;
9481 bool isN0SExt = isSignExtended(N0, DAG);
9482 bool isN1SExt = isSignExtended(N1, DAG);
9483 if (isN0SExt && isN1SExt)
9484 NewOpc = ARMISD::VMULLs;
9485 else {
9486 bool isN0ZExt = isZeroExtended(N0, DAG);
9487 bool isN1ZExt = isZeroExtended(N1, DAG);
9488 if (isN0ZExt && isN1ZExt)
9489 NewOpc = ARMISD::VMULLu;
9490 else if (isN1SExt || isN1ZExt) {
9491 // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
9492 // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
9493 if (isN1SExt && isAddSubSExt(N0, DAG)) {
9494 NewOpc = ARMISD::VMULLs;
9495 isMLA = true;
9496 } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
9497 NewOpc = ARMISD::VMULLu;
9498 isMLA = true;
9499 } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
9500 std::swap(N0, N1);
9501 NewOpc = ARMISD::VMULLu;
9502 isMLA = true;
9503 }
9504 }
9505
9506 if (!NewOpc) {
9507 if (VT == MVT::v2i64)
9508 // Fall through to expand this. It is not legal.
9509 return SDValue();
9510 else
9511 // Other vector multiplications are legal.
9512 return Op;
9513 }
9514 }
9515
9516 // Legalize to a VMULL instruction.
9517 SDLoc DL(Op);
9518 SDValue Op0;
9519 SDValue Op1 = SkipExtensionForVMULL(N1, DAG);
9520 if (!isMLA) {
9521 Op0 = SkipExtensionForVMULL(N0, DAG);
9523 Op1.getValueType().is64BitVector() &&
9524 "unexpected types for extended operands to VMULL");
9525 return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
9526 }
9527
9528 // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
9529 // isel lowering to take advantage of no-stall back to back vmul + vmla.
9530 // vmull q0, d4, d6
9531 // vmlal q0, d5, d6
9532 // is faster than
9533 // vaddl q0, d4, d5
9534 // vmovl q1, d6
9535 // vmul q0, q0, q1
9536 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG);
9537 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG);
9538 EVT Op1VT = Op1.getValueType();
9539 return DAG.getNode(N0->getOpcode(), DL, VT,
9540 DAG.getNode(NewOpc, DL, VT,
9541 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
9542 DAG.getNode(NewOpc, DL, VT,
9543 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
9544}
9545
9547 SelectionDAG &DAG) {
9548 // TODO: Should this propagate fast-math-flags?
9549
9550 // Convert to float
9551 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo));
9552 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo));
9553 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X);
9554 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y);
9555 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X);
9556 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y);
9557 // Get reciprocal estimate.
9558 // float4 recip = vrecpeq_f32(yf);
9559 Y = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9560 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9561 Y);
9562 // Because char has a smaller range than uchar, we can actually get away
9563 // without any newton steps. This requires that we use a weird bias
9564 // of 0xb000, however (again, this has been exhaustively tested).
9565 // float4 result = as_float4(as_int4(xf*recip) + 0xb000);
9566 X = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, X, Y);
9567 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, X);
9568 Y = DAG.getConstant(0xb000, dl, MVT::v4i32);
9569 X = DAG.getNode(ISD::ADD, dl, MVT::v4i32, X, Y);
9570 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, X);
9571 // Convert back to short.
9572 X = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, X);
9573 X = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, X);
9574 return X;
9575}
9576
9578 SelectionDAG &DAG) {
9579 // TODO: Should this propagate fast-math-flags?
9580
9581 SDValue N2;
9582 // Convert to float.
9583 // float4 yf = vcvt_f32_s32(vmovl_s16(y));
9584 // float4 xf = vcvt_f32_s32(vmovl_s16(x));
9585 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N0);
9586 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N1);
9587 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9588 N1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9589
9590 // Use reciprocal estimate and one refinement step.
9591 // float4 recip = vrecpeq_f32(yf);
9592 // recip *= vrecpsq_f32(yf, recip);
9593 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9594 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9595 N1);
9596 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9597 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9598 N1, N2);
9599 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9600 // Because short has a smaller range than ushort, we can actually get away
9601 // with only a single newton step. This requires that we use a weird bias
9602 // of 89, however (again, this has been exhaustively tested).
9603 // float4 result = as_float4(as_int4(xf*recip) + 0x89);
9604 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9605 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9606 N1 = DAG.getConstant(0x89, dl, MVT::v4i32);
9607 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9608 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9609 // Convert back to integer and return.
9610 // return vmovn_s32(vcvt_s32_f32(result));
9611 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9612 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9613 return N0;
9614}
9615
9617 const ARMSubtarget *ST) {
9618 EVT VT = Op.getValueType();
9619 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9620 "unexpected type for custom-lowering ISD::SDIV");
9621
9622 SDLoc dl(Op);
9623 SDValue N0 = Op.getOperand(0);
9624 SDValue N1 = Op.getOperand(1);
9625 SDValue N2, N3;
9626
9627 if (VT == MVT::v8i8) {
9628 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N0);
9629 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N1);
9630
9631 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9632 DAG.getIntPtrConstant(4, dl));
9633 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9634 DAG.getIntPtrConstant(4, dl));
9635 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9636 DAG.getIntPtrConstant(0, dl));
9637 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9638 DAG.getIntPtrConstant(0, dl));
9639
9640 N0 = LowerSDIV_v4i8(N0, N1, dl, DAG); // v4i16
9641 N2 = LowerSDIV_v4i8(N2, N3, dl, DAG); // v4i16
9642
9643 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9644 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9645
9646 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v8i8, N0);
9647 return N0;
9648 }
9649 return LowerSDIV_v4i16(N0, N1, dl, DAG);
9650}
9651
9653 const ARMSubtarget *ST) {
9654 // TODO: Should this propagate fast-math-flags?
9655 EVT VT = Op.getValueType();
9656 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9657 "unexpected type for custom-lowering ISD::UDIV");
9658
9659 SDLoc dl(Op);
9660 SDValue N0 = Op.getOperand(0);
9661 SDValue N1 = Op.getOperand(1);
9662 SDValue N2, N3;
9663
9664 if (VT == MVT::v8i8) {
9665 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N0);
9666 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N1);
9667
9668 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9669 DAG.getIntPtrConstant(4, dl));
9670 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9671 DAG.getIntPtrConstant(4, dl));
9672 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9673 DAG.getIntPtrConstant(0, dl));
9674 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9675 DAG.getIntPtrConstant(0, dl));
9676
9677 N0 = LowerSDIV_v4i16(N0, N1, dl, DAG); // v4i16
9678 N2 = LowerSDIV_v4i16(N2, N3, dl, DAG); // v4i16
9679
9680 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9681 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9682
9683 N0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v8i8,
9684 DAG.getConstant(Intrinsic::arm_neon_vqmovnsu, dl,
9685 MVT::i32),
9686 N0);
9687 return N0;
9688 }
9689
9690 // v4i16 sdiv ... Convert to float.
9691 // float4 yf = vcvt_f32_s32(vmovl_u16(y));
9692 // float4 xf = vcvt_f32_s32(vmovl_u16(x));
9693 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N0);
9694 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N1);
9695 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9696 SDValue BN1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9697
9698 // Use reciprocal estimate and two refinement steps.
9699 // float4 recip = vrecpeq_f32(yf);
9700 // recip *= vrecpsq_f32(yf, recip);
9701 // recip *= vrecpsq_f32(yf, recip);
9702 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9703 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9704 BN1);
9705 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9706 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9707 BN1, N2);
9708 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9709 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9710 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9711 BN1, N2);
9712 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9713 // Simply multiplying by the reciprocal estimate can leave us a few ulps
9714 // too low, so we add 2 ulps (exhaustive testing shows that this is enough,
9715 // and that it will never cause us to return an answer too large).
9716 // float4 result = as_float4(as_int4(xf*recip) + 2);
9717 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9718 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9719 N1 = DAG.getConstant(2, dl, MVT::v4i32);
9720 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9721 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9722 // Convert back to integer and return.
9723 // return vmovn_u32(vcvt_s32_f32(result));
9724 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9725 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9726 return N0;
9727}
9728
9730 unsigned Opcode, bool IsSigned) {
9731 EVT VT0 = Op.getValue(0).getValueType();
9732 EVT VT1 = Op.getValue(1).getValueType();
9733
9734 bool InvertCarry = Opcode == ARMISD::SUBE;
9735 SDValue OpLHS = Op.getOperand(0);
9736 SDValue OpRHS = Op.getOperand(1);
9737 SDValue OpCarryIn = valueToCarryFlag(Op.getOperand(2), DAG, InvertCarry);
9738
9739 SDLoc DL(Op);
9740
9741 SDValue Result = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::i32), OpLHS,
9742 OpRHS, OpCarryIn);
9743
9744 SDValue OutFlag =
9745 IsSigned ? overflowFlagToValue(Result.getValue(1), VT1, DAG)
9746 : carryFlagToValue(Result.getValue(1), VT1, DAG, InvertCarry);
9747
9748 return DAG.getMergeValues({Result, OutFlag}, DL);
9749}
9750
9751SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
9752 bool Signed,
9753 SDValue &Chain) const {
9754 EVT VT = Op.getValueType();
9755 assert((VT == MVT::i32 || VT == MVT::i64) &&
9756 "unexpected type for custom lowering DIV");
9757 SDLoc dl(Op);
9758
9759 const auto &DL = DAG.getDataLayout();
9760 RTLIB::Libcall LC;
9761 if (Signed)
9762 LC = VT == MVT::i32 ? RTLIB::SDIVREM_I32 : RTLIB::SDIVREM_I64;
9763 else
9764 LC = VT == MVT::i32 ? RTLIB::UDIVREM_I32 : RTLIB::UDIVREM_I64;
9765
9766 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
9767 SDValue ES = DAG.getExternalSymbol(LCImpl, getPointerTy(DL));
9768
9770
9771 for (auto AI : {1, 0}) {
9772 SDValue Operand = Op.getOperand(AI);
9773 Args.emplace_back(Operand,
9774 Operand.getValueType().getTypeForEVT(*DAG.getContext()));
9775 }
9776
9777 CallLoweringInfo CLI(DAG);
9778 CLI.setDebugLoc(dl).setChain(Chain).setCallee(
9780 VT.getTypeForEVT(*DAG.getContext()), ES, std::move(Args));
9781
9782 return LowerCallTo(CLI).first;
9783}
9784
9785// This is a code size optimisation: return the original SDIV node to
9786// DAGCombiner when we don't want to expand SDIV into a sequence of
9787// instructions, and an empty node otherwise which will cause the
9788// SDIV to be expanded in DAGCombine.
9789SDValue
9790ARMTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
9791 SelectionDAG &DAG,
9792 SmallVectorImpl<SDNode *> &Created) const {
9793 // TODO: Support SREM
9794 if (N->getOpcode() != ISD::SDIV)
9795 return SDValue();
9796
9797 const auto &ST = DAG.getSubtarget<ARMSubtarget>();
9798 const bool MinSize = ST.hasMinSize();
9799 const bool HasDivide = ST.isThumb() ? ST.hasDivideInThumbMode()
9800 : ST.hasDivideInARMMode();
9801
9802 // Don't touch vector types; rewriting this may lead to scalarizing
9803 // the int divs.
9804 if (N->getOperand(0).getValueType().isVector())
9805 return SDValue();
9806
9807 // Bail if MinSize is not set, and also for both ARM and Thumb mode we need
9808 // hwdiv support for this to be really profitable.
9809 if (!(MinSize && HasDivide))
9810 return SDValue();
9811
9812 // ARM mode is a bit simpler than Thumb: we can handle large power
9813 // of 2 immediates with 1 mov instruction; no further checks required,
9814 // just return the sdiv node.
9815 if (!ST.isThumb())
9816 return SDValue(N, 0);
9817
9818 // In Thumb mode, immediates larger than 128 need a wide 4-byte MOV,
9819 // and thus lose the code size benefits of a MOVS that requires only 2.
9820 // TargetTransformInfo and 'getIntImmCodeSizeCost' could be helpful here,
9821 // but as it's doing exactly this, it's not worth the trouble to get TTI.
9822 if (Divisor.sgt(128))
9823 return SDValue();
9824
9825 return SDValue(N, 0);
9826}
9827
9828SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
9829 bool Signed) const {
9830 assert(Op.getValueType() == MVT::i32 &&
9831 "unexpected type for custom lowering DIV");
9832 SDLoc dl(Op);
9833
9834 SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
9835 DAG.getEntryNode(), Op.getOperand(1));
9836
9837 return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9838}
9839
9841 SDLoc DL(N);
9842 SDValue Op = N->getOperand(1);
9843 if (N->getValueType(0) == MVT::i32)
9844 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
9845 SDValue Lo, Hi;
9846 std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32);
9847 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
9848 DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
9849}
9850
9851void ARMTargetLowering::ExpandDIV_Windows(
9852 SDValue Op, SelectionDAG &DAG, bool Signed,
9854 const auto &DL = DAG.getDataLayout();
9855
9856 assert(Op.getValueType() == MVT::i64 &&
9857 "unexpected type for custom lowering DIV");
9858 SDLoc dl(Op);
9859
9860 SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
9861
9862 SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9863
9864 SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
9865 SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
9866 DAG.getConstant(32, dl, getPointerTy(DL)));
9867 Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper);
9868
9869 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lower, Upper));
9870}
9871
9872std::pair<SDValue, SDValue>
9873ARMTargetLowering::LowerAEABIUnalignedLoad(SDValue Op,
9874 SelectionDAG &DAG) const {
9875 // If we have an unaligned load from a i32 or i64 that would normally be
9876 // split into separate ldrb's, we can use the __aeabi_uread4/__aeabi_uread8
9877 // functions instead.
9878 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9879 EVT MemVT = LD->getMemoryVT();
9880 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9881 return std::make_pair(SDValue(), SDValue());
9882
9883 const auto &MF = DAG.getMachineFunction();
9884 unsigned AS = LD->getAddressSpace();
9885 Align Alignment = LD->getAlign();
9886 const DataLayout &DL = DAG.getDataLayout();
9887 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9888 RTLIB::Libcall LC =
9889 (MemVT == MVT::i32) ? RTLIB::AEABI_UREAD4 : RTLIB::AEABI_UREAD8;
9890
9891 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9892 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9893 MakeLibCallOptions Opts;
9894 SDLoc dl(Op);
9895
9896 auto Pair = makeLibCall(DAG, LC, MemVT.getSimpleVT(), LD->getBasePtr(),
9897 Opts, dl, LD->getChain());
9898
9899 // If necessary, extend the node to 64bit
9900 if (LD->getExtensionType() != ISD::NON_EXTLOAD) {
9901 unsigned ExtType = LD->getExtensionType() == ISD::SEXTLOAD
9904 SDValue EN = DAG.getNode(ExtType, dl, LD->getValueType(0), Pair.first);
9905 Pair.first = EN;
9906 }
9907 return Pair;
9908 }
9909
9910 // Default expand to individual loads
9911 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9912 return expandUnalignedLoad(LD, DAG);
9913 return std::make_pair(SDValue(), SDValue());
9914}
9915
9916SDValue ARMTargetLowering::LowerAEABIUnalignedStore(SDValue Op,
9917 SelectionDAG &DAG) const {
9918 // If we have an unaligned store to a i32 or i64 that would normally be
9919 // split into separate ldrb's, we can use the __aeabi_uwrite4/__aeabi_uwrite8
9920 // functions instead.
9921 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9922 EVT MemVT = ST->getMemoryVT();
9923 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9924 return SDValue();
9925
9926 const auto &MF = DAG.getMachineFunction();
9927 unsigned AS = ST->getAddressSpace();
9928 Align Alignment = ST->getAlign();
9929 const DataLayout &DL = DAG.getDataLayout();
9930 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9931 RTLIB::Libcall LC =
9932 (MemVT == MVT::i32) ? RTLIB::AEABI_UWRITE4 : RTLIB::AEABI_UWRITE8;
9933
9934 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9935 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9936
9937 SDLoc dl(Op);
9938
9939 // If necessary, trunc the value to 32bit
9940 SDValue StoreVal = ST->getOperand(1);
9941 if (ST->isTruncatingStore())
9942 StoreVal = DAG.getNode(ISD::TRUNCATE, dl, MemVT, ST->getOperand(1));
9943
9944 MakeLibCallOptions Opts;
9945 auto CallResult =
9946 makeLibCall(DAG, LC, MVT::isVoid, {StoreVal, ST->getBasePtr()}, Opts,
9947 dl, ST->getChain());
9948
9949 return CallResult.second;
9950 }
9951
9952 // Default expand to individual stores
9953 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9954 return expandUnalignedStore(ST, DAG);
9955 return SDValue();
9956}
9957
9959 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9960 EVT MemVT = LD->getMemoryVT();
9961 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9962 MemVT == MVT::v16i1) &&
9963 "Expected a predicate type!");
9964 assert(MemVT == Op.getValueType());
9965 assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
9966 "Expected a non-extending load");
9967 assert(LD->isUnindexed() && "Expected a unindexed load");
9968
9969 // The basic MVE VLDR on a v2i1/v4i1/v8i1 actually loads the entire 16bit
9970 // predicate, with the "v4i1" bits spread out over the 16 bits loaded. We
9971 // need to make sure that 8/4/2 bits are actually loaded into the correct
9972 // place, which means loading the value and then shuffling the values into
9973 // the bottom bits of the predicate.
9974 // Equally, VLDR for an v16i1 will actually load 32bits (so will be incorrect
9975 // for BE).
9976 // Speaking of BE, apparently the rest of llvm will assume a reverse order to
9977 // a natural VMSR(load), so needs to be reversed.
9978
9979 SDLoc dl(Op);
9980 SDValue Load = DAG.getExtLoad(
9981 ISD::EXTLOAD, dl, MVT::i32, LD->getChain(), LD->getBasePtr(),
9983 LD->getMemOperand());
9984 SDValue Val = Load;
9985 if (DAG.getDataLayout().isBigEndian())
9986 Val = DAG.getNode(ISD::SRL, dl, MVT::i32,
9987 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Load),
9988 DAG.getConstant(32 - MemVT.getSizeInBits(), dl, MVT::i32));
9989 SDValue Pred = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Val);
9990 if (MemVT != MVT::v16i1)
9991 Pred = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MemVT, Pred,
9992 DAG.getConstant(0, dl, MVT::i32));
9993 return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
9994}
9995
9996void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9997 SelectionDAG &DAG) const {
9998 LoadSDNode *LD = cast<LoadSDNode>(N);
9999 EVT MemVT = LD->getMemoryVT();
10000
10001 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10002 !Subtarget->isThumb1Only() && LD->isVolatile() &&
10003 LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10004 assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
10005 SDLoc dl(N);
10006 SDValue Result = DAG.getMemIntrinsicNode(
10007 ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
10008 {LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
10009 SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
10010 SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
10011 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
10012 Results.append({Pair, Result.getValue(2)});
10013 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10014 auto Pair = LowerAEABIUnalignedLoad(SDValue(N, 0), DAG);
10015 if (Pair.first) {
10016 Results.push_back(Pair.first);
10017 Results.push_back(Pair.second);
10018 }
10019 }
10020}
10021
10023 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10024 EVT MemVT = ST->getMemoryVT();
10025 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10026 MemVT == MVT::v16i1) &&
10027 "Expected a predicate type!");
10028 assert(MemVT == ST->getValue().getValueType());
10029 assert(!ST->isTruncatingStore() && "Expected a non-extending store");
10030 assert(ST->isUnindexed() && "Expected a unindexed store");
10031
10032 // Only store the v2i1 or v4i1 or v8i1 worth of bits, via a buildvector with
10033 // top bits unset and a scalar store.
10034 SDLoc dl(Op);
10035 SDValue Build = ST->getValue();
10036 if (MemVT != MVT::v16i1) {
10038 for (unsigned I = 0; I < MemVT.getVectorNumElements(); I++) {
10039 unsigned Elt = DAG.getDataLayout().isBigEndian()
10040 ? MemVT.getVectorNumElements() - I - 1
10041 : I;
10042 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Build,
10043 DAG.getConstant(Elt, dl, MVT::i32)));
10044 }
10045 for (unsigned I = MemVT.getVectorNumElements(); I < 16; I++)
10046 Ops.push_back(DAG.getUNDEF(MVT::i32));
10047 Build = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i1, Ops);
10048 }
10049 SDValue GRP = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Build);
10050 if (MemVT == MVT::v16i1 && DAG.getDataLayout().isBigEndian())
10051 GRP = DAG.getNode(ISD::SRL, dl, MVT::i32,
10052 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, GRP),
10053 DAG.getConstant(16, dl, MVT::i32));
10054 return DAG.getTruncStore(
10055 ST->getChain(), dl, GRP, ST->getBasePtr(),
10057 ST->getMemOperand());
10058}
10059
10060SDValue ARMTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG,
10061 const ARMSubtarget *Subtarget) const {
10062 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10063 EVT MemVT = ST->getMemoryVT();
10064
10065 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10066 !Subtarget->isThumb1Only() && ST->isVolatile() &&
10067 ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10068 assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
10069 SDNode *N = Op.getNode();
10070 SDLoc dl(N);
10071
10072 SDValue Lo = DAG.getNode(
10073 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10074 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
10075 MVT::i32));
10076 SDValue Hi = DAG.getNode(
10077 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10078 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
10079 MVT::i32));
10080
10081 return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
10082 {ST->getChain(), Lo, Hi, ST->getBasePtr()},
10083 MemVT, ST->getMemOperand());
10084 } else if (Subtarget->hasMVEIntegerOps() &&
10085 ((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10086 MemVT == MVT::v16i1))) {
10087 return LowerPredicateStore(Op, DAG);
10088 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10089 return LowerAEABIUnalignedStore(Op, DAG);
10090 }
10091 return SDValue();
10092}
10093
10094static bool isZeroVector(SDValue N) {
10095 return (ISD::isBuildVectorAllZeros(N.getNode()) ||
10096 (N->getOpcode() == ARMISD::VMOVIMM &&
10097 isNullConstant(N->getOperand(0))));
10098}
10099
10102 MVT VT = Op.getSimpleValueType();
10103 SDValue Mask = N->getMask();
10104 SDValue PassThru = N->getPassThru();
10105 SDLoc dl(Op);
10106
10107 if (isZeroVector(PassThru))
10108 return Op;
10109
10110 // MVE Masked loads use zero as the passthru value. Here we convert undef to
10111 // zero too, and other values are lowered to a select.
10112 SDValue ZeroVec = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
10113 DAG.getTargetConstant(0, dl, MVT::i32));
10114 SDValue NewLoad = DAG.getMaskedLoad(
10115 VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask, ZeroVec,
10116 N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
10117 N->getExtensionType(), N->isExpandingLoad());
10118 SDValue Combo = NewLoad;
10119 bool PassThruIsCastZero = (PassThru.getOpcode() == ISD::BITCAST ||
10120 PassThru.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
10121 isZeroVector(PassThru->getOperand(0));
10122 if (!PassThru.isUndef() && !PassThruIsCastZero)
10123 Combo = DAG.getNode(ISD::VSELECT, dl, VT, Mask, NewLoad, PassThru);
10124 return DAG.getMergeValues({Combo, NewLoad.getValue(1)}, dl);
10125}
10126
10128 const ARMSubtarget *ST) {
10129 if (!ST->hasMVEIntegerOps())
10130 return SDValue();
10131
10132 SDLoc dl(Op);
10133 unsigned BaseOpcode = 0;
10134 switch (Op->getOpcode()) {
10135 default: llvm_unreachable("Expected VECREDUCE opcode");
10136 case ISD::VECREDUCE_FADD: BaseOpcode = ISD::FADD; break;
10137 case ISD::VECREDUCE_FMUL: BaseOpcode = ISD::FMUL; break;
10138 case ISD::VECREDUCE_MUL: BaseOpcode = ISD::MUL; break;
10139 case ISD::VECREDUCE_AND: BaseOpcode = ISD::AND; break;
10140 case ISD::VECREDUCE_OR: BaseOpcode = ISD::OR; break;
10141 case ISD::VECREDUCE_XOR: BaseOpcode = ISD::XOR; break;
10142 case ISD::VECREDUCE_FMAX: BaseOpcode = ISD::FMAXNUM; break;
10143 case ISD::VECREDUCE_FMIN: BaseOpcode = ISD::FMINNUM; break;
10144 }
10145
10146 SDValue Op0 = Op->getOperand(0);
10147 EVT VT = Op0.getValueType();
10148 EVT EltVT = VT.getVectorElementType();
10149 unsigned NumElts = VT.getVectorNumElements();
10150 unsigned NumActiveLanes = NumElts;
10151
10152 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10153 NumActiveLanes == 2) &&
10154 "Only expected a power 2 vector size");
10155
10156 // Use Mul(X, Rev(X)) until 4 items remain. Going down to 4 vector elements
10157 // allows us to easily extract vector elements from the lanes.
10158 while (NumActiveLanes > 4) {
10159 unsigned RevOpcode = NumActiveLanes == 16 ? ARMISD::VREV16 : ARMISD::VREV32;
10160 SDValue Rev = DAG.getNode(RevOpcode, dl, VT, Op0);
10161 Op0 = DAG.getNode(BaseOpcode, dl, VT, Op0, Rev);
10162 NumActiveLanes /= 2;
10163 }
10164
10165 SDValue Res;
10166 if (NumActiveLanes == 4) {
10167 // The remaining 4 elements are summed sequentially
10168 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10169 DAG.getConstant(0 * NumElts / 4, dl, MVT::i32));
10170 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10171 DAG.getConstant(1 * NumElts / 4, dl, MVT::i32));
10172 SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10173 DAG.getConstant(2 * NumElts / 4, dl, MVT::i32));
10174 SDValue Ext3 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10175 DAG.getConstant(3 * NumElts / 4, dl, MVT::i32));
10176 SDValue Res0 = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10177 SDValue Res1 = DAG.getNode(BaseOpcode, dl, EltVT, Ext2, Ext3, Op->getFlags());
10178 Res = DAG.getNode(BaseOpcode, dl, EltVT, Res0, Res1, Op->getFlags());
10179 } else {
10180 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10181 DAG.getConstant(0, dl, MVT::i32));
10182 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10183 DAG.getConstant(1, dl, MVT::i32));
10184 Res = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10185 }
10186
10187 // Result type may be wider than element type.
10188 if (EltVT != Op->getValueType(0))
10189 Res = DAG.getNode(ISD::ANY_EXTEND, dl, Op->getValueType(0), Res);
10190 return Res;
10191}
10192
10194 const ARMSubtarget *ST) {
10195 if (!ST->hasMVEFloatOps())
10196 return SDValue();
10197 return LowerVecReduce(Op, DAG, ST);
10198}
10199
10201 const ARMSubtarget *ST) {
10202 if (!ST->hasNEON())
10203 return SDValue();
10204
10205 SDLoc dl(Op);
10206 SDValue Op0 = Op->getOperand(0);
10207 EVT VT = Op0.getValueType();
10208 EVT EltVT = VT.getVectorElementType();
10209
10210 unsigned PairwiseIntrinsic = 0;
10211 switch (Op->getOpcode()) {
10212 default:
10213 llvm_unreachable("Expected VECREDUCE opcode");
10215 PairwiseIntrinsic = Intrinsic::arm_neon_vpminu;
10216 break;
10218 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxu;
10219 break;
10221 PairwiseIntrinsic = Intrinsic::arm_neon_vpmins;
10222 break;
10224 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxs;
10225 break;
10226 }
10227 SDValue PairwiseOp = DAG.getConstant(PairwiseIntrinsic, dl, MVT::i32);
10228
10229 unsigned NumElts = VT.getVectorNumElements();
10230 unsigned NumActiveLanes = NumElts;
10231
10232 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10233 NumActiveLanes == 2) &&
10234 "Only expected a power 2 vector size");
10235
10236 // Split 128-bit vectors, since vpmin/max takes 2 64-bit vectors.
10237 if (VT.is128BitVector()) {
10238 SDValue Lo, Hi;
10239 std::tie(Lo, Hi) = DAG.SplitVector(Op0, dl);
10240 VT = Lo.getValueType();
10241 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Lo, Hi});
10242 NumActiveLanes /= 2;
10243 }
10244
10245 // Use pairwise reductions until one lane remains
10246 while (NumActiveLanes > 1) {
10247 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Op0, Op0});
10248 NumActiveLanes /= 2;
10249 }
10250
10251 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10252 DAG.getConstant(0, dl, MVT::i32));
10253
10254 // Result type may be wider than element type.
10255 if (EltVT != Op.getValueType()) {
10256 unsigned Extend = 0;
10257 switch (Op->getOpcode()) {
10258 default:
10259 llvm_unreachable("Expected VECREDUCE opcode");
10262 Extend = ISD::ZERO_EXTEND;
10263 break;
10266 Extend = ISD::SIGN_EXTEND;
10267 break;
10268 }
10269 Res = DAG.getNode(Extend, dl, Op.getValueType(), Res);
10270 }
10271 return Res;
10272}
10273
10275 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering()))
10276 // Acquire/Release load/store is not legal for targets without a dmb or
10277 // equivalent available.
10278 return SDValue();
10279
10280 // Monotonic load/store is legal for all targets.
10281 return Op;
10282}
10283
10286 SelectionDAG &DAG,
10287 const ARMSubtarget *Subtarget) {
10288 SDLoc DL(N);
10289 // Under Power Management extensions, the cycle-count is:
10290 // mrc p15, #0, <Rt>, c9, c13, #0
10291 SDValue Ops[] = { N->getOperand(0), // Chain
10292 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
10293 DAG.getTargetConstant(15, DL, MVT::i32),
10294 DAG.getTargetConstant(0, DL, MVT::i32),
10295 DAG.getTargetConstant(9, DL, MVT::i32),
10296 DAG.getTargetConstant(13, DL, MVT::i32),
10297 DAG.getTargetConstant(0, DL, MVT::i32)
10298 };
10299
10300 SDValue Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
10301 DAG.getVTList(MVT::i32, MVT::Other), Ops);
10302 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Cycles32,
10303 DAG.getConstant(0, DL, MVT::i32)));
10304 Results.push_back(Cycles32.getValue(1));
10305}
10306
10308 SDValue V1) {
10309 SDLoc dl(V0.getNode());
10310 SDValue RegClass =
10311 DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
10312 SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
10313 SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
10314 const SDValue Ops[] = {RegClass, V0, SubReg0, V1, SubReg1};
10315 return SDValue(
10316 DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
10317}
10318
10320 SDLoc dl(V.getNode());
10321 auto [VLo, VHi] = DAG.SplitScalar(V, dl, MVT::i32, MVT::i32);
10322 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10323 if (isBigEndian)
10324 std::swap(VLo, VHi);
10325 return createGPRPairNode2xi32(DAG, VLo, VHi);
10326}
10327
10330 SelectionDAG &DAG) {
10331 assert(N->getValueType(0) == MVT::i64 &&
10332 "AtomicCmpSwap on types less than 64 should be legal");
10333 SDValue Ops[] = {
10334 createGPRPairNode2xi32(DAG, N->getOperand(1),
10335 DAG.getUNDEF(MVT::i32)), // pointer, temp
10336 createGPRPairNodei64(DAG, N->getOperand(2)), // expected
10337 createGPRPairNodei64(DAG, N->getOperand(3)), // new
10338 N->getOperand(0), // chain in
10339 };
10340 SDNode *CmpSwap = DAG.getMachineNode(
10341 ARM::CMP_SWAP_64, SDLoc(N),
10342 DAG.getVTList(MVT::Untyped, MVT::Untyped, MVT::Other), Ops);
10343
10344 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
10345 DAG.setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
10346
10347 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10348
10349 SDValue Lo =
10350 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0,
10351 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10352 SDValue Hi =
10353 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1,
10354 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10355 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i64, Lo, Hi));
10356 Results.push_back(SDValue(CmpSwap, 2));
10357}
10358
10359SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
10360 SDLoc dl(Op);
10361 EVT VT = Op.getValueType();
10362 SDValue Chain = Op.getOperand(0);
10363 SDValue LHS = Op.getOperand(1);
10364 SDValue RHS = Op.getOperand(2);
10365 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
10366 bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
10367
10368 // If we don't have instructions of this float type then soften to a libcall
10369 // and use SETCC instead.
10370 if (isUnsupportedFloatingType(LHS.getValueType())) {
10371 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS,
10372 Chain, IsSignaling);
10373 if (!RHS.getNode()) {
10374 RHS = DAG.getConstant(0, dl, LHS.getValueType());
10375 CC = ISD::SETNE;
10376 }
10377 SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
10378 DAG.getCondCode(CC));
10379 return DAG.getMergeValues({Result, Chain}, dl);
10380 }
10381
10382 ARMCC::CondCodes CondCode, CondCode2;
10383 FPCCToARMCC(CC, CondCode, CondCode2);
10384
10385 SDValue True = DAG.getConstant(1, dl, VT);
10386 SDValue False = DAG.getConstant(0, dl, VT);
10387 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
10388 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
10389 SDValue Result = getCMOV(dl, VT, False, True, ARMcc, Cmp, DAG);
10390 if (CondCode2 != ARMCC::AL) {
10391 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
10392 Result = getCMOV(dl, VT, Result, True, ARMcc, Cmp, DAG);
10393 }
10394 return DAG.getMergeValues({Result, Chain}, dl);
10395}
10396
10397SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
10398 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
10399
10400 EVT VT = getPointerTy(DAG.getDataLayout());
10401 int FI = MFI.CreateFixedObject(4, 0, false);
10402 return DAG.getFrameIndex(FI, VT);
10403}
10404
10405SDValue ARMTargetLowering::LowerFP_TO_BF16(SDValue Op,
10406 SelectionDAG &DAG) const {
10407 SDLoc DL(Op);
10408 MakeLibCallOptions CallOptions;
10409 MVT SVT = Op.getOperand(0).getSimpleValueType();
10410 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, MVT::bf16);
10411 SDValue Res =
10412 makeLibCall(DAG, LC, MVT::f32, Op.getOperand(0), CallOptions, DL).first;
10413 return DAG.getBitcast(MVT::i32, Res);
10414}
10415
10416SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
10417 SDLoc dl(Op);
10418 SDValue LHS = Op.getOperand(0);
10419 SDValue RHS = Op.getOperand(1);
10420
10421 // Determine if this is signed or unsigned comparison
10422 bool IsSigned = (Op.getOpcode() == ISD::SCMP);
10423
10424 // Special case for Thumb1 UCMP only
10425 if (!IsSigned && Subtarget->isThumb1Only()) {
10426 // For Thumb unsigned comparison, use this sequence:
10427 // subs r2, r0, r1 ; r2 = LHS - RHS, sets flags
10428 // sbc r2, r2 ; r2 = r2 - r2 - !carry
10429 // cmp r1, r0 ; compare RHS with LHS
10430 // sbc r1, r1 ; r1 = r1 - r1 - !carry
10431 // subs r0, r2, r1 ; r0 = r2 - r1 (final result)
10432
10433 // First subtraction: LHS - RHS
10434 SDValue Sub1WithFlags = DAG.getNode(
10435 ARMISD::SUBC, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10436 SDValue Sub1Result = Sub1WithFlags.getValue(0);
10437 SDValue Flags1 = Sub1WithFlags.getValue(1);
10438
10439 // SUBE: Sub1Result - Sub1Result - !carry
10440 // This gives 0 if LHS >= RHS (unsigned), -1 if LHS < RHS (unsigned)
10441 SDValue Sbc1 =
10442 DAG.getNode(ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT),
10443 Sub1Result, Sub1Result, Flags1);
10444 SDValue Sbc1Result = Sbc1.getValue(0);
10445
10446 // Second comparison: RHS vs LHS (reverse comparison)
10447 SDValue CmpFlags = DAG.getNode(ARMISD::CMP, dl, FlagsVT, RHS, LHS);
10448
10449 // SUBE: RHS - RHS - !carry
10450 // This gives 0 if RHS <= LHS (unsigned), -1 if RHS > LHS (unsigned)
10451 SDValue Sbc2 = DAG.getNode(
10452 ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT), RHS, RHS, CmpFlags);
10453 SDValue Sbc2Result = Sbc2.getValue(0);
10454
10455 // Final subtraction: Sbc1Result - Sbc2Result (no flags needed)
10456 SDValue Result =
10457 DAG.getNode(ISD::SUB, dl, MVT::i32, Sbc1Result, Sbc2Result);
10458 if (Op.getValueType() != MVT::i32)
10459 Result = DAG.getSExtOrTrunc(Result, dl, Op.getValueType());
10460
10461 return Result;
10462 }
10463
10464 // For the ARM assembly pattern:
10465 // subs r0, r0, r1 ; subtract RHS from LHS and set flags
10466 // movgt r0, #1 ; if LHS > RHS, set result to 1 (GT for signed, HI for
10467 // unsigned) mvnlt r0, #0 ; if LHS < RHS, set result to -1 (LT for
10468 // signed, LO for unsigned)
10469 // ; if LHS == RHS, result remains 0 from the subs
10470
10471 // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
10472 unsigned Opcode = ARMISD::SUBC;
10473
10474 // Check if RHS is a subtraction against 0: (0 - X)
10475 if (RHS.getOpcode() == ISD::SUB) {
10476 SDValue SubLHS = RHS.getOperand(0);
10477 SDValue SubRHS = RHS.getOperand(1);
10478
10479 // Check if it's 0 - X
10480 if (isNullConstant(SubLHS)) {
10481 bool CanUseAdd = false;
10482 if (IsSigned) {
10483 // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
10484 if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
10486 .isMinSignedValue()) {
10487 CanUseAdd = true;
10488 }
10489 } else {
10490 // For UCMP: only if X is known to never be zero
10491 if (DAG.isKnownNeverZero(SubRHS)) {
10492 CanUseAdd = true;
10493 }
10494 }
10495
10496 if (CanUseAdd) {
10497 Opcode = ARMISD::ADDC;
10498 RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
10499 // LHS - (0 - X)
10500 }
10501 }
10502 }
10503
10504 // Generate the operation with flags
10505 SDValue OpWithFlags =
10506 DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10507
10508 SDValue OpResult = OpWithFlags.getValue(0);
10509 SDValue Flags = OpWithFlags.getValue(1);
10510
10511 // Constants for conditional moves
10512 SDValue One = DAG.getConstant(1, dl, MVT::i32);
10513 SDValue MinusOne = DAG.getAllOnesConstant(dl, MVT::i32);
10514
10515 // Select condition codes based on signed vs unsigned
10516 ARMCC::CondCodes GTCond = IsSigned ? ARMCC::GT : ARMCC::HI;
10517 ARMCC::CondCodes LTCond = IsSigned ? ARMCC::LT : ARMCC::LO;
10518
10519 // First conditional move: if greater than, set to 1
10520 SDValue GTCondValue = DAG.getConstant(GTCond, dl, MVT::i32);
10521 SDValue Result1 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, OpResult, One,
10522 GTCondValue, Flags);
10523
10524 // Second conditional move: if less than, set to -1
10525 SDValue LTCondValue = DAG.getConstant(LTCond, dl, MVT::i32);
10526 SDValue Result2 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, Result1, MinusOne,
10527 LTCondValue, Flags);
10528
10529 if (Op.getValueType() != MVT::i32)
10530 Result2 = DAG.getSExtOrTrunc(Result2, dl, Op.getValueType());
10531
10532 return Result2;
10533}
10534
10536 LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
10537 switch (Op.getOpcode()) {
10538 default: llvm_unreachable("Don't know how to custom lower this!");
10539 case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
10540 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
10541 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
10542 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
10543 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
10544 case ISD::SELECT: return LowerSELECT(Op, DAG);
10545 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10546 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
10547 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
10548 case ISD::BR_JT: return LowerBR_JT(Op, DAG);
10549 case ISD::VASTART: return LowerVASTART(Op, DAG);
10550 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget);
10551 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget);
10554 case ISD::SINT_TO_FP:
10555 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
10558 case ISD::FP_TO_SINT:
10559 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
10561 case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG, Subtarget);
10562 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
10563 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
10564 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
10565 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
10566 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
10567 case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
10568 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
10569 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
10570 Subtarget);
10571 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);
10572 case ISD::SHL:
10573 case ISD::SRL:
10574 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget);
10575 case ISD::SREM: return LowerREM(Op.getNode(), DAG);
10576 case ISD::UREM: return LowerREM(Op.getNode(), DAG);
10577 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
10578 case ISD::SRL_PARTS:
10579 case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
10580 case ISD::CTTZ:
10581 case ISD::CTTZ_ZERO_POISON: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
10582 case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
10583 case ISD::SETCC: return LowerVSETCC(Op, DAG, Subtarget);
10584 case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
10585 case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
10586 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
10587 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
10588 case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG, Subtarget);
10589 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
10590 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
10591 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
10592 case ISD::TRUNCATE: return LowerTruncate(Op.getNode(), DAG, Subtarget);
10593 case ISD::SIGN_EXTEND:
10594 case ISD::ZERO_EXTEND: return LowerVectorExtend(Op.getNode(), DAG, Subtarget);
10595 case ISD::GET_ROUNDING: return LowerGET_ROUNDING(Op, DAG);
10596 case ISD::SET_ROUNDING: return LowerSET_ROUNDING(Op, DAG);
10597 case ISD::SET_FPMODE:
10598 return LowerSET_FPMODE(Op, DAG);
10599 case ISD::RESET_FPMODE:
10600 return LowerRESET_FPMODE(Op, DAG);
10601 case ISD::MUL: return LowerMUL(Op, DAG);
10602 case ISD::SDIV:
10603 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10604 !Op.getValueType().isVector())
10605 return LowerDIV_Windows(Op, DAG, /* Signed */ true);
10606 return LowerSDIV(Op, DAG, Subtarget);
10607 case ISD::UDIV:
10608 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10609 !Op.getValueType().isVector())
10610 return LowerDIV_Windows(Op, DAG, /* Signed */ false);
10611 return LowerUDIV(Op, DAG, Subtarget);
10612 case ISD::UADDO_CARRY:
10613 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, false /*unsigned*/);
10614 case ISD::USUBO_CARRY:
10615 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, false /*unsigned*/);
10616 case ISD::SADDO_CARRY:
10617 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, true /*signed*/);
10618 case ISD::SSUBO_CARRY:
10619 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, true /*signed*/);
10620 case ISD::UADDO:
10621 case ISD::USUBO:
10622 case ISD::UMULO:
10623 case ISD::SADDO:
10624 case ISD::SSUBO:
10625 case ISD::SMULO:
10626 return LowerALUO(Op, DAG);
10627 case ISD::SADDSAT:
10628 case ISD::SSUBSAT:
10629 case ISD::UADDSAT:
10630 case ISD::USUBSAT:
10631 return LowerADDSUBSAT(Op, DAG, Subtarget);
10632 case ISD::LOAD: {
10633 auto *LD = cast<LoadSDNode>(Op);
10634 EVT MemVT = LD->getMemoryVT();
10635 if (Subtarget->hasMVEIntegerOps() &&
10636 (MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10637 MemVT == MVT::v16i1))
10638 return LowerPredicateLoad(Op, DAG);
10639
10640 auto Pair = LowerAEABIUnalignedLoad(Op, DAG);
10641 if (Pair.first)
10642 return DAG.getMergeValues({Pair.first, Pair.second}, SDLoc(Pair.first));
10643 return SDValue();
10644 }
10645 case ISD::STORE:
10646 return LowerSTORE(Op, DAG, Subtarget);
10647 case ISD::MLOAD:
10648 return LowerMLOAD(Op, DAG);
10649 case ISD::VECREDUCE_MUL:
10650 case ISD::VECREDUCE_AND:
10651 case ISD::VECREDUCE_OR:
10652 case ISD::VECREDUCE_XOR:
10653 return LowerVecReduce(Op, DAG, Subtarget);
10658 return LowerVecReduceF(Op, DAG, Subtarget);
10663 return LowerVecReduceMinMax(Op, DAG, Subtarget);
10664 case ISD::ATOMIC_LOAD:
10665 case ISD::ATOMIC_STORE:
10666 return LowerAtomicLoadStore(Op, DAG);
10667 case ISD::SDIVREM:
10668 case ISD::UDIVREM: return LowerDivRem(Op, DAG);
10670 if (getTargetMachine().getTargetTriple().isOSWindows())
10671 return LowerDYNAMIC_STACKALLOC(Op, DAG);
10672 llvm_unreachable("Don't know how to custom lower this!");
10674 case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
10676 case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
10677 case ISD::STRICT_FSETCC:
10678 case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
10679 case ISD::SPONENTRY:
10680 return LowerSPONENTRY(Op, DAG);
10681 case ISD::FP_TO_BF16:
10682 return LowerFP_TO_BF16(Op, DAG);
10683 case ARMISD::WIN__DBZCHK: return SDValue();
10684 case ISD::UCMP:
10685 case ISD::SCMP:
10686 return LowerCMP(Op, DAG);
10687 case ISD::ABS:
10688 return LowerABS(Op, DAG);
10689 case ISD::STRICT_LROUND:
10691 case ISD::STRICT_LRINT:
10692 case ISD::STRICT_LLRINT: {
10693 assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10694 Op.getOperand(1).getValueType() == MVT::bf16) &&
10695 "Expected custom lowering of rounding operations only for f16");
10696 SDLoc DL(Op);
10697 SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10698 {Op.getOperand(0), Op.getOperand(1)});
10699 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10700 {Ext.getValue(1), Ext.getValue(0)});
10701 }
10702 }
10703}
10704
10706 SelectionDAG &DAG) {
10707 unsigned IntNo = N->getConstantOperandVal(0);
10708 unsigned Opc = 0;
10709 if (IntNo == Intrinsic::arm_smlald)
10710 Opc = ARMISD::SMLALD;
10711 else if (IntNo == Intrinsic::arm_smlaldx)
10712 Opc = ARMISD::SMLALDX;
10713 else if (IntNo == Intrinsic::arm_smlsld)
10714 Opc = ARMISD::SMLSLD;
10715 else if (IntNo == Intrinsic::arm_smlsldx)
10716 Opc = ARMISD::SMLSLDX;
10717 else
10718 return;
10719
10720 SDLoc dl(N);
10721 SDValue Lo, Hi;
10722 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32);
10723
10724 SDValue LongMul = DAG.getNode(Opc, dl,
10725 DAG.getVTList(MVT::i32, MVT::i32),
10726 N->getOperand(1), N->getOperand(2),
10727 Lo, Hi);
10728 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
10729 LongMul.getValue(0), LongMul.getValue(1)));
10730}
10731
10732/// ReplaceNodeResults - Replace the results of node with an illegal result
10733/// type with new values built out of custom code.
10736 SelectionDAG &DAG) const {
10737 SDValue Res;
10738 switch (N->getOpcode()) {
10739 default:
10740 llvm_unreachable("Don't know how to custom expand this!");
10741 case ISD::READ_REGISTER:
10743 break;
10744 case ISD::BITCAST:
10745 Res = ExpandBITCAST(N, DAG, Subtarget);
10746 break;
10747 case ISD::SRL:
10748 case ISD::SRA:
10749 case ISD::SHL:
10750 Res = Expand64BitShift(N, DAG, Subtarget);
10751 break;
10752 case ISD::SREM:
10753 case ISD::UREM:
10754 Res = LowerREM(N, DAG);
10755 break;
10756 case ISD::SDIVREM:
10757 case ISD::UDIVREM:
10758 Res = LowerDivRem(SDValue(N, 0), DAG);
10759 assert(Res.getNumOperands() == 2 && "DivRem needs two values");
10760 Results.push_back(Res.getValue(0));
10761 Results.push_back(Res.getValue(1));
10762 return;
10763 case ISD::SADDSAT:
10764 case ISD::SSUBSAT:
10765 case ISD::UADDSAT:
10766 case ISD::USUBSAT:
10767 Res = LowerADDSUBSAT(SDValue(N, 0), DAG, Subtarget);
10768 break;
10770 ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
10771 return;
10772 case ISD::UDIV:
10773 case ISD::SDIV:
10774 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
10775 "can only expand DIV on Windows");
10776 return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
10777 Results);
10780 return;
10782 return ReplaceLongIntrinsic(N, Results, DAG);
10783 case ISD::LOAD:
10784 LowerLOAD(N, Results, DAG);
10785 break;
10786 case ISD::STORE:
10787 Res = LowerAEABIUnalignedStore(SDValue(N, 0), DAG);
10788 break;
10789 case ISD::TRUNCATE:
10790 Res = LowerTruncate(N, DAG, Subtarget);
10791 break;
10792 case ISD::SIGN_EXTEND:
10793 case ISD::ZERO_EXTEND:
10794 Res = LowerVectorExtend(N, DAG, Subtarget);
10795 break;
10798 Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
10799 break;
10800 }
10801 if (Res.getNode())
10802 Results.push_back(Res);
10803}
10804
10805//===----------------------------------------------------------------------===//
10806// ARM Scheduler Hooks
10807//===----------------------------------------------------------------------===//
10808
10809/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and
10810/// registers the function context.
10811void ARMTargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
10813 MachineBasicBlock *DispatchBB,
10814 int FI) const {
10815 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
10816 "ROPI/RWPI not currently supported with SjLj");
10817 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10818 DebugLoc dl = MI.getDebugLoc();
10819 MachineFunction *MF = MBB->getParent();
10820 MachineRegisterInfo *MRI = &MF->getRegInfo();
10823 const Function &F = MF->getFunction();
10824
10825 bool isThumb = Subtarget->isThumb();
10826 bool isThumb2 = Subtarget->isThumb2();
10827
10828 unsigned PCLabelId = AFI->createPICLabelUId();
10829 unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8;
10831 ARMConstantPoolMBB::Create(F.getContext(), DispatchBB, PCLabelId, PCAdj);
10832 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
10833
10834 const TargetRegisterClass *TRC = isThumb ? &ARM::tGPRRegClass
10835 : &ARM::GPRRegClass;
10836
10837 // Grab constant pool and fixed stack memory operands.
10838 MachineMemOperand *CPMMO =
10841
10842 MachineMemOperand *FIMMOSt =
10845
10846 // Load the address of the dispatch MBB into the jump buffer.
10847 if (isThumb2) {
10848 // Incoming value: jbuf
10849 // ldr.n r5, LCPI1_1
10850 // orr r5, r5, #1
10851 // add r5, pc
10852 // str r5, [$jbuf, #+4] ; &jbuf[1]
10853 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10854 BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1)
10856 .addMemOperand(CPMMO)
10858 // Set the low bit because of thumb mode.
10859 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10860 BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2)
10861 .addReg(NewVReg1, RegState::Kill)
10862 .addImm(0x01)
10864 .add(condCodeOp());
10865 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10866 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3)
10867 .addReg(NewVReg2, RegState::Kill)
10868 .addImm(PCLabelId);
10869 BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12))
10870 .addReg(NewVReg3, RegState::Kill)
10871 .addFrameIndex(FI)
10872 .addImm(36) // &jbuf[1] :: pc
10873 .addMemOperand(FIMMOSt)
10875 } else if (isThumb) {
10876 // Incoming value: jbuf
10877 // ldr.n r1, LCPI1_4
10878 // add r1, pc
10879 // mov r2, #1
10880 // orrs r1, r2
10881 // add r2, $jbuf, #+4 ; &jbuf[1]
10882 // str r1, [r2]
10883 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10884 BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1)
10886 .addMemOperand(CPMMO)
10888 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10889 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2)
10890 .addReg(NewVReg1, RegState::Kill)
10891 .addImm(PCLabelId);
10892 // Set the low bit because of thumb mode.
10893 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10894 BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3)
10895 .addReg(ARM::CPSR, RegState::Define)
10896 .addImm(1)
10898 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10899 BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4)
10900 .addReg(ARM::CPSR, RegState::Define)
10901 .addReg(NewVReg2, RegState::Kill)
10902 .addReg(NewVReg3, RegState::Kill)
10904 Register NewVReg5 = MRI->createVirtualRegister(TRC);
10905 BuildMI(*MBB, MI, dl, TII->get(ARM::tADDframe), NewVReg5)
10906 .addFrameIndex(FI)
10907 .addImm(36); // &jbuf[1] :: pc
10908 BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi))
10909 .addReg(NewVReg4, RegState::Kill)
10910 .addReg(NewVReg5, RegState::Kill)
10911 .addImm(0)
10912 .addMemOperand(FIMMOSt)
10914 } else {
10915 // Incoming value: jbuf
10916 // ldr r1, LCPI1_1
10917 // add r1, pc, r1
10918 // str r1, [$jbuf, #+4] ; &jbuf[1]
10919 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10920 BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1)
10922 .addImm(0)
10923 .addMemOperand(CPMMO)
10925 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10926 BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
10927 .addReg(NewVReg1, RegState::Kill)
10928 .addImm(PCLabelId)
10930 BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
10931 .addReg(NewVReg2, RegState::Kill)
10932 .addFrameIndex(FI)
10933 .addImm(36) // &jbuf[1] :: pc
10934 .addMemOperand(FIMMOSt)
10936 }
10937}
10938
10939void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
10940 MachineBasicBlock *MBB) const {
10941 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10942 DebugLoc dl = MI.getDebugLoc();
10943 MachineFunction *MF = MBB->getParent();
10944 MachineRegisterInfo *MRI = &MF->getRegInfo();
10945 MachineFrameInfo &MFI = MF->getFrameInfo();
10946 int FI = MFI.getFunctionContextIndex();
10947
10948 const TargetRegisterClass *TRC = Subtarget->isThumb() ? &ARM::tGPRRegClass
10949 : &ARM::GPRnopcRegClass;
10950
10951 // Get a mapping of the call site numbers to all of the landing pads they're
10952 // associated with.
10953 DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2>> CallSiteNumToLPad;
10954 unsigned MaxCSNum = 0;
10955 for (MachineBasicBlock &BB : *MF) {
10956 if (!BB.isEHPad())
10957 continue;
10958
10959 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
10960 // pad.
10961 for (MachineInstr &II : BB) {
10962 if (!II.isEHLabel())
10963 continue;
10964
10965 MCSymbol *Sym = II.getOperand(0).getMCSymbol();
10966 if (!MF->hasCallSiteLandingPad(Sym)) continue;
10967
10968 SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
10969 for (unsigned Idx : CallSiteIdxs) {
10970 CallSiteNumToLPad[Idx].push_back(&BB);
10971 MaxCSNum = std::max(MaxCSNum, Idx);
10972 }
10973 break;
10974 }
10975 }
10976
10977 // Get an ordered list of the machine basic blocks for the jump table.
10978 std::vector<MachineBasicBlock*> LPadList;
10979 SmallPtrSet<MachineBasicBlock*, 32> InvokeBBs;
10980 LPadList.reserve(CallSiteNumToLPad.size());
10981 for (unsigned I = 1; I <= MaxCSNum; ++I) {
10982 SmallVectorImpl<MachineBasicBlock*> &MBBList = CallSiteNumToLPad[I];
10983 for (MachineBasicBlock *MBB : MBBList) {
10984 LPadList.push_back(MBB);
10985 InvokeBBs.insert_range(MBB->predecessors());
10986 }
10987 }
10988
10989 assert(!LPadList.empty() &&
10990 "No landing pad destinations for the dispatch jump table!");
10991
10992 // Create the jump table and associated information.
10993 MachineJumpTableInfo *JTI =
10994 MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline);
10995 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
10996
10997 // Create the MBBs for the dispatch code.
10998
10999 // Shove the dispatch's address into the return slot in the function context.
11000 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
11001 DispatchBB->setIsEHPad();
11002
11003 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11004
11005 BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
11006 DispatchBB->addSuccessor(TrapBB);
11007
11008 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
11009 DispatchBB->addSuccessor(DispContBB);
11010
11011 // Insert and MBBs.
11012 MF->insert(MF->end(), DispatchBB);
11013 MF->insert(MF->end(), DispContBB);
11014 MF->insert(MF->end(), TrapBB);
11015
11016 // Insert code into the entry block that creates and registers the function
11017 // context.
11018 SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI);
11019
11020 MachineMemOperand *FIMMOLd = MF->getMachineMemOperand(
11023
11024 MachineInstrBuilder MIB;
11025 MIB = BuildMI(DispatchBB, dl, TII->get(ARM::Int_eh_sjlj_dispatchsetup));
11026
11027 const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
11028 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
11029
11030 // Add a register mask with no preserved registers. This results in all
11031 // registers being marked as clobbered. This can't work if the dispatch block
11032 // is in a Thumb1 function and is linked with ARM code which uses the FP
11033 // registers, as there is no way to preserve the FP registers in Thumb1 mode.
11035
11036 bool IsPositionIndependent = isPositionIndependent();
11037 unsigned NumLPads = LPadList.size();
11038 if (Subtarget->isThumb2()) {
11039 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11040 BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1)
11041 .addFrameIndex(FI)
11042 .addImm(4)
11043 .addMemOperand(FIMMOLd)
11045
11046 if (NumLPads < 256) {
11047 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri))
11048 .addReg(NewVReg1)
11049 .addImm(LPadList.size())
11051 } else {
11052 Register VReg1 = MRI->createVirtualRegister(TRC);
11053 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVi16), VReg1)
11054 .addImm(NumLPads & 0xFFFF)
11056
11057 unsigned VReg2 = VReg1;
11058 if ((NumLPads & 0xFFFF0000) != 0) {
11059 VReg2 = MRI->createVirtualRegister(TRC);
11060 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVTi16), VReg2)
11061 .addReg(VReg1)
11062 .addImm(NumLPads >> 16)
11064 }
11065
11066 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPrr))
11067 .addReg(NewVReg1)
11068 .addReg(VReg2)
11070 }
11071
11072 BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc))
11073 .addMBB(TrapBB)
11075 .addReg(ARM::CPSR);
11076
11077 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11078 BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT), NewVReg3)
11079 .addJumpTableIndex(MJTI)
11081
11082 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11083 BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg4)
11084 .addReg(NewVReg3, RegState::Kill)
11085 .addReg(NewVReg1)
11088 .add(condCodeOp());
11089
11090 BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT))
11091 .addReg(NewVReg4, RegState::Kill)
11092 .addReg(NewVReg1)
11093 .addJumpTableIndex(MJTI);
11094 } else if (Subtarget->isThumb()) {
11095 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11096 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1)
11097 .addFrameIndex(FI)
11098 .addImm(1)
11099 .addMemOperand(FIMMOLd)
11101
11102 if (NumLPads < 256) {
11103 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8))
11104 .addReg(NewVReg1)
11105 .addImm(NumLPads)
11107 } else {
11108 MachineConstantPool *ConstantPool = MF->getConstantPool();
11109 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11110 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11111
11112 // MachineConstantPool wants an explicit alignment.
11113 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11114 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11115
11116 Register VReg1 = MRI->createVirtualRegister(TRC);
11117 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRpci))
11118 .addReg(VReg1, RegState::Define)
11121 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPr))
11122 .addReg(NewVReg1)
11123 .addReg(VReg1)
11125 }
11126
11127 BuildMI(DispatchBB, dl, TII->get(ARM::tBcc))
11128 .addMBB(TrapBB)
11130 .addReg(ARM::CPSR);
11131
11132 Register NewVReg2 = MRI->createVirtualRegister(TRC);
11133 BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2)
11134 .addReg(ARM::CPSR, RegState::Define)
11135 .addReg(NewVReg1)
11136 .addImm(2)
11138
11139 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11140 BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3)
11141 .addJumpTableIndex(MJTI)
11143
11144 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11145 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4)
11146 .addReg(ARM::CPSR, RegState::Define)
11147 .addReg(NewVReg2, RegState::Kill)
11148 .addReg(NewVReg3)
11150
11151 MachineMemOperand *JTMMOLd =
11152 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11154
11155 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11156 BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5)
11157 .addReg(NewVReg4, RegState::Kill)
11158 .addImm(0)
11159 .addMemOperand(JTMMOLd)
11161
11162 unsigned NewVReg6 = NewVReg5;
11163 if (IsPositionIndependent) {
11164 NewVReg6 = MRI->createVirtualRegister(TRC);
11165 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6)
11166 .addReg(ARM::CPSR, RegState::Define)
11167 .addReg(NewVReg5, RegState::Kill)
11168 .addReg(NewVReg3)
11170 }
11171
11172 BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr))
11173 .addReg(NewVReg6, RegState::Kill)
11174 .addJumpTableIndex(MJTI);
11175 } else {
11176 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11177 BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1)
11178 .addFrameIndex(FI)
11179 .addImm(4)
11180 .addMemOperand(FIMMOLd)
11182
11183 if (NumLPads < 256) {
11184 BuildMI(DispatchBB, dl, TII->get(ARM::CMPri))
11185 .addReg(NewVReg1)
11186 .addImm(NumLPads)
11188 } else if (Subtarget->hasV6T2Ops() && isUInt<16>(NumLPads)) {
11189 Register VReg1 = MRI->createVirtualRegister(TRC);
11190 BuildMI(DispatchBB, dl, TII->get(ARM::MOVi16), VReg1)
11191 .addImm(NumLPads & 0xFFFF)
11193
11194 unsigned VReg2 = VReg1;
11195 if ((NumLPads & 0xFFFF0000) != 0) {
11196 VReg2 = MRI->createVirtualRegister(TRC);
11197 BuildMI(DispatchBB, dl, TII->get(ARM::MOVTi16), VReg2)
11198 .addReg(VReg1)
11199 .addImm(NumLPads >> 16)
11201 }
11202
11203 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11204 .addReg(NewVReg1)
11205 .addReg(VReg2)
11207 } else {
11208 MachineConstantPool *ConstantPool = MF->getConstantPool();
11209 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11210 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11211
11212 // MachineConstantPool wants an explicit alignment.
11213 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11214 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11215
11216 Register VReg1 = MRI->createVirtualRegister(TRC);
11217 BuildMI(DispatchBB, dl, TII->get(ARM::LDRcp))
11218 .addReg(VReg1, RegState::Define)
11220 .addImm(0)
11222 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11223 .addReg(NewVReg1)
11224 .addReg(VReg1, RegState::Kill)
11226 }
11227
11228 BuildMI(DispatchBB, dl, TII->get(ARM::Bcc))
11229 .addMBB(TrapBB)
11231 .addReg(ARM::CPSR);
11232
11233 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11234 BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg3)
11235 .addReg(NewVReg1)
11238 .add(condCodeOp());
11239 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11240 BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg4)
11241 .addJumpTableIndex(MJTI)
11243
11244 MachineMemOperand *JTMMOLd =
11245 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11247 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11248 BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg5)
11249 .addReg(NewVReg3, RegState::Kill)
11250 .addReg(NewVReg4)
11251 .addImm(0)
11252 .addMemOperand(JTMMOLd)
11254
11255 if (IsPositionIndependent) {
11256 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd))
11257 .addReg(NewVReg5, RegState::Kill)
11258 .addReg(NewVReg4)
11259 .addJumpTableIndex(MJTI);
11260 } else {
11261 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTr))
11262 .addReg(NewVReg5, RegState::Kill)
11263 .addJumpTableIndex(MJTI);
11264 }
11265 }
11266
11267 // Add the jump table entries as successors to the MBB.
11268 SmallPtrSet<MachineBasicBlock*, 8> SeenMBBs;
11269 for (MachineBasicBlock *CurMBB : LPadList) {
11270 if (SeenMBBs.insert(CurMBB).second)
11271 DispContBB->addSuccessor(CurMBB);
11272 }
11273
11274 // N.B. the order the invoke BBs are processed in doesn't matter here.
11275 const MCPhysReg *SavedRegs = RI.getCalleeSavedRegs(MF);
11277 for (MachineBasicBlock *BB : InvokeBBs) {
11278
11279 // Remove the landing pad successor from the invoke block and replace it
11280 // with the new dispatch block.
11281 SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
11282 while (!Successors.empty()) {
11283 MachineBasicBlock *SMBB = Successors.pop_back_val();
11284 if (SMBB->isEHPad()) {
11285 BB->removeSuccessor(SMBB);
11286 MBBLPads.push_back(SMBB);
11287 }
11288 }
11289
11290 BB->addSuccessor(DispatchBB, BranchProbability::getZero());
11291 BB->normalizeSuccProbs();
11292
11293 // Find the invoke call and mark all of the callee-saved registers as
11294 // 'implicit defined' so that they're spilled. This prevents code from
11295 // moving instructions to before the EH block, where they will never be
11296 // executed.
11298 II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
11299 if (!II->isCall()) continue;
11300
11301 DenseSet<unsigned> DefRegs;
11303 OI = II->operands_begin(), OE = II->operands_end();
11304 OI != OE; ++OI) {
11305 if (!OI->isReg()) continue;
11306 DefRegs.insert(OI->getReg());
11307 }
11308
11309 MachineInstrBuilder MIB(*MF, &*II);
11310
11311 for (unsigned i = 0; SavedRegs[i] != 0; ++i) {
11312 unsigned Reg = SavedRegs[i];
11313 if (Subtarget->isThumb2() &&
11314 !ARM::tGPRRegClass.contains(Reg) &&
11315 !ARM::hGPRRegClass.contains(Reg))
11316 continue;
11317 if (Subtarget->isThumb1Only() && !ARM::tGPRRegClass.contains(Reg))
11318 continue;
11319 if (!Subtarget->isThumb() && !ARM::GPRRegClass.contains(Reg))
11320 continue;
11321 if (!DefRegs.contains(Reg))
11323 }
11324
11325 break;
11326 }
11327 }
11328
11329 // Mark all former landing pads as non-landing pads. The dispatch is the only
11330 // landing pad now.
11331 for (MachineBasicBlock *MBBLPad : MBBLPads)
11332 MBBLPad->setIsEHPad(false);
11333
11334 // The instruction is gone now.
11335 MI.eraseFromParent();
11336}
11337
11338static
11340 for (MachineBasicBlock *S : MBB->successors())
11341 if (S != Succ)
11342 return S;
11343 llvm_unreachable("Expecting a BB with two successors!");
11344}
11345
11346/// Return the load opcode for a given load size. If load size >= 8,
11347/// neon opcode will be returned.
11348static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2) {
11349 if (LdSize >= 8)
11350 return LdSize == 16 ? ARM::VLD1q32wb_fixed
11351 : LdSize == 8 ? ARM::VLD1d32wb_fixed : 0;
11352 if (IsThumb1)
11353 return LdSize == 4 ? ARM::tLDRi
11354 : LdSize == 2 ? ARM::tLDRHi
11355 : LdSize == 1 ? ARM::tLDRBi : 0;
11356 if (IsThumb2)
11357 return LdSize == 4 ? ARM::t2LDR_POST
11358 : LdSize == 2 ? ARM::t2LDRH_POST
11359 : LdSize == 1 ? ARM::t2LDRB_POST : 0;
11360 return LdSize == 4 ? ARM::LDR_POST_IMM
11361 : LdSize == 2 ? ARM::LDRH_POST
11362 : LdSize == 1 ? ARM::LDRB_POST_IMM : 0;
11363}
11364
11365/// Return the store opcode for a given store size. If store size >= 8,
11366/// neon opcode will be returned.
11367static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2) {
11368 if (StSize >= 8)
11369 return StSize == 16 ? ARM::VST1q32wb_fixed
11370 : StSize == 8 ? ARM::VST1d32wb_fixed : 0;
11371 if (IsThumb1)
11372 return StSize == 4 ? ARM::tSTRi
11373 : StSize == 2 ? ARM::tSTRHi
11374 : StSize == 1 ? ARM::tSTRBi : 0;
11375 if (IsThumb2)
11376 return StSize == 4 ? ARM::t2STR_POST
11377 : StSize == 2 ? ARM::t2STRH_POST
11378 : StSize == 1 ? ARM::t2STRB_POST : 0;
11379 return StSize == 4 ? ARM::STR_POST_IMM
11380 : StSize == 2 ? ARM::STRH_POST
11381 : StSize == 1 ? ARM::STRB_POST_IMM : 0;
11382}
11383
11384/// Emit a post-increment load operation with given size. The instructions
11385/// will be added to BB at Pos.
11387 const TargetInstrInfo *TII, const DebugLoc &dl,
11388 unsigned LdSize, unsigned Data, unsigned AddrIn,
11389 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11390 unsigned LdOpc = getLdOpcode(LdSize, IsThumb1, IsThumb2);
11391 assert(LdOpc != 0 && "Should have a load opcode");
11392 if (LdSize >= 8) {
11393 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11394 .addReg(AddrOut, RegState::Define)
11395 .addReg(AddrIn)
11396 .addImm(0)
11398 } else if (IsThumb1) {
11399 // load + update AddrIn
11400 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11401 .addReg(AddrIn)
11402 .addImm(0)
11404 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11405 .add(t1CondCodeOp())
11406 .addReg(AddrIn)
11407 .addImm(LdSize)
11409 } else if (IsThumb2) {
11410 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11411 .addReg(AddrOut, RegState::Define)
11412 .addReg(AddrIn)
11413 .addImm(LdSize)
11415 } else { // arm
11416 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11417 .addReg(AddrOut, RegState::Define)
11418 .addReg(AddrIn)
11419 .addReg(0)
11420 .addImm(LdSize)
11422 }
11423}
11424
11425/// Emit a post-increment store operation with given size. The instructions
11426/// will be added to BB at Pos.
11428 const TargetInstrInfo *TII, const DebugLoc &dl,
11429 unsigned StSize, unsigned Data, unsigned AddrIn,
11430 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11431 unsigned StOpc = getStOpcode(StSize, IsThumb1, IsThumb2);
11432 assert(StOpc != 0 && "Should have a store opcode");
11433 if (StSize >= 8) {
11434 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11435 .addReg(AddrIn)
11436 .addImm(0)
11437 .addReg(Data)
11439 } else if (IsThumb1) {
11440 // store + update AddrIn
11441 BuildMI(*BB, Pos, dl, TII->get(StOpc))
11442 .addReg(Data)
11443 .addReg(AddrIn)
11444 .addImm(0)
11446 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11447 .add(t1CondCodeOp())
11448 .addReg(AddrIn)
11449 .addImm(StSize)
11451 } else if (IsThumb2) {
11452 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11453 .addReg(Data)
11454 .addReg(AddrIn)
11455 .addImm(StSize)
11457 } else { // arm
11458 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11459 .addReg(Data)
11460 .addReg(AddrIn)
11461 .addReg(0)
11462 .addImm(StSize)
11464 }
11465}
11466
11468ARMTargetLowering::EmitStructByval(MachineInstr &MI,
11469 MachineBasicBlock *BB) const {
11470 // This pseudo instruction has 3 operands: dst, src, size
11471 // We expand it to a loop if size > Subtarget->getMaxInlineSizeThreshold().
11472 // Otherwise, we will generate unrolled scalar copies.
11473 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11474 const BasicBlock *LLVM_BB = BB->getBasicBlock();
11476
11477 Register dest = MI.getOperand(0).getReg();
11478 Register src = MI.getOperand(1).getReg();
11479 unsigned SizeVal = MI.getOperand(2).getImm();
11480 unsigned Alignment = MI.getOperand(3).getImm();
11481 DebugLoc dl = MI.getDebugLoc();
11482
11483 MachineFunction *MF = BB->getParent();
11484 MachineRegisterInfo &MRI = MF->getRegInfo();
11485 unsigned UnitSize = 0;
11486 const TargetRegisterClass *TRC = nullptr;
11487 const TargetRegisterClass *VecTRC = nullptr;
11488
11489 bool IsThumb1 = Subtarget->isThumb1Only();
11490 bool IsThumb2 = Subtarget->isThumb2();
11491 bool IsThumb = Subtarget->isThumb();
11492
11493 if (Alignment & 1) {
11494 UnitSize = 1;
11495 } else if (Alignment & 2) {
11496 UnitSize = 2;
11497 } else {
11498 // Check whether we can use NEON instructions.
11499 if (!MF->getFunction().hasFnAttribute(Attribute::NoImplicitFloat) &&
11500 Subtarget->hasNEON()) {
11501 if ((Alignment % 16 == 0) && SizeVal >= 16)
11502 UnitSize = 16;
11503 else if ((Alignment % 8 == 0) && SizeVal >= 8)
11504 UnitSize = 8;
11505 }
11506 // Can't use NEON instructions.
11507 if (UnitSize == 0)
11508 UnitSize = 4;
11509 }
11510
11511 // Select the correct opcode and register class for unit size load/store
11512 bool IsNeon = UnitSize >= 8;
11513 TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
11514 if (IsNeon)
11515 VecTRC = UnitSize == 16 ? &ARM::DPairRegClass
11516 : UnitSize == 8 ? &ARM::DPRRegClass
11517 : nullptr;
11518
11519 unsigned BytesLeft = SizeVal % UnitSize;
11520 unsigned LoopSize = SizeVal - BytesLeft;
11521
11522 if (SizeVal <= Subtarget->getMaxInlineSizeThreshold()) {
11523 // Use LDR and STR to copy.
11524 // [scratch, srcOut] = LDR_POST(srcIn, UnitSize)
11525 // [destOut] = STR_POST(scratch, destIn, UnitSize)
11526 unsigned srcIn = src;
11527 unsigned destIn = dest;
11528 for (unsigned i = 0; i < LoopSize; i+=UnitSize) {
11529 Register srcOut = MRI.createVirtualRegister(TRC);
11530 Register destOut = MRI.createVirtualRegister(TRC);
11531 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11532 emitPostLd(BB, MI, TII, dl, UnitSize, scratch, srcIn, srcOut,
11533 IsThumb1, IsThumb2);
11534 emitPostSt(BB, MI, TII, dl, UnitSize, scratch, destIn, destOut,
11535 IsThumb1, IsThumb2);
11536 srcIn = srcOut;
11537 destIn = destOut;
11538 }
11539
11540 // Handle the leftover bytes with LDRB and STRB.
11541 // [scratch, srcOut] = LDRB_POST(srcIn, 1)
11542 // [destOut] = STRB_POST(scratch, destIn, 1)
11543 for (unsigned i = 0; i < BytesLeft; i++) {
11544 Register srcOut = MRI.createVirtualRegister(TRC);
11545 Register destOut = MRI.createVirtualRegister(TRC);
11546 Register scratch = MRI.createVirtualRegister(TRC);
11547 emitPostLd(BB, MI, TII, dl, 1, scratch, srcIn, srcOut,
11548 IsThumb1, IsThumb2);
11549 emitPostSt(BB, MI, TII, dl, 1, scratch, destIn, destOut,
11550 IsThumb1, IsThumb2);
11551 srcIn = srcOut;
11552 destIn = destOut;
11553 }
11554 MI.eraseFromParent(); // The instruction is gone now.
11555 return BB;
11556 }
11557
11558 // Expand the pseudo op to a loop.
11559 // thisMBB:
11560 // ...
11561 // movw varEnd, # --> with thumb2
11562 // movt varEnd, #
11563 // ldrcp varEnd, idx --> without thumb2
11564 // fallthrough --> loopMBB
11565 // loopMBB:
11566 // PHI varPhi, varEnd, varLoop
11567 // PHI srcPhi, src, srcLoop
11568 // PHI destPhi, dst, destLoop
11569 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11570 // [destLoop] = STR_POST(scratch, destPhi, UnitSize)
11571 // subs varLoop, varPhi, #UnitSize
11572 // bne loopMBB
11573 // fallthrough --> exitMBB
11574 // exitMBB:
11575 // epilogue to handle left-over bytes
11576 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11577 // [destOut] = STRB_POST(scratch, destLoop, 1)
11578 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11579 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11580 MF->insert(It, loopMBB);
11581 MF->insert(It, exitMBB);
11582
11583 // Set the call frame size on entry to the new basic blocks.
11584 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11585 loopMBB->setCallFrameSize(CallFrameSize);
11586 exitMBB->setCallFrameSize(CallFrameSize);
11587
11588 // Transfer the remainder of BB and its successor edges to exitMBB.
11589 exitMBB->splice(exitMBB->begin(), BB,
11590 std::next(MachineBasicBlock::iterator(MI)), BB->end());
11592
11593 // Load an immediate to varEnd.
11594 Register varEnd = MRI.createVirtualRegister(TRC);
11595 if (Subtarget->useMovt()) {
11596 BuildMI(BB, dl, TII->get(IsThumb ? ARM::t2MOVi32imm : ARM::MOVi32imm),
11597 varEnd)
11598 .addImm(LoopSize);
11599 } else if (Subtarget->genExecuteOnly()) {
11600 assert(IsThumb && "Non-thumb expected to have used movt");
11601 BuildMI(BB, dl, TII->get(ARM::tMOVi32imm), varEnd).addImm(LoopSize);
11602 } else {
11603 MachineConstantPool *ConstantPool = MF->getConstantPool();
11604 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11605 const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
11606
11607 // MachineConstantPool wants an explicit alignment.
11609 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11610 MachineMemOperand *CPMMO =
11613
11614 if (IsThumb)
11615 BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci))
11616 .addReg(varEnd, RegState::Define)
11619 .addMemOperand(CPMMO);
11620 else
11621 BuildMI(*BB, MI, dl, TII->get(ARM::LDRcp))
11622 .addReg(varEnd, RegState::Define)
11624 .addImm(0)
11626 .addMemOperand(CPMMO);
11627 }
11628 BB->addSuccessor(loopMBB);
11629
11630 // Generate the loop body:
11631 // varPhi = PHI(varLoop, varEnd)
11632 // srcPhi = PHI(srcLoop, src)
11633 // destPhi = PHI(destLoop, dst)
11634 MachineBasicBlock *entryBB = BB;
11635 BB = loopMBB;
11636 Register varLoop = MRI.createVirtualRegister(TRC);
11637 Register varPhi = MRI.createVirtualRegister(TRC);
11638 Register srcLoop = MRI.createVirtualRegister(TRC);
11639 Register srcPhi = MRI.createVirtualRegister(TRC);
11640 Register destLoop = MRI.createVirtualRegister(TRC);
11641 Register destPhi = MRI.createVirtualRegister(TRC);
11642
11643 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), varPhi)
11644 .addReg(varLoop).addMBB(loopMBB)
11645 .addReg(varEnd).addMBB(entryBB);
11646 BuildMI(BB, dl, TII->get(ARM::PHI), srcPhi)
11647 .addReg(srcLoop).addMBB(loopMBB)
11648 .addReg(src).addMBB(entryBB);
11649 BuildMI(BB, dl, TII->get(ARM::PHI), destPhi)
11650 .addReg(destLoop).addMBB(loopMBB)
11651 .addReg(dest).addMBB(entryBB);
11652
11653 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11654 // [destLoop] = STR_POST(scratch, destPhi, UnitSiz)
11655 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11656 emitPostLd(BB, BB->end(), TII, dl, UnitSize, scratch, srcPhi, srcLoop,
11657 IsThumb1, IsThumb2);
11658 emitPostSt(BB, BB->end(), TII, dl, UnitSize, scratch, destPhi, destLoop,
11659 IsThumb1, IsThumb2);
11660
11661 // Decrement loop variable by UnitSize.
11662 if (IsThumb1) {
11663 BuildMI(*BB, BB->end(), dl, TII->get(ARM::tSUBi8), varLoop)
11664 .add(t1CondCodeOp())
11665 .addReg(varPhi)
11666 .addImm(UnitSize)
11668 } else {
11669 MachineInstrBuilder MIB =
11670 BuildMI(*BB, BB->end(), dl,
11671 TII->get(IsThumb2 ? ARM::t2SUBri : ARM::SUBri), varLoop);
11672 MIB.addReg(varPhi)
11673 .addImm(UnitSize)
11675 .add(condCodeOp());
11676 MIB->getOperand(5).setReg(ARM::CPSR);
11677 MIB->getOperand(5).setIsDef(true);
11678 }
11679 BuildMI(*BB, BB->end(), dl,
11680 TII->get(IsThumb1 ? ARM::tBcc : IsThumb2 ? ARM::t2Bcc : ARM::Bcc))
11681 .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
11682
11683 // loopMBB can loop back to loopMBB or fall through to exitMBB.
11684 BB->addSuccessor(loopMBB);
11685 BB->addSuccessor(exitMBB);
11686
11687 // Add epilogue to handle BytesLeft.
11688 BB = exitMBB;
11689 auto StartOfExit = exitMBB->begin();
11690
11691 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11692 // [destOut] = STRB_POST(scratch, destLoop, 1)
11693 unsigned srcIn = srcLoop;
11694 unsigned destIn = destLoop;
11695 for (unsigned i = 0; i < BytesLeft; i++) {
11696 Register srcOut = MRI.createVirtualRegister(TRC);
11697 Register destOut = MRI.createVirtualRegister(TRC);
11698 Register scratch = MRI.createVirtualRegister(TRC);
11699 emitPostLd(BB, StartOfExit, TII, dl, 1, scratch, srcIn, srcOut,
11700 IsThumb1, IsThumb2);
11701 emitPostSt(BB, StartOfExit, TII, dl, 1, scratch, destIn, destOut,
11702 IsThumb1, IsThumb2);
11703 srcIn = srcOut;
11704 destIn = destOut;
11705 }
11706
11707 MI.eraseFromParent(); // The instruction is gone now.
11708 return BB;
11709}
11710
11712ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
11713 MachineBasicBlock *MBB) const {
11714 const TargetMachine &TM = getTargetMachine();
11715 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
11716 DebugLoc DL = MI.getDebugLoc();
11717
11718 assert(TM.getTargetTriple().isOSWindows() &&
11719 "__chkstk is only supported on Windows");
11720 assert(Subtarget->isThumb2() && "Windows on ARM requires Thumb-2 mode");
11721
11722 // __chkstk takes the number of words to allocate on the stack in R4, and
11723 // returns the stack adjustment in number of bytes in R4. This will not
11724 // clober any other registers (other than the obvious lr).
11725 //
11726 // Although, technically, IP should be considered a register which may be
11727 // clobbered, the call itself will not touch it. Windows on ARM is a pure
11728 // thumb-2 environment, so there is no interworking required. As a result, we
11729 // do not expect a veneer to be emitted by the linker, clobbering IP.
11730 //
11731 // Each module receives its own copy of __chkstk, so no import thunk is
11732 // required, again, ensuring that IP is not clobbered.
11733 //
11734 // Finally, although some linkers may theoretically provide a trampoline for
11735 // out of range calls (which is quite common due to a 32M range limitation of
11736 // branches for Thumb), we can generate the long-call version via
11737 // -mcmodel=large, alleviating the need for the trampoline which may clobber
11738 // IP.
11739
11740 RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE);
11741 if (ChkStkLibcall == RTLIB::Unsupported)
11742 reportFatalUsageError("no available implementation of __chkstk");
11743
11744 const char *ChkStk = getLibcallImplName(ChkStkLibcall).data();
11745 switch (TM.getCodeModel()) {
11746 case CodeModel::Tiny:
11747 llvm_unreachable("Tiny code model not available on ARM.");
11748 case CodeModel::Small:
11749 case CodeModel::Medium:
11750 case CodeModel::Kernel:
11751 BuildMI(*MBB, MI, DL, TII.get(ARM::tBL))
11753 .addExternalSymbol(ChkStk)
11756 .addReg(ARM::R12,
11758 .addReg(ARM::CPSR,
11760 break;
11761 case CodeModel::Large: {
11762 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
11763 Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11764
11765 BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
11766 .addExternalSymbol(ChkStk);
11772 .addReg(ARM::R12,
11774 .addReg(ARM::CPSR,
11776 break;
11777 }
11778 }
11779
11780 BuildMI(*MBB, MI, DL, TII.get(ARM::t2SUBrr), ARM::SP)
11781 .addReg(ARM::SP, RegState::Kill)
11782 .addReg(ARM::R4, RegState::Kill)
11785 .add(condCodeOp());
11786
11787 MI.eraseFromParent();
11788 return MBB;
11789}
11790
11792ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
11793 MachineBasicBlock *MBB) const {
11794 DebugLoc DL = MI.getDebugLoc();
11795 MachineFunction *MF = MBB->getParent();
11796 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11797
11798 MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
11799 MF->insert(++MBB->getIterator(), ContBB);
11800 ContBB->splice(ContBB->begin(), MBB,
11801 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
11803 MBB->addSuccessor(ContBB);
11804
11805 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11806 BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
11807 MF->push_back(TrapBB);
11808 MBB->addSuccessor(TrapBB);
11809
11810 BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
11811 .addReg(MI.getOperand(0).getReg())
11812 .addImm(0)
11814 BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
11815 .addMBB(TrapBB)
11817 .addReg(ARM::CPSR);
11818
11819 MI.eraseFromParent();
11820 return ContBB;
11821}
11822
11823// The CPSR operand of SelectItr might be missing a kill marker
11824// because there were multiple uses of CPSR, and ISel didn't know
11825// which to mark. Figure out whether SelectItr should have had a
11826// kill marker, and set it if it should. Returns the correct kill
11827// marker value.
11830 const TargetRegisterInfo* TRI) {
11831 // Scan forward through BB for a use/def of CPSR.
11832 MachineBasicBlock::iterator miI(std::next(SelectItr));
11833 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
11834 const MachineInstr& mi = *miI;
11835 if (mi.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
11836 return false;
11837 if (mi.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
11838 break; // Should have kill-flag - update below.
11839 }
11840
11841 // If we hit the end of the block, check whether CPSR is live into a
11842 // successor.
11843 if (miI == BB->end()) {
11844 for (MachineBasicBlock *Succ : BB->successors())
11845 if (Succ->isLiveIn(ARM::CPSR))
11846 return false;
11847 }
11848
11849 // We found a def, or hit the end of the basic block and CPSR wasn't live
11850 // out. SelectMI should have a kill flag on CPSR.
11851 SelectItr->addRegisterKilled(ARM::CPSR, TRI);
11852 return true;
11853}
11854
11855/// Adds logic in loop entry MBB to calculate loop iteration count and adds
11856/// t2WhileLoopSetup and t2WhileLoopStart to generate WLS loop
11858 MachineBasicBlock *TpLoopBody,
11859 MachineBasicBlock *TpExit, Register OpSizeReg,
11860 const TargetInstrInfo *TII, DebugLoc Dl,
11861 MachineRegisterInfo &MRI) {
11862 // Calculates loop iteration count = ceil(n/16) = (n + 15) >> 4.
11863 Register AddDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11864 BuildMI(TpEntry, Dl, TII->get(ARM::t2ADDri), AddDestReg)
11865 .addUse(OpSizeReg)
11866 .addImm(15)
11868 .addReg(0);
11869
11870 Register LsrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11871 BuildMI(TpEntry, Dl, TII->get(ARM::t2LSRri), LsrDestReg)
11872 .addUse(AddDestReg, RegState::Kill)
11873 .addImm(4)
11875 .addReg(0);
11876
11877 Register TotalIterationsReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11878 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopSetup), TotalIterationsReg)
11879 .addUse(LsrDestReg, RegState::Kill);
11880
11881 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopStart))
11882 .addUse(TotalIterationsReg)
11883 .addMBB(TpExit);
11884
11885 BuildMI(TpEntry, Dl, TII->get(ARM::t2B))
11886 .addMBB(TpLoopBody)
11888
11889 return TotalIterationsReg;
11890}
11891
11892/// Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and
11893/// t2DoLoopEnd. These are used by later passes to generate tail predicated
11894/// loops.
11895static void genTPLoopBody(MachineBasicBlock *TpLoopBody,
11896 MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit,
11897 const TargetInstrInfo *TII, DebugLoc Dl,
11898 MachineRegisterInfo &MRI, Register OpSrcReg,
11899 Register OpDestReg, Register ElementCountReg,
11900 Register TotalIterationsReg, bool IsMemcpy) {
11901 // First insert 4 PHI nodes for: Current pointer to Src (if memcpy), Dest
11902 // array, loop iteration counter, predication counter.
11903
11904 Register SrcPhiReg, CurrSrcReg;
11905 if (IsMemcpy) {
11906 // Current position in the src array
11907 SrcPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11908 CurrSrcReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11909 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), SrcPhiReg)
11910 .addUse(OpSrcReg)
11911 .addMBB(TpEntry)
11912 .addUse(CurrSrcReg)
11913 .addMBB(TpLoopBody);
11914 }
11915
11916 // Current position in the dest array
11917 Register DestPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11918 Register CurrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11919 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), DestPhiReg)
11920 .addUse(OpDestReg)
11921 .addMBB(TpEntry)
11922 .addUse(CurrDestReg)
11923 .addMBB(TpLoopBody);
11924
11925 // Current loop counter
11926 Register LoopCounterPhiReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11927 Register RemainingLoopIterationsReg =
11928 MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11929 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), LoopCounterPhiReg)
11930 .addUse(TotalIterationsReg)
11931 .addMBB(TpEntry)
11932 .addUse(RemainingLoopIterationsReg)
11933 .addMBB(TpLoopBody);
11934
11935 // Predication counter
11936 Register PredCounterPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11937 Register RemainingElementsReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11938 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), PredCounterPhiReg)
11939 .addUse(ElementCountReg)
11940 .addMBB(TpEntry)
11941 .addUse(RemainingElementsReg)
11942 .addMBB(TpLoopBody);
11943
11944 // Pass predication counter to VCTP
11945 Register VccrReg = MRI.createVirtualRegister(&ARM::VCCRRegClass);
11946 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VCTP8), VccrReg)
11947 .addUse(PredCounterPhiReg)
11949 .addReg(0)
11950 .addReg(0);
11951
11952 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2SUBri), RemainingElementsReg)
11953 .addUse(PredCounterPhiReg)
11954 .addImm(16)
11956 .addReg(0);
11957
11958 // VLDRB (only if memcpy) and VSTRB instructions, predicated using VPR
11959 Register SrcValueReg;
11960 if (IsMemcpy) {
11961 SrcValueReg = MRI.createVirtualRegister(&ARM::MQPRRegClass);
11962 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VLDRBU8_post))
11963 .addDef(CurrSrcReg)
11964 .addDef(SrcValueReg)
11965 .addReg(SrcPhiReg)
11966 .addImm(16)
11968 .addUse(VccrReg)
11969 .addReg(0);
11970 } else
11971 SrcValueReg = OpSrcReg;
11972
11973 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VSTRBU8_post))
11974 .addDef(CurrDestReg)
11975 .addUse(SrcValueReg)
11976 .addReg(DestPhiReg)
11977 .addImm(16)
11979 .addUse(VccrReg)
11980 .addReg(0);
11981
11982 // Add the pseudoInstrs for decrementing the loop counter and marking the
11983 // end:t2DoLoopDec and t2DoLoopEnd
11984 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopDec), RemainingLoopIterationsReg)
11985 .addUse(LoopCounterPhiReg)
11986 .addImm(1);
11987
11988 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopEnd))
11989 .addUse(RemainingLoopIterationsReg)
11990 .addMBB(TpLoopBody);
11991
11992 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2B))
11993 .addMBB(TpExit)
11995}
11996
11998 // KCFI is supported in all ARM/Thumb modes
11999 return true;
12000}
12001
12005 const TargetInstrInfo *TII) const {
12006 assert(MBBI->isCall() && MBBI->getCFIType() &&
12007 "Invalid call instruction for a KCFI check");
12008
12009 MachineOperand *TargetOp = nullptr;
12010 switch (MBBI->getOpcode()) {
12011 // ARM mode opcodes
12012 case ARM::BLX:
12013 case ARM::BLX_pred:
12014 case ARM::BLX_noip:
12015 case ARM::BLX_pred_noip:
12016 case ARM::BX_CALL:
12017 TargetOp = &MBBI->getOperand(0);
12018 break;
12019 case ARM::TCRETURNri:
12020 case ARM::TCRETURNrinotr12:
12021 case ARM::TAILJMPr:
12022 case ARM::TAILJMPr4:
12023 TargetOp = &MBBI->getOperand(0);
12024 break;
12025 // Thumb mode opcodes (Thumb1 and Thumb2)
12026 // Note: Most Thumb call instructions have predicate operands before the
12027 // target register Format: tBLXr pred, predreg, target_register, ...
12028 case ARM::tBLXr: // Thumb1/Thumb2: BLX register (requires V5T)
12029 case ARM::tBLXr_noip: // Thumb1/Thumb2: BLX register, no IP clobber
12030 case ARM::tBX_CALL: // Thumb1 only: BX call (push LR, BX)
12031 TargetOp = &MBBI->getOperand(2);
12032 break;
12033 // Tail call instructions don't have predicates, target is operand 0
12034 case ARM::tTAILJMPr: // Thumb1/Thumb2: Tail call via register
12035 TargetOp = &MBBI->getOperand(0);
12036 break;
12037 default:
12038 llvm_unreachable("Unexpected CFI call opcode");
12039 }
12040
12041 assert(TargetOp && TargetOp->isReg() && "Invalid target operand");
12042 TargetOp->setIsRenamable(false);
12043
12044 // Select the appropriate KCFI_CHECK variant based on the instruction set
12045 unsigned KCFICheckOpcode;
12046 if (Subtarget->isThumb()) {
12047 if (Subtarget->isThumb2()) {
12048 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb2;
12049 } else {
12050 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb1;
12051 }
12052 } else {
12053 KCFICheckOpcode = ARM::KCFI_CHECK_ARM;
12054 }
12055
12056 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(KCFICheckOpcode))
12057 .addReg(TargetOp->getReg())
12058 .addImm(MBBI->getCFIType())
12059 .getInstr();
12060}
12061
12064 MachineBasicBlock *BB) const {
12065 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
12066 DebugLoc dl = MI.getDebugLoc();
12067 bool isThumb2 = Subtarget->isThumb2();
12068 switch (MI.getOpcode()) {
12069 default: {
12070 MI.print(errs());
12071 llvm_unreachable("Unexpected instr type to insert");
12072 }
12073
12074 // Thumb1 post-indexed loads are really just single-register LDMs.
12075 case ARM::tLDR_postidx: {
12076 MachineOperand Def(MI.getOperand(1));
12077 BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD))
12078 .add(Def) // Rn_wb
12079 .add(MI.getOperand(2)) // Rn
12080 .add(MI.getOperand(3)) // PredImm
12081 .add(MI.getOperand(4)) // PredReg
12082 .add(MI.getOperand(0)) // Rt
12083 .cloneMemRefs(MI);
12084 MI.eraseFromParent();
12085 return BB;
12086 }
12087
12088 case ARM::MVE_MEMCPYLOOPINST:
12089 case ARM::MVE_MEMSETLOOPINST: {
12090
12091 // Transformation below expands MVE_MEMCPYLOOPINST/MVE_MEMSETLOOPINST Pseudo
12092 // into a Tail Predicated (TP) Loop. It adds the instructions to calculate
12093 // the iteration count =ceil(size_in_bytes/16)) in the TP entry block and
12094 // adds the relevant instructions in the TP loop Body for generation of a
12095 // WLSTP loop.
12096
12097 // Below is relevant portion of the CFG after the transformation.
12098 // The Machine Basic Blocks are shown along with branch conditions (in
12099 // brackets). Note that TP entry/exit MBBs depict the entry/exit of this
12100 // portion of the CFG and may not necessarily be the entry/exit of the
12101 // function.
12102
12103 // (Relevant) CFG after transformation:
12104 // TP entry MBB
12105 // |
12106 // |-----------------|
12107 // (n <= 0) (n > 0)
12108 // | |
12109 // | TP loop Body MBB<--|
12110 // | | |
12111 // \ |___________|
12112 // \ /
12113 // TP exit MBB
12114
12115 MachineFunction *MF = BB->getParent();
12116 MachineFunctionProperties &Properties = MF->getProperties();
12117 MachineRegisterInfo &MRI = MF->getRegInfo();
12118
12119 Register OpDestReg = MI.getOperand(0).getReg();
12120 Register OpSrcReg = MI.getOperand(1).getReg();
12121 Register OpSizeReg = MI.getOperand(2).getReg();
12122
12123 // Allocate the required MBBs and add to parent function.
12124 MachineBasicBlock *TpEntry = BB;
12125 MachineBasicBlock *TpLoopBody = MF->CreateMachineBasicBlock();
12126 MachineBasicBlock *TpExit;
12127
12128 MF->push_back(TpLoopBody);
12129
12130 // If any instructions are present in the current block after
12131 // MVE_MEMCPYLOOPINST or MVE_MEMSETLOOPINST, split the current block and
12132 // move the instructions into the newly created exit block. If there are no
12133 // instructions add an explicit branch to the FallThrough block and then
12134 // split.
12135 //
12136 // The split is required for two reasons:
12137 // 1) A terminator(t2WhileLoopStart) will be placed at that site.
12138 // 2) Since a TPLoopBody will be added later, any phis in successive blocks
12139 // need to be updated. splitAt() already handles this.
12140 TpExit = BB->splitAt(MI, false);
12141 if (TpExit == BB) {
12142 assert(BB->canFallThrough() && "Exit Block must be Fallthrough of the "
12143 "block containing memcpy/memset Pseudo");
12144 TpExit = BB->getFallThrough();
12145 BuildMI(BB, dl, TII->get(ARM::t2B))
12146 .addMBB(TpExit)
12148 TpExit = BB->splitAt(MI, false);
12149 }
12150
12151 // Add logic for iteration count
12152 Register TotalIterationsReg =
12153 genTPEntry(TpEntry, TpLoopBody, TpExit, OpSizeReg, TII, dl, MRI);
12154
12155 // Add the vectorized (and predicated) loads/store instructions
12156 bool IsMemcpy = MI.getOpcode() == ARM::MVE_MEMCPYLOOPINST;
12157 genTPLoopBody(TpLoopBody, TpEntry, TpExit, TII, dl, MRI, OpSrcReg,
12158 OpDestReg, OpSizeReg, TotalIterationsReg, IsMemcpy);
12159
12160 // Required to avoid conflict with the MachineVerifier during testing.
12161 Properties.resetNoPHIs();
12162
12163 // Connect the blocks
12164 TpEntry->addSuccessor(TpLoopBody);
12165 TpLoopBody->addSuccessor(TpLoopBody);
12166 TpLoopBody->addSuccessor(TpExit);
12167
12168 // Reorder for a more natural layout
12169 TpLoopBody->moveAfter(TpEntry);
12170 TpExit->moveAfter(TpLoopBody);
12171
12172 // Finally, remove the memcpy Pseudo Instruction
12173 MI.eraseFromParent();
12174
12175 // Return the exit block as it may contain other instructions requiring a
12176 // custom inserter
12177 return TpExit;
12178 }
12179
12180 // The Thumb2 pre-indexed stores have the same MI operands, they just
12181 // define them differently in the .td files from the isel patterns, so
12182 // they need pseudos.
12183 case ARM::t2STR_preidx:
12184 MI.setDesc(TII->get(ARM::t2STR_PRE));
12185 return BB;
12186 case ARM::t2STRB_preidx:
12187 MI.setDesc(TII->get(ARM::t2STRB_PRE));
12188 return BB;
12189 case ARM::t2STRH_preidx:
12190 MI.setDesc(TII->get(ARM::t2STRH_PRE));
12191 return BB;
12192
12193 case ARM::STRi_preidx:
12194 case ARM::STRBi_preidx: {
12195 unsigned NewOpc = MI.getOpcode() == ARM::STRi_preidx ? ARM::STR_PRE_IMM
12196 : ARM::STRB_PRE_IMM;
12197 // Decode the offset.
12198 unsigned Offset = MI.getOperand(4).getImm();
12199 bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub;
12201 if (isSub)
12202 Offset = -Offset;
12203
12204 MachineMemOperand *MMO = *MI.memoperands_begin();
12205 BuildMI(*BB, MI, dl, TII->get(NewOpc))
12206 .add(MI.getOperand(0)) // Rn_wb
12207 .add(MI.getOperand(1)) // Rt
12208 .add(MI.getOperand(2)) // Rn
12209 .addImm(Offset) // offset (skip GPR==zero_reg)
12210 .add(MI.getOperand(5)) // pred
12211 .add(MI.getOperand(6))
12212 .addMemOperand(MMO);
12213 MI.eraseFromParent();
12214 return BB;
12215 }
12216 case ARM::STRr_preidx:
12217 case ARM::STRBr_preidx:
12218 case ARM::STRH_preidx: {
12219 unsigned NewOpc;
12220 switch (MI.getOpcode()) {
12221 default: llvm_unreachable("unexpected opcode!");
12222 case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break;
12223 case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break;
12224 case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break;
12225 }
12226 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc));
12227 for (const MachineOperand &MO : MI.operands())
12228 MIB.add(MO);
12229 MI.eraseFromParent();
12230 return BB;
12231 }
12232
12233 case ARM::tMOVCCr_pseudo: {
12234 // To "insert" a SELECT_CC instruction, we actually have to insert the
12235 // diamond control-flow pattern. The incoming instruction knows the
12236 // destination vreg to set, the condition code register to branch on, the
12237 // true/false values to select between, and a branch opcode to use.
12238 const BasicBlock *LLVM_BB = BB->getBasicBlock();
12240
12241 // thisMBB:
12242 // ...
12243 // TrueVal = ...
12244 // cmpTY ccX, r1, r2
12245 // bCC copy1MBB
12246 // fallthrough --> copy0MBB
12247 MachineBasicBlock *thisMBB = BB;
12248 MachineFunction *F = BB->getParent();
12249 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12250 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
12251 F->insert(It, copy0MBB);
12252 F->insert(It, sinkMBB);
12253
12254 // Set the call frame size on entry to the new basic blocks.
12255 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12256 copy0MBB->setCallFrameSize(CallFrameSize);
12257 sinkMBB->setCallFrameSize(CallFrameSize);
12258
12259 // Check whether CPSR is live past the tMOVCCr_pseudo.
12260 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
12261 if (!MI.killsRegister(ARM::CPSR, /*TRI=*/nullptr) &&
12262 !checkAndUpdateCPSRKill(MI, thisMBB, TRI)) {
12263 copy0MBB->addLiveIn(ARM::CPSR);
12264 sinkMBB->addLiveIn(ARM::CPSR);
12265 }
12266
12267 // Transfer the remainder of BB and its successor edges to sinkMBB.
12268 sinkMBB->splice(sinkMBB->begin(), BB,
12269 std::next(MachineBasicBlock::iterator(MI)), BB->end());
12271
12272 BB->addSuccessor(copy0MBB);
12273 BB->addSuccessor(sinkMBB);
12274
12275 BuildMI(BB, dl, TII->get(ARM::tBcc))
12276 .addMBB(sinkMBB)
12277 .addImm(MI.getOperand(3).getImm())
12278 .addReg(MI.getOperand(4).getReg());
12279
12280 // copy0MBB:
12281 // %FalseValue = ...
12282 // # fallthrough to sinkMBB
12283 BB = copy0MBB;
12284
12285 // Update machine-CFG edges
12286 BB->addSuccessor(sinkMBB);
12287
12288 // sinkMBB:
12289 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12290 // ...
12291 BB = sinkMBB;
12292 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), MI.getOperand(0).getReg())
12293 .addReg(MI.getOperand(1).getReg())
12294 .addMBB(copy0MBB)
12295 .addReg(MI.getOperand(2).getReg())
12296 .addMBB(thisMBB);
12297
12298 MI.eraseFromParent(); // The pseudo instruction is gone now.
12299 return BB;
12300 }
12301
12302 case ARM::BCCi64:
12303 case ARM::BCCZi64: {
12304 // If there is an unconditional branch to the other successor, remove it.
12305 BB->erase(std::next(MachineBasicBlock::iterator(MI)), BB->end());
12306
12307 // Compare both parts that make up the double comparison separately for
12308 // equality.
12309 bool RHSisZero = MI.getOpcode() == ARM::BCCZi64;
12310
12311 Register LHS1 = MI.getOperand(1).getReg();
12312 Register LHS2 = MI.getOperand(2).getReg();
12313 if (RHSisZero) {
12314 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12315 .addReg(LHS1)
12316 .addImm(0)
12318 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12319 .addReg(LHS2).addImm(0)
12320 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12321 } else {
12322 Register RHS1 = MI.getOperand(3).getReg();
12323 Register RHS2 = MI.getOperand(4).getReg();
12324 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12325 .addReg(LHS1)
12326 .addReg(RHS1)
12328 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12329 .addReg(LHS2).addReg(RHS2)
12330 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12331 }
12332
12333 MachineBasicBlock *destMBB = MI.getOperand(RHSisZero ? 3 : 5).getMBB();
12334 MachineBasicBlock *exitMBB = OtherSucc(BB, destMBB);
12335 if (MI.getOperand(0).getImm() == ARMCC::NE)
12336 std::swap(destMBB, exitMBB);
12337
12338 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))
12339 .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
12340 if (isThumb2)
12341 BuildMI(BB, dl, TII->get(ARM::t2B))
12342 .addMBB(exitMBB)
12344 else
12345 BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);
12346
12347 MI.eraseFromParent(); // The pseudo instruction is gone now.
12348 return BB;
12349 }
12350
12351 case ARM::Int_eh_sjlj_setjmp:
12352 case ARM::Int_eh_sjlj_setjmp_nofp:
12353 case ARM::tInt_eh_sjlj_setjmp:
12354 case ARM::t2Int_eh_sjlj_setjmp:
12355 case ARM::t2Int_eh_sjlj_setjmp_nofp:
12356 return BB;
12357
12358 case ARM::Int_eh_sjlj_setup_dispatch:
12359 EmitSjLjDispatchBlock(MI, BB);
12360 return BB;
12361 case ARM::COPY_STRUCT_BYVAL_I32:
12362 ++NumLoopByVals;
12363 return EmitStructByval(MI, BB);
12364 case ARM::WIN__CHKSTK:
12365 return EmitLowered__chkstk(MI, BB);
12366 case ARM::WIN__DBZCHK:
12367 return EmitLowered__dbzchk(MI, BB);
12368 }
12369}
12370
12371/// Attaches vregs to MEMCPY that it will use as scratch registers
12372/// when it is expanded into LDM/STM. This is done as a post-isel lowering
12373/// instead of as a custom inserter because we need the use list from the SDNode.
12374static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget,
12375 MachineInstr &MI, const SDNode *Node) {
12376 bool isThumb1 = Subtarget->isThumb1Only();
12377
12378 MachineFunction *MF = MI.getParent()->getParent();
12379 MachineRegisterInfo &MRI = MF->getRegInfo();
12380 MachineInstrBuilder MIB(*MF, MI);
12381
12382 // If the new dst/src is unused mark it as dead.
12383 if (!Node->hasAnyUseOfValue(0)) {
12384 MI.getOperand(0).setIsDead(true);
12385 }
12386 if (!Node->hasAnyUseOfValue(1)) {
12387 MI.getOperand(1).setIsDead(true);
12388 }
12389
12390 // The MEMCPY both defines and kills the scratch registers.
12391 for (unsigned I = 0; I != MI.getOperand(4).getImm(); ++I) {
12392 Register TmpReg = MRI.createVirtualRegister(isThumb1 ? &ARM::tGPRRegClass
12393 : &ARM::GPRRegClass);
12395 }
12396}
12397
12399 SDNode *Node) const {
12400 if (MI.getOpcode() == ARM::MEMCPY) {
12401 attachMEMCPYScratchRegs(Subtarget, MI, Node);
12402 return;
12403 }
12404
12405 const MCInstrDesc *MCID = &MI.getDesc();
12406 // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB,
12407 // RSC. Coming out of isel, they have an implicit CPSR def, but the optional
12408 // operand is still set to noreg. If needed, set the optional operand's
12409 // register to CPSR, and remove the redundant implicit def.
12410 //
12411 // e.g. ADCS (..., implicit-def CPSR) -> ADC (... opt:def CPSR).
12412
12413 // Rename pseudo opcodes.
12414 unsigned NewOpc = convertAddSubFlagsOpcode(MI.getOpcode());
12415 unsigned ccOutIdx;
12416 if (NewOpc) {
12417 const ARMBaseInstrInfo *TII = Subtarget->getInstrInfo();
12418 MCID = &TII->get(NewOpc);
12419
12420 assert(MCID->getNumOperands() ==
12421 MI.getDesc().getNumOperands() + 5 - MI.getDesc().getSize()
12422 && "converted opcode should be the same except for cc_out"
12423 " (and, on Thumb1, pred)");
12424
12425 MI.setDesc(*MCID);
12426
12427 // Add the optional cc_out operand
12428 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
12429
12430 // On Thumb1, move all input operands to the end, then add the predicate
12431 if (Subtarget->isThumb1Only()) {
12432 for (unsigned c = MCID->getNumOperands() - 4; c--;) {
12433 MI.addOperand(MI.getOperand(1));
12434 MI.removeOperand(1);
12435 }
12436
12437 // Restore the ties
12438 for (unsigned i = MI.getNumOperands(); i--;) {
12439 const MachineOperand& op = MI.getOperand(i);
12440 if (op.isReg() && op.isUse()) {
12441 int DefIdx = MCID->getOperandConstraint(i, MCOI::TIED_TO);
12442 if (DefIdx != -1)
12443 MI.tieOperands(DefIdx, i);
12444 }
12445 }
12446
12448 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/false));
12449 ccOutIdx = 1;
12450 } else
12451 ccOutIdx = MCID->getNumOperands() - 1;
12452 } else
12453 ccOutIdx = MCID->getNumOperands() - 1;
12454
12455 // Any ARM instruction that sets the 's' bit should specify an optional
12456 // "cc_out" operand in the last operand position.
12457 if (!MI.hasOptionalDef() || !MCID->operands()[ccOutIdx].isOptionalDef()) {
12458 assert(!NewOpc && "Optional cc_out operand required");
12459 return;
12460 }
12461 // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it
12462 // since we already have an optional CPSR def.
12463 bool definesCPSR = false;
12464 bool deadCPSR = false;
12465 for (unsigned i = MCID->getNumOperands(), e = MI.getNumOperands(); i != e;
12466 ++i) {
12467 const MachineOperand &MO = MI.getOperand(i);
12468 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
12469 definesCPSR = true;
12470 if (MO.isDead())
12471 deadCPSR = true;
12472 MI.removeOperand(i);
12473 break;
12474 }
12475 }
12476 if (!definesCPSR) {
12477 assert(!NewOpc && "Optional cc_out operand required");
12478 return;
12479 }
12480 assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag");
12481 if (deadCPSR) {
12482 assert(!MI.getOperand(ccOutIdx).getReg() &&
12483 "expect uninitialized optional cc_out operand");
12484 // Thumb1 instructions must have the S bit even if the CPSR is dead.
12485 if (!Subtarget->isThumb1Only())
12486 return;
12487 }
12488
12489 // If this instruction was defined with an optional CPSR def and its dag node
12490 // had a live implicit CPSR def, then activate the optional CPSR def.
12491 MachineOperand &MO = MI.getOperand(ccOutIdx);
12492 MO.setReg(ARM::CPSR);
12493 MO.setIsDef(true);
12494}
12495
12496//===----------------------------------------------------------------------===//
12497// ARM Optimization Hooks
12498//===----------------------------------------------------------------------===//
12499
12500// Helper function that checks if N is a null or all ones constant.
12501static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
12503}
12504
12505// Return true if N is conditionally 0 or all ones.
12506// Detects these expressions where cc is an i1 value:
12507//
12508// (select cc 0, y) [AllOnes=0]
12509// (select cc y, 0) [AllOnes=0]
12510// (zext cc) [AllOnes=0]
12511// (sext cc) [AllOnes=0/1]
12512// (select cc -1, y) [AllOnes=1]
12513// (select cc y, -1) [AllOnes=1]
12514//
12515// Invert is set when N is the null/all ones constant when CC is false.
12516// OtherOp is set to the alternative value of N.
12518 SDValue &CC, bool &Invert,
12519 SDValue &OtherOp,
12520 SelectionDAG &DAG) {
12521 switch (N->getOpcode()) {
12522 default: return false;
12523 case ISD::SELECT: {
12524 CC = N->getOperand(0);
12525 SDValue N1 = N->getOperand(1);
12526 SDValue N2 = N->getOperand(2);
12527 if (isZeroOrAllOnes(N1, AllOnes)) {
12528 Invert = false;
12529 OtherOp = N2;
12530 return true;
12531 }
12532 if (isZeroOrAllOnes(N2, AllOnes)) {
12533 Invert = true;
12534 OtherOp = N1;
12535 return true;
12536 }
12537 return false;
12538 }
12539 case ISD::ZERO_EXTEND:
12540 // (zext cc) can never be the all ones value.
12541 if (AllOnes)
12542 return false;
12543 [[fallthrough]];
12544 case ISD::SIGN_EXTEND: {
12545 SDLoc dl(N);
12546 EVT VT = N->getValueType(0);
12547 CC = N->getOperand(0);
12548 if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC)
12549 return false;
12550 Invert = !AllOnes;
12551 if (AllOnes)
12552 // When looking for an AllOnes constant, N is an sext, and the 'other'
12553 // value is 0.
12554 OtherOp = DAG.getConstant(0, dl, VT);
12555 else if (N->getOpcode() == ISD::ZERO_EXTEND)
12556 // When looking for a 0 constant, N can be zext or sext.
12557 OtherOp = DAG.getConstant(1, dl, VT);
12558 else
12559 OtherOp = DAG.getAllOnesConstant(dl, VT);
12560 return true;
12561 }
12562 }
12563}
12564
12565// Combine a constant select operand into its use:
12566//
12567// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
12568// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
12569// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
12570// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
12571// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
12572//
12573// The transform is rejected if the select doesn't have a constant operand that
12574// is null, or all ones when AllOnes is set.
12575//
12576// Also recognize sext/zext from i1:
12577//
12578// (add (zext cc), x) -> (select cc (add x, 1), x)
12579// (add (sext cc), x) -> (select cc (add x, -1), x)
12580//
12581// These transformations eventually create predicated instructions.
12582//
12583// @param N The node to transform.
12584// @param Slct The N operand that is a select.
12585// @param OtherOp The other N operand (x above).
12586// @param DCI Context.
12587// @param AllOnes Require the select constant to be all ones instead of null.
12588// @returns The new node, or SDValue() on failure.
12589static
12592 bool AllOnes = false) {
12593 SelectionDAG &DAG = DCI.DAG;
12594 EVT VT = N->getValueType(0);
12595 SDValue NonConstantVal;
12596 SDValue CCOp;
12597 bool SwapSelectOps;
12598 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
12599 NonConstantVal, DAG))
12600 return SDValue();
12601
12602 // Slct is now know to be the desired identity constant when CC is true.
12603 SDValue TrueVal = OtherOp;
12604 SDValue FalseVal = DAG.getNode(N->getOpcode(), SDLoc(N), VT,
12605 OtherOp, NonConstantVal);
12606 // Unless SwapSelectOps says CC should be false.
12607 if (SwapSelectOps)
12608 std::swap(TrueVal, FalseVal);
12609
12610 return DAG.getNode(ISD::SELECT, SDLoc(N), VT,
12611 CCOp, TrueVal, FalseVal);
12612}
12613
12614// Attempt combineSelectAndUse on each operand of a commutative operator N.
12615static
12618 SDValue N0 = N->getOperand(0);
12619 SDValue N1 = N->getOperand(1);
12620 if (N0.getNode()->hasOneUse())
12621 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
12622 return Result;
12623 if (N1.getNode()->hasOneUse())
12624 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
12625 return Result;
12626 return SDValue();
12627}
12628
12630 // VUZP shuffle node.
12631 if (N->getOpcode() == ARMISD::VUZP)
12632 return true;
12633
12634 // "VUZP" on i32 is an alias for VTRN.
12635 if (N->getOpcode() == ARMISD::VTRN && N->getValueType(0) == MVT::v2i32)
12636 return true;
12637
12638 return false;
12639}
12640
12643 const ARMSubtarget *Subtarget) {
12644 // Look for ADD(VUZP.0, VUZP.1).
12645 if (!IsVUZPShuffleNode(N0.getNode()) || N0.getNode() != N1.getNode() ||
12646 N0 == N1)
12647 return SDValue();
12648
12649 // Make sure the ADD is a 64-bit add; there is no 128-bit VPADD.
12650 if (!N->getValueType(0).is64BitVector())
12651 return SDValue();
12652
12653 // Generate vpadd.
12654 SelectionDAG &DAG = DCI.DAG;
12655 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12656 SDLoc dl(N);
12657 SDNode *Unzip = N0.getNode();
12658 EVT VT = N->getValueType(0);
12659
12661 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpadd, dl,
12662 TLI.getPointerTy(DAG.getDataLayout())));
12663 Ops.push_back(Unzip->getOperand(0));
12664 Ops.push_back(Unzip->getOperand(1));
12665
12666 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12667}
12668
12671 const ARMSubtarget *Subtarget) {
12672 // Check for two extended operands.
12673 if (!(N0.getOpcode() == ISD::SIGN_EXTEND &&
12674 N1.getOpcode() == ISD::SIGN_EXTEND) &&
12675 !(N0.getOpcode() == ISD::ZERO_EXTEND &&
12676 N1.getOpcode() == ISD::ZERO_EXTEND))
12677 return SDValue();
12678
12679 SDValue N00 = N0.getOperand(0);
12680 SDValue N10 = N1.getOperand(0);
12681
12682 // Look for ADD(SEXT(VUZP.0), SEXT(VUZP.1))
12683 if (!IsVUZPShuffleNode(N00.getNode()) || N00.getNode() != N10.getNode() ||
12684 N00 == N10)
12685 return SDValue();
12686
12687 // We only recognize Q register paddl here; this can't be reached until
12688 // after type legalization.
12689 if (!N00.getValueType().is64BitVector() ||
12691 return SDValue();
12692
12693 // Generate vpaddl.
12694 SelectionDAG &DAG = DCI.DAG;
12695 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12696 SDLoc dl(N);
12697 EVT VT = N->getValueType(0);
12698
12700 // Form vpaddl.sN or vpaddl.uN depending on the kind of extension.
12701 unsigned Opcode;
12702 if (N0.getOpcode() == ISD::SIGN_EXTEND)
12703 Opcode = Intrinsic::arm_neon_vpaddls;
12704 else
12705 Opcode = Intrinsic::arm_neon_vpaddlu;
12706 Ops.push_back(DAG.getConstant(Opcode, dl,
12707 TLI.getPointerTy(DAG.getDataLayout())));
12709 unsigned NumElts = VT.getVectorNumElements();
12710 EVT ConcatVT = EVT::getVectorVT(*DAG.getContext(), ElemTy, NumElts * 2);
12711 SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), ConcatVT,
12712 N00.getOperand(0), N00.getOperand(1));
12713 Ops.push_back(Concat);
12714
12715 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12716}
12717
12718// FIXME: This function shouldn't be necessary; if we lower BUILD_VECTOR in
12719// an appropriate manner, we end up with ADD(VUZP(ZEXT(N))), which is
12720// much easier to match.
12721static SDValue
12724 const ARMSubtarget *Subtarget) {
12725 // Only perform optimization if after legalize, and if NEON is available. We
12726 // also expected both operands to be BUILD_VECTORs.
12727 if (DCI.isBeforeLegalize() || !Subtarget->hasNEON()
12728 || N0.getOpcode() != ISD::BUILD_VECTOR
12729 || N1.getOpcode() != ISD::BUILD_VECTOR)
12730 return SDValue();
12731
12732 // Check output type since VPADDL operand elements can only be 8, 16, or 32.
12733 EVT VT = N->getValueType(0);
12734 if (!VT.isInteger() || VT.getVectorElementType() == MVT::i64)
12735 return SDValue();
12736
12737 // Check that the vector operands are of the right form.
12738 // N0 and N1 are BUILD_VECTOR nodes with N number of EXTRACT_VECTOR
12739 // operands, where N is the size of the formed vector.
12740 // Each EXTRACT_VECTOR should have the same input vector and odd or even
12741 // index such that we have a pair wise add pattern.
12742
12743 // Grab the vector that all EXTRACT_VECTOR nodes should be referencing.
12745 return SDValue();
12746 SDValue Vec = N0->getOperand(0)->getOperand(0);
12747 SDNode *V = Vec.getNode();
12748 unsigned nextIndex = 0;
12749
12750 // For each operands to the ADD which are BUILD_VECTORs,
12751 // check to see if each of their operands are an EXTRACT_VECTOR with
12752 // the same vector and appropriate index.
12753 for (unsigned i = 0, e = N0->getNumOperands(); i != e; ++i) {
12756
12757 SDValue ExtVec0 = N0->getOperand(i);
12758 SDValue ExtVec1 = N1->getOperand(i);
12759
12760 // First operand is the vector, verify its the same.
12761 if (V != ExtVec0->getOperand(0).getNode() ||
12762 V != ExtVec1->getOperand(0).getNode())
12763 return SDValue();
12764
12765 // Second is the constant, verify its correct.
12768
12769 // For the constant, we want to see all the even or all the odd.
12770 if (!C0 || !C1 || C0->getZExtValue() != nextIndex
12771 || C1->getZExtValue() != nextIndex+1)
12772 return SDValue();
12773
12774 // Increment index.
12775 nextIndex+=2;
12776 } else
12777 return SDValue();
12778 }
12779
12780 // Don't generate vpaddl+vmovn; we'll match it to vpadd later. Also make sure
12781 // we're using the entire input vector, otherwise there's a size/legality
12782 // mismatch somewhere.
12783 if (nextIndex != Vec.getValueType().getVectorNumElements() ||
12785 return SDValue();
12786
12787 // Create VPADDL node.
12788 SelectionDAG &DAG = DCI.DAG;
12789 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12790
12791 SDLoc dl(N);
12792
12793 // Build operand list.
12795 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddls, dl,
12796 TLI.getPointerTy(DAG.getDataLayout())));
12797
12798 // Input is the vector.
12799 Ops.push_back(Vec);
12800
12801 // Get widened type and narrowed type.
12802 MVT widenType;
12803 unsigned numElem = VT.getVectorNumElements();
12804
12805 EVT inputLaneType = Vec.getValueType().getVectorElementType();
12806 switch (inputLaneType.getSimpleVT().SimpleTy) {
12807 case MVT::i8: widenType = MVT::getVectorVT(MVT::i16, numElem); break;
12808 case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break;
12809 case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break;
12810 default:
12811 llvm_unreachable("Invalid vector element type for padd optimization.");
12812 }
12813
12814 SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, widenType, Ops);
12815 unsigned ExtOp = VT.bitsGT(tmp.getValueType()) ? ISD::ANY_EXTEND : ISD::TRUNCATE;
12816 return DAG.getNode(ExtOp, dl, VT, tmp);
12817}
12818
12820 if (V->getOpcode() == ISD::UMUL_LOHI ||
12821 V->getOpcode() == ISD::SMUL_LOHI)
12822 return V;
12823 return SDValue();
12824}
12825
12826static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode,
12828 const ARMSubtarget *Subtarget) {
12829 if (!Subtarget->hasBaseDSP())
12830 return SDValue();
12831
12832 // SMLALBB, SMLALBT, SMLALTB, SMLALTT multiply two 16-bit values and
12833 // accumulates the product into a 64-bit value. The 16-bit values will
12834 // be sign extended somehow or SRA'd into 32-bit values
12835 // (addc (adde (mul 16bit, 16bit), lo), hi)
12836 SDValue Mul = AddcNode->getOperand(0);
12837 SDValue Lo = AddcNode->getOperand(1);
12838 if (Mul.getOpcode() != ISD::MUL) {
12839 Lo = AddcNode->getOperand(0);
12840 Mul = AddcNode->getOperand(1);
12841 if (Mul.getOpcode() != ISD::MUL)
12842 return SDValue();
12843 }
12844
12845 SDValue SRA = AddeNode->getOperand(0);
12846 SDValue Hi = AddeNode->getOperand(1);
12847 if (SRA.getOpcode() != ISD::SRA) {
12848 SRA = AddeNode->getOperand(1);
12849 Hi = AddeNode->getOperand(0);
12850 if (SRA.getOpcode() != ISD::SRA)
12851 return SDValue();
12852 }
12853 if (auto Const = dyn_cast<ConstantSDNode>(SRA.getOperand(1))) {
12854 if (Const->getZExtValue() != 31)
12855 return SDValue();
12856 } else
12857 return SDValue();
12858
12859 if (SRA.getOperand(0) != Mul)
12860 return SDValue();
12861
12862 SelectionDAG &DAG = DCI.DAG;
12863 SDLoc dl(AddcNode);
12864 unsigned Opcode = 0;
12865 SDValue Op0;
12866 SDValue Op1;
12867
12868 if (isS16(Mul.getOperand(0), DAG) && isS16(Mul.getOperand(1), DAG)) {
12869 Opcode = ARMISD::SMLALBB;
12870 Op0 = Mul.getOperand(0);
12871 Op1 = Mul.getOperand(1);
12872 } else if (isS16(Mul.getOperand(0), DAG) && isSRA16(Mul.getOperand(1))) {
12873 Opcode = ARMISD::SMLALBT;
12874 Op0 = Mul.getOperand(0);
12875 Op1 = Mul.getOperand(1).getOperand(0);
12876 } else if (isSRA16(Mul.getOperand(0)) && isS16(Mul.getOperand(1), DAG)) {
12877 Opcode = ARMISD::SMLALTB;
12878 Op0 = Mul.getOperand(0).getOperand(0);
12879 Op1 = Mul.getOperand(1);
12880 } else if (isSRA16(Mul.getOperand(0)) && isSRA16(Mul.getOperand(1))) {
12881 Opcode = ARMISD::SMLALTT;
12882 Op0 = Mul->getOperand(0).getOperand(0);
12883 Op1 = Mul->getOperand(1).getOperand(0);
12884 }
12885
12886 if (!Op0 || !Op1)
12887 return SDValue();
12888
12889 SDValue SMLAL = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
12890 Op0, Op1, Lo, Hi);
12891 // Replace the ADDs' nodes uses by the MLA node's values.
12892 SDValue HiMLALResult(SMLAL.getNode(), 1);
12893 SDValue LoMLALResult(SMLAL.getNode(), 0);
12894
12895 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult);
12896 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult);
12897
12898 // Return original node to notify the driver to stop replacing.
12899 SDValue resNode(AddcNode, 0);
12900 return resNode;
12901}
12902
12905 const ARMSubtarget *Subtarget) {
12906 // Look for multiply add opportunities.
12907 // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where
12908 // each add nodes consumes a value from ISD::UMUL_LOHI and there is
12909 // a glue link from the first add to the second add.
12910 // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by
12911 // a S/UMLAL instruction.
12912 // UMUL_LOHI
12913 // / :lo \ :hi
12914 // V \ [no multiline comment]
12915 // loAdd -> ADDC |
12916 // \ :carry /
12917 // V V
12918 // ADDE <- hiAdd
12919 //
12920 // In the special case where only the higher part of a signed result is used
12921 // and the add to the low part of the result of ISD::UMUL_LOHI adds or subtracts
12922 // a constant with the exact value of 0x80000000, we recognize we are dealing
12923 // with a "rounded multiply and add" (or subtract) and transform it into
12924 // either a ARMISD::SMMLAR or ARMISD::SMMLSR respectively.
12925
12926 assert((AddeSubeNode->getOpcode() == ARMISD::ADDE ||
12927 AddeSubeNode->getOpcode() == ARMISD::SUBE) &&
12928 "Expect an ADDE or SUBE");
12929
12930 assert(AddeSubeNode->getNumOperands() == 3 &&
12931 AddeSubeNode->getOperand(2).getValueType() == MVT::i32 &&
12932 "ADDE node has the wrong inputs");
12933
12934 // Check that we are chained to the right ADDC or SUBC node.
12935 SDNode *AddcSubcNode = AddeSubeNode->getOperand(2).getNode();
12936 if ((AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12937 AddcSubcNode->getOpcode() != ARMISD::ADDC) ||
12938 (AddeSubeNode->getOpcode() == ARMISD::SUBE &&
12939 AddcSubcNode->getOpcode() != ARMISD::SUBC))
12940 return SDValue();
12941
12942 SDValue AddcSubcOp0 = AddcSubcNode->getOperand(0);
12943 SDValue AddcSubcOp1 = AddcSubcNode->getOperand(1);
12944
12945 // Check if the two operands are from the same mul_lohi node.
12946 if (AddcSubcOp0.getNode() == AddcSubcOp1.getNode())
12947 return SDValue();
12948
12949 assert(AddcSubcNode->getNumValues() == 2 &&
12950 AddcSubcNode->getValueType(0) == MVT::i32 &&
12951 "Expect ADDC with two result values. First: i32");
12952
12953 // Check that the ADDC adds the low result of the S/UMUL_LOHI. If not, it
12954 // maybe a SMLAL which multiplies two 16-bit values.
12955 if (AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12956 AddcSubcOp0->getOpcode() != ISD::UMUL_LOHI &&
12957 AddcSubcOp0->getOpcode() != ISD::SMUL_LOHI &&
12958 AddcSubcOp1->getOpcode() != ISD::UMUL_LOHI &&
12959 AddcSubcOp1->getOpcode() != ISD::SMUL_LOHI)
12960 return AddCombineTo64BitSMLAL16(AddcSubcNode, AddeSubeNode, DCI, Subtarget);
12961
12962 // Check for the triangle shape.
12963 SDValue AddeSubeOp0 = AddeSubeNode->getOperand(0);
12964 SDValue AddeSubeOp1 = AddeSubeNode->getOperand(1);
12965
12966 // Make sure that the ADDE/SUBE operands are not coming from the same node.
12967 if (AddeSubeOp0.getNode() == AddeSubeOp1.getNode())
12968 return SDValue();
12969
12970 // Find the MUL_LOHI node walking up ADDE/SUBE's operands.
12971 bool IsLeftOperandMUL = false;
12972 SDValue MULOp = findMUL_LOHI(AddeSubeOp0);
12973 if (MULOp == SDValue())
12974 MULOp = findMUL_LOHI(AddeSubeOp1);
12975 else
12976 IsLeftOperandMUL = true;
12977 if (MULOp == SDValue())
12978 return SDValue();
12979
12980 // Figure out the right opcode.
12981 unsigned Opc = MULOp->getOpcode();
12982 unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
12983
12984 // Figure out the high and low input values to the MLAL node.
12985 SDValue *HiAddSub = nullptr;
12986 SDValue *LoMul = nullptr;
12987 SDValue *LowAddSub = nullptr;
12988
12989 // Ensure that ADDE/SUBE is from high result of ISD::xMUL_LOHI.
12990 if ((AddeSubeOp0 != MULOp.getValue(1)) && (AddeSubeOp1 != MULOp.getValue(1)))
12991 return SDValue();
12992
12993 if (IsLeftOperandMUL)
12994 HiAddSub = &AddeSubeOp1;
12995 else
12996 HiAddSub = &AddeSubeOp0;
12997
12998 // Ensure that LoMul and LowAddSub are taken from correct ISD::SMUL_LOHI node
12999 // whose low result is fed to the ADDC/SUBC we are checking.
13000
13001 if (AddcSubcOp0 == MULOp.getValue(0)) {
13002 LoMul = &AddcSubcOp0;
13003 LowAddSub = &AddcSubcOp1;
13004 }
13005 if (AddcSubcOp1 == MULOp.getValue(0)) {
13006 LoMul = &AddcSubcOp1;
13007 LowAddSub = &AddcSubcOp0;
13008 }
13009
13010 if (!LoMul)
13011 return SDValue();
13012
13013 // If HiAddSub is the same node as ADDC/SUBC or is a predecessor of ADDC/SUBC
13014 // the replacement below will create a cycle.
13015 if (AddcSubcNode == HiAddSub->getNode() ||
13016 AddcSubcNode->isPredecessorOf(HiAddSub->getNode()))
13017 return SDValue();
13018
13019 // Create the merged node.
13020 SelectionDAG &DAG = DCI.DAG;
13021
13022 // Start building operand list.
13024 Ops.push_back(LoMul->getOperand(0));
13025 Ops.push_back(LoMul->getOperand(1));
13026
13027 // Check whether we can use SMMLAR, SMMLSR or SMMULR instead. For this to be
13028 // the case, we must be doing signed multiplication and only use the higher
13029 // part of the result of the MLAL, furthermore the LowAddSub must be a constant
13030 // addition or subtraction with the value of 0x800000.
13031 if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && Subtarget->useMulOps() &&
13032 FinalOpc == ARMISD::SMLAL && !AddeSubeNode->hasAnyUseOfValue(1) &&
13033 LowAddSub->getNode()->getOpcode() == ISD::Constant &&
13034 static_cast<ConstantSDNode *>(LowAddSub->getNode())->getZExtValue() ==
13035 0x80000000) {
13036 Ops.push_back(*HiAddSub);
13037 if (AddcSubcNode->getOpcode() == ARMISD::SUBC) {
13038 FinalOpc = ARMISD::SMMLSR;
13039 } else {
13040 FinalOpc = ARMISD::SMMLAR;
13041 }
13042 SDValue NewNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode), MVT::i32, Ops);
13043 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), NewNode);
13044
13045 return SDValue(AddeSubeNode, 0);
13046 } else if (AddcSubcNode->getOpcode() == ARMISD::SUBC)
13047 // SMMLS is generated during instruction selection and the rest of this
13048 // function can not handle the case where AddcSubcNode is a SUBC.
13049 return SDValue();
13050
13051 // Finish building the operand list for {U/S}MLAL
13052 Ops.push_back(*LowAddSub);
13053 Ops.push_back(*HiAddSub);
13054
13055 SDValue MLALNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode),
13056 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13057
13058 // Replace the ADDs' nodes uses by the MLA node's values.
13059 SDValue HiMLALResult(MLALNode.getNode(), 1);
13060 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), HiMLALResult);
13061
13062 SDValue LoMLALResult(MLALNode.getNode(), 0);
13063 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcSubcNode, 0), LoMLALResult);
13064
13065 // Return original node to notify the driver to stop replacing.
13066 return SDValue(AddeSubeNode, 0);
13067}
13068
13071 const ARMSubtarget *Subtarget) {
13072 // UMAAL is similar to UMLAL except that it adds two unsigned values.
13073 // While trying to combine for the other MLAL nodes, first search for the
13074 // chance to use UMAAL. Check if Addc uses a node which has already
13075 // been combined into a UMLAL. The other pattern is UMLAL using Addc/Adde
13076 // as the addend, and it's handled in PerformUMLALCombine.
13077
13078 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13079 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13080
13081 // Check that we have a glued ADDC node.
13082 SDNode* AddcNode = AddeNode->getOperand(2).getNode();
13083 if (AddcNode->getOpcode() != ARMISD::ADDC)
13084 return SDValue();
13085
13086 // Find the converted UMAAL or quit if it doesn't exist.
13087 SDNode *UmlalNode = nullptr;
13088 SDValue AddHi;
13089 if (AddcNode->getOperand(0).getOpcode() == ARMISD::UMLAL) {
13090 UmlalNode = AddcNode->getOperand(0).getNode();
13091 AddHi = AddcNode->getOperand(1);
13092 } else if (AddcNode->getOperand(1).getOpcode() == ARMISD::UMLAL) {
13093 UmlalNode = AddcNode->getOperand(1).getNode();
13094 AddHi = AddcNode->getOperand(0);
13095 } else {
13096 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13097 }
13098
13099 // The ADDC should be glued to an ADDE node, which uses the same UMLAL as
13100 // the ADDC as well as Zero.
13101 if (!isNullConstant(UmlalNode->getOperand(3)))
13102 return SDValue();
13103
13104 if ((isNullConstant(AddeNode->getOperand(0)) &&
13105 AddeNode->getOperand(1).getNode() == UmlalNode) ||
13106 (AddeNode->getOperand(0).getNode() == UmlalNode &&
13107 isNullConstant(AddeNode->getOperand(1)))) {
13108 SelectionDAG &DAG = DCI.DAG;
13109 SDValue Ops[] = { UmlalNode->getOperand(0), UmlalNode->getOperand(1),
13110 UmlalNode->getOperand(2), AddHi };
13111 SDValue UMAAL = DAG.getNode(ARMISD::UMAAL, SDLoc(AddcNode),
13112 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13113
13114 // Replace the ADDs' nodes uses by the UMAAL node's values.
13115 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), SDValue(UMAAL.getNode(), 1));
13116 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), SDValue(UMAAL.getNode(), 0));
13117
13118 // Return original node to notify the driver to stop replacing.
13119 return SDValue(AddeNode, 0);
13120 }
13121 return SDValue();
13122}
13123
13125 const ARMSubtarget *Subtarget) {
13126 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13127 return SDValue();
13128
13129 // Check that we have a pair of ADDC and ADDE as operands.
13130 // Both addends of the ADDE must be zero.
13131 SDNode* AddcNode = N->getOperand(2).getNode();
13132 SDNode* AddeNode = N->getOperand(3).getNode();
13133 if ((AddcNode->getOpcode() == ARMISD::ADDC) &&
13134 (AddeNode->getOpcode() == ARMISD::ADDE) &&
13135 isNullConstant(AddeNode->getOperand(0)) &&
13136 isNullConstant(AddeNode->getOperand(1)) &&
13137 (AddeNode->getOperand(2).getNode() == AddcNode))
13138 return DAG.getNode(ARMISD::UMAAL, SDLoc(N),
13139 DAG.getVTList(MVT::i32, MVT::i32),
13140 {N->getOperand(0), N->getOperand(1),
13141 AddcNode->getOperand(0), AddcNode->getOperand(1)});
13142 else
13143 return SDValue();
13144}
13145
13148 const ARMSubtarget *Subtarget) {
13149 SelectionDAG &DAG(DCI.DAG);
13150
13151 if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
13152 // (SUBC (ADDE 0, 0, C), 1) -> C
13153 SDValue LHS = N->getOperand(0);
13154 SDValue RHS = N->getOperand(1);
13155 if (LHS->getOpcode() == ARMISD::ADDE &&
13156 isNullConstant(LHS->getOperand(0)) &&
13157 isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
13158 return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
13159 }
13160 }
13161
13162 if (Subtarget->isThumb1Only()) {
13163 SDValue RHS = N->getOperand(1);
13165 int32_t imm = C->getSExtValue();
13166 if (imm < 0 && imm > std::numeric_limits<int>::min()) {
13167 SDLoc DL(N);
13168 RHS = DAG.getConstant(-imm, DL, MVT::i32);
13169 unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
13170 : ARMISD::ADDC;
13171 return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
13172 }
13173 }
13174 }
13175
13176 return SDValue();
13177}
13178
13181 const ARMSubtarget *Subtarget) {
13182 if (Subtarget->isThumb1Only()) {
13183 SelectionDAG &DAG = DCI.DAG;
13184 SDValue RHS = N->getOperand(1);
13186 int64_t imm = C->getSExtValue();
13187 if (imm < 0) {
13188 SDLoc DL(N);
13189
13190 // The with-carry-in form matches bitwise not instead of the negation.
13191 // Effectively, the inverse interpretation of the carry flag already
13192 // accounts for part of the negation.
13193 RHS = DAG.getConstant(~imm, DL, MVT::i32);
13194
13195 unsigned Opcode = (N->getOpcode() == ARMISD::ADDE) ? ARMISD::SUBE
13196 : ARMISD::ADDE;
13197 return DAG.getNode(Opcode, DL, N->getVTList(),
13198 N->getOperand(0), RHS, N->getOperand(2));
13199 }
13200 }
13201 } else if (N->getOperand(1)->getOpcode() == ISD::SMUL_LOHI) {
13202 return AddCombineTo64bitMLAL(N, DCI, Subtarget);
13203 }
13204 return SDValue();
13205}
13206
13209 const ARMSubtarget *Subtarget) {
13210 if (!Subtarget->hasMVEIntegerOps())
13211 return SDValue();
13212
13213 SDLoc dl(N);
13214 SDValue SetCC;
13215 SDValue LHS;
13216 SDValue RHS;
13217 ISD::CondCode CC;
13218 SDValue TrueVal;
13219 SDValue FalseVal;
13220
13221 if (N->getOpcode() == ISD::SELECT &&
13222 N->getOperand(0)->getOpcode() == ISD::SETCC) {
13223 SetCC = N->getOperand(0);
13224 LHS = SetCC->getOperand(0);
13225 RHS = SetCC->getOperand(1);
13226 CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
13227 TrueVal = N->getOperand(1);
13228 FalseVal = N->getOperand(2);
13229 } else if (N->getOpcode() == ISD::SELECT_CC) {
13230 LHS = N->getOperand(0);
13231 RHS = N->getOperand(1);
13232 CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
13233 TrueVal = N->getOperand(2);
13234 FalseVal = N->getOperand(3);
13235 } else {
13236 return SDValue();
13237 }
13238
13239 unsigned int Opcode = 0;
13240 if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
13241 FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
13242 (CC == ISD::SETULT || CC == ISD::SETUGT)) {
13243 Opcode = ARMISD::VMINVu;
13244 if (CC == ISD::SETUGT)
13245 std::swap(TrueVal, FalseVal);
13246 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
13247 FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
13248 (CC == ISD::SETLT || CC == ISD::SETGT)) {
13249 Opcode = ARMISD::VMINVs;
13250 if (CC == ISD::SETGT)
13251 std::swap(TrueVal, FalseVal);
13252 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
13253 FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
13254 (CC == ISD::SETUGT || CC == ISD::SETULT)) {
13255 Opcode = ARMISD::VMAXVu;
13256 if (CC == ISD::SETULT)
13257 std::swap(TrueVal, FalseVal);
13258 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
13259 FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
13260 (CC == ISD::SETGT || CC == ISD::SETLT)) {
13261 Opcode = ARMISD::VMAXVs;
13262 if (CC == ISD::SETLT)
13263 std::swap(TrueVal, FalseVal);
13264 } else
13265 return SDValue();
13266
13267 // Normalise to the right hand side being the vector reduction
13268 switch (TrueVal->getOpcode()) {
13273 std::swap(LHS, RHS);
13274 std::swap(TrueVal, FalseVal);
13275 break;
13276 }
13277
13278 EVT VectorType = FalseVal->getOperand(0).getValueType();
13279
13280 if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
13281 VectorType != MVT::v4i32)
13282 return SDValue();
13283
13284 EVT VectorScalarType = VectorType.getVectorElementType();
13285
13286 // The values being selected must also be the ones being compared
13287 if (TrueVal != LHS || FalseVal != RHS)
13288 return SDValue();
13289
13290 EVT LeftType = LHS->getValueType(0);
13291 EVT RightType = RHS->getValueType(0);
13292
13293 // The types must match the reduced type too
13294 if (LeftType != VectorScalarType || RightType != VectorScalarType)
13295 return SDValue();
13296
13297 // Legalise the scalar to an i32
13298 if (VectorScalarType != MVT::i32)
13299 LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
13300
13301 // Generate the reduction as an i32 for legalisation purposes
13302 auto Reduction =
13303 DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
13304
13305 // The result isn't actually an i32 so truncate it back to its original type
13306 if (VectorScalarType != MVT::i32)
13307 Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
13308
13309 return Reduction;
13310}
13311
13312// A special combine for the vqdmulh family of instructions. This is one of the
13313// potential set of patterns that could patch this instruction. The base pattern
13314// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
13315// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
13316// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
13317// the max is unnecessary.
13319 EVT VT = N->getValueType(0);
13320 SDValue Shft;
13321 ConstantSDNode *Clamp;
13322
13323 if (!VT.isVector() || VT.getScalarSizeInBits() > 64)
13324 return SDValue();
13325
13326 if (N->getOpcode() == ISD::SMIN) {
13327 Shft = N->getOperand(0);
13328 Clamp = isConstOrConstSplat(N->getOperand(1));
13329 } else if (N->getOpcode() == ISD::VSELECT) {
13330 // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
13331 SDValue Cmp = N->getOperand(0);
13332 if (Cmp.getOpcode() != ISD::SETCC ||
13333 cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
13334 Cmp.getOperand(0) != N->getOperand(1) ||
13335 Cmp.getOperand(1) != N->getOperand(2))
13336 return SDValue();
13337 Shft = N->getOperand(1);
13338 Clamp = isConstOrConstSplat(N->getOperand(2));
13339 } else
13340 return SDValue();
13341
13342 if (!Clamp)
13343 return SDValue();
13344
13345 MVT ScalarType;
13346 int ShftAmt = 0;
13347 switch (Clamp->getSExtValue()) {
13348 case (1 << 7) - 1:
13349 ScalarType = MVT::i8;
13350 ShftAmt = 7;
13351 break;
13352 case (1 << 15) - 1:
13353 ScalarType = MVT::i16;
13354 ShftAmt = 15;
13355 break;
13356 case (1ULL << 31) - 1:
13357 ScalarType = MVT::i32;
13358 ShftAmt = 31;
13359 break;
13360 default:
13361 return SDValue();
13362 }
13363
13364 if (Shft.getOpcode() != ISD::SRA)
13365 return SDValue();
13367 if (!N1 || N1->getSExtValue() != ShftAmt)
13368 return SDValue();
13369
13370 SDValue Mul = Shft.getOperand(0);
13371 if (Mul.getOpcode() != ISD::MUL)
13372 return SDValue();
13373
13374 SDValue Ext0 = Mul.getOperand(0);
13375 SDValue Ext1 = Mul.getOperand(1);
13376 if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
13377 Ext1.getOpcode() != ISD::SIGN_EXTEND)
13378 return SDValue();
13379 EVT VecVT = Ext0.getOperand(0).getValueType();
13380 if (!VecVT.isPow2VectorType() || VecVT.getVectorNumElements() == 1)
13381 return SDValue();
13382 if (Ext1.getOperand(0).getValueType() != VecVT ||
13383 VecVT.getScalarType() != ScalarType ||
13384 VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
13385 return SDValue();
13386
13387 SDLoc DL(Mul);
13388 unsigned LegalLanes = 128 / (ShftAmt + 1);
13389 EVT LegalVecVT = MVT::getVectorVT(ScalarType, LegalLanes);
13390 // For types smaller than legal vectors extend to be legal and only use needed
13391 // lanes.
13392 if (VecVT.getSizeInBits() < 128) {
13393 EVT ExtVecVT =
13395 VecVT.getVectorNumElements());
13396 SDValue Inp0 =
13397 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext0.getOperand(0));
13398 SDValue Inp1 =
13399 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext1.getOperand(0));
13400 Inp0 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp0);
13401 Inp1 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp1);
13402 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13403 SDValue Trunc = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, ExtVecVT, VQDMULH);
13404 Trunc = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Trunc);
13405 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Trunc);
13406 }
13407
13408 // For larger types, split into legal sized chunks.
13409 assert(VecVT.getSizeInBits() % 128 == 0 && "Expected a power2 type");
13410 unsigned NumParts = VecVT.getSizeInBits() / 128;
13412 for (unsigned I = 0; I < NumParts; ++I) {
13413 SDValue Inp0 =
13414 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext0.getOperand(0),
13415 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13416 SDValue Inp1 =
13417 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext1.getOperand(0),
13418 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13419 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13420 Parts.push_back(VQDMULH);
13421 }
13422 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT,
13423 DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
13424}
13425
13428 const ARMSubtarget *Subtarget) {
13429 if (!Subtarget->hasMVEIntegerOps())
13430 return SDValue();
13431
13432 // Constant fold vselect 0, A, B -> B
13433 // and vselect 0xffff, A, B -> A
13434 if (N->getOperand(0).getOpcode() == ARMISD::PREDICATE_CAST &&
13435 isa<ConstantSDNode>(N->getOperand(0).getOperand(0))) {
13436 unsigned C = N->getOperand(0).getConstantOperandVal(0);
13437 if (C == 0)
13438 return N->getOperand(2);
13439 if (C == 0xffff)
13440 return N->getOperand(1);
13441 }
13442
13443 if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
13444 return V;
13445
13446 // Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
13447 //
13448 // We need to re-implement this optimization here as the implementation in the
13449 // Target-Independent DAGCombiner does not handle the kind of constant we make
13450 // (it calls isConstOrConstSplat with AllowTruncation set to false - and for
13451 // good reason, allowing truncation there would break other targets).
13452 //
13453 // Currently, this is only done for MVE, as it's the only target that benefits
13454 // from this transformation (e.g. VPNOT+VPSEL becomes a single VPSEL).
13455 if (N->getOperand(0).getOpcode() != ISD::XOR)
13456 return SDValue();
13457 SDValue XOR = N->getOperand(0);
13458
13459 // Check if the XOR's RHS is either a 1, or a BUILD_VECTOR of 1s.
13460 // It is important to check with truncation allowed as the BUILD_VECTORs we
13461 // generate in those situations will truncate their operands.
13462 ConstantSDNode *Const =
13463 isConstOrConstSplat(XOR->getOperand(1), /*AllowUndefs*/ false,
13464 /*AllowTruncation*/ true);
13465 if (!Const || !Const->isOne())
13466 return SDValue();
13467
13468 // Rewrite into vselect(cond, rhs, lhs).
13469 SDValue Cond = XOR->getOperand(0);
13470 SDValue LHS = N->getOperand(1);
13471 SDValue RHS = N->getOperand(2);
13472 EVT Type = N->getValueType(0);
13473 return DCI.DAG.getNode(ISD::VSELECT, SDLoc(N), Type, Cond, RHS, LHS);
13474}
13475
13476// Convert vsetcc([0,1,2,..], splat(n), ult) -> vctp n
13479 const ARMSubtarget *Subtarget) {
13480 SDValue Op0 = N->getOperand(0);
13481 SDValue Op1 = N->getOperand(1);
13482 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
13483 EVT VT = N->getValueType(0);
13484
13485 if (!Subtarget->hasMVEIntegerOps() ||
13487 return SDValue();
13488
13489 if (CC == ISD::SETUGE) {
13490 std::swap(Op0, Op1);
13491 CC = ISD::SETULT;
13492 }
13493
13494 if (CC != ISD::SETULT || VT.getScalarSizeInBits() != 1 ||
13496 return SDValue();
13497
13498 // Check first operand is BuildVector of 0,1,2,...
13499 for (unsigned I = 0; I < VT.getVectorNumElements(); I++) {
13500 if (!Op0.getOperand(I).isUndef() &&
13502 Op0.getConstantOperandVal(I) == I))
13503 return SDValue();
13504 }
13505
13506 // The second is a Splat of Op1S
13507 SDValue Op1S = DCI.DAG.getSplatValue(Op1);
13508 if (!Op1S)
13509 return SDValue();
13510
13511 unsigned Opc;
13512 switch (VT.getVectorNumElements()) {
13513 case 2:
13514 Opc = Intrinsic::arm_mve_vctp64;
13515 break;
13516 case 4:
13517 Opc = Intrinsic::arm_mve_vctp32;
13518 break;
13519 case 8:
13520 Opc = Intrinsic::arm_mve_vctp16;
13521 break;
13522 case 16:
13523 Opc = Intrinsic::arm_mve_vctp8;
13524 break;
13525 default:
13526 return SDValue();
13527 }
13528
13529 SDLoc DL(N);
13530 return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT,
13531 DCI.DAG.getConstant(Opc, DL, MVT::i32),
13532 DCI.DAG.getZExtOrTrunc(Op1S, DL, MVT::i32));
13533}
13534
13535/// PerformADDECombine - Target-specific dag combine transform from
13536/// ARMISD::ADDC, ARMISD::ADDE, and ISD::MUL_LOHI to MLAL or
13537/// ARMISD::ADDC, ARMISD::ADDE and ARMISD::UMLAL to ARMISD::UMAAL
13540 const ARMSubtarget *Subtarget) {
13541 // Only ARM and Thumb2 support UMLAL/SMLAL.
13542 if (Subtarget->isThumb1Only())
13543 return PerformAddeSubeCombine(N, DCI, Subtarget);
13544
13545 // Only perform the checks after legalize when the pattern is available.
13546 if (DCI.isBeforeLegalize()) return SDValue();
13547
13548 return AddCombineTo64bitUMAAL(N, DCI, Subtarget);
13549}
13550
13551/// PerformADDCombineWithOperands - Try DAG combinations for an ADD with
13552/// operands N0 and N1. This is a helper for PerformADDCombine that is
13553/// called with the default operands, and if that fails, with commuted
13554/// operands.
13557 const ARMSubtarget *Subtarget){
13558 // Attempt to create vpadd for this add.
13559 if (SDValue Result = AddCombineToVPADD(N, N0, N1, DCI, Subtarget))
13560 return Result;
13561
13562 // Attempt to create vpaddl for this add.
13563 if (SDValue Result = AddCombineVUZPToVPADDL(N, N0, N1, DCI, Subtarget))
13564 return Result;
13565 if (SDValue Result = AddCombineBUILD_VECTORToVPADDL(N, N0, N1, DCI,
13566 Subtarget))
13567 return Result;
13568
13569 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
13570 if (N0.getNode()->hasOneUse())
13571 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI))
13572 return Result;
13573 return SDValue();
13574}
13575
13577 EVT VT = N->getValueType(0);
13578 SDValue N0 = N->getOperand(0);
13579 SDValue N1 = N->getOperand(1);
13580 SDLoc dl(N);
13581
13582 auto IsVecReduce = [](SDValue Op) {
13583 switch (Op.getOpcode()) {
13584 case ISD::VECREDUCE_ADD:
13585 case ARMISD::VADDVs:
13586 case ARMISD::VADDVu:
13587 case ARMISD::VMLAVs:
13588 case ARMISD::VMLAVu:
13589 return true;
13590 }
13591 return false;
13592 };
13593
13594 auto DistrubuteAddAddVecReduce = [&](SDValue N0, SDValue N1) {
13595 // Distribute add(X, add(vecreduce(Y), vecreduce(Z))) ->
13596 // add(add(X, vecreduce(Y)), vecreduce(Z))
13597 // to make better use of vaddva style instructions.
13598 if (VT == MVT::i32 && N1.getOpcode() == ISD::ADD && !IsVecReduce(N0) &&
13599 IsVecReduce(N1.getOperand(0)) && IsVecReduce(N1.getOperand(1)) &&
13600 !isa<ConstantSDNode>(N0) && N1->hasOneUse()) {
13601 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0, N1.getOperand(0));
13602 return DAG.getNode(ISD::ADD, dl, VT, Add0, N1.getOperand(1));
13603 }
13604 // And turn add(add(A, reduce(B)), add(C, reduce(D))) ->
13605 // add(add(add(A, C), reduce(B)), reduce(D))
13606 if (VT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
13607 N1.getOpcode() == ISD::ADD && N0->hasOneUse() && N1->hasOneUse()) {
13608 unsigned N0RedOp = 0;
13609 if (!IsVecReduce(N0.getOperand(N0RedOp))) {
13610 N0RedOp = 1;
13611 if (!IsVecReduce(N0.getOperand(N0RedOp)))
13612 return SDValue();
13613 }
13614
13615 unsigned N1RedOp = 0;
13616 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13617 N1RedOp = 1;
13618 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13619 return SDValue();
13620
13621 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0.getOperand(1 - N0RedOp),
13622 N1.getOperand(1 - N1RedOp));
13623 SDValue Add1 =
13624 DAG.getNode(ISD::ADD, dl, VT, Add0, N0.getOperand(N0RedOp));
13625 return DAG.getNode(ISD::ADD, dl, VT, Add1, N1.getOperand(N1RedOp));
13626 }
13627 return SDValue();
13628 };
13629 if (SDValue R = DistrubuteAddAddVecReduce(N0, N1))
13630 return R;
13631 if (SDValue R = DistrubuteAddAddVecReduce(N1, N0))
13632 return R;
13633
13634 // Distribute add(vecreduce(load(Y)), vecreduce(load(Z)))
13635 // Or add(add(X, vecreduce(load(Y))), vecreduce(load(Z)))
13636 // by ascending load offsets. This can help cores prefetch if the order of
13637 // loads is more predictable.
13638 auto DistrubuteVecReduceLoad = [&](SDValue N0, SDValue N1, bool IsForward) {
13639 // Check if two reductions are known to load data where one is before/after
13640 // another. Return negative if N0 loads data before N1, positive if N1 is
13641 // before N0 and 0 otherwise if nothing is known.
13642 auto IsKnownOrderedLoad = [&](SDValue N0, SDValue N1) {
13643 // Look through to the first operand of a MUL, for the VMLA case.
13644 // Currently only looks at the first operand, in the hope they are equal.
13645 if (N0.getOpcode() == ISD::MUL)
13646 N0 = N0.getOperand(0);
13647 if (N1.getOpcode() == ISD::MUL)
13648 N1 = N1.getOperand(0);
13649
13650 // Return true if the two operands are loads to the same object and the
13651 // offset of the first is known to be less than the offset of the second.
13652 LoadSDNode *Load0 = dyn_cast<LoadSDNode>(N0);
13653 LoadSDNode *Load1 = dyn_cast<LoadSDNode>(N1);
13654 if (!Load0 || !Load1 || Load0->getChain() != Load1->getChain() ||
13655 !Load0->isSimple() || !Load1->isSimple() || Load0->isIndexed() ||
13656 Load1->isIndexed())
13657 return 0;
13658
13659 auto BaseLocDecomp0 = BaseIndexOffset::match(Load0, DAG);
13660 auto BaseLocDecomp1 = BaseIndexOffset::match(Load1, DAG);
13661
13662 if (!BaseLocDecomp0.getBase() ||
13663 BaseLocDecomp0.getBase() != BaseLocDecomp1.getBase() ||
13664 !BaseLocDecomp0.hasValidOffset() || !BaseLocDecomp1.hasValidOffset())
13665 return 0;
13666 if (BaseLocDecomp0.getOffset() < BaseLocDecomp1.getOffset())
13667 return -1;
13668 if (BaseLocDecomp0.getOffset() > BaseLocDecomp1.getOffset())
13669 return 1;
13670 return 0;
13671 };
13672
13673 SDValue X;
13674 if (N0.getOpcode() == ISD::ADD && N0->hasOneUse()) {
13675 if (IsVecReduce(N0.getOperand(0)) && IsVecReduce(N0.getOperand(1))) {
13676 int IsBefore = IsKnownOrderedLoad(N0.getOperand(0).getOperand(0),
13677 N0.getOperand(1).getOperand(0));
13678 if (IsBefore < 0) {
13679 X = N0.getOperand(0);
13680 N0 = N0.getOperand(1);
13681 } else if (IsBefore > 0) {
13682 X = N0.getOperand(1);
13683 N0 = N0.getOperand(0);
13684 } else
13685 return SDValue();
13686 } else if (IsVecReduce(N0.getOperand(0))) {
13687 X = N0.getOperand(1);
13688 N0 = N0.getOperand(0);
13689 } else if (IsVecReduce(N0.getOperand(1))) {
13690 X = N0.getOperand(0);
13691 N0 = N0.getOperand(1);
13692 } else
13693 return SDValue();
13694 } else if (IsForward && IsVecReduce(N0) && IsVecReduce(N1) &&
13695 IsKnownOrderedLoad(N0.getOperand(0), N1.getOperand(0)) < 0) {
13696 // Note this is backward to how you would expect. We create
13697 // add(reduce(load + 16), reduce(load + 0)) so that the
13698 // add(reduce(load+16), X) is combined into VADDVA(X, load+16)), leaving
13699 // the X as VADDV(load + 0)
13700 return DAG.getNode(ISD::ADD, dl, VT, N1, N0);
13701 } else
13702 return SDValue();
13703
13704 if (!IsVecReduce(N0) || !IsVecReduce(N1))
13705 return SDValue();
13706
13707 if (IsKnownOrderedLoad(N1.getOperand(0), N0.getOperand(0)) >= 0)
13708 return SDValue();
13709
13710 // Switch from add(add(X, N0), N1) to add(add(X, N1), N0)
13711 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, X, N1);
13712 return DAG.getNode(ISD::ADD, dl, VT, Add0, N0);
13713 };
13714 if (SDValue R = DistrubuteVecReduceLoad(N0, N1, true))
13715 return R;
13716 if (SDValue R = DistrubuteVecReduceLoad(N1, N0, false))
13717 return R;
13718 return SDValue();
13719}
13720
13722 const ARMSubtarget *Subtarget) {
13723 if (!Subtarget->hasMVEIntegerOps())
13724 return SDValue();
13725
13727 return R;
13728
13729 EVT VT = N->getValueType(0);
13730 SDValue N0 = N->getOperand(0);
13731 SDValue N1 = N->getOperand(1);
13732 SDLoc dl(N);
13733
13734 if (VT != MVT::i64)
13735 return SDValue();
13736
13737 // We are looking for a i64 add of a VADDLVx. Due to these being i64's, this
13738 // will look like:
13739 // t1: i32,i32 = ARMISD::VADDLVs x
13740 // t2: i64 = build_pair t1, t1:1
13741 // t3: i64 = add t2, y
13742 // Otherwise we try to push the add up above VADDLVAx, to potentially allow
13743 // the add to be simplified separately.
13744 // We also need to check for sext / zext and commutitive adds.
13745 auto MakeVecReduce = [&](unsigned Opcode, unsigned OpcodeA, SDValue NA,
13746 SDValue NB) {
13747 if (NB->getOpcode() != ISD::BUILD_PAIR)
13748 return SDValue();
13749 SDValue VecRed = NB->getOperand(0);
13750 if ((VecRed->getOpcode() != Opcode && VecRed->getOpcode() != OpcodeA) ||
13751 VecRed.getResNo() != 0 ||
13752 NB->getOperand(1) != SDValue(VecRed.getNode(), 1))
13753 return SDValue();
13754
13755 if (VecRed->getOpcode() == OpcodeA) {
13756 // add(NA, VADDLVA(Inp), Y) -> VADDLVA(add(NA, Inp), Y)
13757 SDValue Inp = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
13758 VecRed.getOperand(0), VecRed.getOperand(1));
13759 NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA);
13760 }
13761
13763 std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32);
13764
13765 unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0;
13766 for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++)
13767 Ops.push_back(VecRed->getOperand(I));
13768 SDValue Red =
13769 DAG.getNode(OpcodeA, dl, DAG.getVTList({MVT::i32, MVT::i32}), Ops);
13770 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Red,
13771 SDValue(Red.getNode(), 1));
13772 };
13773
13774 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N0, N1))
13775 return M;
13776 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N0, N1))
13777 return M;
13778 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N1, N0))
13779 return M;
13780 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N1, N0))
13781 return M;
13782 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N0, N1))
13783 return M;
13784 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N0, N1))
13785 return M;
13786 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N1, N0))
13787 return M;
13788 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N1, N0))
13789 return M;
13790 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N0, N1))
13791 return M;
13792 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N0, N1))
13793 return M;
13794 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N1, N0))
13795 return M;
13796 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
13797 return M;
13798 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
13799 return M;
13800 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
13801 return M;
13802 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
13803 return M;
13804 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
13805 return M;
13806 return SDValue();
13807}
13808
13809bool
13811 CombineLevel Level) const {
13812 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
13813 N->getOpcode() == ISD::SRL) &&
13814 "Expected shift op");
13815
13816 SDValue ShiftLHS = N->getOperand(0);
13817 if (!ShiftLHS->hasOneUse())
13818 return false;
13819
13820 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
13821 !ShiftLHS.getOperand(0)->hasOneUse())
13822 return false;
13823
13824 if (Level == BeforeLegalizeTypes)
13825 return true;
13826
13827 if (N->getOpcode() != ISD::SHL)
13828 return true;
13829
13830 if (Subtarget->isThumb1Only()) {
13831 // Avoid making expensive immediates by commuting shifts. (This logic
13832 // only applies to Thumb1 because ARM and Thumb2 immediates can be shifted
13833 // for free.)
13834 if (N->getOpcode() != ISD::SHL)
13835 return true;
13836 SDValue N1 = N->getOperand(0);
13837 if (N1->getOpcode() != ISD::ADD && N1->getOpcode() != ISD::AND &&
13838 N1->getOpcode() != ISD::OR && N1->getOpcode() != ISD::XOR)
13839 return true;
13840 if (auto *Const = dyn_cast<ConstantSDNode>(N1->getOperand(1))) {
13841 if (Const->getAPIntValue().ult(256))
13842 return false;
13843 if (N1->getOpcode() == ISD::ADD && Const->getAPIntValue().slt(0) &&
13844 Const->getAPIntValue().sgt(-256))
13845 return false;
13846 }
13847 return true;
13848 }
13849
13850 // Turn off commute-with-shift transform after legalization, so it doesn't
13851 // conflict with PerformSHLSimplify. (We could try to detect when
13852 // PerformSHLSimplify would trigger more precisely, but it isn't
13853 // really necessary.)
13854 return false;
13855}
13856
13858 const SDNode *N) const {
13859 assert(N->getOpcode() == ISD::XOR &&
13860 (N->getOperand(0).getOpcode() == ISD::SHL ||
13861 N->getOperand(0).getOpcode() == ISD::SRL) &&
13862 "Expected XOR(SHIFT) pattern");
13863
13864 // Only commute if the entire NOT mask is a hidden shifted mask.
13865 auto *XorC = dyn_cast<ConstantSDNode>(N->getOperand(1));
13866 auto *ShiftC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1));
13867 if (XorC && ShiftC) {
13868 unsigned MaskIdx, MaskLen;
13869 if (XorC->getAPIntValue().isShiftedMask(MaskIdx, MaskLen)) {
13870 unsigned ShiftAmt = ShiftC->getZExtValue();
13871 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
13872 if (N->getOperand(0).getOpcode() == ISD::SHL)
13873 return MaskIdx == ShiftAmt && MaskLen == (BitWidth - ShiftAmt);
13874 return MaskIdx == 0 && MaskLen == (BitWidth - ShiftAmt);
13875 }
13876 }
13877
13878 return false;
13879}
13880
13882 const SDNode *N) const {
13883 assert(((N->getOpcode() == ISD::SHL &&
13884 N->getOperand(0).getOpcode() == ISD::SRL) ||
13885 (N->getOpcode() == ISD::SRL &&
13886 N->getOperand(0).getOpcode() == ISD::SHL)) &&
13887 "Expected shift-shift mask");
13888
13889 if (!Subtarget->isThumb1Only())
13890 return true;
13891
13892 EVT VT = N->getValueType(0);
13893 if (VT.getScalarSizeInBits() > 32)
13894 return true;
13895
13896 return false;
13897}
13898
13900 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
13901 SDValue Y) const {
13902 return Subtarget->hasMVEIntegerOps() && isTypeLegal(VT) &&
13903 SelectOpcode == ISD::VSELECT;
13904}
13905
13907 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps()) {
13908 if (Subtarget->isThumb1Only())
13909 return VT.getScalarSizeInBits() <= 32;
13910 return true;
13911 }
13912 return VT.isScalarInteger();
13913}
13914
13916 EVT VT) const {
13917 if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
13918 return false;
13919
13920 switch (FPVT.getSimpleVT().SimpleTy) {
13921 case MVT::f16:
13922 return Subtarget->hasVFP2Base();
13923 case MVT::f32:
13924 return Subtarget->hasVFP2Base();
13925 case MVT::f64:
13926 return Subtarget->hasFP64();
13927 case MVT::v4f32:
13928 case MVT::v8f16:
13929 return Subtarget->hasMVEFloatOps();
13930 default:
13931 return false;
13932 }
13933}
13934
13937 const ARMSubtarget *ST) {
13938 // Allow the generic combiner to identify potential bswaps.
13939 if (DCI.isBeforeLegalize())
13940 return SDValue();
13941
13942 // DAG combiner will fold:
13943 // (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
13944 // (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2
13945 // Other code patterns that can be also be modified have the following form:
13946 // b + ((a << 1) | 510)
13947 // b + ((a << 1) & 510)
13948 // b + ((a << 1) ^ 510)
13949 // b + ((a << 1) + 510)
13950
13951 // Many instructions can perform the shift for free, but it requires both
13952 // the operands to be registers. If c1 << c2 is too large, a mov immediate
13953 // instruction will needed. So, unfold back to the original pattern if:
13954 // - if c1 and c2 are small enough that they don't require mov imms.
13955 // - the user(s) of the node can perform an shl
13956
13957 // No shifted operands for 16-bit instructions.
13958 if (ST->isThumb1Only())
13959 return SDValue();
13960
13961 // Check that all the users could perform the shl themselves.
13962 for (auto *U : N->users()) {
13963 switch(U->getOpcode()) {
13964 default:
13965 return SDValue();
13966 case ISD::SUB:
13967 case ISD::ADD:
13968 case ISD::AND:
13969 case ISD::OR:
13970 case ISD::XOR:
13971 case ISD::SETCC:
13972 case ARMISD::CMP:
13973 // Check that the user isn't already using a constant because there
13974 // aren't any instructions that support an immediate operand and a
13975 // shifted operand.
13976 if (isa<ConstantSDNode>(U->getOperand(0)) ||
13977 isa<ConstantSDNode>(U->getOperand(1)))
13978 return SDValue();
13979
13980 // Check that it's not already using a shift.
13981 if (U->getOperand(0).getOpcode() == ISD::SHL ||
13982 U->getOperand(1).getOpcode() == ISD::SHL)
13983 return SDValue();
13984 break;
13985 }
13986 }
13987
13988 if (N->getOpcode() != ISD::ADD && N->getOpcode() != ISD::OR &&
13989 N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND)
13990 return SDValue();
13991
13992 if (N->getOperand(0).getOpcode() != ISD::SHL)
13993 return SDValue();
13994
13995 SDValue SHL = N->getOperand(0);
13996
13997 auto *C1ShlC2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
13998 auto *C2 = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
13999 if (!C1ShlC2 || !C2)
14000 return SDValue();
14001
14002 APInt C2Int = C2->getAPIntValue();
14003 APInt C1Int = C1ShlC2->getAPIntValue();
14004 unsigned C2Width = C2Int.getBitWidth();
14005 if (C2Int.uge(C2Width))
14006 return SDValue();
14007 uint64_t C2Value = C2Int.getZExtValue();
14008
14009 // Check that performing a lshr will not lose any information.
14010 APInt Mask = APInt::getHighBitsSet(C2Width, C2Width - C2Value);
14011 if ((C1Int & Mask) != C1Int)
14012 return SDValue();
14013
14014 // Shift the first constant.
14015 C1Int.lshrInPlace(C2Int);
14016
14017 // The immediates are encoded as an 8-bit value that can be rotated.
14018 auto LargeImm = [](const APInt &Imm) {
14019 unsigned Zeros = Imm.countl_zero() + Imm.countr_zero();
14020 return Imm.getBitWidth() - Zeros > 8;
14021 };
14022
14023 if (LargeImm(C1Int) || LargeImm(C2Int))
14024 return SDValue();
14025
14026 SelectionDAG &DAG = DCI.DAG;
14027 SDLoc dl(N);
14028 SDValue X = SHL.getOperand(0);
14029 SDValue BinOp = DAG.getNode(N->getOpcode(), dl, MVT::i32, X,
14030 DAG.getConstant(C1Int, dl, MVT::i32));
14031 // Shift left to compensate for the lshr of C1Int.
14032 SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
14033
14034 LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
14035 SHL.dump(); N->dump());
14036 LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
14037 return Res;
14038}
14039
14040
14041/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
14042///
14045 const ARMSubtarget *Subtarget) {
14046 SDValue N0 = N->getOperand(0);
14047 SDValue N1 = N->getOperand(1);
14048
14049 // Only works one way, because it needs an immediate operand.
14050 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14051 return Result;
14052
14053 if (SDValue Result = PerformADDVecReduce(N, DCI.DAG, Subtarget))
14054 return Result;
14055
14056 // First try with the default operand order.
14057 if (SDValue Result = PerformADDCombineWithOperands(N, N0, N1, DCI, Subtarget))
14058 return Result;
14059
14060 // If that didn't work, try again with the operands commuted.
14061 return PerformADDCombineWithOperands(N, N1, N0, DCI, Subtarget);
14062}
14063
14064// Combine (sub 0, (csinc X, Y, CC)) -> (csinv -X, Y, CC)
14065// providing -X is as cheap as X (currently, just a constant).
14067 if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
14068 return SDValue();
14069 SDValue CSINC = N->getOperand(1);
14070 if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
14071 return SDValue();
14072
14074 if (!X)
14075 return SDValue();
14076
14077 return DAG.getNode(ARMISD::CSINV, SDLoc(N), MVT::i32,
14078 DAG.getNode(ISD::SUB, SDLoc(N), MVT::i32, N->getOperand(0),
14079 CSINC.getOperand(0)),
14080 CSINC.getOperand(1), CSINC.getOperand(2),
14081 CSINC.getOperand(3));
14082}
14083
14085 // Free to negate.
14087 return 0;
14088
14089 // Will save one instruction.
14090 if (Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)))
14091 return -1;
14092
14093 // Can freely negate by converting sra <-> srl.
14094 if (Op.getOpcode() == ISD::SRA || Op.getOpcode() == ISD::SRL) {
14095 ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1));
14096 if (Op.hasOneUse() && ShiftAmt &&
14097 ShiftAmt->getZExtValue() == Op.getValueType().getScalarSizeInBits() - 1)
14098 return 0;
14099 }
14100
14101 // Will have to create sub.
14102 return 1;
14103}
14104
14105// Try to fold
14106//
14107// (neg (cmov X, Y)) -> (cmov (neg X), (neg Y))
14108//
14109// The folding helps cmov to be matched with csneg without generating
14110// redundant neg instruction.
14112 assert(N->getOpcode() == ISD::SUB);
14113 if (!isNullConstant(N->getOperand(0)))
14114 return SDValue();
14115
14116 SDValue CMov = N->getOperand(1);
14117 if (CMov.getOpcode() != ARMISD::CMOV || !CMov->hasOneUse())
14118 return SDValue();
14119
14120 SDValue N0 = CMov.getOperand(0);
14121 SDValue N1 = CMov.getOperand(1);
14122
14123 // Only perform the fold if we actually save something.
14124 if (getNegationCost(N0) + getNegationCost(N1) > 0)
14125 return SDValue();
14126
14127 SDLoc DL(N);
14128 EVT VT = CMov.getValueType();
14129
14130 SDValue N0N = DAG.getNegative(N0, DL, VT);
14131 SDValue N1N = DAG.getNegative(N1, DL, VT);
14132 return DAG.getNode(ARMISD::CMOV, DL, VT, N0N, N1N, CMov.getOperand(2),
14133 CMov.getOperand(3));
14134}
14135
14136/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
14137///
14140 const ARMSubtarget *Subtarget) {
14141 SDValue N0 = N->getOperand(0);
14142 SDValue N1 = N->getOperand(1);
14143
14144 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
14145 if (N1.getNode()->hasOneUse())
14146 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI))
14147 return Result;
14148
14149 if (SDValue R = PerformSubCSINCCombine(N, DCI.DAG))
14150 return R;
14151
14152 if (SDValue Val = performNegCMovCombine(N, DCI.DAG))
14153 return Val;
14154
14155 if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector())
14156 return SDValue();
14157
14158 // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x))
14159 // so that we can readily pattern match more mve instructions which can use
14160 // a scalar operand.
14161 SDValue VDup = N->getOperand(1);
14162 if (VDup->getOpcode() != ARMISD::VDUP)
14163 return SDValue();
14164
14165 SDValue VMov = N->getOperand(0);
14166 if (VMov->getOpcode() == ISD::BITCAST)
14167 VMov = VMov->getOperand(0);
14168
14169 if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov))
14170 return SDValue();
14171
14172 SDLoc dl(N);
14173 SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32,
14174 DCI.DAG.getConstant(0, dl, MVT::i32),
14175 VDup->getOperand(0));
14176 return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate);
14177}
14178
14179/// PerformVMULCombine
14180/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the
14181/// special multiplier accumulator forwarding.
14182/// vmul d3, d0, d2
14183/// vmla d3, d1, d2
14184/// is faster than
14185/// vadd d3, d0, d1
14186/// vmul d3, d3, d2
14187// However, for (A + B) * (A + B),
14188// vadd d2, d0, d1
14189// vmul d3, d0, d2
14190// vmla d3, d1, d2
14191// is slower than
14192// vadd d2, d0, d1
14193// vmul d3, d2, d2
14196 const ARMSubtarget *Subtarget) {
14197 if (!Subtarget->hasVMLxForwarding())
14198 return SDValue();
14199
14200 SelectionDAG &DAG = DCI.DAG;
14201 SDValue N0 = N->getOperand(0);
14202 SDValue N1 = N->getOperand(1);
14203 unsigned Opcode = N0.getOpcode();
14204 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14205 Opcode != ISD::FADD && Opcode != ISD::FSUB) {
14206 Opcode = N1.getOpcode();
14207 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14208 Opcode != ISD::FADD && Opcode != ISD::FSUB)
14209 return SDValue();
14210 std::swap(N0, N1);
14211 }
14212
14213 if (N0 == N1)
14214 return SDValue();
14215
14216 EVT VT = N->getValueType(0);
14217 SDLoc DL(N);
14218 SDValue N00 = N0->getOperand(0);
14219 SDValue N01 = N0->getOperand(1);
14220 return DAG.getNode(Opcode, DL, VT,
14221 DAG.getNode(ISD::MUL, DL, VT, N00, N1),
14222 DAG.getNode(ISD::MUL, DL, VT, N01, N1));
14223}
14224
14226 const ARMSubtarget *Subtarget) {
14227 EVT VT = N->getValueType(0);
14228 if (VT != MVT::v2i64)
14229 return SDValue();
14230
14231 SDValue N0 = N->getOperand(0);
14232 SDValue N1 = N->getOperand(1);
14233
14234 auto IsSignExt = [&](SDValue Op) {
14235 if (Op->getOpcode() != ISD::SIGN_EXTEND_INREG)
14236 return SDValue();
14237 EVT VT = cast<VTSDNode>(Op->getOperand(1))->getVT();
14238 if (VT.getScalarSizeInBits() == 32)
14239 return Op->getOperand(0);
14240 return SDValue();
14241 };
14242 auto IsZeroExt = [&](SDValue Op) {
14243 // Zero extends are a little more awkward. At the point we are matching
14244 // this, we are looking for an AND with a (-1, 0, -1, 0) buildvector mask.
14245 // That might be before of after a bitcast depending on how the and is
14246 // placed. Because this has to look through bitcasts, it is currently only
14247 // supported on LE.
14248 if (!Subtarget->isLittle())
14249 return SDValue();
14250
14251 SDValue And = Op;
14252 if (And->getOpcode() == ISD::BITCAST)
14253 And = And->getOperand(0);
14254 if (And->getOpcode() != ISD::AND)
14255 return SDValue();
14256 SDValue Mask = And->getOperand(1);
14257 if (Mask->getOpcode() == ISD::BITCAST)
14258 Mask = Mask->getOperand(0);
14259
14260 if (Mask->getOpcode() != ISD::BUILD_VECTOR ||
14261 Mask.getValueType() != MVT::v4i32)
14262 return SDValue();
14263 if (isAllOnesConstant(Mask->getOperand(0)) &&
14264 isNullConstant(Mask->getOperand(1)) &&
14265 isAllOnesConstant(Mask->getOperand(2)) &&
14266 isNullConstant(Mask->getOperand(3)))
14267 return And->getOperand(0);
14268 return SDValue();
14269 };
14270
14271 SDLoc dl(N);
14272 if (SDValue Op0 = IsSignExt(N0)) {
14273 if (SDValue Op1 = IsSignExt(N1)) {
14274 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14275 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14276 return DAG.getNode(ARMISD::VMULLs, dl, VT, New0a, New1a);
14277 }
14278 }
14279 if (SDValue Op0 = IsZeroExt(N0)) {
14280 if (SDValue Op1 = IsZeroExt(N1)) {
14281 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14282 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14283 return DAG.getNode(ARMISD::VMULLu, dl, VT, New0a, New1a);
14284 }
14285 }
14286
14287 return SDValue();
14288}
14289
14292 const ARMSubtarget *Subtarget) {
14293 SelectionDAG &DAG = DCI.DAG;
14294
14295 EVT VT = N->getValueType(0);
14296 if (Subtarget->hasMVEIntegerOps() && VT == MVT::v2i64)
14297 return PerformMVEVMULLCombine(N, DAG, Subtarget);
14298
14299 if (Subtarget->isThumb1Only())
14300 return SDValue();
14301
14302 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14303 return SDValue();
14304
14305 if (VT.is64BitVector() || VT.is128BitVector())
14306 return PerformVMULCombine(N, DCI, Subtarget);
14307 if (VT != MVT::i32)
14308 return SDValue();
14309
14310 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14311 if (!C)
14312 return SDValue();
14313
14314 int64_t MulAmt = C->getSExtValue();
14315 unsigned ShiftAmt = llvm::countr_zero<uint64_t>(MulAmt);
14316
14317 ShiftAmt = ShiftAmt & (32 - 1);
14318 SDValue V = N->getOperand(0);
14319 SDLoc DL(N);
14320
14321 SDValue Res;
14322 MulAmt >>= ShiftAmt;
14323
14324 if (MulAmt >= 0) {
14325 if (llvm::has_single_bit<uint32_t>(MulAmt - 1)) {
14326 // (mul x, 2^N + 1) => (add (shl x, N), x)
14327 Res = DAG.getNode(ISD::ADD, DL, VT,
14328 V,
14329 DAG.getNode(ISD::SHL, DL, VT,
14330 V,
14331 DAG.getConstant(Log2_32(MulAmt - 1), DL,
14332 MVT::i32)));
14333 } else if (llvm::has_single_bit<uint32_t>(MulAmt + 1)) {
14334 // (mul x, 2^N - 1) => (sub (shl x, N), x)
14335 Res = DAG.getNode(ISD::SUB, DL, VT,
14336 DAG.getNode(ISD::SHL, DL, VT,
14337 V,
14338 DAG.getConstant(Log2_32(MulAmt + 1), DL,
14339 MVT::i32)),
14340 V);
14341 } else
14342 return SDValue();
14343 } else {
14344 uint64_t MulAmtAbs = -MulAmt;
14345 if (llvm::has_single_bit<uint32_t>(MulAmtAbs + 1)) {
14346 // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
14347 Res = DAG.getNode(ISD::SUB, DL, VT,
14348 V,
14349 DAG.getNode(ISD::SHL, DL, VT,
14350 V,
14351 DAG.getConstant(Log2_32(MulAmtAbs + 1), DL,
14352 MVT::i32)));
14353 } else if (llvm::has_single_bit<uint32_t>(MulAmtAbs - 1)) {
14354 // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
14355 Res = DAG.getNode(ISD::ADD, DL, VT,
14356 V,
14357 DAG.getNode(ISD::SHL, DL, VT,
14358 V,
14359 DAG.getConstant(Log2_32(MulAmtAbs - 1), DL,
14360 MVT::i32)));
14361 Res = DAG.getNode(ISD::SUB, DL, VT,
14362 DAG.getConstant(0, DL, MVT::i32), Res);
14363 } else
14364 return SDValue();
14365 }
14366
14367 if (ShiftAmt != 0)
14368 Res = DAG.getNode(ISD::SHL, DL, VT,
14369 Res, DAG.getConstant(ShiftAmt, DL, MVT::i32));
14370
14371 // Do not add new nodes to DAG combiner worklist.
14372 DCI.CombineTo(N, Res, false);
14373 return SDValue();
14374}
14375
14378 const ARMSubtarget *Subtarget) {
14379 // Allow DAGCombine to pattern-match before we touch the canonical form.
14380 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14381 return SDValue();
14382
14383 if (N->getValueType(0) != MVT::i32)
14384 return SDValue();
14385
14386 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14387 if (!N1C)
14388 return SDValue();
14389
14390 uint32_t C1 = (uint32_t)N1C->getZExtValue();
14391 // Don't transform uxtb/uxth.
14392 if (C1 == 255 || C1 == 65535)
14393 return SDValue();
14394
14395 SDNode *N0 = N->getOperand(0).getNode();
14396 if (!N0->hasOneUse())
14397 return SDValue();
14398
14399 if (N0->getOpcode() != ISD::SHL && N0->getOpcode() != ISD::SRL)
14400 return SDValue();
14401
14402 bool LeftShift = N0->getOpcode() == ISD::SHL;
14403
14405 if (!N01C)
14406 return SDValue();
14407
14408 uint32_t C2 = (uint32_t)N01C->getZExtValue();
14409 if (!C2 || C2 >= 32)
14410 return SDValue();
14411
14412 // Clear irrelevant bits in the mask.
14413 if (LeftShift)
14414 C1 &= (-1U << C2);
14415 else
14416 C1 &= (-1U >> C2);
14417
14418 SelectionDAG &DAG = DCI.DAG;
14419 SDLoc DL(N);
14420
14421 // We have a pattern of the form "(and (shl x, c2) c1)" or
14422 // "(and (srl x, c2) c1)", where c1 is a shifted mask. Try to
14423 // transform to a pair of shifts, to save materializing c1.
14424
14425 // First pattern: right shift, then mask off leading bits.
14426 // FIXME: Use demanded bits?
14427 if (!LeftShift && isMask_32(C1)) {
14428 uint32_t C3 = llvm::countl_zero(C1);
14429 if (C2 < C3) {
14430 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14431 DAG.getConstant(C3 - C2, DL, MVT::i32));
14432 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14433 DAG.getConstant(C3, DL, MVT::i32));
14434 }
14435 }
14436
14437 // First pattern, reversed: left shift, then mask off trailing bits.
14438 if (LeftShift && isMask_32(~C1)) {
14439 uint32_t C3 = llvm::countr_zero(C1);
14440 if (C2 < C3) {
14441 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14442 DAG.getConstant(C3 - C2, DL, MVT::i32));
14443 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14444 DAG.getConstant(C3, DL, MVT::i32));
14445 }
14446 }
14447
14448 // Second pattern: left shift, then mask off leading bits.
14449 // FIXME: Use demanded bits?
14450 if (LeftShift && isShiftedMask_32(C1)) {
14451 uint32_t Trailing = llvm::countr_zero(C1);
14452 uint32_t C3 = llvm::countl_zero(C1);
14453 if (Trailing == C2 && C2 + C3 < 32) {
14454 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14455 DAG.getConstant(C2 + C3, DL, MVT::i32));
14456 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14457 DAG.getConstant(C3, DL, MVT::i32));
14458 }
14459 }
14460
14461 // Second pattern, reversed: right shift, then mask off trailing bits.
14462 // FIXME: Handle other patterns of known/demanded bits.
14463 if (!LeftShift && isShiftedMask_32(C1)) {
14464 uint32_t Leading = llvm::countl_zero(C1);
14465 uint32_t C3 = llvm::countr_zero(C1);
14466 if (Leading == C2 && C2 + C3 < 32) {
14467 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14468 DAG.getConstant(C2 + C3, DL, MVT::i32));
14469 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14470 DAG.getConstant(C3, DL, MVT::i32));
14471 }
14472 }
14473
14474 // Transform "(and (shl x, c2) c1)" into "(shl (and x, c1>>c2), c2)"
14475 // if "c1 >> c2" is a cheaper immediate than "c1"
14476 if (LeftShift &&
14477 HasLowerConstantMaterializationCost(C1 >> C2, C1, Subtarget)) {
14478
14479 SDValue And = DAG.getNode(ISD::AND, DL, MVT::i32, N0->getOperand(0),
14480 DAG.getConstant(C1 >> C2, DL, MVT::i32));
14481 return DAG.getNode(ISD::SHL, DL, MVT::i32, And,
14482 DAG.getConstant(C2, DL, MVT::i32));
14483 }
14484
14485 return SDValue();
14486}
14487
14490 const ARMSubtarget *Subtarget) {
14491 // Attempt to use immediate-form VBIC
14492 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14493 SDLoc dl(N);
14494 EVT VT = N->getValueType(0);
14495 SelectionDAG &DAG = DCI.DAG;
14496
14497 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) || VT == MVT::v2i1 ||
14498 VT == MVT::v4i1 || VT == MVT::v8i1 || VT == MVT::v16i1)
14499 return SDValue();
14500
14501 APInt SplatBits, SplatUndef;
14502 unsigned SplatBitSize;
14503 bool HasAnyUndefs;
14504 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14505 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14506 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14507 SplatBitSize == 64) {
14508 EVT VbicVT;
14509 SDValue Val = isVMOVModifiedImm((~SplatBits).getZExtValue(),
14510 SplatUndef.getZExtValue(), SplatBitSize,
14511 DAG, dl, VbicVT, VT, OtherModImm);
14512 if (Val.getNode()) {
14513 SDValue Input =
14514 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VbicVT, N->getOperand(0));
14515 SDValue Vbic = DAG.getNode(ARMISD::VBICIMM, dl, VbicVT, Input, Val);
14516 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vbic);
14517 }
14518 }
14519 }
14520
14521 if (!Subtarget->isThumb1Only()) {
14522 // fold (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))
14523 if (SDValue Result = combineSelectAndUseCommutative(N, true, DCI))
14524 return Result;
14525
14526 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14527 return Result;
14528 }
14529
14530 if (Subtarget->isThumb1Only())
14531 if (SDValue Result = CombineANDShift(N, DCI, Subtarget))
14532 return Result;
14533
14534 return SDValue();
14535}
14536
14537// Try combining OR nodes to SMULWB, SMULWT.
14540 const ARMSubtarget *Subtarget) {
14541 if (!Subtarget->hasV6Ops() ||
14542 (Subtarget->isThumb() &&
14543 (!Subtarget->hasThumb2() || !Subtarget->hasDSP())))
14544 return SDValue();
14545
14546 SDValue SRL = OR->getOperand(0);
14547 SDValue SHL = OR->getOperand(1);
14548
14549 if (SRL.getOpcode() != ISD::SRL || SHL.getOpcode() != ISD::SHL) {
14550 SRL = OR->getOperand(1);
14551 SHL = OR->getOperand(0);
14552 }
14553 if (!isSRL16(SRL) || !isSHL16(SHL))
14554 return SDValue();
14555
14556 // The first operands to the shifts need to be the two results from the
14557 // same smul_lohi node.
14558 if ((SRL.getOperand(0).getNode() != SHL.getOperand(0).getNode()) ||
14559 SRL.getOperand(0).getOpcode() != ISD::SMUL_LOHI)
14560 return SDValue();
14561
14562 SDNode *SMULLOHI = SRL.getOperand(0).getNode();
14563 if (SRL.getOperand(0) != SDValue(SMULLOHI, 0) ||
14564 SHL.getOperand(0) != SDValue(SMULLOHI, 1))
14565 return SDValue();
14566
14567 // Now we have:
14568 // (or (srl (smul_lohi ?, ?), 16), (shl (smul_lohi ?, ?), 16)))
14569 // For SMUL[B|T] smul_lohi will take a 32-bit and a 16-bit arguments.
14570 // For SMUWB the 16-bit value will signed extended somehow.
14571 // For SMULWT only the SRA is required.
14572 // Check both sides of SMUL_LOHI
14573 SDValue OpS16 = SMULLOHI->getOperand(0);
14574 SDValue OpS32 = SMULLOHI->getOperand(1);
14575
14576 SelectionDAG &DAG = DCI.DAG;
14577 if (!isS16(OpS16, DAG) && !isSRA16(OpS16)) {
14578 OpS16 = OpS32;
14579 OpS32 = SMULLOHI->getOperand(0);
14580 }
14581
14582 SDLoc dl(OR);
14583 unsigned Opcode = 0;
14584 if (isS16(OpS16, DAG))
14585 Opcode = ARMISD::SMULWB;
14586 else if (isSRA16(OpS16)) {
14587 Opcode = ARMISD::SMULWT;
14588 OpS16 = OpS16->getOperand(0);
14589 }
14590 else
14591 return SDValue();
14592
14593 SDValue Res = DAG.getNode(Opcode, dl, MVT::i32, OpS32, OpS16);
14594 DAG.ReplaceAllUsesOfValueWith(SDValue(OR, 0), Res);
14595 return SDValue(OR, 0);
14596}
14597
14600 const ARMSubtarget *Subtarget) {
14601 // BFI is only available on V6T2+
14602 if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
14603 return SDValue();
14604
14605 EVT VT = N->getValueType(0);
14606 SDValue N0 = N->getOperand(0);
14607 SDValue N1 = N->getOperand(1);
14608 SelectionDAG &DAG = DCI.DAG;
14609 SDLoc DL(N);
14610 // 1) or (and A, mask), val => ARMbfi A, val, mask
14611 // iff (val & mask) == val
14612 //
14613 // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14614 // 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
14615 // && mask == ~mask2
14616 // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
14617 // && ~mask == mask2
14618 // (i.e., copy a bitfield value into another bitfield of the same width)
14619
14620 if (VT != MVT::i32)
14621 return SDValue();
14622
14623 SDValue N00 = N0.getOperand(0);
14624
14625 // The value and the mask need to be constants so we can verify this is
14626 // actually a bitfield set. If the mask is 0xffff, we can do better
14627 // via a movt instruction, so don't use BFI in that case.
14628 SDValue MaskOp = N0.getOperand(1);
14630 if (!MaskC)
14631 return SDValue();
14632 unsigned Mask = MaskC->getZExtValue();
14633 if (Mask == 0xffff)
14634 return SDValue();
14635 SDValue Res;
14636 // Case (1): or (and A, mask), val => ARMbfi A, val, mask
14638 if (N1C) {
14639 unsigned Val = N1C->getZExtValue();
14640 if ((Val & ~Mask) != Val)
14641 return SDValue();
14642
14643 if (ARM::isBitFieldInvertedMask(Mask)) {
14644 Val >>= llvm::countr_zero(~Mask);
14645
14646 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
14647 DAG.getConstant(Val, DL, MVT::i32),
14648 DAG.getConstant(Mask, DL, MVT::i32));
14649
14650 DCI.CombineTo(N, Res, false);
14651 // Return value from the original node to inform the combiner than N is
14652 // now dead.
14653 return SDValue(N, 0);
14654 }
14655 } else if (N1.getOpcode() == ISD::AND) {
14656 // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14658 if (!N11C)
14659 return SDValue();
14660 unsigned Mask2 = N11C->getZExtValue();
14661
14662 // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
14663 // as is to match.
14664 if (ARM::isBitFieldInvertedMask(Mask) &&
14665 (Mask == ~Mask2)) {
14666 // The pack halfword instruction works better for masks that fit it,
14667 // so use that when it's available.
14668 if (Subtarget->hasDSP() &&
14669 (Mask == 0xffff || Mask == 0xffff0000))
14670 return SDValue();
14671 // 2a
14672 unsigned amt = llvm::countr_zero(Mask2);
14673 Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
14674 DAG.getConstant(amt, DL, MVT::i32));
14675 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
14676 DAG.getConstant(Mask, DL, MVT::i32));
14677 DCI.CombineTo(N, Res, false);
14678 // Return value from the original node to inform the combiner than N is
14679 // now dead.
14680 return SDValue(N, 0);
14681 } else if (ARM::isBitFieldInvertedMask(~Mask) &&
14682 (~Mask == Mask2)) {
14683 // The pack halfword instruction works better for masks that fit it,
14684 // so use that when it's available.
14685 if (Subtarget->hasDSP() &&
14686 (Mask2 == 0xffff || Mask2 == 0xffff0000))
14687 return SDValue();
14688 // 2b
14689 unsigned lsb = llvm::countr_zero(Mask);
14690 Res = DAG.getNode(ISD::SRL, DL, VT, N00,
14691 DAG.getConstant(lsb, DL, MVT::i32));
14692 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
14693 DAG.getConstant(Mask2, DL, MVT::i32));
14694 DCI.CombineTo(N, Res, false);
14695 // Return value from the original node to inform the combiner than N is
14696 // now dead.
14697 return SDValue(N, 0);
14698 }
14699 }
14700
14701 if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
14702 N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
14704 // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
14705 // where lsb(mask) == #shamt and masked bits of B are known zero.
14706 SDValue ShAmt = N00.getOperand(1);
14707 unsigned ShAmtC = ShAmt->getAsZExtVal();
14708 unsigned LSB = llvm::countr_zero(Mask);
14709 if (ShAmtC != LSB)
14710 return SDValue();
14711
14712 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
14713 DAG.getConstant(~Mask, DL, MVT::i32));
14714
14715 DCI.CombineTo(N, Res, false);
14716 // Return value from the original node to inform the combiner than N is
14717 // now dead.
14718 return SDValue(N, 0);
14719 }
14720
14721 return SDValue();
14722}
14723
14724static bool isValidMVECond(unsigned CC, bool IsFloat) {
14725 switch (CC) {
14726 case ARMCC::EQ:
14727 case ARMCC::NE:
14728 case ARMCC::LE:
14729 case ARMCC::GT:
14730 case ARMCC::GE:
14731 case ARMCC::LT:
14732 return true;
14733 case ARMCC::HS:
14734 case ARMCC::HI:
14735 return !IsFloat;
14736 default:
14737 return false;
14738 };
14739}
14740
14742 if (N->getOpcode() == ARMISD::VCMP)
14743 return (ARMCC::CondCodes)N->getConstantOperandVal(2);
14744 else if (N->getOpcode() == ARMISD::VCMPZ)
14745 return (ARMCC::CondCodes)N->getConstantOperandVal(1);
14746 else
14747 llvm_unreachable("Not a VCMP/VCMPZ!");
14748}
14749
14752 return isValidMVECond(CC, N->getOperand(0).getValueType().isFloatingPoint());
14753}
14754
14756 const ARMSubtarget *Subtarget) {
14757 // Try to invert "or A, B" -> "and ~A, ~B", as the "and" is easier to chain
14758 // together with predicates
14759 EVT VT = N->getValueType(0);
14760 SDLoc DL(N);
14761 SDValue N0 = N->getOperand(0);
14762 SDValue N1 = N->getOperand(1);
14763
14764 auto IsFreelyInvertable = [&](SDValue V) {
14765 if (V->getOpcode() == ARMISD::VCMP || V->getOpcode() == ARMISD::VCMPZ)
14766 return CanInvertMVEVCMP(V);
14767 return false;
14768 };
14769
14770 // At least one operand must be freely invertable.
14771 if (!(IsFreelyInvertable(N0) || IsFreelyInvertable(N1)))
14772 return SDValue();
14773
14774 SDValue NewN0 = DAG.getLogicalNOT(DL, N0, VT);
14775 SDValue NewN1 = DAG.getLogicalNOT(DL, N1, VT);
14776 SDValue And = DAG.getNode(ISD::AND, DL, VT, NewN0, NewN1);
14777 return DAG.getLogicalNOT(DL, And, VT);
14778}
14779
14780// Try to form a NEON shift-{right, left}-and-insert (VSRI/VSLI) from:
14781// (or (and X, splat (i32 C1)), (srl Y, splat (i32 C2))) -> VSRI X, Y, #C2
14782// (or (and X, splat (i32 C1)), (shl Y, splat (i32 C2))) -> VSLI X, Y, #C2
14783// where C1 is a mask that preserves the bits not written by the shift/insert,
14784// i.e. `C1 == (1 << C2) - 1`.
14786 SDValue ShiftOp, EVT VT,
14787 SDLoc dl) {
14788 // Match (and X, Mask)
14789 if (AndOp.getOpcode() != ISD::AND)
14790 return SDValue();
14791
14792 SDValue X = AndOp.getOperand(0);
14793 SDValue Mask = AndOp.getOperand(1);
14794
14795 ConstantSDNode *MaskC = isConstOrConstSplat(Mask, false, true);
14796 if (!MaskC)
14797 return SDValue();
14798 APInt MaskBits =
14799 MaskC->getAPIntValue().trunc(Mask.getScalarValueSizeInBits());
14800
14801 // Match shift (srl/shl Y, CntVec)
14802 int64_t Cnt = 0;
14803 bool IsShiftRight = false;
14804 SDValue Y;
14805
14806 if (ShiftOp.getOpcode() == ARMISD::VSHRuIMM) {
14807 IsShiftRight = true;
14808 Y = ShiftOp.getOperand(0);
14809 Cnt = ShiftOp.getConstantOperandVal(1);
14810 } else if (ShiftOp.getOpcode() == ARMISD::VSHLIMM) {
14811 Y = ShiftOp.getOperand(0);
14812 Cnt = ShiftOp.getConstantOperandVal(1);
14813 } else {
14814 return SDValue();
14815 }
14816
14817 unsigned ElemBits = VT.getScalarSizeInBits();
14818 APInt RequiredMask = IsShiftRight
14819 ? APInt::getHighBitsSet(ElemBits, (unsigned)Cnt)
14820 : APInt::getLowBitsSet(ElemBits, (unsigned)Cnt);
14821 if (MaskBits != RequiredMask)
14822 return SDValue();
14823
14824 unsigned Opc = IsShiftRight ? ARMISD::VSRIIMM : ARMISD::VSLIIMM;
14825 return DAG.getNode(Opc, dl, VT, X, Y, DAG.getConstant(Cnt, dl, MVT::i32));
14826}
14827
14828/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
14830 const ARMSubtarget *Subtarget) {
14831 // Attempt to use immediate-form VORR
14832 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14833 SDLoc dl(N);
14834 EVT VT = N->getValueType(0);
14835 SelectionDAG &DAG = DCI.DAG;
14836
14837 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14838 return SDValue();
14839
14840 if (Subtarget->hasMVEIntegerOps() && (VT == MVT::v2i1 || VT == MVT::v4i1 ||
14841 VT == MVT::v8i1 || VT == MVT::v16i1))
14842 return PerformORCombine_i1(N, DAG, Subtarget);
14843
14844 APInt SplatBits, SplatUndef;
14845 unsigned SplatBitSize;
14846 bool HasAnyUndefs;
14847 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14848 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14849 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14850 SplatBitSize == 64) {
14851 EVT VorrVT;
14852 SDValue Val =
14853 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
14854 SplatBitSize, DAG, dl, VorrVT, VT, OtherModImm);
14855 if (Val.getNode()) {
14856 SDValue Input =
14857 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VorrVT, N->getOperand(0));
14858 SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
14859 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vorr);
14860 }
14861 }
14862 }
14863
14864 if (!Subtarget->isThumb1Only()) {
14865 // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
14866 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14867 return Result;
14868 if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
14869 return Result;
14870 }
14871
14872 SDValue N0 = N->getOperand(0);
14873 SDValue N1 = N->getOperand(1);
14874
14875 // (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
14876 // (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
14877 if (VT.isVector() &&
14878 ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
14879 (Subtarget->hasMVEIntegerOps() &&
14880 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
14881 if (SDValue ShiftInsert =
14882 PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
14883 return ShiftInsert;
14884
14885 if (SDValue ShiftInsert =
14886 PerformORCombineToShiftInsert(DAG, N1, N0, VT, dl))
14887 return ShiftInsert;
14888 }
14889
14890 // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
14891 if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
14893
14894 // The code below optimizes (or (and X, Y), Z).
14895 // The AND operand needs to have a single user to make these optimizations
14896 // profitable.
14897 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
14898 return SDValue();
14899
14900 APInt SplatUndef;
14901 unsigned SplatBitSize;
14902 bool HasAnyUndefs;
14903
14904 APInt SplatBits0, SplatBits1;
14907 // Ensure that the second operand of both ands are constants
14908 if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
14909 HasAnyUndefs) && !HasAnyUndefs) {
14910 if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
14911 HasAnyUndefs) && !HasAnyUndefs) {
14912 // Ensure that the bit width of the constants are the same and that
14913 // the splat arguments are logical inverses as per the pattern we
14914 // are trying to simplify.
14915 if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
14916 SplatBits0 == ~SplatBits1) {
14917 // Canonicalize the vector type to make instruction selection
14918 // simpler.
14919 EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
14920 SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
14921 N0->getOperand(1),
14922 N0->getOperand(0),
14923 N1->getOperand(0));
14924 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Result);
14925 }
14926 }
14927 }
14928 }
14929
14930 // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
14931 // reasonable.
14932 if (N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
14933 if (SDValue Res = PerformORCombineToBFI(N, DCI, Subtarget))
14934 return Res;
14935 }
14936
14937 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14938 return Result;
14939
14940 // (or x, (csinc 0, 0, cc)) -> (csinc x, 0, cc)
14941 // providing that the x is 0 or 1.
14942 SDValue CSINC = N1;
14943 SDValue Other = N0;
14944 if (CSINC.getOpcode() != ARMISD::CSINC)
14945 std::swap(CSINC, Other);
14946 if (CSINC.getOpcode() == ARMISD::CSINC &&
14947 isNullConstant(CSINC.getOperand(0)) &&
14948 isNullConstant(CSINC.getOperand(1)) &&
14950 return DAG.getNode(ARMISD::CSINC, dl, VT, Other, CSINC.getOperand(1),
14951 CSINC.getOperand(2), CSINC.getOperand(3));
14952
14953 return SDValue();
14954}
14955
14958 const ARMSubtarget *Subtarget) {
14959 EVT VT = N->getValueType(0);
14960 SelectionDAG &DAG = DCI.DAG;
14961
14962 if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14963 return SDValue();
14964
14965 if (!Subtarget->isThumb1Only()) {
14966 // fold (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
14967 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14968 return Result;
14969
14970 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14971 return Result;
14972 }
14973
14974 if (Subtarget->hasMVEIntegerOps()) {
14975 // fold (xor(vcmp/z, 1)) into a vcmp with the opposite condition.
14976 SDValue N0 = N->getOperand(0);
14977 SDValue N1 = N->getOperand(1);
14978 const TargetLowering *TLI = Subtarget->getTargetLowering();
14979 if (TLI->isConstTrueVal(N1) &&
14980 (N0->getOpcode() == ARMISD::VCMP || N0->getOpcode() == ARMISD::VCMPZ)) {
14981 if (CanInvertMVEVCMP(N0)) {
14982 SDLoc DL(N0);
14984
14986 Ops.push_back(N0->getOperand(0));
14987 if (N0->getOpcode() == ARMISD::VCMP)
14988 Ops.push_back(N0->getOperand(1));
14989 Ops.push_back(DAG.getConstant(CC, DL, MVT::i32));
14990 return DAG.getNode(N0->getOpcode(), DL, N0->getValueType(0), Ops);
14991 }
14992 }
14993 }
14994
14995 return SDValue();
14996}
14997
14998// ParseBFI - given a BFI instruction in N, extract the "from" value (Rn) and return it,
14999// and fill in FromMask and ToMask with (consecutive) bits in "from" to be extracted and
15000// their position in "to" (Rd).
15001static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask) {
15002 assert(N->getOpcode() == ARMISD::BFI);
15003
15004 SDValue From = N->getOperand(1);
15005 ToMask = ~N->getConstantOperandAPInt(2);
15006 FromMask = APInt::getLowBitsSet(ToMask.getBitWidth(), ToMask.popcount());
15007
15008 // If the Base came from a SHR #C, we can deduce that it is really testing bit
15009 // #C in the base of the SHR.
15010 if (From->getOpcode() == ISD::SRL &&
15011 isa<ConstantSDNode>(From->getOperand(1))) {
15012 APInt Shift = From->getConstantOperandAPInt(1);
15013 assert(Shift.getLimitedValue() < 32 && "Shift too large!");
15014 FromMask <<= Shift.getLimitedValue(31);
15015 From = From->getOperand(0);
15016 }
15017
15018 return From;
15019}
15020
15021// If A and B contain one contiguous set of bits, does A | B == A . B?
15022//
15023// Neither A nor B must be zero.
15024static bool BitsProperlyConcatenate(const APInt &A, const APInt &B) {
15025 unsigned LastActiveBitInA = A.countr_zero();
15026 unsigned FirstActiveBitInB = B.getBitWidth() - B.countl_zero() - 1;
15027 return LastActiveBitInA - 1 == FirstActiveBitInB;
15028}
15029
15031 // We have a BFI in N. Find a BFI it can combine with, if one exists.
15032 APInt ToMask, FromMask;
15033 SDValue From = ParseBFI(N, ToMask, FromMask);
15034 SDValue To = N->getOperand(0);
15035
15036 SDValue V = To;
15037 if (V.getOpcode() != ARMISD::BFI)
15038 return SDValue();
15039
15040 APInt NewToMask, NewFromMask;
15041 SDValue NewFrom = ParseBFI(V.getNode(), NewToMask, NewFromMask);
15042 if (NewFrom != From)
15043 return SDValue();
15044
15045 // Do the written bits conflict with any we've seen so far?
15046 if ((NewToMask & ToMask).getBoolValue())
15047 // Conflicting bits.
15048 return SDValue();
15049
15050 // Are the new bits contiguous when combined with the old bits?
15051 if (BitsProperlyConcatenate(ToMask, NewToMask) &&
15052 BitsProperlyConcatenate(FromMask, NewFromMask))
15053 return V;
15054 if (BitsProperlyConcatenate(NewToMask, ToMask) &&
15055 BitsProperlyConcatenate(NewFromMask, FromMask))
15056 return V;
15057
15058 return SDValue();
15059}
15060
15062 SDValue N0 = N->getOperand(0);
15063 SDValue N1 = N->getOperand(1);
15064
15065 if (N1.getOpcode() == ISD::AND) {
15066 // (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
15067 // the bits being cleared by the AND are not demanded by the BFI.
15069 if (!N11C)
15070 return SDValue();
15071 unsigned InvMask = N->getConstantOperandVal(2);
15072 unsigned LSB = llvm::countr_zero(~InvMask);
15073 unsigned Width = llvm::bit_width<unsigned>(~InvMask) - LSB;
15074 assert(Width <
15075 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
15076 "undefined behavior");
15077 unsigned Mask = (1u << Width) - 1;
15078 unsigned Mask2 = N11C->getZExtValue();
15079 if ((Mask & (~Mask2)) == 0)
15080 return DAG.getNode(ARMISD::BFI, SDLoc(N), N->getValueType(0),
15081 N->getOperand(0), N1.getOperand(0), N->getOperand(2));
15082 return SDValue();
15083 }
15084
15085 // Look for another BFI to combine with.
15086 if (SDValue CombineBFI = FindBFIToCombineWith(N)) {
15087 // We've found a BFI.
15088 APInt ToMask1, FromMask1;
15089 SDValue From1 = ParseBFI(N, ToMask1, FromMask1);
15090
15091 APInt ToMask2, FromMask2;
15092 SDValue From2 = ParseBFI(CombineBFI.getNode(), ToMask2, FromMask2);
15093 assert(From1 == From2);
15094 (void)From2;
15095
15096 // Create a new BFI, combining the two together.
15097 APInt NewFromMask = FromMask1 | FromMask2;
15098 APInt NewToMask = ToMask1 | ToMask2;
15099
15100 EVT VT = N->getValueType(0);
15101 SDLoc dl(N);
15102
15103 if (NewFromMask[0] == 0)
15104 From1 = DAG.getNode(ISD::SRL, dl, VT, From1,
15105 DAG.getConstant(NewFromMask.countr_zero(), dl, VT));
15106 return DAG.getNode(ARMISD::BFI, dl, VT, CombineBFI.getOperand(0), From1,
15107 DAG.getConstant(~NewToMask, dl, VT));
15108 }
15109
15110 // Reassociate BFI(BFI (A, B, M1), C, M2) to BFI(BFI (A, C, M2), B, M1) so
15111 // that lower bit insertions are performed first, providing that M1 and M2
15112 // do no overlap. This can allow multiple BFI instructions to be combined
15113 // together by the other folds above.
15114 if (N->getOperand(0).getOpcode() == ARMISD::BFI) {
15115 APInt ToMask1 = ~N->getConstantOperandAPInt(2);
15116 APInt ToMask2 = ~N0.getConstantOperandAPInt(2);
15117
15118 if (!N0.hasOneUse() || (ToMask1 & ToMask2) != 0 ||
15119 ToMask1.countl_zero() < ToMask2.countl_zero())
15120 return SDValue();
15121
15122 EVT VT = N->getValueType(0);
15123 SDLoc dl(N);
15124 SDValue BFI1 = DAG.getNode(ARMISD::BFI, dl, VT, N0.getOperand(0),
15125 N->getOperand(1), N->getOperand(2));
15126 return DAG.getNode(ARMISD::BFI, dl, VT, BFI1, N0.getOperand(1),
15127 N0.getOperand(2));
15128 }
15129
15130 return SDValue();
15131}
15132
15133// Check that N is CMPZ(CSINC(0, 0, CC, X)),
15134// or CMPZ(CMOV(1, 0, CC, X))
15135// return X if valid.
15137 if (Cmp->getOpcode() != ARMISD::CMPZ || !isNullConstant(Cmp->getOperand(1)))
15138 return SDValue();
15139 SDValue CSInc = Cmp->getOperand(0);
15140
15141 // Ignore any `And 1` nodes that may not yet have been removed. We are
15142 // looking for a value that produces 1/0, so these have no effect on the
15143 // code.
15144 while (CSInc.getOpcode() == ISD::AND &&
15145 isa<ConstantSDNode>(CSInc.getOperand(1)) &&
15146 CSInc.getConstantOperandVal(1) == 1 && CSInc->hasOneUse())
15147 CSInc = CSInc.getOperand(0);
15148
15149 if (CSInc.getOpcode() == ARMISD::CSINC &&
15150 isNullConstant(CSInc.getOperand(0)) &&
15151 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15153 return CSInc.getOperand(3);
15154 }
15155 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(0)) &&
15156 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15158 return CSInc.getOperand(3);
15159 }
15160 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(1)) &&
15161 isNullConstant(CSInc.getOperand(0)) && CSInc->hasOneUse()) {
15164 return CSInc.getOperand(3);
15165 }
15166 return SDValue();
15167}
15168
15170 // Given CMPZ(CSINC(C, 0, 0, EQ), 0), we can just use C directly. As in
15171 // t92: flags = ARMISD::CMPZ t74, 0
15172 // t93: i32 = ARMISD::CSINC 0, 0, 1, t92
15173 // t96: flags = ARMISD::CMPZ t93, 0
15174 // t114: i32 = ARMISD::CSINV 0, 0, 0, t96
15176 if (SDValue C = IsCMPZCSINC(N, Cond))
15177 if (Cond == ARMCC::EQ)
15178 return C;
15179 return SDValue();
15180}
15181
15183 // Fold away an unnecessary CMPZ/CSINC
15184 // CSXYZ A, B, C1 (CMPZ (CSINC 0, 0, C2, D), 0) ->
15185 // if C1==EQ -> CSXYZ A, B, C2, D
15186 // if C1==NE -> CSXYZ A, B, NOT(C2), D
15188 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
15189 if (N->getConstantOperandVal(2) == ARMCC::EQ)
15190 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15191 N->getOperand(1),
15192 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
15193 if (N->getConstantOperandVal(2) == ARMCC::NE)
15194 return DAG.getNode(
15195 N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15196 N->getOperand(1),
15198 }
15199 return SDValue();
15200}
15201
15202/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
15203/// ARMISD::VMOVRRD.
15206 const ARMSubtarget *Subtarget) {
15207 // vmovrrd(vmovdrr x, y) -> x,y
15208 SDValue InDouble = N->getOperand(0);
15209 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
15210 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
15211
15212 // vmovrrd(load f64) -> (load i32), (load i32)
15213 SDNode *InNode = InDouble.getNode();
15214 if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
15215 InNode->getValueType(0) == MVT::f64 &&
15216 InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
15217 !cast<LoadSDNode>(InNode)->isVolatile()) {
15218 // TODO: Should this be done for non-FrameIndex operands?
15219 LoadSDNode *LD = cast<LoadSDNode>(InNode);
15220
15221 SelectionDAG &DAG = DCI.DAG;
15222 SDLoc DL(LD);
15223 SDValue BasePtr = LD->getBasePtr();
15224 SDValue NewLD1 =
15225 DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, LD->getPointerInfo(),
15226 LD->getAlign(), LD->getMemOperand()->getFlags());
15227
15228 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
15229 DAG.getConstant(4, DL, MVT::i32));
15230
15231 SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, LD->getChain(), OffsetPtr,
15232 LD->getPointerInfo().getWithOffset(4),
15233 commonAlignment(LD->getAlign(), 4),
15234 LD->getMemOperand()->getFlags());
15235
15236 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
15237 if (DCI.DAG.getDataLayout().isBigEndian())
15238 std::swap (NewLD1, NewLD2);
15239 SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
15240 return Result;
15241 }
15242
15243 // VMOVRRD(extract(..(build_vector(a, b, c, d)))) -> a,b or c,d
15244 // VMOVRRD(extract(insert_vector(insert_vector(.., a, l1), b, l2))) -> a,b
15245 if (InDouble.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15246 isa<ConstantSDNode>(InDouble.getOperand(1))) {
15247 SDValue BV = InDouble.getOperand(0);
15248 // Look up through any nop bitcasts and vector_reg_casts. bitcasts may
15249 // change lane order under big endian.
15250 bool BVSwap = BV.getOpcode() == ISD::BITCAST;
15251 while (
15252 (BV.getOpcode() == ISD::BITCAST ||
15253 BV.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
15254 (BV.getValueType() == MVT::v2f64 || BV.getValueType() == MVT::v2i64)) {
15255 BVSwap = BV.getOpcode() == ISD::BITCAST;
15256 BV = BV.getOperand(0);
15257 }
15258 if (BV.getValueType() != MVT::v4i32)
15259 return SDValue();
15260
15261 // Handle buildvectors, pulling out the correct lane depending on
15262 // endianness.
15263 unsigned Offset = InDouble.getConstantOperandVal(1) == 1 ? 2 : 0;
15264 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
15265 SDValue Op0 = BV.getOperand(Offset);
15266 SDValue Op1 = BV.getOperand(Offset + 1);
15267 if (!Subtarget->isLittle() && BVSwap)
15268 std::swap(Op0, Op1);
15269
15270 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15271 }
15272
15273 // A chain of insert_vectors, grabbing the correct value of the chain of
15274 // inserts.
15275 SDValue Op0, Op1;
15276 while (BV.getOpcode() == ISD::INSERT_VECTOR_ELT) {
15277 if (isa<ConstantSDNode>(BV.getOperand(2))) {
15278 if (BV.getConstantOperandVal(2) == Offset && !Op0)
15279 Op0 = BV.getOperand(1);
15280 if (BV.getConstantOperandVal(2) == Offset + 1 && !Op1)
15281 Op1 = BV.getOperand(1);
15282 }
15283 BV = BV.getOperand(0);
15284 }
15285 if (!Subtarget->isLittle() && BVSwap)
15286 std::swap(Op0, Op1);
15287 if (Op0 && Op1)
15288 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15289 }
15290
15291 return SDValue();
15292}
15293
15294/// PerformVMOVDRRCombine - Target-specific dag combine xforms for
15295/// ARMISD::VMOVDRR. This is also used for BUILD_VECTORs with 2 operands.
15297 // N=vmovrrd(X); vmovdrr(N:0, N:1) -> bit_convert(X)
15298 SDValue Op0 = N->getOperand(0);
15299 SDValue Op1 = N->getOperand(1);
15300 if (Op0.getOpcode() == ISD::BITCAST)
15301 Op0 = Op0.getOperand(0);
15302 if (Op1.getOpcode() == ISD::BITCAST)
15303 Op1 = Op1.getOperand(0);
15304 if (Op0.getOpcode() == ARMISD::VMOVRRD &&
15305 Op0.getNode() == Op1.getNode() &&
15306 Op0.getResNo() == 0 && Op1.getResNo() == 1)
15307 return DAG.getNode(ISD::BITCAST, SDLoc(N),
15308 N->getValueType(0), Op0.getOperand(0));
15309 return SDValue();
15310}
15311
15314 SDValue Op0 = N->getOperand(0);
15315
15316 // VMOVhr (VMOVrh (X)) -> X
15317 if (Op0->getOpcode() == ARMISD::VMOVrh)
15318 return Op0->getOperand(0);
15319
15320 // FullFP16: half values are passed in S-registers, and we don't
15321 // need any of the bitcast and moves:
15322 //
15323 // t2: f32,ch1,gl1? = CopyFromReg ch, Register:f32 %0, gl?
15324 // t5: i32 = bitcast t2
15325 // t18: f16 = ARMISD::VMOVhr t5
15326 // =>
15327 // tN: f16,ch2,gl2? = CopyFromReg ch, Register::f32 %0, gl?
15328 if (Op0->getOpcode() == ISD::BITCAST) {
15329 SDValue Copy = Op0->getOperand(0);
15330 if (Copy.getValueType() == MVT::f32 &&
15331 Copy->getOpcode() == ISD::CopyFromReg) {
15332 bool HasGlue = Copy->getNumOperands() == 3;
15333 SDValue Ops[] = {Copy->getOperand(0), Copy->getOperand(1),
15334 HasGlue ? Copy->getOperand(2) : SDValue()};
15335 EVT OutTys[] = {N->getValueType(0), MVT::Other, MVT::Glue};
15336 SDValue NewCopy =
15338 DCI.DAG.getVTList(ArrayRef(OutTys, HasGlue ? 3 : 2)),
15339 ArrayRef(Ops, HasGlue ? 3 : 2));
15340
15341 // Update Users, Chains, and Potential Glue.
15342 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), NewCopy.getValue(0));
15343 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(1), NewCopy.getValue(1));
15344 if (HasGlue)
15345 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(2),
15346 NewCopy.getValue(2));
15347
15348 return NewCopy;
15349 }
15350 }
15351
15352 // fold (VMOVhr (load x)) -> (load (f16*)x)
15353 if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(Op0)) {
15354 if (LN0->hasOneUse() && LN0->isUnindexed() &&
15355 LN0->getMemoryVT() == MVT::i16) {
15356 SDValue Load =
15357 DCI.DAG.getLoad(N->getValueType(0), SDLoc(N), LN0->getChain(),
15358 LN0->getBasePtr(), LN0->getMemOperand());
15359 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15360 DCI.DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Load.getValue(1));
15361 return Load;
15362 }
15363 }
15364
15365 // Only the bottom 16 bits of the source register are used.
15366 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15367 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15368 if (TLI.SimplifyDemandedBits(Op0, DemandedMask, DCI))
15369 return SDValue(N, 0);
15370
15371 return SDValue();
15372}
15373
15375 SDValue N0 = N->getOperand(0);
15376 EVT VT = N->getValueType(0);
15377
15378 // fold (VMOVrh (fpconst x)) -> const x
15380 APFloat V = C->getValueAPF();
15381 return DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
15382 }
15383
15384 // fold (VMOVrh (load x)) -> (zextload (i16*)x)
15385 if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
15386 LoadSDNode *LN0 = cast<LoadSDNode>(N0);
15387
15388 SDValue Load =
15389 DAG.getExtLoad(ISD::ZEXTLOAD, SDLoc(N), VT, LN0->getChain(),
15390 LN0->getBasePtr(), MVT::i16, LN0->getMemOperand());
15391 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15392 DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
15393 return Load;
15394 }
15395
15396 // Fold VMOVrh(extract(x, n)) -> vgetlaneu(x, n)
15397 if (N0->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15399 return DAG.getNode(ARMISD::VGETLANEu, SDLoc(N), VT, N0->getOperand(0),
15400 N0->getOperand(1));
15401
15402 return SDValue();
15403}
15404
15405/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
15406/// are normal, non-volatile loads. If so, it is profitable to bitcast an
15407/// i64 vector to have f64 elements, since the value can then be loaded
15408/// directly into a VFP register.
15410 unsigned NumElts = N->getValueType(0).getVectorNumElements();
15411 for (unsigned i = 0; i < NumElts; ++i) {
15412 SDNode *Elt = N->getOperand(i).getNode();
15413 if (ISD::isNormalLoad(Elt) && !cast<LoadSDNode>(Elt)->isVolatile())
15414 return true;
15415 }
15416 return false;
15417}
15418
15419/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for
15420/// ISD::BUILD_VECTOR.
15423 const ARMSubtarget *Subtarget) {
15424 // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X):
15425 // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value
15426 // into a pair of GPRs, which is fine when the value is used as a scalar,
15427 // but if the i64 value is converted to a vector, we need to undo the VMOVRRD.
15428 SelectionDAG &DAG = DCI.DAG;
15429 if (N->getNumOperands() == 2)
15430 if (SDValue RV = PerformVMOVDRRCombine(N, DAG))
15431 return RV;
15432
15433 // Load i64 elements as f64 values so that type legalization does not split
15434 // them up into i32 values.
15435 EVT VT = N->getValueType(0);
15436 if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N))
15437 return SDValue();
15438 SDLoc dl(N);
15440 unsigned NumElts = VT.getVectorNumElements();
15441 for (unsigned i = 0; i < NumElts; ++i) {
15442 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i));
15443 Ops.push_back(V);
15444 // Make the DAGCombiner fold the bitcast.
15445 DCI.AddToWorklist(V.getNode());
15446 }
15447 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts);
15448 SDValue BV = DAG.getBuildVector(FloatVT, dl, Ops);
15449 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
15450}
15451
15452/// Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
15453static SDValue
15455 // ARMISD::BUILD_VECTOR is introduced when legalizing ISD::BUILD_VECTOR.
15456 // At that time, we may have inserted bitcasts from integer to float.
15457 // If these bitcasts have survived DAGCombine, change the lowering of this
15458 // BUILD_VECTOR in something more vector friendly, i.e., that does not
15459 // force to use floating point types.
15460
15461 // Make sure we can change the type of the vector.
15462 // This is possible iff:
15463 // 1. The vector is only used in a bitcast to a integer type. I.e.,
15464 // 1.1. Vector is used only once.
15465 // 1.2. Use is a bit convert to an integer type.
15466 // 2. The size of its operands are 32-bits (64-bits are not legal).
15467 EVT VT = N->getValueType(0);
15468 EVT EltVT = VT.getVectorElementType();
15469
15470 // Check 1.1. and 2.
15471 if (EltVT.getSizeInBits() != 32 || !N->hasOneUse())
15472 return SDValue();
15473
15474 // By construction, the input type must be float.
15475 assert(EltVT == MVT::f32 && "Unexpected type!");
15476
15477 // Check 1.2.
15478 SDNode *Use = *N->user_begin();
15479 if (Use->getOpcode() != ISD::BITCAST ||
15480 Use->getValueType(0).isFloatingPoint())
15481 return SDValue();
15482
15483 // Check profitability.
15484 // Model is, if more than half of the relevant operands are bitcast from
15485 // i32, turn the build_vector into a sequence of insert_vector_elt.
15486 // Relevant operands are everything that is not statically
15487 // (i.e., at compile time) bitcasted.
15488 unsigned NumOfBitCastedElts = 0;
15489 unsigned NumElts = VT.getVectorNumElements();
15490 unsigned NumOfRelevantElts = NumElts;
15491 for (unsigned Idx = 0; Idx < NumElts; ++Idx) {
15492 SDValue Elt = N->getOperand(Idx);
15493 if (Elt->getOpcode() == ISD::BITCAST) {
15494 // Assume only bit cast to i32 will go away.
15495 if (Elt->getOperand(0).getValueType() == MVT::i32)
15496 ++NumOfBitCastedElts;
15497 } else if (Elt.isUndef() || isa<ConstantSDNode>(Elt))
15498 // Constants are statically casted, thus do not count them as
15499 // relevant operands.
15500 --NumOfRelevantElts;
15501 }
15502
15503 // Check if more than half of the elements require a non-free bitcast.
15504 if (NumOfBitCastedElts <= NumOfRelevantElts / 2)
15505 return SDValue();
15506
15507 SelectionDAG &DAG = DCI.DAG;
15508 // Create the new vector type.
15509 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
15510 // Check if the type is legal.
15511 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15512 if (!TLI.isTypeLegal(VecVT))
15513 return SDValue();
15514
15515 // Combine:
15516 // ARMISD::BUILD_VECTOR E1, E2, ..., EN.
15517 // => BITCAST INSERT_VECTOR_ELT
15518 // (INSERT_VECTOR_ELT (...), (BITCAST EN-1), N-1),
15519 // (BITCAST EN), N.
15520 SDValue Vec = DAG.getUNDEF(VecVT);
15521 SDLoc dl(N);
15522 for (unsigned Idx = 0 ; Idx < NumElts; ++Idx) {
15523 SDValue V = N->getOperand(Idx);
15524 if (V.isUndef())
15525 continue;
15526 if (V.getOpcode() == ISD::BITCAST &&
15527 V->getOperand(0).getValueType() == MVT::i32)
15528 // Fold obvious case.
15529 V = V.getOperand(0);
15530 else {
15531 V = DAG.getNode(ISD::BITCAST, SDLoc(V), MVT::i32, V);
15532 // Make the DAGCombiner fold the bitcasts.
15533 DCI.AddToWorklist(V.getNode());
15534 }
15535 SDValue LaneIdx = DAG.getConstant(Idx, dl, MVT::i32);
15536 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Vec, V, LaneIdx);
15537 }
15538 Vec = DAG.getNode(ISD::BITCAST, dl, VT, Vec);
15539 // Make the DAGCombiner fold the bitcasts.
15540 DCI.AddToWorklist(Vec.getNode());
15541 return Vec;
15542}
15543
15544static SDValue
15546 EVT VT = N->getValueType(0);
15547 SDValue Op = N->getOperand(0);
15548 SDLoc dl(N);
15549
15550 // PREDICATE_CAST(PREDICATE_CAST(x)) == PREDICATE_CAST(x)
15551 if (Op->getOpcode() == ARMISD::PREDICATE_CAST) {
15552 // If the valuetypes are the same, we can remove the cast entirely.
15553 if (Op->getOperand(0).getValueType() == VT)
15554 return Op->getOperand(0);
15555 return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15556 }
15557
15558 // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
15559 // more VPNOT which might get folded as else predicates.
15560 if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
15561 SDValue X =
15562 DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15563 SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
15564 DCI.DAG.getConstant(65535, dl, MVT::i32));
15565 return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
15566 }
15567
15568 // Only the bottom 16 bits of the source register are used.
15569 if (Op.getValueType() == MVT::i32) {
15570 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15571 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15572 if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
15573 return SDValue(N, 0);
15574 }
15575 return SDValue();
15576}
15577
15579 const ARMSubtarget *ST) {
15580 EVT VT = N->getValueType(0);
15581 SDValue Op = N->getOperand(0);
15582 SDLoc dl(N);
15583
15584 // Under Little endian, a VECTOR_REG_CAST is equivalent to a BITCAST
15585 if (ST->isLittle())
15586 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
15587
15588 // VT VECTOR_REG_CAST (VT Op) -> Op
15589 if (Op.getValueType() == VT)
15590 return Op;
15591 // VECTOR_REG_CAST undef -> undef
15592 if (Op.isUndef())
15593 return DAG.getUNDEF(VT);
15594
15595 // VECTOR_REG_CAST(VECTOR_REG_CAST(x)) == VECTOR_REG_CAST(x)
15596 if (Op->getOpcode() == ARMISD::VECTOR_REG_CAST) {
15597 // If the valuetypes are the same, we can remove the cast entirely.
15598 if (Op->getOperand(0).getValueType() == VT)
15599 return Op->getOperand(0);
15600 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Op->getOperand(0));
15601 }
15602
15603 return SDValue();
15604}
15605
15607 const ARMSubtarget *Subtarget) {
15608 if (!Subtarget->hasMVEIntegerOps())
15609 return SDValue();
15610
15611 EVT VT = N->getValueType(0);
15612 SDValue Op0 = N->getOperand(0);
15613 SDValue Op1 = N->getOperand(1);
15614 ARMCC::CondCodes Cond = (ARMCC::CondCodes)N->getConstantOperandVal(2);
15615 SDLoc dl(N);
15616
15617 // vcmp X, 0, cc -> vcmpz X, cc
15618 if (isZeroVector(Op1))
15619 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op0, N->getOperand(2));
15620
15621 unsigned SwappedCond = getSwappedCondition(Cond);
15622 if (isValidMVECond(SwappedCond, VT.isFloatingPoint())) {
15623 // vcmp 0, X, cc -> vcmpz X, reversed(cc)
15624 if (isZeroVector(Op0))
15625 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op1,
15626 DAG.getConstant(SwappedCond, dl, MVT::i32));
15627 // vcmp vdup(Y), X, cc -> vcmp X, vdup(Y), reversed(cc)
15628 if (Op0->getOpcode() == ARMISD::VDUP && Op1->getOpcode() != ARMISD::VDUP)
15629 return DAG.getNode(ARMISD::VCMP, dl, VT, Op1, Op0,
15630 DAG.getConstant(SwappedCond, dl, MVT::i32));
15631 }
15632
15633 return SDValue();
15634}
15635
15636/// PerformInsertEltCombine - Target-specific dag combine xforms for
15637/// ISD::INSERT_VECTOR_ELT.
15640 // Bitcast an i64 load inserted into a vector to f64.
15641 // Otherwise, the i64 value will be legalized to a pair of i32 values.
15642 EVT VT = N->getValueType(0);
15643 SDNode *Elt = N->getOperand(1).getNode();
15644 if (VT.getVectorElementType() != MVT::i64 ||
15645 !ISD::isNormalLoad(Elt) || cast<LoadSDNode>(Elt)->isVolatile())
15646 return SDValue();
15647
15648 SelectionDAG &DAG = DCI.DAG;
15649 SDLoc dl(N);
15650 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
15652 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0));
15653 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1));
15654 // Make the DAGCombiner fold the bitcasts.
15655 DCI.AddToWorklist(Vec.getNode());
15656 DCI.AddToWorklist(V.getNode());
15657 SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT,
15658 Vec, V, N->getOperand(2));
15659 return DAG.getNode(ISD::BITCAST, dl, VT, InsElt);
15660}
15661
15662// Convert a pair of extracts from the same base vector to a VMOVRRD. Either
15663// directly or bitcast to an integer if the original is a float vector.
15664// extract(x, n); extract(x, n+1) -> VMOVRRD(extract v2f64 x, n/2)
15665// bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD(extract x, n/2)
15666static SDValue
15668 EVT VT = N->getValueType(0);
15669 SDLoc dl(N);
15670
15671 if (!DCI.isAfterLegalizeDAG() || VT != MVT::i32 ||
15672 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(MVT::f64))
15673 return SDValue();
15674
15675 SDValue Ext = SDValue(N, 0);
15676 if (Ext.getOpcode() == ISD::BITCAST &&
15677 Ext.getOperand(0).getValueType() == MVT::f32)
15678 Ext = Ext.getOperand(0);
15679 if (Ext.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
15681 Ext.getConstantOperandVal(1) % 2 != 0)
15682 return SDValue();
15683 if (Ext->hasOneUse() && (Ext->user_begin()->getOpcode() == ISD::SINT_TO_FP ||
15684 Ext->user_begin()->getOpcode() == ISD::UINT_TO_FP))
15685 return SDValue();
15686
15687 SDValue Op0 = Ext.getOperand(0);
15688 EVT VecVT = Op0.getValueType();
15689 unsigned ResNo = Op0.getResNo();
15690 unsigned Lane = Ext.getConstantOperandVal(1);
15691 if (VecVT.getVectorNumElements() != 4)
15692 return SDValue();
15693
15694 // Find another extract, of Lane + 1
15695 auto OtherIt = find_if(Op0->users(), [&](SDNode *V) {
15696 return V->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15697 isa<ConstantSDNode>(V->getOperand(1)) &&
15698 V->getConstantOperandVal(1) == Lane + 1 &&
15699 V->getOperand(0).getResNo() == ResNo;
15700 });
15701 if (OtherIt == Op0->users().end())
15702 return SDValue();
15703
15704 // For float extracts, we need to be converting to a i32 for both vector
15705 // lanes.
15706 SDValue OtherExt(*OtherIt, 0);
15707 if (OtherExt.getValueType() != MVT::i32) {
15708 if (!OtherExt->hasOneUse() ||
15709 OtherExt->user_begin()->getOpcode() != ISD::BITCAST ||
15710 OtherExt->user_begin()->getValueType(0) != MVT::i32)
15711 return SDValue();
15712 OtherExt = SDValue(*OtherExt->user_begin(), 0);
15713 }
15714
15715 // Convert the type to a f64 and extract with a VMOVRRD.
15716 SDValue F64 = DCI.DAG.getNode(
15717 ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
15718 DCI.DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v2f64, Op0),
15719 DCI.DAG.getConstant(Ext.getConstantOperandVal(1) / 2, dl, MVT::i32));
15720 SDValue VMOVRRD =
15721 DCI.DAG.getNode(ARMISD::VMOVRRD, dl, {MVT::i32, MVT::i32}, F64);
15722
15723 DCI.CombineTo(OtherExt.getNode(), SDValue(VMOVRRD.getNode(), 1));
15724 return VMOVRRD;
15725}
15726
15729 const ARMSubtarget *ST) {
15730 SDValue Op0 = N->getOperand(0);
15731 EVT VT = N->getValueType(0);
15732 SDLoc dl(N);
15733
15734 // extract (vdup x) -> x
15735 if (Op0->getOpcode() == ARMISD::VDUP) {
15736 SDValue X = Op0->getOperand(0);
15737 if (VT == MVT::f16 && X.getValueType() == MVT::i32)
15738 return DCI.DAG.getNode(ARMISD::VMOVhr, dl, VT, X);
15739 if (VT == MVT::i32 && X.getValueType() == MVT::f16)
15740 return DCI.DAG.getNode(ARMISD::VMOVrh, dl, VT, X);
15741 if (VT == MVT::f32 && X.getValueType() == MVT::i32)
15742 return DCI.DAG.getNode(ISD::BITCAST, dl, VT, X);
15743
15744 while (X.getValueType() != VT && X->getOpcode() == ISD::BITCAST)
15745 X = X->getOperand(0);
15746 if (X.getValueType() == VT)
15747 return X;
15748 }
15749
15750 // extract ARM_BUILD_VECTOR -> x
15751 if (Op0->getOpcode() == ARMISD::BUILD_VECTOR &&
15752 isa<ConstantSDNode>(N->getOperand(1)) &&
15753 N->getConstantOperandVal(1) < Op0.getNumOperands()) {
15754 return Op0.getOperand(N->getConstantOperandVal(1));
15755 }
15756
15757 // extract(bitcast(BUILD_VECTOR(VMOVDRR(a, b), ..))) -> a or b
15758 if (Op0.getValueType() == MVT::v4i32 &&
15759 isa<ConstantSDNode>(N->getOperand(1)) &&
15760 Op0.getOpcode() == ISD::BITCAST &&
15762 Op0.getOperand(0).getValueType() == MVT::v2f64) {
15763 SDValue BV = Op0.getOperand(0);
15764 unsigned Offset = N->getConstantOperandVal(1);
15765 SDValue MOV = BV.getOperand(Offset < 2 ? 0 : 1);
15766 if (MOV.getOpcode() == ARMISD::VMOVDRR)
15767 return MOV.getOperand(ST->isLittle() ? Offset % 2 : 1 - Offset % 2);
15768 }
15769
15770 // extract x, n; extract x, n+1 -> VMOVRRD x
15771 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
15772 return R;
15773
15774 // extract (MVETrunc(x)) -> extract x
15775 if (Op0->getOpcode() == ARMISD::MVETRUNC) {
15776 unsigned Idx = N->getConstantOperandVal(1);
15777 unsigned Vec =
15779 unsigned SubIdx =
15781 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Op0.getOperand(Vec),
15782 DCI.DAG.getConstant(SubIdx, dl, MVT::i32));
15783 }
15784
15785 // extract(bitcast(BUILD_VECTOR(extract(bitcast(a)), ..))) -> extract(a)
15786 if (ST->isLittle() && Op0.getOpcode() == ISD::BITCAST &&
15788 isa<ConstantSDNode>(N->getOperand(1)) &&
15791 unsigned Lane = N->getConstantOperandVal(1);
15792 EVT ExtVT = Op0.getValueType();
15793 EVT BVVT = Op0.getOperand(0).getValueType();
15794 unsigned BVLane =
15795 (Lane * BVVT.getVectorNumElements()) / ExtVT.getVectorNumElements();
15796 assert(BVLane < Op0.getOperand(0).getNumOperands());
15797 SDValue Ext = Op0.getOperand(0).getOperand(BVLane);
15798 if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15799 Ext.getOperand(0).getOpcode() == ISD::BITCAST &&
15801 Ext.getOperand(0).getOperand(0).getValueType() == ExtVT) {
15802 unsigned InnerLane = Ext.getConstantOperandVal(1);
15803 unsigned BVSubLane = Lane - (BVLane * ExtVT.getVectorNumElements()) /
15804 BVVT.getVectorNumElements();
15805 unsigned FinalLane = (InnerLane * ExtVT.getVectorNumElements()) /
15806 BVVT.getVectorNumElements() +
15807 BVSubLane;
15808 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT,
15809 Ext.getOperand(0).getOperand(0),
15810 DCI.DAG.getConstant(FinalLane, dl, MVT::i32));
15811 }
15812 }
15813
15814 return SDValue();
15815}
15816
15818 SDValue Op = N->getOperand(0);
15819 EVT VT = N->getValueType(0);
15820
15821 // sext_inreg(VGETLANEu) -> VGETLANEs
15822 if (Op.getOpcode() == ARMISD::VGETLANEu &&
15823 cast<VTSDNode>(N->getOperand(1))->getVT() ==
15824 Op.getOperand(0).getValueType().getScalarType())
15825 return DAG.getNode(ARMISD::VGETLANEs, SDLoc(N), VT, Op.getOperand(0),
15826 Op.getOperand(1));
15827
15828 return SDValue();
15829}
15830
15831static SDValue
15833 SDValue Vec = N->getOperand(0);
15834 SDValue SubVec = N->getOperand(1);
15835 uint64_t IdxVal = N->getConstantOperandVal(2);
15836 EVT VecVT = Vec.getValueType();
15837 EVT SubVT = SubVec.getValueType();
15838
15839 // Only do this for legal fixed vector types.
15840 if (!VecVT.isFixedLengthVector() ||
15841 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(VecVT) ||
15843 return SDValue();
15844
15845 // Ignore widening patterns.
15846 if (IdxVal == 0 && Vec.isUndef())
15847 return SDValue();
15848
15849 // Subvector must be half the width and an "aligned" insertion.
15850 unsigned NumSubElts = SubVT.getVectorNumElements();
15851 if ((SubVT.getSizeInBits() * 2) != VecVT.getSizeInBits() ||
15852 (IdxVal != 0 && IdxVal != NumSubElts))
15853 return SDValue();
15854
15855 // Fold insert_subvector -> concat_vectors
15856 // insert_subvector(Vec,Sub,lo) -> concat_vectors(Sub,extract(Vec,hi))
15857 // insert_subvector(Vec,Sub,hi) -> concat_vectors(extract(Vec,lo),Sub)
15858 SDLoc DL(N);
15859 SDValue Lo, Hi;
15860 if (IdxVal == 0) {
15861 Lo = SubVec;
15862 Hi = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15863 DCI.DAG.getVectorIdxConstant(NumSubElts, DL));
15864 } else {
15865 Lo = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15866 DCI.DAG.getVectorIdxConstant(0, DL));
15867 Hi = SubVec;
15868 }
15869 return DCI.DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Lo, Hi);
15870}
15871
15872// shuffle(MVETrunc(x, y)) -> VMOVN(x, y)
15874 SelectionDAG &DAG) {
15875 SDValue Trunc = N->getOperand(0);
15876 EVT VT = Trunc.getValueType();
15877 if (Trunc.getOpcode() != ARMISD::MVETRUNC || !N->getOperand(1).isUndef())
15878 return SDValue();
15879
15880 SDLoc DL(Trunc);
15881 if (isVMOVNTruncMask(N->getMask(), VT, false))
15882 return DAG.getNode(
15883 ARMISD::VMOVN, DL, VT,
15884 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15885 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15886 DAG.getConstant(1, DL, MVT::i32));
15887 else if (isVMOVNTruncMask(N->getMask(), VT, true))
15888 return DAG.getNode(
15889 ARMISD::VMOVN, DL, VT,
15890 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15891 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15892 DAG.getConstant(1, DL, MVT::i32));
15893 return SDValue();
15894}
15895
15896/// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for
15897/// ISD::VECTOR_SHUFFLE.
15900 return R;
15901
15902 // The LLVM shufflevector instruction does not require the shuffle mask
15903 // length to match the operand vector length, but ISD::VECTOR_SHUFFLE does
15904 // have that requirement. When translating to ISD::VECTOR_SHUFFLE, if the
15905 // operands do not match the mask length, they are extended by concatenating
15906 // them with undef vectors. That is probably the right thing for other
15907 // targets, but for NEON it is better to concatenate two double-register
15908 // size vector operands into a single quad-register size vector. Do that
15909 // transformation here:
15910 // shuffle(concat(v1, undef), concat(v2, undef)) ->
15911 // shuffle(concat(v1, v2), undef)
15912 SDValue Op0 = N->getOperand(0);
15913 SDValue Op1 = N->getOperand(1);
15914 if (Op0.getOpcode() != ISD::CONCAT_VECTORS ||
15915 Op1.getOpcode() != ISD::CONCAT_VECTORS ||
15916 Op0.getNumOperands() != 2 ||
15917 Op1.getNumOperands() != 2)
15918 return SDValue();
15919 SDValue Concat0Op1 = Op0.getOperand(1);
15920 SDValue Concat1Op1 = Op1.getOperand(1);
15921 if (!Concat0Op1.isUndef() || !Concat1Op1.isUndef())
15922 return SDValue();
15923 // Skip the transformation if any of the types are illegal.
15924 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15925 EVT VT = N->getValueType(0);
15926 if (!TLI.isTypeLegal(VT) ||
15927 !TLI.isTypeLegal(Concat0Op1.getValueType()) ||
15928 !TLI.isTypeLegal(Concat1Op1.getValueType()))
15929 return SDValue();
15930
15931 SDValue NewConcat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT,
15932 Op0.getOperand(0), Op1.getOperand(0));
15933 // Translate the shuffle mask.
15934 SmallVector<int, 16> NewMask;
15935 unsigned NumElts = VT.getVectorNumElements();
15936 unsigned HalfElts = NumElts/2;
15938 for (unsigned n = 0; n < NumElts; ++n) {
15939 int MaskElt = SVN->getMaskElt(n);
15940 int NewElt = -1;
15941 if (MaskElt < (int)HalfElts)
15942 NewElt = MaskElt;
15943 else if (MaskElt >= (int)NumElts && MaskElt < (int)(NumElts + HalfElts))
15944 NewElt = HalfElts + MaskElt - NumElts;
15945 NewMask.push_back(NewElt);
15946 }
15947 return DAG.getVectorShuffle(VT, SDLoc(N), NewConcat,
15948 DAG.getUNDEF(VT), NewMask);
15949}
15950
15951/// Load/store instruction that can be merged with a base address
15952/// update
15957 unsigned AddrOpIdx;
15958};
15959
15961 /// Instruction that updates a pointer
15963 /// Pointer increment operand
15965 /// Pointer increment value if it is a constant, or 0 otherwise
15966 unsigned ConstInc;
15967};
15968
15970 // Check that the add is independent of the load/store.
15971 // Otherwise, folding it would create a cycle. Search through Addr
15972 // as well, since the User may not be a direct user of Addr and
15973 // only share a base pointer.
15976 Worklist.push_back(N);
15977 Worklist.push_back(User);
15978 const unsigned MaxSteps = 1024;
15979 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
15980 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
15981 return false;
15982 return true;
15983}
15984
15986 struct BaseUpdateUser &User,
15987 bool SimpleConstIncOnly,
15989 SelectionDAG &DAG = DCI.DAG;
15990 SDNode *N = Target.N;
15991 MemSDNode *MemN = cast<MemSDNode>(N);
15992 SDLoc dl(N);
15993
15994 // Find the new opcode for the updating load/store.
15995 bool isLoadOp = true;
15996 bool isLaneOp = false;
15997 // Workaround for vst1x and vld1x intrinsics which do not have alignment
15998 // as an operand.
15999 bool hasAlignment = true;
16000 unsigned NewOpc = 0;
16001 unsigned NumVecs = 0;
16002 if (Target.isIntrinsic) {
16003 unsigned IntNo = N->getConstantOperandVal(1);
16004 switch (IntNo) {
16005 default:
16006 llvm_unreachable("unexpected intrinsic for Neon base update");
16007 case Intrinsic::arm_neon_vld1:
16008 NewOpc = ARMISD::VLD1_UPD;
16009 NumVecs = 1;
16010 break;
16011 case Intrinsic::arm_neon_vld2:
16012 NewOpc = ARMISD::VLD2_UPD;
16013 NumVecs = 2;
16014 break;
16015 case Intrinsic::arm_neon_vld3:
16016 NewOpc = ARMISD::VLD3_UPD;
16017 NumVecs = 3;
16018 break;
16019 case Intrinsic::arm_neon_vld4:
16020 NewOpc = ARMISD::VLD4_UPD;
16021 NumVecs = 4;
16022 break;
16023 case Intrinsic::arm_neon_vld1x2:
16024 NewOpc = ARMISD::VLD1x2_UPD;
16025 NumVecs = 2;
16026 hasAlignment = false;
16027 break;
16028 case Intrinsic::arm_neon_vld1x3:
16029 NewOpc = ARMISD::VLD1x3_UPD;
16030 NumVecs = 3;
16031 hasAlignment = false;
16032 break;
16033 case Intrinsic::arm_neon_vld1x4:
16034 NewOpc = ARMISD::VLD1x4_UPD;
16035 NumVecs = 4;
16036 hasAlignment = false;
16037 break;
16038 case Intrinsic::arm_neon_vld2dup:
16039 NewOpc = ARMISD::VLD2DUP_UPD;
16040 NumVecs = 2;
16041 break;
16042 case Intrinsic::arm_neon_vld3dup:
16043 NewOpc = ARMISD::VLD3DUP_UPD;
16044 NumVecs = 3;
16045 break;
16046 case Intrinsic::arm_neon_vld4dup:
16047 NewOpc = ARMISD::VLD4DUP_UPD;
16048 NumVecs = 4;
16049 break;
16050 case Intrinsic::arm_neon_vld2lane:
16051 NewOpc = ARMISD::VLD2LN_UPD;
16052 NumVecs = 2;
16053 isLaneOp = true;
16054 break;
16055 case Intrinsic::arm_neon_vld3lane:
16056 NewOpc = ARMISD::VLD3LN_UPD;
16057 NumVecs = 3;
16058 isLaneOp = true;
16059 break;
16060 case Intrinsic::arm_neon_vld4lane:
16061 NewOpc = ARMISD::VLD4LN_UPD;
16062 NumVecs = 4;
16063 isLaneOp = true;
16064 break;
16065 case Intrinsic::arm_neon_vst1:
16066 NewOpc = ARMISD::VST1_UPD;
16067 NumVecs = 1;
16068 isLoadOp = false;
16069 break;
16070 case Intrinsic::arm_neon_vst2:
16071 NewOpc = ARMISD::VST2_UPD;
16072 NumVecs = 2;
16073 isLoadOp = false;
16074 break;
16075 case Intrinsic::arm_neon_vst3:
16076 NewOpc = ARMISD::VST3_UPD;
16077 NumVecs = 3;
16078 isLoadOp = false;
16079 break;
16080 case Intrinsic::arm_neon_vst4:
16081 NewOpc = ARMISD::VST4_UPD;
16082 NumVecs = 4;
16083 isLoadOp = false;
16084 break;
16085 case Intrinsic::arm_neon_vst2lane:
16086 NewOpc = ARMISD::VST2LN_UPD;
16087 NumVecs = 2;
16088 isLoadOp = false;
16089 isLaneOp = true;
16090 break;
16091 case Intrinsic::arm_neon_vst3lane:
16092 NewOpc = ARMISD::VST3LN_UPD;
16093 NumVecs = 3;
16094 isLoadOp = false;
16095 isLaneOp = true;
16096 break;
16097 case Intrinsic::arm_neon_vst4lane:
16098 NewOpc = ARMISD::VST4LN_UPD;
16099 NumVecs = 4;
16100 isLoadOp = false;
16101 isLaneOp = true;
16102 break;
16103 case Intrinsic::arm_neon_vst1x2:
16104 NewOpc = ARMISD::VST1x2_UPD;
16105 NumVecs = 2;
16106 isLoadOp = false;
16107 hasAlignment = false;
16108 break;
16109 case Intrinsic::arm_neon_vst1x3:
16110 NewOpc = ARMISD::VST1x3_UPD;
16111 NumVecs = 3;
16112 isLoadOp = false;
16113 hasAlignment = false;
16114 break;
16115 case Intrinsic::arm_neon_vst1x4:
16116 NewOpc = ARMISD::VST1x4_UPD;
16117 NumVecs = 4;
16118 isLoadOp = false;
16119 hasAlignment = false;
16120 break;
16121 }
16122 } else {
16123 isLaneOp = true;
16124 switch (N->getOpcode()) {
16125 default:
16126 llvm_unreachable("unexpected opcode for Neon base update");
16127 case ARMISD::VLD1DUP:
16128 NewOpc = ARMISD::VLD1DUP_UPD;
16129 NumVecs = 1;
16130 break;
16131 case ARMISD::VLD2DUP:
16132 NewOpc = ARMISD::VLD2DUP_UPD;
16133 NumVecs = 2;
16134 break;
16135 case ARMISD::VLD3DUP:
16136 NewOpc = ARMISD::VLD3DUP_UPD;
16137 NumVecs = 3;
16138 break;
16139 case ARMISD::VLD4DUP:
16140 NewOpc = ARMISD::VLD4DUP_UPD;
16141 NumVecs = 4;
16142 break;
16143 case ISD::LOAD:
16144 NewOpc = ARMISD::VLD1_UPD;
16145 NumVecs = 1;
16146 isLaneOp = false;
16147 break;
16148 case ISD::STORE:
16149 NewOpc = ARMISD::VST1_UPD;
16150 NumVecs = 1;
16151 isLaneOp = false;
16152 isLoadOp = false;
16153 break;
16154 }
16155 }
16156
16157 // Find the size of memory referenced by the load/store.
16158 EVT VecTy;
16159 if (isLoadOp) {
16160 VecTy = N->getValueType(0);
16161 } else if (Target.isIntrinsic) {
16162 VecTy = N->getOperand(Target.AddrOpIdx + 1).getValueType();
16163 } else {
16164 assert(Target.isStore &&
16165 "Node has to be a load, a store, or an intrinsic!");
16166 VecTy = N->getOperand(1).getValueType();
16167 }
16168
16169 bool isVLDDUPOp =
16170 NewOpc == ARMISD::VLD1DUP_UPD || NewOpc == ARMISD::VLD2DUP_UPD ||
16171 NewOpc == ARMISD::VLD3DUP_UPD || NewOpc == ARMISD::VLD4DUP_UPD;
16172
16173 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16174 if (isLaneOp || isVLDDUPOp)
16175 NumBytes /= VecTy.getVectorNumElements();
16176
16177 if (NumBytes >= 3 * 16 && User.ConstInc != NumBytes) {
16178 // VLD3/4 and VST3/4 for 128-bit vectors are implemented with two
16179 // separate instructions that make it harder to use a non-constant update.
16180 return false;
16181 }
16182
16183 if (SimpleConstIncOnly && User.ConstInc != NumBytes)
16184 return false;
16185
16186 if (!isValidBaseUpdate(N, User.N))
16187 return false;
16188
16189 // OK, we found an ADD we can fold into the base update.
16190 // Now, create a _UPD node, taking care of not breaking alignment.
16191
16192 EVT AlignedVecTy = VecTy;
16193 Align Alignment = MemN->getAlign();
16194
16195 // If this is a less-than-standard-aligned load/store, change the type to
16196 // match the standard alignment.
16197 // The alignment is overlooked when selecting _UPD variants; and it's
16198 // easier to introduce bitcasts here than fix that.
16199 // There are 3 ways to get to this base-update combine:
16200 // - intrinsics: they are assumed to be properly aligned (to the standard
16201 // alignment of the memory type), so we don't need to do anything.
16202 // - ARMISD::VLDx nodes: they are only generated from the aforementioned
16203 // intrinsics, so, likewise, there's nothing to do.
16204 // - generic load/store instructions: the alignment is specified as an
16205 // explicit operand, rather than implicitly as the standard alignment
16206 // of the memory type (like the intrinsics). We need to change the
16207 // memory type to match the explicit alignment. That way, we don't
16208 // generate non-standard-aligned ARMISD::VLDx nodes.
16209 if (isa<LSBaseSDNode>(N)) {
16210 if (Alignment.value() < VecTy.getScalarSizeInBits() / 8) {
16211 MVT EltTy = MVT::getIntegerVT(Alignment.value() * 8);
16212 assert(NumVecs == 1 && "Unexpected multi-element generic load/store.");
16213 assert(!isLaneOp && "Unexpected generic load/store lane.");
16214 unsigned NumElts = NumBytes / (EltTy.getSizeInBits() / 8);
16215 AlignedVecTy = MVT::getVectorVT(EltTy, NumElts);
16216 }
16217 // Don't set an explicit alignment on regular load/stores that we want
16218 // to transform to VLD/VST 1_UPD nodes.
16219 // This matches the behavior of regular load/stores, which only get an
16220 // explicit alignment if the MMO alignment is larger than the standard
16221 // alignment of the memory type.
16222 // Intrinsics, however, always get an explicit alignment, set to the
16223 // alignment of the MMO.
16224 Alignment = Align(1);
16225 }
16226
16227 // Create the new updating load/store node.
16228 // First, create an SDVTList for the new updating node's results.
16229 EVT Tys[6];
16230 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16231 unsigned n;
16232 for (n = 0; n < NumResultVecs; ++n)
16233 Tys[n] = AlignedVecTy;
16234 Tys[n++] = MVT::i32;
16235 Tys[n] = MVT::Other;
16236 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16237
16238 // Then, gather the new node's operands.
16240 Ops.push_back(N->getOperand(0)); // incoming chain
16241 Ops.push_back(N->getOperand(Target.AddrOpIdx));
16242 Ops.push_back(User.Inc);
16243
16244 if (StoreSDNode *StN = dyn_cast<StoreSDNode>(N)) {
16245 // Try to match the intrinsic's signature
16246 Ops.push_back(StN->getValue());
16247 } else {
16248 // Loads (and of course intrinsics) match the intrinsics' signature,
16249 // so just add all but the alignment operand.
16250 unsigned LastOperand =
16251 hasAlignment ? N->getNumOperands() - 1 : N->getNumOperands();
16252 for (unsigned i = Target.AddrOpIdx + 1; i < LastOperand; ++i)
16253 Ops.push_back(N->getOperand(i));
16254 }
16255
16256 // For all node types, the alignment operand is always the last one.
16257 Ops.push_back(DAG.getConstant(Alignment.value(), dl, MVT::i32));
16258
16259 // If this is a non-standard-aligned STORE, the penultimate operand is the
16260 // stored value. Bitcast it to the aligned type.
16261 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::STORE) {
16262 SDValue &StVal = Ops[Ops.size() - 2];
16263 StVal = DAG.getNode(ISD::BITCAST, dl, AlignedVecTy, StVal);
16264 }
16265
16266 EVT LoadVT = isLaneOp ? VecTy.getVectorElementType() : AlignedVecTy;
16267 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, LoadVT,
16268 MemN->getMemOperand());
16269
16270 // Update the uses.
16271 SmallVector<SDValue, 5> NewResults;
16272 for (unsigned i = 0; i < NumResultVecs; ++i)
16273 NewResults.push_back(SDValue(UpdN.getNode(), i));
16274
16275 // If this is an non-standard-aligned LOAD, the first result is the loaded
16276 // value. Bitcast it to the expected result type.
16277 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::LOAD) {
16278 SDValue &LdVal = NewResults[0];
16279 LdVal = DAG.getNode(ISD::BITCAST, dl, VecTy, LdVal);
16280 }
16281
16282 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16283 DCI.CombineTo(N, NewResults);
16284 DCI.CombineTo(User.N, SDValue(UpdN.getNode(), NumResultVecs));
16285
16286 return true;
16287}
16288
16289// If (opcode ptr inc) is and ADD-like instruction, return the
16290// increment value. Otherwise return 0.
16291static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr,
16292 SDValue Inc, const SelectionDAG &DAG) {
16294 if (!CInc)
16295 return 0;
16296
16297 switch (Opcode) {
16298 case ARMISD::VLD1_UPD:
16299 case ISD::ADD:
16300 return CInc->getZExtValue();
16301 case ISD::OR: {
16302 if (DAG.haveNoCommonBitsSet(Ptr, Inc)) {
16303 // (OR ptr inc) is the same as (ADD ptr inc)
16304 return CInc->getZExtValue();
16305 }
16306 return 0;
16307 }
16308 default:
16309 return 0;
16310 }
16311}
16312
16314 switch (N->getOpcode()) {
16315 case ISD::ADD:
16316 case ISD::OR: {
16317 if (isa<ConstantSDNode>(N->getOperand(1))) {
16318 *Ptr = N->getOperand(0);
16319 *CInc = N->getOperand(1);
16320 return true;
16321 }
16322 return false;
16323 }
16324 case ARMISD::VLD1_UPD: {
16325 if (isa<ConstantSDNode>(N->getOperand(2))) {
16326 *Ptr = N->getOperand(1);
16327 *CInc = N->getOperand(2);
16328 return true;
16329 }
16330 return false;
16331 }
16332 default:
16333 return false;
16334 }
16335}
16336
16337/// CombineBaseUpdate - Target-specific DAG combine function for VLDDUP,
16338/// NEON load/store intrinsics, and generic vector load/stores, to merge
16339/// base address updates.
16340/// For generic load/stores, the memory type is assumed to be a vector.
16341/// The caller is assumed to have checked legality.
16344 const bool isIntrinsic = (N->getOpcode() == ISD::INTRINSIC_VOID ||
16345 N->getOpcode() == ISD::INTRINSIC_W_CHAIN);
16346 const bool isStore = N->getOpcode() == ISD::STORE;
16347 const unsigned AddrOpIdx = ((isIntrinsic || isStore) ? 2 : 1);
16348 BaseUpdateTarget Target = {N, isIntrinsic, isStore, AddrOpIdx};
16349
16350 // Limit the number of possible base-updates we look at to prevent degenerate
16351 // cases.
16352 unsigned MaxBaseUpdates = ArmMaxBaseUpdatesToCheck;
16353
16354 SDValue Addr = N->getOperand(AddrOpIdx);
16355
16357
16358 // Search for a use of the address operand that is an increment.
16359 for (SDUse &Use : Addr->uses()) {
16360 SDNode *User = Use.getUser();
16361 if (Use.getResNo() != Addr.getResNo() || User->getNumOperands() != 2)
16362 continue;
16363
16364 SDValue Inc = User->getOperand(Use.getOperandNo() == 1 ? 0 : 1);
16365 unsigned ConstInc =
16366 getPointerConstIncrement(User->getOpcode(), Addr, Inc, DCI.DAG);
16367
16368 if (ConstInc || User->getOpcode() == ISD::ADD) {
16369 BaseUpdates.push_back({User, Inc, ConstInc});
16370 if (BaseUpdates.size() >= MaxBaseUpdates)
16371 break;
16372 }
16373 }
16374
16375 // If the address is a constant pointer increment itself, find
16376 // another constant increment that has the same base operand
16377 SDValue Base;
16378 SDValue CInc;
16379 if (findPointerConstIncrement(Addr.getNode(), &Base, &CInc)) {
16380 unsigned Offset =
16381 getPointerConstIncrement(Addr->getOpcode(), Base, CInc, DCI.DAG);
16382 if (Offset) {
16383 for (SDUse &Use : Base->uses()) {
16384
16385 SDNode *User = Use.getUser();
16386 if (Use.getResNo() != Base.getResNo() || User == Addr.getNode() ||
16387 User->getNumOperands() != 2)
16388 continue;
16389
16390 SDValue UserInc = User->getOperand(Use.getOperandNo() == 0 ? 1 : 0);
16391 unsigned UserOffset =
16392 getPointerConstIncrement(User->getOpcode(), Base, UserInc, DCI.DAG);
16393
16394 if (!UserOffset || UserOffset <= Offset)
16395 continue;
16396
16397 unsigned NewConstInc = UserOffset - Offset;
16398 SDValue NewInc = DCI.DAG.getConstant(NewConstInc, SDLoc(N), MVT::i32);
16399 BaseUpdates.push_back({User, NewInc, NewConstInc});
16400 if (BaseUpdates.size() >= MaxBaseUpdates)
16401 break;
16402 }
16403 }
16404 }
16405
16406 // Try to fold the load/store with an update that matches memory
16407 // access size. This should work well for sequential loads.
16408 unsigned NumValidUpd = BaseUpdates.size();
16409 for (unsigned I = 0; I < NumValidUpd; I++) {
16410 BaseUpdateUser &User = BaseUpdates[I];
16411 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/true, DCI))
16412 return SDValue();
16413 }
16414
16415 // Try to fold with other users. Non-constant updates are considered
16416 // first, and constant updates are sorted to not break a sequence of
16417 // strided accesses (if there is any).
16418 llvm::stable_sort(BaseUpdates,
16419 [](const BaseUpdateUser &LHS, const BaseUpdateUser &RHS) {
16420 return LHS.ConstInc < RHS.ConstInc;
16421 });
16422 for (BaseUpdateUser &User : BaseUpdates) {
16423 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/false, DCI))
16424 return SDValue();
16425 }
16426 return SDValue();
16427}
16428
16431 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16432 return SDValue();
16433
16434 return CombineBaseUpdate(N, DCI);
16435}
16436
16439 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16440 return SDValue();
16441
16442 SelectionDAG &DAG = DCI.DAG;
16443 SDValue Addr = N->getOperand(2);
16444 MemSDNode *MemN = cast<MemSDNode>(N);
16445 SDLoc dl(N);
16446
16447 // For the stores, where there are multiple intrinsics we only actually want
16448 // to post-inc the last of the them.
16449 unsigned IntNo = N->getConstantOperandVal(1);
16450 if (IntNo == Intrinsic::arm_mve_vst2q && N->getConstantOperandVal(5) != 1)
16451 return SDValue();
16452 if (IntNo == Intrinsic::arm_mve_vst4q && N->getConstantOperandVal(7) != 3)
16453 return SDValue();
16454
16455 // Search for a use of the address operand that is an increment.
16456 for (SDUse &Use : Addr->uses()) {
16457 SDNode *User = Use.getUser();
16458 if (User->getOpcode() != ISD::ADD || Use.getResNo() != Addr.getResNo())
16459 continue;
16460
16461 // Check that the add is independent of the load/store. Otherwise, folding
16462 // it would create a cycle. We can avoid searching through Addr as it's a
16463 // predecessor to both.
16466 Visited.insert(Addr.getNode());
16467 Worklist.push_back(N);
16468 Worklist.push_back(User);
16469 const unsigned MaxSteps = 1024;
16470 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16471 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16472 continue;
16473
16474 // Find the new opcode for the updating load/store.
16475 bool isLoadOp = true;
16476 unsigned NewOpc = 0;
16477 unsigned NumVecs = 0;
16478 switch (IntNo) {
16479 default:
16480 llvm_unreachable("unexpected intrinsic for MVE VLDn combine");
16481 case Intrinsic::arm_mve_vld2q:
16482 NewOpc = ARMISD::VLD2_UPD;
16483 NumVecs = 2;
16484 break;
16485 case Intrinsic::arm_mve_vld4q:
16486 NewOpc = ARMISD::VLD4_UPD;
16487 NumVecs = 4;
16488 break;
16489 case Intrinsic::arm_mve_vst2q:
16490 NewOpc = ARMISD::VST2_UPD;
16491 NumVecs = 2;
16492 isLoadOp = false;
16493 break;
16494 case Intrinsic::arm_mve_vst4q:
16495 NewOpc = ARMISD::VST4_UPD;
16496 NumVecs = 4;
16497 isLoadOp = false;
16498 break;
16499 }
16500
16501 // Find the size of memory referenced by the load/store.
16502 EVT VecTy;
16503 if (isLoadOp) {
16504 VecTy = N->getValueType(0);
16505 } else {
16506 VecTy = N->getOperand(3).getValueType();
16507 }
16508
16509 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16510
16511 // If the increment is a constant, it must match the memory ref size.
16512 SDValue Inc = User->getOperand(User->getOperand(0) == Addr ? 1 : 0);
16514 if (!CInc || CInc->getZExtValue() != NumBytes)
16515 continue;
16516
16517 // Create the new updating load/store node.
16518 // First, create an SDVTList for the new updating node's results.
16519 EVT Tys[6];
16520 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16521 unsigned n;
16522 for (n = 0; n < NumResultVecs; ++n)
16523 Tys[n] = VecTy;
16524 Tys[n++] = MVT::i32;
16525 Tys[n] = MVT::Other;
16526 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16527
16528 // Then, gather the new node's operands.
16530 Ops.push_back(N->getOperand(0)); // incoming chain
16531 Ops.push_back(N->getOperand(2)); // ptr
16532 Ops.push_back(Inc);
16533
16534 for (unsigned i = 3; i < N->getNumOperands(); ++i)
16535 Ops.push_back(N->getOperand(i));
16536
16537 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, VecTy,
16538 MemN->getMemOperand());
16539
16540 // Update the uses.
16541 SmallVector<SDValue, 5> NewResults;
16542 for (unsigned i = 0; i < NumResultVecs; ++i)
16543 NewResults.push_back(SDValue(UpdN.getNode(), i));
16544
16545 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16546 DCI.CombineTo(N, NewResults);
16547 DCI.CombineTo(User, SDValue(UpdN.getNode(), NumResultVecs));
16548
16549 break;
16550 }
16551
16552 return SDValue();
16553}
16554
16555/// CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a
16556/// vldN-lane (N > 1) intrinsic, and if all the other uses of that intrinsic
16557/// are also VDUPLANEs. If so, combine them to a vldN-dup operation and
16558/// return true.
16560 SelectionDAG &DAG = DCI.DAG;
16561 EVT VT = N->getValueType(0);
16562 // vldN-dup instructions only support 64-bit vectors for N > 1.
16563 if (!VT.is64BitVector())
16564 return false;
16565
16566 // Check if the VDUPLANE operand is a vldN-dup intrinsic.
16567 SDNode *VLD = N->getOperand(0).getNode();
16568 if (VLD->getOpcode() != ISD::INTRINSIC_W_CHAIN)
16569 return false;
16570 unsigned NumVecs = 0;
16571 unsigned NewOpc = 0;
16572 unsigned IntNo = VLD->getConstantOperandVal(1);
16573 if (IntNo == Intrinsic::arm_neon_vld2lane) {
16574 NumVecs = 2;
16575 NewOpc = ARMISD::VLD2DUP;
16576 } else if (IntNo == Intrinsic::arm_neon_vld3lane) {
16577 NumVecs = 3;
16578 NewOpc = ARMISD::VLD3DUP;
16579 } else if (IntNo == Intrinsic::arm_neon_vld4lane) {
16580 NumVecs = 4;
16581 NewOpc = ARMISD::VLD4DUP;
16582 } else {
16583 return false;
16584 }
16585
16586 // First check that all the vldN-lane uses are VDUPLANEs and that the lane
16587 // numbers match the load.
16588 unsigned VLDLaneNo = VLD->getConstantOperandVal(NumVecs + 3);
16589 for (SDUse &Use : VLD->uses()) {
16590 // Ignore uses of the chain result.
16591 if (Use.getResNo() == NumVecs)
16592 continue;
16593 SDNode *User = Use.getUser();
16594 if (User->getOpcode() != ARMISD::VDUPLANE ||
16595 VLDLaneNo != User->getConstantOperandVal(1))
16596 return false;
16597 }
16598
16599 // Create the vldN-dup node.
16600 EVT Tys[5];
16601 unsigned n;
16602 for (n = 0; n < NumVecs; ++n)
16603 Tys[n] = VT;
16604 Tys[n] = MVT::Other;
16605 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumVecs + 1));
16606 SDValue Ops[] = { VLD->getOperand(0), VLD->getOperand(2) };
16608 SDValue VLDDup = DAG.getMemIntrinsicNode(NewOpc, SDLoc(VLD), SDTys,
16609 Ops, VLDMemInt->getMemoryVT(),
16610 VLDMemInt->getMemOperand());
16611
16612 // Update the uses.
16613 for (SDUse &Use : VLD->uses()) {
16614 unsigned ResNo = Use.getResNo();
16615 // Ignore uses of the chain result.
16616 if (ResNo == NumVecs)
16617 continue;
16618 DCI.CombineTo(Use.getUser(), SDValue(VLDDup.getNode(), ResNo));
16619 }
16620
16621 // Now the vldN-lane intrinsic is dead except for its chain result.
16622 // Update uses of the chain.
16623 std::vector<SDValue> VLDDupResults;
16624 for (unsigned n = 0; n < NumVecs; ++n)
16625 VLDDupResults.push_back(SDValue(VLDDup.getNode(), n));
16626 VLDDupResults.push_back(SDValue(VLDDup.getNode(), NumVecs));
16627 DCI.CombineTo(VLD, VLDDupResults);
16628
16629 return true;
16630}
16631
16632/// PerformVDUPLANECombine - Target-specific dag combine xforms for
16633/// ARMISD::VDUPLANE.
16636 const ARMSubtarget *Subtarget) {
16637 SDValue Op = N->getOperand(0);
16638 EVT VT = N->getValueType(0);
16639
16640 // On MVE, we just convert the VDUPLANE to a VDUP with an extract.
16641 if (Subtarget->hasMVEIntegerOps()) {
16642 EVT ExtractVT = VT.getVectorElementType();
16643 // We need to ensure we are creating a legal type.
16644 if (!DCI.DAG.getTargetLoweringInfo().isTypeLegal(ExtractVT))
16645 ExtractVT = MVT::i32;
16646 SDValue Extract = DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), ExtractVT,
16647 N->getOperand(0), N->getOperand(1));
16648 return DCI.DAG.getNode(ARMISD::VDUP, SDLoc(N), VT, Extract);
16649 }
16650
16651 // If the source is a vldN-lane (N > 1) intrinsic, and all the other uses
16652 // of that intrinsic are also VDUPLANEs, combine them to a vldN-dup operation.
16653 if (CombineVLDDUP(N, DCI))
16654 return SDValue(N, 0);
16655
16656 // If the source is already a VMOVIMM or VMVNIMM splat, the VDUPLANE is
16657 // redundant. Ignore bit_converts for now; element sizes are checked below.
16658 while (Op.getOpcode() == ISD::BITCAST)
16659 Op = Op.getOperand(0);
16660 if (Op.getOpcode() != ARMISD::VMOVIMM && Op.getOpcode() != ARMISD::VMVNIMM)
16661 return SDValue();
16662
16663 // Make sure the VMOV element size is not bigger than the VDUPLANE elements.
16664 unsigned EltSize = Op.getScalarValueSizeInBits();
16665 // The canonical VMOV for a zero vector uses a 32-bit element size.
16666 unsigned Imm = Op.getConstantOperandVal(0);
16667 unsigned EltBits;
16668 if (ARM_AM::decodeVMOVModImm(Imm, EltBits) == 0)
16669 EltSize = 8;
16670 if (EltSize > VT.getScalarSizeInBits())
16671 return SDValue();
16672
16673 return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
16674}
16675
16676/// PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
16678 const ARMSubtarget *Subtarget) {
16679 SDValue Op = N->getOperand(0);
16680 SDLoc dl(N);
16681
16682 if (Subtarget->hasMVEIntegerOps()) {
16683 // Convert VDUP f32 -> VDUP BITCAST i32 under MVE, as we know the value will
16684 // need to come from a GPR.
16685 if (Op.getValueType() == MVT::f32)
16686 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16687 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op));
16688 else if (Op.getValueType() == MVT::f16)
16689 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16690 DAG.getNode(ARMISD::VMOVrh, dl, MVT::i32, Op));
16691 }
16692
16693 if (!Subtarget->hasNEON())
16694 return SDValue();
16695
16696 // Match VDUP(LOAD) -> VLD1DUP.
16697 // We match this pattern here rather than waiting for isel because the
16698 // transform is only legal for unindexed loads.
16699 LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode());
16700 if (LD && Op.hasOneUse() && LD->isUnindexed() &&
16701 LD->getMemoryVT() == N->getValueType(0).getVectorElementType()) {
16702 SDValue Ops[] = {LD->getOperand(0), LD->getOperand(1),
16703 DAG.getConstant(LD->getAlign().value(), SDLoc(N), MVT::i32)};
16704 SDVTList SDTys = DAG.getVTList(N->getValueType(0), MVT::Other);
16705 SDValue VLDDup =
16707 LD->getMemoryVT(), LD->getMemOperand());
16708 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), VLDDup.getValue(1));
16709 return VLDDup;
16710 }
16711
16712 return SDValue();
16713}
16714
16717 const ARMSubtarget *Subtarget) {
16718 EVT VT = N->getValueType(0);
16719
16720 // If this is a legal vector load, try to combine it into a VLD1_UPD.
16721 if (Subtarget->hasNEON() && ISD::isNormalLoad(N) && VT.isVector() &&
16723 return CombineBaseUpdate(N, DCI);
16724
16725 return SDValue();
16726}
16727
16728// Optimize trunc store (of multiple scalars) to shuffle and store. First,
16729// pack all of the elements in one place. Next, store to memory in fewer
16730// chunks.
16732 SelectionDAG &DAG) {
16733 SDValue StVal = St->getValue();
16734 EVT VT = StVal.getValueType();
16735 if (!St->isTruncatingStore() || !VT.isVector())
16736 return SDValue();
16737 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
16738 EVT StVT = St->getMemoryVT();
16739 unsigned NumElems = VT.getVectorNumElements();
16740 assert(StVT != VT && "Cannot truncate to the same type");
16741 unsigned FromEltSz = VT.getScalarSizeInBits();
16742 unsigned ToEltSz = StVT.getScalarSizeInBits();
16743
16744 // From, To sizes and ElemCount must be pow of two
16745 if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz))
16746 return SDValue();
16747
16748 // We are going to use the original vector elt for storing.
16749 // Accumulated smaller vector elements must be a multiple of the store size.
16750 if (0 != (NumElems * FromEltSz) % ToEltSz)
16751 return SDValue();
16752
16753 unsigned SizeRatio = FromEltSz / ToEltSz;
16754 assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
16755
16756 // Create a type on which we perform the shuffle.
16757 EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
16758 NumElems * SizeRatio);
16759 assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
16760
16761 SDLoc DL(St);
16762 SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
16763 SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
16764 for (unsigned i = 0; i < NumElems; ++i)
16765 ShuffleVec[i] = DAG.getDataLayout().isBigEndian() ? (i + 1) * SizeRatio - 1
16766 : i * SizeRatio;
16767
16768 // Can't shuffle using an illegal type.
16769 if (!TLI.isTypeLegal(WideVecVT))
16770 return SDValue();
16771
16772 SDValue Shuff = DAG.getVectorShuffle(
16773 WideVecVT, DL, WideVec, DAG.getUNDEF(WideVec.getValueType()), ShuffleVec);
16774 // At this point all of the data is stored at the bottom of the
16775 // register. We now need to save it to mem.
16776
16777 // Find the largest store unit
16778 MVT StoreType = MVT::i8;
16779 for (MVT Tp : MVT::integer_valuetypes()) {
16780 if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
16781 StoreType = Tp;
16782 }
16783 // Didn't find a legal store type.
16784 if (!TLI.isTypeLegal(StoreType))
16785 return SDValue();
16786
16787 // Bitcast the original vector into a vector of store-size units
16788 EVT StoreVecVT =
16789 EVT::getVectorVT(*DAG.getContext(), StoreType,
16790 VT.getSizeInBits() / EVT(StoreType).getSizeInBits());
16791 assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
16792 SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
16794 SDValue Increment = DAG.getConstant(StoreType.getSizeInBits() / 8, DL,
16795 TLI.getPointerTy(DAG.getDataLayout()));
16796 SDValue BasePtr = St->getBasePtr();
16797
16798 // Perform one or more big stores into memory.
16799 unsigned E = (ToEltSz * NumElems) / StoreType.getSizeInBits();
16800 for (unsigned I = 0; I < E; I++) {
16801 SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreType,
16802 ShuffWide, DAG.getIntPtrConstant(I, DL));
16803 SDValue Ch =
16804 DAG.getStore(St->getChain(), DL, SubVec, BasePtr, St->getPointerInfo(),
16805 St->getAlign(), St->getMemOperand()->getFlags());
16806 BasePtr =
16807 DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr, Increment);
16808 Chains.push_back(Ch);
16809 }
16810 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
16811}
16812
16813// Try taking a single vector store from an fpround (which would otherwise turn
16814// into an expensive buildvector) and splitting it into a series of narrowing
16815// stores.
16817 SelectionDAG &DAG) {
16818 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16819 return SDValue();
16820 SDValue Trunc = St->getValue();
16821 if (Trunc->getOpcode() != ISD::FP_ROUND)
16822 return SDValue();
16823 EVT FromVT = Trunc->getOperand(0).getValueType();
16824 EVT ToVT = Trunc.getValueType();
16825 if (!ToVT.isVector())
16826 return SDValue();
16828 EVT ToEltVT = ToVT.getVectorElementType();
16829 EVT FromEltVT = FromVT.getVectorElementType();
16830
16831 if (FromEltVT != MVT::f32 || ToEltVT != MVT::f16)
16832 return SDValue();
16833
16834 unsigned NumElements = 4;
16835 if (FromVT.getVectorNumElements() % NumElements != 0)
16836 return SDValue();
16837
16838 // Test if the Trunc will be convertible to a VMOVN with a shuffle, and if so
16839 // use the VMOVN over splitting the store. We are looking for patterns of:
16840 // !rev: 0 N 1 N+1 2 N+2 ...
16841 // rev: N 0 N+1 1 N+2 2 ...
16842 // The shuffle may either be a single source (in which case N = NumElts/2) or
16843 // two inputs extended with concat to the same size (in which case N =
16844 // NumElts).
16845 auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
16846 ArrayRef<int> M = SVN->getMask();
16847 unsigned NumElts = ToVT.getVectorNumElements();
16848 if (SVN->getOperand(1).isUndef())
16849 NumElts /= 2;
16850
16851 unsigned Off0 = Rev ? NumElts : 0;
16852 unsigned Off1 = Rev ? 0 : NumElts;
16853
16854 for (unsigned I = 0; I < NumElts; I += 2) {
16855 if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
16856 return false;
16857 if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
16858 return false;
16859 }
16860
16861 return true;
16862 };
16863
16864 if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
16865 if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
16866 return SDValue();
16867
16868 LLVMContext &C = *DAG.getContext();
16869 SDLoc DL(St);
16870 // Details about the old store
16871 SDValue Ch = St->getChain();
16872 SDValue BasePtr = St->getBasePtr();
16873 Align Alignment = St->getBaseAlign();
16874 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16875 AAMDNodes AAInfo = St->getAAInfo();
16876
16877 // We split the store into slices of NumElements. fp16 trunc stores are vcvt
16878 // and then stored as truncating integer stores.
16879 EVT NewFromVT = EVT::getVectorVT(C, FromEltVT, NumElements);
16880 EVT NewToVT = EVT::getVectorVT(
16881 C, EVT::getIntegerVT(C, ToEltVT.getSizeInBits()), NumElements);
16882
16884 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
16885 unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
16886 SDValue NewPtr =
16887 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16888
16889 SDValue Extract =
16890 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
16891 DAG.getConstant(i * NumElements, DL, MVT::i32));
16892
16893 SDValue FPTrunc =
16894 DAG.getNode(ARMISD::VCVTN, DL, MVT::v8f16, DAG.getUNDEF(MVT::v8f16),
16895 Extract, DAG.getConstant(0, DL, MVT::i32));
16896 Extract = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v4i32, FPTrunc);
16897
16899 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16900 NewToVT, Alignment, MMOFlags, AAInfo);
16901 Stores.push_back(Store);
16902 }
16903 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16904}
16905
16906// Try taking a single vector store from an MVETRUNC (which would otherwise turn
16907// into an expensive buildvector) and splitting it into a series of narrowing
16908// stores.
16910 SelectionDAG &DAG) {
16911 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16912 return SDValue();
16913 SDValue Trunc = St->getValue();
16914 if (Trunc->getOpcode() != ARMISD::MVETRUNC)
16915 return SDValue();
16916 EVT FromVT = Trunc->getOperand(0).getValueType();
16917 EVT ToVT = Trunc.getValueType();
16918
16919 LLVMContext &C = *DAG.getContext();
16920 SDLoc DL(St);
16921 // Details about the old store
16922 SDValue Ch = St->getChain();
16923 SDValue BasePtr = St->getBasePtr();
16924 Align Alignment = St->getBaseAlign();
16925 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16926 AAMDNodes AAInfo = St->getAAInfo();
16927
16928 EVT NewToVT = EVT::getVectorVT(C, ToVT.getVectorElementType(),
16929 FromVT.getVectorNumElements());
16930
16932 for (unsigned i = 0; i < Trunc.getNumOperands(); i++) {
16933 unsigned NewOffset =
16934 i * FromVT.getVectorNumElements() * ToVT.getScalarSizeInBits() / 8;
16935 SDValue NewPtr =
16936 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16937
16938 SDValue Extract = Trunc.getOperand(i);
16940 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16941 NewToVT, Alignment, MMOFlags, AAInfo);
16942 Stores.push_back(Store);
16943 }
16944 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16945}
16946
16947// Given a floating point store from an extracted vector, with an integer
16948// VGETLANE that already exists, store the existing VGETLANEu directly. This can
16949// help reduce fp register pressure, doesn't require the fp extract and allows
16950// use of more integer post-inc stores not available with vstr.
16952 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16953 return SDValue();
16954 SDValue Extract = St->getValue();
16955 EVT VT = Extract.getValueType();
16956 // For now only uses f16. This may be useful for f32 too, but that will
16957 // be bitcast(extract), not the VGETLANEu we currently check here.
16958 if (VT != MVT::f16 || Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
16959 return SDValue();
16960
16961 SDNode *GetLane =
16962 DAG.getNodeIfExists(ARMISD::VGETLANEu, DAG.getVTList(MVT::i32),
16963 {Extract.getOperand(0), Extract.getOperand(1)});
16964 if (!GetLane)
16965 return SDValue();
16966
16967 LLVMContext &C = *DAG.getContext();
16968 SDLoc DL(St);
16969 // Create a new integer store to replace the existing floating point version.
16970 SDValue Ch = St->getChain();
16971 SDValue BasePtr = St->getBasePtr();
16972 Align Alignment = St->getBaseAlign();
16973 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16974 AAMDNodes AAInfo = St->getAAInfo();
16975 EVT NewToVT = EVT::getIntegerVT(C, VT.getSizeInBits());
16976 SDValue Store = DAG.getTruncStore(Ch, DL, SDValue(GetLane, 0), BasePtr,
16977 St->getPointerInfo(), NewToVT, Alignment,
16978 MMOFlags, AAInfo);
16979
16980 return Store;
16981}
16982
16983/// PerformSTORECombine - Target-specific dag combine xforms for
16984/// ISD::STORE.
16987 const ARMSubtarget *Subtarget) {
16989 if (St->isVolatile())
16990 return SDValue();
16991 SDValue StVal = St->getValue();
16992 EVT VT = StVal.getValueType();
16993
16994 if (Subtarget->hasNEON())
16996 return Store;
16997
16998 if (Subtarget->hasMVEFloatOps())
16999 if (SDValue NewToken = PerformSplittingToNarrowingStores(St, DCI.DAG))
17000 return NewToken;
17001
17002 if (Subtarget->hasMVEIntegerOps()) {
17003 if (SDValue NewChain = PerformExtractFpToIntStores(St, DCI.DAG))
17004 return NewChain;
17005 if (SDValue NewToken =
17007 return NewToken;
17008 }
17009
17010 if (!ISD::isNormalStore(St))
17011 return SDValue();
17012
17013 // Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
17014 // ARM stores of arguments in the same cache line.
17015 if (StVal.getOpcode() == ARMISD::VMOVDRR && StVal->hasOneUse()) {
17016 SelectionDAG &DAG = DCI.DAG;
17017 bool isBigEndian = DAG.getDataLayout().isBigEndian();
17018 SDLoc DL(St);
17019 SDValue BasePtr = St->getBasePtr();
17020 SDValue NewST1 =
17021 DAG.getStore(St->getChain(), DL, StVal.getOperand(isBigEndian ? 1 : 0),
17022 BasePtr, St->getPointerInfo(), St->getBaseAlign(),
17023 St->getMemOperand()->getFlags());
17024
17025 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
17026 DAG.getConstant(4, DL, MVT::i32));
17027 return DAG.getStore(NewST1.getValue(0), DL,
17028 StVal.getOperand(isBigEndian ? 0 : 1), OffsetPtr,
17029 St->getPointerInfo().getWithOffset(4),
17030 St->getBaseAlign(), St->getMemOperand()->getFlags());
17031 }
17032
17033 if (StVal.getValueType() == MVT::i64 &&
17035 // Bitcast an i64 store extracted from a vector to f64.
17036 // Otherwise, the i64 value will be legalized to a pair of i32 values.
17037 SelectionDAG &DAG = DCI.DAG;
17038 SDLoc dl(StVal);
17039 SDValue IntVec = StVal.getOperand(0);
17040 EVT FloatVT =
17041 EVT::getVectorVT(*DAG.getContext(), MVT::f64,
17043 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
17044 SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Vec,
17045 StVal.getOperand(1));
17046 dl = SDLoc(N);
17047 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
17048 // Make the DAGCombiner fold the bitcasts.
17049 DCI.AddToWorklist(Vec.getNode());
17050 DCI.AddToWorklist(ExtElt.getNode());
17051 DCI.AddToWorklist(V.getNode());
17052 return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
17053 St->getPointerInfo(), St->getAlign(),
17054 St->getMemOperand()->getFlags(), St->getAAInfo());
17055 }
17056
17057 // If this is a legal vector store, try to combine it into a VST1_UPD.
17058 if (Subtarget->hasNEON() && ISD::isNormalStore(N) && VT.isVector() &&
17060 return CombineBaseUpdate(N, DCI);
17061
17062 return SDValue();
17063}
17064
17065/// PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD)
17066/// can replace combinations of VMUL and VCVT (floating-point to integer)
17067/// when the VMUL has a constant operand that is a power of 2.
17068///
17069/// Example (assume d17 = <float 8.000000e+00, float 8.000000e+00>):
17070/// vmul.f32 d16, d17, d16
17071/// vcvt.s32.f32 d16, d16
17072/// becomes:
17073/// vcvt.s32.f32 d16, d16, #3
17075 const ARMSubtarget *Subtarget) {
17076 if (!Subtarget->hasNEON())
17077 return SDValue();
17078
17079 SDValue Op = N->getOperand(0);
17080 if (!Op.getValueType().isVector() || !Op.getValueType().isSimple() ||
17081 Op.getOpcode() != ISD::FMUL)
17082 return SDValue();
17083
17084 SDValue ConstVec = Op->getOperand(1);
17085 if (!isa<BuildVectorSDNode>(ConstVec))
17086 return SDValue();
17087
17088 MVT FloatTy = Op.getSimpleValueType().getVectorElementType();
17089 uint32_t FloatBits = FloatTy.getSizeInBits();
17090 MVT IntTy = N->getSimpleValueType(0).getVectorElementType();
17091 uint32_t IntBits = IntTy.getSizeInBits();
17092 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17093 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17094 // These instructions only exist converting from f32 to i32. We can handle
17095 // smaller integers by generating an extra truncate, but larger ones would
17096 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17097 // these instructions only support v2i32/v4i32 types.
17098 return SDValue();
17099 }
17100
17101 BitVector UndefElements;
17103 int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33);
17104 if (C == -1 || C == 0 || C > 32)
17105 return SDValue();
17106
17107 SDLoc dl(N);
17108 bool isSigned = N->getOpcode() == ISD::FP_TO_SINT;
17109 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfp2fxs :
17110 Intrinsic::arm_neon_vcvtfp2fxu;
17111 SDValue FixConv = DAG.getNode(
17112 ISD::INTRINSIC_WO_CHAIN, dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32,
17113 DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), Op->getOperand(0),
17114 DAG.getConstant(C, dl, MVT::i32));
17115
17116 if (IntBits < FloatBits)
17117 FixConv = DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), FixConv);
17118
17119 return FixConv;
17120}
17121
17123 const ARMSubtarget *Subtarget) {
17124 if (!Subtarget->hasMVEFloatOps())
17125 return SDValue();
17126
17127 // Turn (fadd x, (vselect c, y, -0.0)) into (vselect c, (fadd x, y), x)
17128 // The second form can be more easily turned into a predicated vadd, and
17129 // possibly combined into a fma to become a predicated vfma.
17130 SDValue Op0 = N->getOperand(0);
17131 SDValue Op1 = N->getOperand(1);
17132 EVT VT = N->getValueType(0);
17133 SDLoc DL(N);
17134
17135 // The identity element for a fadd is -0.0 or +0.0 when the nsz flag is set,
17136 // which these VMOV's represent.
17137 auto isIdentitySplat = [&](SDValue Op, bool NSZ) {
17138 if (Op.getOpcode() != ISD::BITCAST ||
17139 Op.getOperand(0).getOpcode() != ARMISD::VMOVIMM)
17140 return false;
17141 uint64_t ImmVal = Op.getOperand(0).getConstantOperandVal(0);
17142 if (VT == MVT::v4f32 && (ImmVal == 1664 || (ImmVal == 0 && NSZ)))
17143 return true;
17144 if (VT == MVT::v8f16 && (ImmVal == 2688 || (ImmVal == 0 && NSZ)))
17145 return true;
17146 return false;
17147 };
17148
17149 if (Op0.getOpcode() == ISD::VSELECT && Op1.getOpcode() != ISD::VSELECT)
17150 std::swap(Op0, Op1);
17151
17152 if (Op1.getOpcode() != ISD::VSELECT)
17153 return SDValue();
17154
17155 SDNodeFlags FaddFlags = N->getFlags();
17156 bool NSZ = FaddFlags.hasNoSignedZeros();
17157 if (!isIdentitySplat(Op1.getOperand(2), NSZ))
17158 return SDValue();
17159
17160 SDValue FAdd =
17161 DAG.getNode(ISD::FADD, DL, VT, Op0, Op1.getOperand(1), FaddFlags);
17162 return DAG.getNode(ISD::VSELECT, DL, VT, Op1.getOperand(0), FAdd, Op0, FaddFlags);
17163}
17164
17166 SDValue LHS = N->getOperand(0);
17167 SDValue RHS = N->getOperand(1);
17168 EVT VT = N->getValueType(0);
17169 SDLoc DL(N);
17170
17171 if (!N->getFlags().hasAllowReassociation())
17172 return SDValue();
17173
17174 // Combine fadd(a, vcmla(b, c, d)) -> vcmla(fadd(a, b), b, c)
17175 auto ReassocComplex = [&](SDValue A, SDValue B) {
17176 if (A.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
17177 return SDValue();
17178 unsigned Opc = A.getConstantOperandVal(0);
17179 if (Opc != Intrinsic::arm_mve_vcmlaq)
17180 return SDValue();
17181 SDValue VCMLA = DAG.getNode(
17182 ISD::INTRINSIC_WO_CHAIN, DL, VT, A.getOperand(0), A.getOperand(1),
17183 DAG.getNode(ISD::FADD, DL, VT, A.getOperand(2), B, N->getFlags()),
17184 A.getOperand(3), A.getOperand(4));
17185 VCMLA->setFlags(A->getFlags());
17186 return VCMLA;
17187 };
17188 if (SDValue R = ReassocComplex(LHS, RHS))
17189 return R;
17190 if (SDValue R = ReassocComplex(RHS, LHS))
17191 return R;
17192
17193 return SDValue();
17194}
17195
17197 const ARMSubtarget *Subtarget) {
17198 if (SDValue S = PerformFAddVSelectCombine(N, DAG, Subtarget))
17199 return S;
17200 if (SDValue S = PerformFADDVCMLACombine(N, DAG))
17201 return S;
17202 return SDValue();
17203}
17204
17205/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD)
17206/// can replace combinations of VCVT (integer to floating-point) and VMUL
17207/// when the VMUL has a constant operand that is a power of 2.
17208///
17209/// Example (assume d17 = <float 0.125, float 0.125>):
17210/// vcvt.f32.s32 d16, d16
17211/// vmul.f32 d16, d16, d17
17212/// becomes:
17213/// vcvt.f32.s32 d16, d16, #3
17215 const ARMSubtarget *Subtarget) {
17216 if (!Subtarget->hasNEON())
17217 return SDValue();
17218
17219 SDValue Op = N->getOperand(0);
17220 unsigned OpOpcode = Op.getNode()->getOpcode();
17221 if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple() ||
17222 (OpOpcode != ISD::SINT_TO_FP && OpOpcode != ISD::UINT_TO_FP))
17223 return SDValue();
17224
17225 SDValue ConstVec = N->getOperand(1);
17226 if (!isa<BuildVectorSDNode>(ConstVec))
17227 return SDValue();
17228
17229 MVT FloatTy = N->getSimpleValueType(0).getVectorElementType();
17230 uint32_t FloatBits = FloatTy.getSizeInBits();
17231 MVT IntTy = Op.getOperand(0).getSimpleValueType().getVectorElementType();
17232 uint32_t IntBits = IntTy.getSizeInBits();
17233 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17234 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17235 // These instructions only exist converting from i32 to f32. We can handle
17236 // smaller integers by generating an extra extend, but larger ones would
17237 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17238 // these instructions only support v2i32/v4i32 types.
17239 return SDValue();
17240 }
17241
17242 ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true);
17243 APFloat Recip(0.0f);
17244 if (!CN || !CN->getValueAPF().getExactInverse(&Recip))
17245 return SDValue();
17246
17247 bool IsExact;
17248 APSInt IntVal(33);
17249 if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
17250 APFloat::opOK ||
17251 !IsExact)
17252 return SDValue();
17253
17254 int32_t C = IntVal.exactLogBase2();
17255 if (C == -1 || C == 0 || C > 32)
17256 return SDValue();
17257
17258 SDLoc DL(N);
17259 bool isSigned = OpOpcode == ISD::SINT_TO_FP;
17260 SDValue ConvInput = Op.getOperand(0);
17261 if (IntBits < FloatBits)
17263 NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput);
17264
17265 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp
17266 : Intrinsic::arm_neon_vcvtfxu2fp;
17267 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
17268 DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput,
17269 DAG.getConstant(C, DL, MVT::i32));
17270}
17271
17273 const ARMSubtarget *ST) {
17274 if (!ST->hasMVEIntegerOps())
17275 return SDValue();
17276
17277 assert(N->getOpcode() == ISD::VECREDUCE_ADD);
17278 EVT ResVT = N->getValueType(0);
17279 SDValue N0 = N->getOperand(0);
17280 SDLoc dl(N);
17281
17282 // Try to turn vecreduce_add(add(x, y)) into vecreduce(x) + vecreduce(y)
17283 if (ResVT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
17284 (N0.getValueType() == MVT::v4i32 || N0.getValueType() == MVT::v8i16 ||
17285 N0.getValueType() == MVT::v16i8)) {
17286 SDValue Red0 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(0));
17287 SDValue Red1 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(1));
17288 return DAG.getNode(ISD::ADD, dl, ResVT, Red0, Red1);
17289 }
17290
17291 // We are looking for something that will have illegal types if left alone,
17292 // but that we can convert to a single instruction under MVE. For example
17293 // vecreduce_add(sext(A, v8i32)) => VADDV.s16 A
17294 // or
17295 // vecreduce_add(mul(zext(A, v16i32), zext(B, v16i32))) => VMLADAV.u8 A, B
17296
17297 // The legal cases are:
17298 // VADDV u/s 8/16/32
17299 // VMLAV u/s 8/16/32
17300 // VADDLV u/s 32
17301 // VMLALV u/s 16/32
17302
17303 // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
17304 // extend it and use v4i32 instead.
17305 auto ExtTypeMatches = [](SDValue A, ArrayRef<MVT> ExtTypes) {
17306 EVT AVT = A.getValueType();
17307 return any_of(ExtTypes, [&](MVT Ty) {
17308 return AVT.getVectorNumElements() == Ty.getVectorNumElements() &&
17309 AVT.bitsLE(Ty);
17310 });
17311 };
17312 auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
17313 EVT AVT = A.getValueType();
17314 if (!AVT.is128BitVector())
17315 A = DAG.getNode(
17316 ExtendCode, dl,
17318 *DAG.getContext(),
17320 A);
17321 return A;
17322 };
17323 auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
17324 if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
17325 return SDValue();
17326 SDValue A = N0->getOperand(0);
17327 if (ExtTypeMatches(A, ExtTypes))
17328 return ExtendIfNeeded(A, ExtendCode);
17329 return SDValue();
17330 };
17331 auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
17332 ArrayRef<MVT> ExtTypes, SDValue &Mask) {
17333 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17335 return SDValue();
17336 Mask = N0->getOperand(0);
17337 SDValue Ext = N0->getOperand(1);
17338 if (Ext->getOpcode() != ExtendCode)
17339 return SDValue();
17340 SDValue A = Ext->getOperand(0);
17341 if (ExtTypeMatches(A, ExtTypes))
17342 return ExtendIfNeeded(A, ExtendCode);
17343 return SDValue();
17344 };
17345 auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17346 SDValue &A, SDValue &B) {
17347 // For a vmla we are trying to match a larger pattern:
17348 // ExtA = sext/zext A
17349 // ExtB = sext/zext B
17350 // Mul = mul ExtA, ExtB
17351 // vecreduce.add Mul
17352 // There might also be en extra extend between the mul and the addreduce, so
17353 // long as the bitwidth is high enough to make them equivalent (for example
17354 // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
17355 if (ResVT != RetTy)
17356 return false;
17357 SDValue Mul = N0;
17358 if (Mul->getOpcode() == ExtendCode &&
17359 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17360 ResVT.getScalarSizeInBits())
17361 Mul = Mul->getOperand(0);
17362 if (Mul->getOpcode() != ISD::MUL)
17363 return false;
17364 SDValue ExtA = Mul->getOperand(0);
17365 SDValue ExtB = Mul->getOperand(1);
17366 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17367 return false;
17368 A = ExtA->getOperand(0);
17369 B = ExtB->getOperand(0);
17370 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17371 A = ExtendIfNeeded(A, ExtendCode);
17372 B = ExtendIfNeeded(B, ExtendCode);
17373 return true;
17374 }
17375 return false;
17376 };
17377 auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17378 SDValue &A, SDValue &B, SDValue &Mask) {
17379 // Same as the pattern above with a select for the zero predicated lanes
17380 // ExtA = sext/zext A
17381 // ExtB = sext/zext B
17382 // Mul = mul ExtA, ExtB
17383 // N0 = select Mask, Mul, 0
17384 // vecreduce.add N0
17385 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17387 return false;
17388 Mask = N0->getOperand(0);
17389 SDValue Mul = N0->getOperand(1);
17390 if (Mul->getOpcode() == ExtendCode &&
17391 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17392 ResVT.getScalarSizeInBits())
17393 Mul = Mul->getOperand(0);
17394 if (Mul->getOpcode() != ISD::MUL)
17395 return false;
17396 SDValue ExtA = Mul->getOperand(0);
17397 SDValue ExtB = Mul->getOperand(1);
17398 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17399 return false;
17400 A = ExtA->getOperand(0);
17401 B = ExtB->getOperand(0);
17402 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17403 A = ExtendIfNeeded(A, ExtendCode);
17404 B = ExtendIfNeeded(B, ExtendCode);
17405 return true;
17406 }
17407 return false;
17408 };
17409 auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
17410 // Split illegal MVT::v16i8->i64 vector reductions into two legal v8i16->i64
17411 // reductions. The operands are extended with MVEEXT, but as they are
17412 // reductions the lane orders do not matter. MVEEXT may be combined with
17413 // loads to produce two extending loads, or else they will be expanded to
17414 // VREV/VMOVL.
17415 EVT VT = Ops[0].getValueType();
17416 if (VT == MVT::v16i8) {
17417 assert((Opcode == ARMISD::VMLALVs || Opcode == ARMISD::VMLALVu) &&
17418 "Unexpected illegal long reduction opcode");
17419 bool IsUnsigned = Opcode == ARMISD::VMLALVu;
17420
17421 SDValue Ext0 =
17422 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17423 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[0]);
17424 SDValue Ext1 =
17425 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17426 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[1]);
17427
17428 SDValue MLA0 = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
17429 Ext0, Ext1);
17430 SDValue MLA1 =
17431 DAG.getNode(IsUnsigned ? ARMISD::VMLALVAu : ARMISD::VMLALVAs, dl,
17432 DAG.getVTList(MVT::i32, MVT::i32), MLA0, MLA0.getValue(1),
17433 Ext0.getValue(1), Ext1.getValue(1));
17434 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, MLA1, MLA1.getValue(1));
17435 }
17436 SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
17437 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
17438 SDValue(Node.getNode(), 1));
17439 };
17440
17441 SDValue A, B;
17442 SDValue Mask;
17443 if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17444 return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
17445 if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17446 return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
17447 if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17448 A, B))
17449 return Create64bitNode(ARMISD::VMLALVs, {A, B});
17450 if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17451 A, B))
17452 return Create64bitNode(ARMISD::VMLALVu, {A, B});
17453 if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
17454 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17455 DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
17456 if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
17457 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17458 DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
17459
17460 if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17461 Mask))
17462 return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
17463 if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17464 Mask))
17465 return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
17466 if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17467 Mask))
17468 return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
17469 if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17470 Mask))
17471 return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
17472 if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
17473 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17474 DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
17475 if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
17476 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17477 DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
17478
17479 if (SDValue A = IsVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}))
17480 return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
17481 if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
17482 return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
17483 if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}))
17484 return Create64bitNode(ARMISD::VADDLVs, {A});
17485 if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}))
17486 return Create64bitNode(ARMISD::VADDLVu, {A});
17487 if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
17488 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17489 DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
17490 if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
17491 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17492 DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
17493
17494 if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17495 return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
17496 if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17497 return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
17498 if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}, Mask))
17499 return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
17500 if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}, Mask))
17501 return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
17502 if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
17503 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17504 DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
17505 if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
17506 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17507 DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
17508
17509 // Some complications. We can get a case where the two inputs of the mul are
17510 // the same, then the output sext will have been helpfully converted to a
17511 // zext. Turn it back.
17512 SDValue Op = N0;
17513 if (Op->getOpcode() == ISD::VSELECT)
17514 Op = Op->getOperand(1);
17515 if (Op->getOpcode() == ISD::ZERO_EXTEND &&
17516 Op->getOperand(0)->getOpcode() == ISD::MUL) {
17517 SDValue Mul = Op->getOperand(0);
17518 if (Mul->getOperand(0) == Mul->getOperand(1) &&
17519 Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
17520 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
17521 if (Op != N0)
17522 Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
17523 N0->getOperand(0), Ext, N0->getOperand(2));
17524 return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
17525 }
17526 }
17527
17528 return SDValue();
17529}
17530
17531// Looks for vaddv(shuffle) or vmlav(shuffle, shuffle), with a shuffle where all
17532// the lanes are used. Due to the reduction being commutative the shuffle can be
17533// removed.
17535 unsigned VecOp = N->getOperand(0).getValueType().isVector() ? 0 : 2;
17536 auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp));
17537 if (!Shuf || !Shuf->getOperand(1).isUndef())
17538 return SDValue();
17539
17540 // Check all elements are used once in the mask.
17541 ArrayRef<int> Mask = Shuf->getMask();
17542 APInt SetElts(Mask.size(), 0);
17543 for (int E : Mask) {
17544 if (E < 0 || E >= (int)Mask.size())
17545 return SDValue();
17546 SetElts.setBit(E);
17547 }
17548 if (!SetElts.isAllOnes())
17549 return SDValue();
17550
17551 if (N->getNumOperands() != VecOp + 1) {
17552 auto *Shuf2 = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp + 1));
17553 if (!Shuf2 || !Shuf2->getOperand(1).isUndef() || Shuf2->getMask() != Mask)
17554 return SDValue();
17555 }
17556
17558 for (SDValue Op : N->ops()) {
17559 if (Op.getValueType().isVector())
17560 Ops.push_back(Op.getOperand(0));
17561 else
17562 Ops.push_back(Op);
17563 }
17564 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Ops);
17565}
17566
17569 SDValue Op0 = N->getOperand(0);
17570 SDValue Op1 = N->getOperand(1);
17571 unsigned IsTop = N->getConstantOperandVal(2);
17572
17573 // VMOVNT a undef -> a
17574 // VMOVNB a undef -> a
17575 // VMOVNB undef a -> a
17576 if (Op1->isUndef())
17577 return Op0;
17578 if (Op0->isUndef() && !IsTop)
17579 return Op1;
17580
17581 // VMOVNt(c, VQMOVNb(a, b)) => VQMOVNt(c, b)
17582 // VMOVNb(c, VQMOVNb(a, b)) => VQMOVNb(c, b)
17583 if ((Op1->getOpcode() == ARMISD::VQMOVNs ||
17584 Op1->getOpcode() == ARMISD::VQMOVNu) &&
17585 Op1->getConstantOperandVal(2) == 0)
17586 return DCI.DAG.getNode(Op1->getOpcode(), SDLoc(Op1), N->getValueType(0),
17587 Op0, Op1->getOperand(1), N->getOperand(2));
17588
17589 // Only the bottom lanes from Qm (Op1) and either the top or bottom lanes from
17590 // Qd (Op0) are demanded from a VMOVN, depending on whether we are inserting
17591 // into the top or bottom lanes.
17592 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17593 APInt Op1DemandedElts = APInt::getSplat(NumElts, APInt::getLowBitsSet(2, 1));
17594 APInt Op0DemandedElts =
17595 IsTop ? Op1DemandedElts
17596 : APInt::getSplat(NumElts, APInt::getHighBitsSet(2, 1));
17597
17598 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17599 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17600 return SDValue(N, 0);
17601 if (TLI.SimplifyDemandedVectorElts(Op1, Op1DemandedElts, DCI))
17602 return SDValue(N, 0);
17603
17604 return SDValue();
17605}
17606
17609 SDValue Op0 = N->getOperand(0);
17610 unsigned IsTop = N->getConstantOperandVal(2);
17611
17612 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17613 APInt Op0DemandedElts =
17614 APInt::getSplat(NumElts, IsTop ? APInt::getLowBitsSet(2, 1)
17615 : APInt::getHighBitsSet(2, 1));
17616
17617 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17618 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17619 return SDValue(N, 0);
17620 return SDValue();
17621}
17622
17625 EVT VT = N->getValueType(0);
17626 SDValue LHS = N->getOperand(0);
17627 SDValue RHS = N->getOperand(1);
17628
17629 auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
17630 auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
17631 // Turn VQDMULH(shuffle, shuffle) -> shuffle(VQDMULH)
17632 if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&
17633 LHS.getOperand(1).isUndef() && RHS.getOperand(1).isUndef() &&
17634 (LHS.hasOneUse() || RHS.hasOneUse() || LHS == RHS)) {
17635 SDLoc DL(N);
17636 SDValue NewBinOp = DCI.DAG.getNode(N->getOpcode(), DL, VT,
17637 LHS.getOperand(0), RHS.getOperand(0));
17638 SDValue UndefV = LHS.getOperand(1);
17639 return DCI.DAG.getVectorShuffle(VT, DL, NewBinOp, UndefV, Shuf0->getMask());
17640 }
17641 return SDValue();
17642}
17643
17645 SDLoc DL(N);
17646 SDValue Op0 = N->getOperand(0);
17647 SDValue Op1 = N->getOperand(1);
17648
17649 // Turn X << -C -> X >> C and viceversa. The negative shifts can come up from
17650 // uses of the intrinsics.
17651 if (auto C = dyn_cast<ConstantSDNode>(N->getOperand(2))) {
17652 int ShiftAmt = C->getSExtValue();
17653 if (ShiftAmt == 0) {
17654 SDValue Merge = DAG.getMergeValues({Op0, Op1}, DL);
17655 DAG.ReplaceAllUsesWith(N, Merge.getNode());
17656 return SDValue();
17657 }
17658
17659 if (ShiftAmt >= -32 && ShiftAmt < 0) {
17660 unsigned NewOpcode =
17661 N->getOpcode() == ARMISD::LSLL ? ARMISD::LSRL : ARMISD::LSLL;
17662 SDValue NewShift = DAG.getNode(NewOpcode, DL, N->getVTList(), Op0, Op1,
17663 DAG.getConstant(-ShiftAmt, DL, MVT::i32));
17664 DAG.ReplaceAllUsesWith(N, NewShift.getNode());
17665 return NewShift;
17666 }
17667 }
17668
17669 return SDValue();
17670}
17671
17672/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
17674 DAGCombinerInfo &DCI) const {
17675 SelectionDAG &DAG = DCI.DAG;
17676 unsigned IntNo = N->getConstantOperandVal(0);
17677 switch (IntNo) {
17678 default:
17679 // Don't do anything for most intrinsics.
17680 break;
17681
17682 // Vector shifts: check for immediate versions and lower them.
17683 // Note: This is done during DAG combining instead of DAG legalizing because
17684 // the build_vectors for 64-bit vector element shift counts are generally
17685 // not legal, and it is hard to see their values after they get legalized to
17686 // loads from a constant pool.
17687 case Intrinsic::arm_neon_vshifts:
17688 case Intrinsic::arm_neon_vshiftu:
17689 case Intrinsic::arm_neon_vrshifts:
17690 case Intrinsic::arm_neon_vrshiftu:
17691 case Intrinsic::arm_neon_vrshiftn:
17692 case Intrinsic::arm_neon_vqshifts:
17693 case Intrinsic::arm_neon_vqshiftu:
17694 case Intrinsic::arm_neon_vqshiftsu:
17695 case Intrinsic::arm_neon_vqshiftns:
17696 case Intrinsic::arm_neon_vqshiftnu:
17697 case Intrinsic::arm_neon_vqshiftnsu:
17698 case Intrinsic::arm_neon_vqrshiftns:
17699 case Intrinsic::arm_neon_vqrshiftnu:
17700 case Intrinsic::arm_neon_vqrshiftnsu: {
17701 EVT VT = N->getOperand(1).getValueType();
17702 int64_t Cnt;
17703 unsigned VShiftOpc = 0;
17704
17705 switch (IntNo) {
17706 case Intrinsic::arm_neon_vshifts:
17707 case Intrinsic::arm_neon_vshiftu:
17708 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) {
17709 VShiftOpc = ARMISD::VSHLIMM;
17710 break;
17711 }
17712 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) {
17713 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? ARMISD::VSHRsIMM
17714 : ARMISD::VSHRuIMM);
17715 break;
17716 }
17717 return SDValue();
17718
17719 case Intrinsic::arm_neon_vrshifts:
17720 case Intrinsic::arm_neon_vrshiftu:
17721 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt))
17722 break;
17723 return SDValue();
17724
17725 case Intrinsic::arm_neon_vqshifts:
17726 case Intrinsic::arm_neon_vqshiftu:
17727 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17728 break;
17729 return SDValue();
17730
17731 case Intrinsic::arm_neon_vqshiftsu:
17732 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17733 break;
17734 llvm_unreachable("invalid shift count for vqshlu intrinsic");
17735
17736 case Intrinsic::arm_neon_vrshiftn:
17737 case Intrinsic::arm_neon_vqshiftns:
17738 case Intrinsic::arm_neon_vqshiftnu:
17739 case Intrinsic::arm_neon_vqshiftnsu:
17740 case Intrinsic::arm_neon_vqrshiftns:
17741 case Intrinsic::arm_neon_vqrshiftnu:
17742 case Intrinsic::arm_neon_vqrshiftnsu:
17743 // Narrowing shifts require an immediate right shift.
17744 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt))
17745 break;
17746 llvm_unreachable("invalid shift count for narrowing vector shift "
17747 "intrinsic");
17748
17749 default:
17750 llvm_unreachable("unhandled vector shift");
17751 }
17752
17753 switch (IntNo) {
17754 case Intrinsic::arm_neon_vshifts:
17755 case Intrinsic::arm_neon_vshiftu:
17756 // Opcode already set above.
17757 break;
17758 case Intrinsic::arm_neon_vrshifts:
17759 VShiftOpc = ARMISD::VRSHRsIMM;
17760 break;
17761 case Intrinsic::arm_neon_vrshiftu:
17762 VShiftOpc = ARMISD::VRSHRuIMM;
17763 break;
17764 case Intrinsic::arm_neon_vrshiftn:
17765 VShiftOpc = ARMISD::VRSHRNIMM;
17766 break;
17767 case Intrinsic::arm_neon_vqshifts:
17768 VShiftOpc = ARMISD::VQSHLsIMM;
17769 break;
17770 case Intrinsic::arm_neon_vqshiftu:
17771 VShiftOpc = ARMISD::VQSHLuIMM;
17772 break;
17773 case Intrinsic::arm_neon_vqshiftsu:
17774 VShiftOpc = ARMISD::VQSHLsuIMM;
17775 break;
17776 case Intrinsic::arm_neon_vqshiftns:
17777 VShiftOpc = ARMISD::VQSHRNsIMM;
17778 break;
17779 case Intrinsic::arm_neon_vqshiftnu:
17780 VShiftOpc = ARMISD::VQSHRNuIMM;
17781 break;
17782 case Intrinsic::arm_neon_vqshiftnsu:
17783 VShiftOpc = ARMISD::VQSHRNsuIMM;
17784 break;
17785 case Intrinsic::arm_neon_vqrshiftns:
17786 VShiftOpc = ARMISD::VQRSHRNsIMM;
17787 break;
17788 case Intrinsic::arm_neon_vqrshiftnu:
17789 VShiftOpc = ARMISD::VQRSHRNuIMM;
17790 break;
17791 case Intrinsic::arm_neon_vqrshiftnsu:
17792 VShiftOpc = ARMISD::VQRSHRNsuIMM;
17793 break;
17794 }
17795
17796 SDLoc dl(N);
17797 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17798 N->getOperand(1), DAG.getConstant(Cnt, dl, MVT::i32));
17799 }
17800
17801 case Intrinsic::arm_neon_vshiftins: {
17802 EVT VT = N->getOperand(1).getValueType();
17803 int64_t Cnt;
17804 unsigned VShiftOpc = 0;
17805
17806 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt))
17807 VShiftOpc = ARMISD::VSLIIMM;
17808 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt))
17809 VShiftOpc = ARMISD::VSRIIMM;
17810 else {
17811 llvm_unreachable("invalid shift count for vsli/vsri intrinsic");
17812 }
17813
17814 SDLoc dl(N);
17815 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17816 N->getOperand(1), N->getOperand(2),
17817 DAG.getConstant(Cnt, dl, MVT::i32));
17818 }
17819
17820 case Intrinsic::arm_neon_vqrshifts:
17821 case Intrinsic::arm_neon_vqrshiftu:
17822 // No immediate versions of these to check for.
17823 break;
17824
17825 case Intrinsic::arm_neon_vbsl: {
17826 SDLoc dl(N);
17827 return DAG.getNode(ARMISD::VBSP, dl, N->getValueType(0), N->getOperand(1),
17828 N->getOperand(2), N->getOperand(3));
17829 }
17830 case Intrinsic::arm_mve_vqdmlah:
17831 case Intrinsic::arm_mve_vqdmlash:
17832 case Intrinsic::arm_mve_vqrdmlah:
17833 case Intrinsic::arm_mve_vqrdmlash:
17834 case Intrinsic::arm_mve_vmla_n_predicated:
17835 case Intrinsic::arm_mve_vmlas_n_predicated:
17836 case Intrinsic::arm_mve_vqdmlah_predicated:
17837 case Intrinsic::arm_mve_vqdmlash_predicated:
17838 case Intrinsic::arm_mve_vqrdmlah_predicated:
17839 case Intrinsic::arm_mve_vqrdmlash_predicated: {
17840 // These intrinsics all take an i32 scalar operand which is narrowed to the
17841 // size of a single lane of the vector type they return. So we don't need
17842 // any bits of that operand above that point, which allows us to eliminate
17843 // uxth/sxth.
17844 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
17845 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17846 if (SimplifyDemandedBits(N->getOperand(3), DemandedMask, DCI))
17847 return SDValue();
17848 break;
17849 }
17850
17851 case Intrinsic::arm_mve_minv:
17852 case Intrinsic::arm_mve_maxv:
17853 case Intrinsic::arm_mve_minav:
17854 case Intrinsic::arm_mve_maxav:
17855 case Intrinsic::arm_mve_minv_predicated:
17856 case Intrinsic::arm_mve_maxv_predicated:
17857 case Intrinsic::arm_mve_minav_predicated:
17858 case Intrinsic::arm_mve_maxav_predicated: {
17859 // These intrinsics all take an i32 scalar operand which is narrowed to the
17860 // size of a single lane of the vector type they take as the other input.
17861 unsigned BitWidth = N->getOperand(2)->getValueType(0).getScalarSizeInBits();
17862 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17863 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
17864 return SDValue();
17865 break;
17866 }
17867
17868 case Intrinsic::arm_mve_addv: {
17869 // Turn this intrinsic straight into the appropriate ARMISD::VADDV node,
17870 // which allow PerformADDVecReduce to turn it into VADDLV when possible.
17871 bool Unsigned = N->getConstantOperandVal(2);
17872 unsigned Opc = Unsigned ? ARMISD::VADDVu : ARMISD::VADDVs;
17873 return DAG.getNode(Opc, SDLoc(N), N->getVTList(), N->getOperand(1));
17874 }
17875
17876 case Intrinsic::arm_mve_addlv:
17877 case Intrinsic::arm_mve_addlv_predicated: {
17878 // Same for these, but ARMISD::VADDLV has to be followed by a BUILD_PAIR
17879 // which recombines the two outputs into an i64
17880 bool Unsigned = N->getConstantOperandVal(2);
17881 unsigned Opc = IntNo == Intrinsic::arm_mve_addlv ?
17882 (Unsigned ? ARMISD::VADDLVu : ARMISD::VADDLVs) :
17883 (Unsigned ? ARMISD::VADDLVpu : ARMISD::VADDLVps);
17884
17886 for (unsigned i = 1, e = N->getNumOperands(); i < e; i++)
17887 if (i != 2) // skip the unsigned flag
17888 Ops.push_back(N->getOperand(i));
17889
17890 SDLoc dl(N);
17891 SDValue val = DAG.getNode(Opc, dl, {MVT::i32, MVT::i32}, Ops);
17892 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, val.getValue(0),
17893 val.getValue(1));
17894 }
17895 }
17896
17897 return SDValue();
17898}
17899
17901 EVT VT = Y.getValueType();
17902 if (!VT.isVector())
17903 return hasAndNotCompare(Y);
17904 if (Subtarget->hasMVEIntegerOps())
17905 return VT.is128BitVector();
17906 if (Subtarget->hasNEON())
17907 return VT.is64BitVector() || VT.is128BitVector();
17908 return false;
17909}
17910
17911/// PerformShiftCombine - Checks for immediate versions of vector shifts and
17912/// lowers them. As with the vector shift intrinsics, this is done during DAG
17913/// combining instead of DAG legalizing because the build_vectors for 64-bit
17914/// vector element shift counts are generally not legal, and it is hard to see
17915/// their values after they get legalized to loads from a constant pool.
17918 const ARMSubtarget *ST) {
17919 SelectionDAG &DAG = DCI.DAG;
17920 EVT VT = N->getValueType(0);
17921
17922 if (ST->isThumb1Only() && N->getOpcode() == ISD::SHL && VT == MVT::i32 &&
17923 N->getOperand(0)->getOpcode() == ISD::AND &&
17924 N->getOperand(0)->hasOneUse()) {
17925 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
17926 return SDValue();
17927 // Look for the pattern (shl (and x, AndMask), ShiftAmt). This doesn't
17928 // usually show up because instcombine prefers to canonicalize it to
17929 // (and (shl x, ShiftAmt) (shl AndMask, ShiftAmt)), but the shift can come
17930 // out of GEP lowering in some cases.
17931 SDValue N0 = N->getOperand(0);
17932 ConstantSDNode *ShiftAmtNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
17933 if (!ShiftAmtNode)
17934 return SDValue();
17935 uint32_t ShiftAmt = static_cast<uint32_t>(ShiftAmtNode->getZExtValue());
17936 ConstantSDNode *AndMaskNode = dyn_cast<ConstantSDNode>(N0->getOperand(1));
17937 if (!AndMaskNode)
17938 return SDValue();
17939 uint32_t AndMask = static_cast<uint32_t>(AndMaskNode->getZExtValue());
17940 // Don't transform uxtb/uxth.
17941 if (AndMask == 255 || AndMask == 65535)
17942 return SDValue();
17943 if (isMask_32(AndMask)) {
17944 uint32_t MaskedBits = llvm::countl_zero(AndMask);
17945 if (MaskedBits > ShiftAmt) {
17946 SDLoc DL(N);
17947 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
17948 DAG.getConstant(MaskedBits, DL, MVT::i32));
17949 return DAG.getNode(
17950 ISD::SRL, DL, MVT::i32, SHL,
17951 DAG.getConstant(MaskedBits - ShiftAmt, DL, MVT::i32));
17952 }
17953 }
17954 }
17955
17956 // Nothing to be done for scalar shifts.
17957 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
17958 if (!VT.isVector() || !TLI.isTypeLegal(VT))
17959 return SDValue();
17960 if (ST->hasMVEIntegerOps())
17961 return SDValue();
17962
17963 int64_t Cnt;
17964
17965 switch (N->getOpcode()) {
17966 default: llvm_unreachable("unexpected shift opcode");
17967
17968 case ISD::SHL:
17969 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) {
17970 SDLoc dl(N);
17971 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
17972 DAG.getConstant(Cnt, dl, MVT::i32));
17973 }
17974 break;
17975
17976 case ISD::SRA:
17977 case ISD::SRL:
17978 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
17979 unsigned VShiftOpc =
17980 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
17981 SDLoc dl(N);
17982 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
17983 DAG.getConstant(Cnt, dl, MVT::i32));
17984 }
17985 }
17986 return SDValue();
17987}
17988
17989// Look for a sign/zero/fpextend extend of a larger than legal load. This can be
17990// split into multiple extending loads, which are simpler to deal with than an
17991// arbitrary extend. For fp extends we use an integer extending load and a VCVTL
17992// to convert the type to an f32.
17994 SDValue N0 = N->getOperand(0);
17995 if (N0.getOpcode() != ISD::LOAD)
17996 return SDValue();
17998 if (!LD->isSimple() || !N0.hasOneUse() || LD->isIndexed() ||
17999 LD->getExtensionType() != ISD::NON_EXTLOAD)
18000 return SDValue();
18001 EVT FromVT = LD->getValueType(0);
18002 EVT ToVT = N->getValueType(0);
18003 if (!ToVT.isVector())
18004 return SDValue();
18006 EVT ToEltVT = ToVT.getVectorElementType();
18007 EVT FromEltVT = FromVT.getVectorElementType();
18008
18009 unsigned NumElements = 0;
18010 if (ToEltVT == MVT::i32 && FromEltVT == MVT::i8)
18011 NumElements = 4;
18012 if (ToEltVT == MVT::f32 && FromEltVT == MVT::f16)
18013 NumElements = 4;
18014 if (NumElements == 0 ||
18015 (FromEltVT != MVT::f16 && FromVT.getVectorNumElements() == NumElements) ||
18016 FromVT.getVectorNumElements() % NumElements != 0 ||
18017 !isPowerOf2_32(NumElements))
18018 return SDValue();
18019
18020 LLVMContext &C = *DAG.getContext();
18021 SDLoc DL(LD);
18022 // Details about the old load
18023 SDValue Ch = LD->getChain();
18024 SDValue BasePtr = LD->getBasePtr();
18025 Align Alignment = LD->getBaseAlign();
18026 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18027 AAMDNodes AAInfo = LD->getAAInfo();
18028
18029 ISD::LoadExtType NewExtType =
18030 N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18031 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
18032 EVT NewFromVT = EVT::getVectorVT(
18033 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
18034 EVT NewToVT = EVT::getVectorVT(
18035 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18036
18039 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18040 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18041 SDValue NewPtr =
18042 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18043
18044 SDValue NewLoad =
18045 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18046 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18047 Alignment, MMOFlags, AAInfo);
18048 Loads.push_back(NewLoad);
18049 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18050 }
18051
18052 // Float truncs need to extended with VCVTB's into their floating point types.
18053 if (FromEltVT == MVT::f16) {
18055
18056 for (unsigned i = 0; i < Loads.size(); i++) {
18057 SDValue LoadBC =
18058 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v8f16, Loads[i]);
18059 SDValue FPExt = DAG.getNode(ARMISD::VCVTL, DL, MVT::v4f32, LoadBC,
18060 DAG.getConstant(0, DL, MVT::i32));
18061 Extends.push_back(FPExt);
18062 }
18063
18064 Loads = Extends;
18065 }
18066
18067 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18068 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18069 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Loads);
18070}
18071
18072/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND,
18073/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND.
18075 const ARMSubtarget *ST) {
18076 SDValue N0 = N->getOperand(0);
18077 EVT VT = N->getValueType(0);
18078 SDLoc DL(N);
18079
18080 // Check for sign- and zero-extensions of vector extract operations of 8- and
18081 // 16-bit vector elements. NEON and MVE support these directly. They are
18082 // handled during DAG combining because type legalization will promote them
18083 // to 32-bit types and it is messy to recognize the operations after that.
18084 if ((ST->hasNEON() || ST->hasMVEIntegerOps()) &&
18086 SDValue Vec = N0.getOperand(0);
18087 SDValue Lane = N0.getOperand(1);
18088 EVT EltVT = N0.getValueType();
18089 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18090
18091 if (VT == MVT::i32 &&
18092 (EltVT == MVT::i8 || EltVT == MVT::i16) &&
18093 TLI.isTypeLegal(Vec.getValueType()) &&
18094 isa<ConstantSDNode>(Lane)) {
18095
18096 unsigned Opc = 0;
18097 switch (N->getOpcode()) {
18098 default: llvm_unreachable("unexpected opcode");
18099 case ISD::SIGN_EXTEND:
18100 Opc = ARMISD::VGETLANEs;
18101 break;
18102 case ISD::ZERO_EXTEND:
18103 case ISD::ANY_EXTEND:
18104 Opc = ARMISD::VGETLANEu;
18105 break;
18106 }
18107 return DAG.getNode(Opc, DL, VT, Vec, Lane);
18108 }
18109 }
18110
18111 if (ST->hasMVEIntegerOps())
18112 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18113 return NewLoad;
18114
18115 // Combine sext(buildvector(..)) to buildvector(sext(..)) to help avoid
18116 // difficult to lower i1 buildvector.
18117 if (ST->hasMVEIntegerOps() && N0.getValueType().getScalarSizeInBits() == 1 &&
18118 N0.getOpcode() == ISD::BUILD_VECTOR && VT.getScalarSizeInBits() <= 32) {
18120 for (unsigned I = 0; I < N0.getNumOperands(); I++) {
18121 SDValue InReg = N0.getOperand(I);
18122 if (N->getOpcode() == ISD::ZERO_EXTEND)
18123 InReg = DAG.getNode(ISD::AND, DL, InReg.getValueType(), InReg,
18124 DAG.getConstant(1, DL, InReg.getValueType()));
18125 else if (N->getOpcode() == ISD::SIGN_EXTEND)
18126 InReg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InReg.getValueType(),
18127 InReg, DAG.getValueType(MVT::i1));
18128 SDValue Ext = DAG.getNode(N->getOpcode(), DL, MVT::i32, InReg);
18129 Ops.push_back(Ext);
18130 }
18131 return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
18132 }
18133
18134 return SDValue();
18135}
18136
18138 const ARMSubtarget *ST) {
18139 if (ST->hasMVEFloatOps())
18140 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18141 return NewLoad;
18142
18143 return SDValue();
18144}
18145
18146// Lower smin(smax(x, C1), C2) to ssat or usat, if they have saturating
18147// constant bounds.
18149 const ARMSubtarget *Subtarget) {
18150 if ((Subtarget->isThumb() || !Subtarget->hasV6Ops()) &&
18151 !Subtarget->isThumb2())
18152 return SDValue();
18153
18154 EVT VT = Op.getValueType();
18155 SDValue Op0 = Op.getOperand(0);
18156
18157 if (VT != MVT::i32 ||
18158 (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
18159 !isa<ConstantSDNode>(Op.getOperand(1)) ||
18161 return SDValue();
18162
18163 SDValue Min = Op;
18164 SDValue Max = Op0;
18165 SDValue Input = Op0.getOperand(0);
18166 if (Min.getOpcode() == ISD::SMAX)
18167 std::swap(Min, Max);
18168
18169 if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX)
18170 return SDValue();
18171
18172 APInt MinC = Min.getConstantOperandAPInt(1);
18173 APInt MaxC = Max.getConstantOperandAPInt(1);
18174 if (MaxC.sgt(MinC))
18175 return SDValue();
18176
18177 SDLoc DL(Op);
18178
18179 // A clamp whose bounds are already a saturation range maps to a single
18180 // SSAT / USAT.
18181 if ((MinC + 1).isPowerOf2()) {
18182 if (MinC == ~MaxC)
18183 return DAG.getNode(ARMISD::SSAT, DL, VT, Input,
18184 DAG.getConstant(MinC.countr_one(), DL, VT));
18185 if (MaxC == 0)
18186 return DAG.getNode(ARMISD::USAT, DL, VT, Input,
18187 DAG.getConstant(MinC.countr_one(), DL, VT));
18188 }
18189
18190 // For power-of-two clamp widths, convert the range to be zero-centered,
18191 // apply SSAT, and convert the result back.
18192 //
18193 // Width = Hi - Lo + 1
18194 // Center = Lo + Width / 2
18195 // Result = ssat(X - Center) + Center
18196 //
18197 // The idea is to shift the input so that the clamp range is centered
18198 // around zero, apply ssat, and then shift the result back.
18199 //
18200 // For example clamp(X, -118, 137) -> Width = 256, Center = 10, so it becomes
18201 // ssat(X - 10, 8) + 10
18202
18203 APInt Width = MinC - MaxC + 1;
18204 if (!Width.isPowerOf2() || Width.isOne())
18205 return SDValue();
18206 unsigned SatBit = Width.logBase2() - 1; // ssat to SatBit + 1 signed bits
18207 APInt Center = MaxC + Width.lshr(1);
18208
18209 // The rewrite is only valid when X - Center does not overflow;
18210 SDValue NegC = DAG.getConstant(-Center, DL, VT);
18212 return SDValue();
18213
18214 SDValue Shifted = DAG.getNode(ISD::ADD, DL, VT, Input, NegC);
18215 SDValue Sat = DAG.getNode(ARMISD::SSAT, DL, VT, Shifted,
18216 DAG.getConstant(SatBit, DL, VT));
18217 return DAG.getNode(ISD::ADD, DL, VT, Sat, DAG.getConstant(Center, DL, VT));
18218}
18219
18220/// PerformMinMaxCombine - Target-specific DAG combining for creating truncating
18221/// saturates.
18223 const ARMSubtarget *ST) {
18224 EVT VT = N->getValueType(0);
18225 SDValue N0 = N->getOperand(0);
18226
18227 if (VT == MVT::i32)
18228 return PerformMinMaxToSatCombine(SDValue(N, 0), DAG, ST);
18229
18230 if (!ST->hasMVEIntegerOps())
18231 return SDValue();
18232
18233 if (SDValue V = PerformVQDMULHCombine(N, DAG))
18234 return V;
18235
18236 if (VT != MVT::v4i32 && VT != MVT::v8i16)
18237 return SDValue();
18238
18239 auto IsSignedSaturate = [&](SDNode *Min, SDNode *Max) {
18240 // Check one is a smin and the other is a smax
18241 if (Min->getOpcode() != ISD::SMIN)
18242 std::swap(Min, Max);
18243 if (Min->getOpcode() != ISD::SMIN || Max->getOpcode() != ISD::SMAX)
18244 return false;
18245
18246 APInt SaturateC;
18247 if (VT == MVT::v4i32)
18248 SaturateC = APInt(32, (1 << 15) - 1, true);
18249 else //if (VT == MVT::v8i16)
18250 SaturateC = APInt(16, (1 << 7) - 1, true);
18251
18252 APInt MinC, MaxC;
18253 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18254 MinC != SaturateC)
18255 return false;
18256 if (!ISD::isConstantSplatVector(Max->getOperand(1).getNode(), MaxC) ||
18257 MaxC != ~SaturateC)
18258 return false;
18259 return true;
18260 };
18261
18262 if (IsSignedSaturate(N, N0.getNode())) {
18263 SDLoc DL(N);
18264 MVT ExtVT, HalfVT;
18265 if (VT == MVT::v4i32) {
18266 HalfVT = MVT::v8i16;
18267 ExtVT = MVT::v4i16;
18268 } else { // if (VT == MVT::v8i16)
18269 HalfVT = MVT::v16i8;
18270 ExtVT = MVT::v8i8;
18271 }
18272
18273 // Create a VQMOVNB with undef top lanes, then signed extended into the top
18274 // half. That extend will hopefully be removed if only the bottom bits are
18275 // demanded (though a truncating store, for example).
18276 SDValue VQMOVN =
18277 DAG.getNode(ARMISD::VQMOVNs, DL, HalfVT, DAG.getUNDEF(HalfVT),
18278 N0->getOperand(0), DAG.getConstant(0, DL, MVT::i32));
18279 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18280 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Bitcast,
18281 DAG.getValueType(ExtVT));
18282 }
18283
18284 auto IsUnsignedSaturate = [&](SDNode *Min) {
18285 // For unsigned, we just need to check for <= 0xffff
18286 if (Min->getOpcode() != ISD::UMIN)
18287 return false;
18288
18289 APInt SaturateC;
18290 if (VT == MVT::v4i32)
18291 SaturateC = APInt(32, (1 << 16) - 1, true);
18292 else //if (VT == MVT::v8i16)
18293 SaturateC = APInt(16, (1 << 8) - 1, true);
18294
18295 APInt MinC;
18296 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18297 MinC != SaturateC)
18298 return false;
18299 return true;
18300 };
18301
18302 if (IsUnsignedSaturate(N)) {
18303 SDLoc DL(N);
18304 MVT HalfVT;
18305 unsigned ExtConst;
18306 if (VT == MVT::v4i32) {
18307 HalfVT = MVT::v8i16;
18308 ExtConst = 0x0000FFFF;
18309 } else { //if (VT == MVT::v8i16)
18310 HalfVT = MVT::v16i8;
18311 ExtConst = 0x00FF;
18312 }
18313
18314 // Create a VQMOVNB with undef top lanes, then ZExt into the top half with
18315 // an AND. That extend will hopefully be removed if only the bottom bits are
18316 // demanded (though a truncating store, for example).
18317 SDValue VQMOVN =
18318 DAG.getNode(ARMISD::VQMOVNu, DL, HalfVT, DAG.getUNDEF(HalfVT), N0,
18319 DAG.getConstant(0, DL, MVT::i32));
18320 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18321 return DAG.getNode(ISD::AND, DL, VT, Bitcast,
18322 DAG.getConstant(ExtConst, DL, VT));
18323 }
18324
18325 return SDValue();
18326}
18327
18330 if (!C)
18331 return nullptr;
18332 const APInt *CV = &C->getAPIntValue();
18333 return CV->isPowerOf2() ? CV : nullptr;
18334}
18335
18337 // If we have a CMOV, OR and AND combination such as:
18338 // if (x & CN)
18339 // y |= CM;
18340 //
18341 // And:
18342 // * CN is a single bit;
18343 // * All bits covered by CM are known zero in y
18344 //
18345 // Then we can convert this into a sequence of BFI instructions. This will
18346 // always be a win if CM is a single bit, will always be no worse than the
18347 // TST&OR sequence if CM is two bits, and for thumb will be no worse if CM is
18348 // three bits (due to the extra IT instruction).
18349
18350 SDValue Op0 = CMOV->getOperand(0);
18351 SDValue Op1 = CMOV->getOperand(1);
18352 auto CC = CMOV->getConstantOperandAPInt(2).getLimitedValue();
18353 SDValue CmpZ = CMOV->getOperand(3);
18354
18355 // The compare must be against zero.
18356 if (!isNullConstant(CmpZ->getOperand(1)))
18357 return SDValue();
18358
18359 assert(CmpZ->getOpcode() == ARMISD::CMPZ);
18360 SDValue And = CmpZ->getOperand(0);
18361 if (And->getOpcode() != ISD::AND)
18362 return SDValue();
18363 const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
18364 if (!AndC)
18365 return SDValue();
18366 SDValue X = And->getOperand(0);
18367
18368 if (CC == ARMCC::EQ) {
18369 // We're performing an "equal to zero" compare. Swap the operands so we
18370 // canonicalize on a "not equal to zero" compare.
18371 std::swap(Op0, Op1);
18372 } else {
18373 assert(CC == ARMCC::NE && "How can a CMPZ node not be EQ or NE?");
18374 }
18375
18376 if (Op1->getOpcode() != ISD::OR)
18377 return SDValue();
18378
18380 if (!OrC)
18381 return SDValue();
18382 SDValue Y = Op1->getOperand(0);
18383
18384 if (Op0 != Y)
18385 return SDValue();
18386
18387 // Now, is it profitable to continue?
18388 APInt OrCI = OrC->getAPIntValue();
18389 unsigned Heuristic = Subtarget->isThumb() ? 3 : 2;
18390 if (OrCI.popcount() > Heuristic)
18391 return SDValue();
18392
18393 // Lastly, can we determine that the bits defined by OrCI
18394 // are zero in Y?
18396 if ((OrCI & Known.Zero) != OrCI)
18397 return SDValue();
18398
18399 // OK, we can do the combine.
18400 SDValue V = Y;
18401 SDLoc dl(X);
18402 EVT VT = X.getValueType();
18403 unsigned BitInX = AndC->logBase2();
18404
18405 if (BitInX != 0) {
18406 // We must shift X first.
18407 X = DAG.getNode(ISD::SRL, dl, VT, X,
18408 DAG.getConstant(BitInX, dl, VT));
18409 }
18410
18411 for (unsigned BitInY = 0, NumActiveBits = OrCI.getActiveBits();
18412 BitInY < NumActiveBits; ++BitInY) {
18413 if (OrCI[BitInY] == 0)
18414 continue;
18415 APInt Mask(VT.getSizeInBits(), 0);
18416 Mask.setBit(BitInY);
18417 V = DAG.getNode(ARMISD::BFI, dl, VT, V, X,
18418 // Confusingly, the operand is an *inverted* mask.
18419 DAG.getConstant(~Mask, dl, VT));
18420 }
18421
18422 return V;
18423}
18424
18425// Given N, the value controlling the conditional branch, search for the loop
18426// intrinsic, returning it, along with how the value is used. We need to handle
18427// patterns such as the following:
18428// (brcond (xor (setcc (loop.decrement), 0, ne), 1), exit)
18429// (brcond (setcc (loop.decrement), 0, eq), exit)
18430// (brcond (setcc (loop.decrement), 0, ne), header)
18432 bool &Negate) {
18433 switch (N->getOpcode()) {
18434 default:
18435 break;
18436 case ISD::XOR: {
18437 if (!isa<ConstantSDNode>(N.getOperand(1)))
18438 return SDValue();
18439 if (!cast<ConstantSDNode>(N.getOperand(1))->isOne())
18440 return SDValue();
18441 Negate = !Negate;
18442 return SearchLoopIntrinsic(N.getOperand(0), CC, Imm, Negate);
18443 }
18444 case ISD::SETCC: {
18445 auto *Const = dyn_cast<ConstantSDNode>(N.getOperand(1));
18446 if (!Const)
18447 return SDValue();
18448 if (Const->isZero())
18449 Imm = 0;
18450 else if (Const->isOne())
18451 Imm = 1;
18452 else
18453 return SDValue();
18454 CC = cast<CondCodeSDNode>(N.getOperand(2))->get();
18455 return SearchLoopIntrinsic(N->getOperand(0), CC, Imm, Negate);
18456 }
18458 unsigned IntOp = N.getConstantOperandVal(1);
18459 if (IntOp != Intrinsic::test_start_loop_iterations &&
18460 IntOp != Intrinsic::loop_decrement_reg)
18461 return SDValue();
18462 return N;
18463 }
18464 }
18465 return SDValue();
18466}
18467
18470 const ARMSubtarget *ST) {
18471
18472 // The hwloop intrinsics that we're interested are used for control-flow,
18473 // either for entering or exiting the loop:
18474 // - test.start.loop.iterations will test whether its operand is zero. If it
18475 // is zero, the proceeding branch should not enter the loop.
18476 // - loop.decrement.reg also tests whether its operand is zero. If it is
18477 // zero, the proceeding branch should not branch back to the beginning of
18478 // the loop.
18479 // So here, we need to check that how the brcond is using the result of each
18480 // of the intrinsics to ensure that we're branching to the right place at the
18481 // right time.
18482
18483 ISD::CondCode CC;
18484 SDValue Cond;
18485 int Imm = 1;
18486 bool Negate = false;
18487 SDValue Chain = N->getOperand(0);
18488 SDValue Dest;
18489
18490 if (N->getOpcode() == ISD::BRCOND) {
18491 CC = ISD::SETEQ;
18492 Cond = N->getOperand(1);
18493 Dest = N->getOperand(2);
18494 } else {
18495 assert(N->getOpcode() == ISD::BR_CC && "Expected BRCOND or BR_CC!");
18496 CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
18497 Cond = N->getOperand(2);
18498 Dest = N->getOperand(4);
18499 if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(3))) {
18500 if (!Const->isOne() && !Const->isZero())
18501 return SDValue();
18502 Imm = Const->getZExtValue();
18503 } else
18504 return SDValue();
18505 }
18506
18507 SDValue Int = SearchLoopIntrinsic(Cond, CC, Imm, Negate);
18508 if (!Int)
18509 return SDValue();
18510
18511 if (Negate)
18512 CC = ISD::getSetCCInverse(CC, /* Integer inverse */ MVT::i32);
18513
18514 auto IsTrueIfZero = [](ISD::CondCode CC, int Imm) {
18515 return (CC == ISD::SETEQ && Imm == 0) ||
18516 (CC == ISD::SETNE && Imm == 1) ||
18517 (CC == ISD::SETLT && Imm == 1) ||
18518 (CC == ISD::SETULT && Imm == 1);
18519 };
18520
18521 auto IsFalseIfZero = [](ISD::CondCode CC, int Imm) {
18522 return (CC == ISD::SETEQ && Imm == 1) ||
18523 (CC == ISD::SETNE && Imm == 0) ||
18524 (CC == ISD::SETGT && Imm == 0) ||
18525 (CC == ISD::SETUGT && Imm == 0) ||
18526 (CC == ISD::SETGE && Imm == 1) ||
18527 (CC == ISD::SETUGE && Imm == 1);
18528 };
18529
18530 assert((IsTrueIfZero(CC, Imm) || IsFalseIfZero(CC, Imm)) &&
18531 "unsupported condition");
18532
18533 SDLoc dl(Int);
18534 SelectionDAG &DAG = DCI.DAG;
18535 SDValue Elements = Int.getOperand(2);
18536 unsigned IntOp = Int->getConstantOperandVal(1);
18537 assert((N->hasOneUse() && N->user_begin()->getOpcode() == ISD::BR) &&
18538 "expected single br user");
18539 SDNode *Br = *N->user_begin();
18540 SDValue OtherTarget = Br->getOperand(1);
18541
18542 // Update the unconditional branch to branch to the given Dest.
18543 auto UpdateUncondBr = [](SDNode *Br, SDValue Dest, SelectionDAG &DAG) {
18544 SDValue NewBrOps[] = { Br->getOperand(0), Dest };
18545 SDValue NewBr = DAG.getNode(ISD::BR, SDLoc(Br), MVT::Other, NewBrOps);
18546 DAG.ReplaceAllUsesOfValueWith(SDValue(Br, 0), NewBr);
18547 };
18548
18549 if (IntOp == Intrinsic::test_start_loop_iterations) {
18550 SDValue Res;
18551 SDValue Setup = DAG.getNode(ARMISD::WLSSETUP, dl, MVT::i32, Elements);
18552 // We expect this 'instruction' to branch when the counter is zero.
18553 if (IsTrueIfZero(CC, Imm)) {
18554 SDValue Ops[] = {Chain, Setup, Dest};
18555 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18556 } else {
18557 // The logic is the reverse of what we need for WLS, so find the other
18558 // basic block target: the target of the proceeding br.
18559 UpdateUncondBr(Br, Dest, DAG);
18560
18561 SDValue Ops[] = {Chain, Setup, OtherTarget};
18562 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18563 }
18564 // Update LR count to the new value
18565 DAG.ReplaceAllUsesOfValueWith(Int.getValue(0), Setup);
18566 // Update chain
18567 DAG.ReplaceAllUsesOfValueWith(Int.getValue(2), Int.getOperand(0));
18568 return Res;
18569 } else {
18570 SDValue Size =
18571 DAG.getTargetConstant(Int.getConstantOperandVal(3), dl, MVT::i32);
18572 SDValue Args[] = { Int.getOperand(0), Elements, Size, };
18573 SDValue LoopDec = DAG.getNode(ARMISD::LOOP_DEC, dl,
18574 DAG.getVTList(MVT::i32, MVT::Other), Args);
18575 DAG.ReplaceAllUsesWith(Int.getNode(), LoopDec.getNode());
18576
18577 // We expect this instruction to branch when the count is not zero.
18578 SDValue Target = IsFalseIfZero(CC, Imm) ? Dest : OtherTarget;
18579
18580 // Update the unconditional branch to target the loop preheader if we've
18581 // found the condition has been reversed.
18582 if (Target == OtherTarget)
18583 UpdateUncondBr(Br, Dest, DAG);
18584
18585 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
18586 SDValue(LoopDec.getNode(), 1), Chain);
18587
18588 SDValue EndArgs[] = { Chain, SDValue(LoopDec.getNode(), 0), Target };
18589 return DAG.getNode(ARMISD::LE, dl, MVT::Other, EndArgs);
18590 }
18591 return SDValue();
18592}
18593
18594/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
18595SDValue
18597 SDValue Cmp = N->getOperand(3);
18598 if (Cmp.getOpcode() != ARMISD::CMPZ)
18599 // Only looking at NE cases.
18600 return SDValue();
18601
18602 SDLoc dl(N);
18603 SDValue LHS = Cmp.getOperand(0);
18604 SDValue RHS = Cmp.getOperand(1);
18605 SDValue Chain = N->getOperand(0);
18606 SDValue BB = N->getOperand(1);
18607 SDValue ARMcc = N->getOperand(2);
18609
18610 // (brcond Chain BB ne (cmpz (and (cmov 0 1 CC Flags) 1) 0))
18611 // -> (brcond Chain BB CC Flags)
18612 if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
18613 LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
18614 LHS->getOperand(0)->hasOneUse() &&
18615 isNullConstant(LHS->getOperand(0)->getOperand(0)) &&
18616 isOneConstant(LHS->getOperand(0)->getOperand(1)) &&
18617 isOneConstant(LHS->getOperand(1)) && isNullConstant(RHS)) {
18618 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, BB,
18619 LHS->getOperand(0)->getOperand(2),
18620 LHS->getOperand(0)->getOperand(3));
18621 }
18622
18623 return SDValue();
18624}
18625
18626/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
18627SDValue
18629 SDLoc dl(N);
18630 EVT VT = N->getValueType(0);
18631 SDValue FalseVal = N->getOperand(0);
18632 SDValue TrueVal = N->getOperand(1);
18633 SDValue ARMcc = N->getOperand(2);
18634 SDValue Cmp = N->getOperand(3);
18635
18636 // Try to form CSINV etc.
18637 unsigned Opcode;
18638 bool InvertCond;
18639 if (SDValue CSetOp =
18640 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
18641 if (InvertCond) {
18642 ARMCC::CondCodes CondCode =
18643 (ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
18644 CondCode = ARMCC::getOppositeCondition(CondCode);
18645 ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
18646 }
18647 return DAG.getNode(Opcode, dl, VT, CSetOp, CSetOp, ARMcc, Cmp);
18648 }
18649
18650 if (Cmp.getOpcode() != ARMISD::CMPZ)
18651 // Only looking at EQ and NE cases.
18652 return SDValue();
18653
18654 SDValue LHS = Cmp.getOperand(0);
18655 SDValue RHS = Cmp.getOperand(1);
18657
18658 // BFI is only available on V6T2+.
18659 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops()) {
18661 if (R)
18662 return R;
18663 }
18664
18665 // Simplify
18666 // mov r1, r0
18667 // cmp r1, x
18668 // mov r0, y
18669 // moveq r0, x
18670 // to
18671 // cmp r0, x
18672 // movne r0, y
18673 //
18674 // mov r1, r0
18675 // cmp r1, x
18676 // mov r0, x
18677 // movne r0, y
18678 // to
18679 // cmp r0, x
18680 // movne r0, y
18681 /// FIXME: Turn this into a target neutral optimization?
18682 SDValue Res;
18683 if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) {
18684 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, Cmp);
18685 } else if (CC == ARMCC::EQ && TrueVal == RHS) {
18686 SDValue ARMcc;
18687 SDValue NewCmp = getARMCmp(LHS, RHS, ISD::SETNE, ARMcc, DAG, dl);
18688 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, FalseVal, ARMcc, NewCmp);
18689 }
18690
18691 // (cmov F T ne (cmpz (cmov 0 1 CC Flags) 0))
18692 // -> (cmov F T CC Flags)
18693 if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse() &&
18694 isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
18695 isNullConstant(RHS)) {
18696 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
18697 LHS->getOperand(2), LHS->getOperand(3));
18698 }
18699
18700 if (!VT.isInteger())
18701 return SDValue();
18702
18703 // Fold away an unnecessary CMPZ/CMOV
18704 // CMOV A, B, C1, (CMPZ (CMOV 1, 0, C2, D), 0) ->
18705 // if C1==EQ -> CMOV A, B, C2, D
18706 // if C1==NE -> CMOV A, B, NOT(C2), D
18707 if (N->getConstantOperandVal(2) == ARMCC::EQ ||
18708 N->getConstantOperandVal(2) == ARMCC::NE) {
18710 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
18711 if (N->getConstantOperandVal(2) == ARMCC::NE)
18713 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
18714 N->getOperand(1),
18715 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
18716 }
18717 }
18718
18719 // Materialize a boolean comparison for integers so we can avoid branching.
18720 if (isNullConstant(FalseVal)) {
18721 if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
18722 if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
18723 // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
18724 // right 5 bits will make that 32 be 1, otherwise it will be 0.
18725 // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
18726 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18727 Res = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Sub),
18728 DAG.getConstant(5, dl, MVT::i32));
18729 } else {
18730 // CMOV 0, 1, ==, (CMPZ x, y) ->
18731 // (UADDO_CARRY (SUB x, y), t:0, t:1)
18732 // where t = (USUBO_CARRY 0, (SUB x, y), 0)
18733 //
18734 // The USUBO_CARRY computes 0 - (x - y) and this will give a borrow when
18735 // x != y. In other words, a carry C == 1 when x == y, C == 0
18736 // otherwise.
18737 // The final UADDO_CARRY computes
18738 // x - y + (0 - (x - y)) + C == C
18739 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18740 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18741 SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
18742 // ISD::USUBO_CARRY returns a borrow but we want the carry here
18743 // actually.
18744 SDValue Carry =
18745 DAG.getNode(ISD::SUB, dl, MVT::i32,
18746 DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
18747 Res = DAG.getNode(ISD::UADDO_CARRY, dl, VTs, Sub, Neg, Carry);
18748 }
18749 } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
18750 (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
18751 // This seems pointless but will allow us to combine it further below.
18752 // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18753 SDValue Sub =
18754 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18755 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
18756 Sub.getValue(1));
18757 FalseVal = Sub;
18758 }
18759 } else if (isNullConstant(TrueVal)) {
18760 if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
18761 (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
18762 // This seems pointless but will allow us to combine it further below
18763 // Note that we change == for != as this is the dual for the case above.
18764 // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18765 SDValue Sub =
18766 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18767 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
18768 DAG.getConstant(ARMCC::NE, dl, MVT::i32),
18769 Sub.getValue(1));
18770 FalseVal = Sub;
18771 }
18772 }
18773
18774 // On Thumb1, the DAG above may be further combined if z is a power of 2
18775 // (z == 2 ^ K).
18776 // CMOV (SUBC x, y), z, !=, (SUBC x, y):1 ->
18777 // t1 = (USUBO (SUB x, y), 1)
18778 // t2 = (USUBO_CARRY (SUB x, y), t1:0, t1:1)
18779 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18780 //
18781 // This also handles the special case of comparing against zero; it's
18782 // essentially, the same pattern, except there's no SUBC:
18783 // CMOV x, z, !=, (CMPZ x, 0) ->
18784 // t1 = (USUBO x, 1)
18785 // t2 = (USUBO_CARRY x, t1:0, t1:1)
18786 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18787 const APInt *TrueConst;
18788 if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
18789 ((FalseVal.getOpcode() == ARMISD::SUBC && FalseVal.getOperand(0) == LHS &&
18790 FalseVal.getOperand(1) == RHS) ||
18791 (FalseVal == LHS && isNullConstant(RHS))) &&
18792 (TrueConst = isPowerOf2Constant(TrueVal))) {
18793 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18794 unsigned ShiftAmount = TrueConst->logBase2();
18795 if (ShiftAmount)
18796 TrueVal = DAG.getConstant(1, dl, VT);
18797 SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
18798 Res = DAG.getNode(ISD::USUBO_CARRY, dl, VTs, FalseVal, Subc,
18799 Subc.getValue(1));
18800
18801 if (ShiftAmount)
18802 Res = DAG.getNode(ISD::SHL, dl, VT, Res,
18803 DAG.getConstant(ShiftAmount, dl, MVT::i32));
18804 }
18805
18806 if (Res.getNode()) {
18808 // Capture demanded bits information that would be otherwise lost.
18809 if (Known.Zero == 0xfffffffe)
18810 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18811 DAG.getValueType(MVT::i1));
18812 else if (Known.Zero == 0xffffff00)
18813 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18814 DAG.getValueType(MVT::i8));
18815 else if (Known.Zero == 0xffff0000)
18816 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18817 DAG.getValueType(MVT::i16));
18818 }
18819
18820 return Res;
18821}
18822
18825 const ARMSubtarget *ST) {
18826 SelectionDAG &DAG = DCI.DAG;
18827 SDValue Src = N->getOperand(0);
18828 EVT DstVT = N->getValueType(0);
18829
18830 // Convert v4f32 bitcast (v4i32 vdup (i32)) -> v4f32 vdup (i32) under MVE.
18831 if (ST->hasMVEIntegerOps() && Src.getOpcode() == ARMISD::VDUP) {
18832 EVT SrcVT = Src.getValueType();
18833 if (SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits())
18834 return DAG.getNode(ARMISD::VDUP, SDLoc(N), DstVT, Src.getOperand(0));
18835 }
18836
18837 // We may have a bitcast of something that has already had this bitcast
18838 // combine performed on it, so skip past any VECTOR_REG_CASTs.
18839 if (Src.getOpcode() == ARMISD::VECTOR_REG_CAST &&
18840 Src.getOperand(0).getValueType().getScalarSizeInBits() <=
18841 Src.getValueType().getScalarSizeInBits())
18842 Src = Src.getOperand(0);
18843
18844 // Bitcast from element-wise VMOV or VMVN doesn't need VREV if the VREV that
18845 // would be generated is at least the width of the element type.
18846 EVT SrcVT = Src.getValueType();
18847 if ((Src.getOpcode() == ARMISD::VMOVIMM ||
18848 Src.getOpcode() == ARMISD::VMVNIMM ||
18849 Src.getOpcode() == ARMISD::VMOVFPIMM) &&
18850 SrcVT.getScalarSizeInBits() <= DstVT.getScalarSizeInBits() &&
18851 DAG.getDataLayout().isBigEndian())
18852 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(N), DstVT, Src);
18853
18854 // bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD x
18855 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
18856 return R;
18857
18858 return SDValue();
18859}
18860
18861// Some combines for the MVETrunc truncations legalizer helper. Also lowers the
18862// node into stack operations after legalizeOps.
18865 SelectionDAG &DAG = DCI.DAG;
18866 EVT VT = N->getValueType(0);
18867 SDLoc DL(N);
18868
18869 // MVETrunc(Undef, Undef) -> Undef
18870 if (all_of(N->ops(), [](SDValue Op) { return Op.isUndef(); }))
18871 return DAG.getUNDEF(VT);
18872
18873 // MVETrunc(MVETrunc a b, MVETrunc c, d) -> MVETrunc
18874 if (N->getNumOperands() == 2 &&
18875 N->getOperand(0).getOpcode() == ARMISD::MVETRUNC &&
18876 N->getOperand(1).getOpcode() == ARMISD::MVETRUNC)
18877 return DAG.getNode(ARMISD::MVETRUNC, DL, VT, N->getOperand(0).getOperand(0),
18878 N->getOperand(0).getOperand(1),
18879 N->getOperand(1).getOperand(0),
18880 N->getOperand(1).getOperand(1));
18881
18882 // MVETrunc(shuffle, shuffle) -> VMOVN
18883 if (N->getNumOperands() == 2 &&
18884 N->getOperand(0).getOpcode() == ISD::VECTOR_SHUFFLE &&
18885 N->getOperand(1).getOpcode() == ISD::VECTOR_SHUFFLE) {
18886 auto *S0 = cast<ShuffleVectorSDNode>(N->getOperand(0).getNode());
18887 auto *S1 = cast<ShuffleVectorSDNode>(N->getOperand(1).getNode());
18888
18889 if (S0->getOperand(0) == S1->getOperand(0) &&
18890 S0->getOperand(1) == S1->getOperand(1)) {
18891 // Construct complete shuffle mask
18892 SmallVector<int, 8> Mask(S0->getMask());
18893 Mask.append(S1->getMask().begin(), S1->getMask().end());
18894
18895 if (isVMOVNTruncMask(Mask, VT, false))
18896 return DAG.getNode(
18897 ARMISD::VMOVN, DL, VT,
18898 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18899 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18900 DAG.getConstant(1, DL, MVT::i32));
18901 if (isVMOVNTruncMask(Mask, VT, true))
18902 return DAG.getNode(
18903 ARMISD::VMOVN, DL, VT,
18904 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18905 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18906 DAG.getConstant(1, DL, MVT::i32));
18907 }
18908 }
18909
18910 // For MVETrunc of a buildvector or shuffle, it can be beneficial to lower the
18911 // truncate to a buildvector to allow the generic optimisations to kick in.
18912 if (all_of(N->ops(), [](SDValue Op) {
18913 return Op.getOpcode() == ISD::BUILD_VECTOR ||
18914 Op.getOpcode() == ISD::VECTOR_SHUFFLE ||
18915 (Op.getOpcode() == ISD::BITCAST &&
18916 Op.getOperand(0).getOpcode() == ISD::BUILD_VECTOR);
18917 })) {
18918 SmallVector<SDValue, 8> Extracts;
18919 for (unsigned Op = 0; Op < N->getNumOperands(); Op++) {
18920 SDValue O = N->getOperand(Op);
18921 for (unsigned i = 0; i < O.getValueType().getVectorNumElements(); i++) {
18922 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, O,
18923 DAG.getConstant(i, DL, MVT::i32));
18924 Extracts.push_back(Ext);
18925 }
18926 }
18927 return DAG.getBuildVector(VT, DL, Extracts);
18928 }
18929
18930 // If we are late in the legalization process and nothing has optimised
18931 // the trunc to anything better, lower it to a stack store and reload,
18932 // performing the truncation whilst keeping the lanes in the correct order:
18933 // VSTRH.32 a, stack; VSTRH.32 b, stack+8; VLDRW.32 stack;
18934 if (!DCI.isAfterLegalizeDAG())
18935 return SDValue();
18936
18937 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
18938 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
18939 int NumIns = N->getNumOperands();
18940 assert((NumIns == 2 || NumIns == 4) &&
18941 "Expected 2 or 4 inputs to an MVETrunc");
18942 EVT StoreVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
18943 if (N->getNumOperands() == 4)
18944 StoreVT = StoreVT.getHalfNumVectorElementsVT(*DAG.getContext());
18945
18946 SmallVector<SDValue> Chains;
18947 for (int I = 0; I < NumIns; I++) {
18948 SDValue Ptr = DAG.getNode(
18949 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
18950 DAG.getConstant(I * 16 / NumIns, DL, StackPtr.getValueType()));
18952 DAG.getMachineFunction(), SPFI, I * 16 / NumIns);
18953 SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), DL, N->getOperand(I),
18954 Ptr, MPI, StoreVT, Align(4));
18955 Chains.push_back(Ch);
18956 }
18957
18958 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18959 MachinePointerInfo MPI =
18961 return DAG.getLoad(VT, DL, Chain, StackPtr, MPI, Align(4));
18962}
18963
18964// Take a MVEEXT(load x) and split that into (extload x, extload x+8)
18966 SelectionDAG &DAG) {
18967 SDValue N0 = N->getOperand(0);
18969 if (!LD || !LD->isSimple() || !N0.hasOneUse() || LD->isIndexed())
18970 return SDValue();
18971
18972 EVT FromVT = LD->getMemoryVT();
18973 EVT ToVT = N->getValueType(0);
18974 if (!ToVT.isVector())
18975 return SDValue();
18976 assert(FromVT.getVectorNumElements() == ToVT.getVectorNumElements() * 2);
18977 EVT ToEltVT = ToVT.getVectorElementType();
18978 EVT FromEltVT = FromVT.getVectorElementType();
18979
18980 unsigned NumElements = 0;
18981 if (ToEltVT == MVT::i32 && (FromEltVT == MVT::i16 || FromEltVT == MVT::i8))
18982 NumElements = 4;
18983 if (ToEltVT == MVT::i16 && FromEltVT == MVT::i8)
18984 NumElements = 8;
18985 assert(NumElements != 0);
18986
18987 ISD::LoadExtType NewExtType =
18988 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18989 if (LD->getExtensionType() != ISD::NON_EXTLOAD &&
18990 LD->getExtensionType() != ISD::EXTLOAD &&
18991 LD->getExtensionType() != NewExtType)
18992 return SDValue();
18993
18994 LLVMContext &C = *DAG.getContext();
18995 SDLoc DL(LD);
18996 // Details about the old load
18997 SDValue Ch = LD->getChain();
18998 SDValue BasePtr = LD->getBasePtr();
18999 Align Alignment = LD->getBaseAlign();
19000 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
19001 AAMDNodes AAInfo = LD->getAAInfo();
19002
19003 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
19004 EVT NewFromVT = EVT::getVectorVT(
19005 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
19006 EVT NewToVT = EVT::getVectorVT(
19007 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
19008
19011 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
19012 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
19013 SDValue NewPtr =
19014 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
19015
19016 SDValue NewLoad =
19017 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
19018 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
19019 Alignment, MMOFlags, AAInfo);
19020 Loads.push_back(NewLoad);
19021 Chains.push_back(SDValue(NewLoad.getNode(), 1));
19022 }
19023
19024 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
19025 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
19026 return DAG.getMergeValues(Loads, DL);
19027}
19028
19029// Perform combines for MVEEXT. If it has not be optimized to anything better
19030// before lowering, it gets converted to stack store and extloads performing the
19031// extend whilst still keeping the same lane ordering.
19034 SelectionDAG &DAG = DCI.DAG;
19035 EVT VT = N->getValueType(0);
19036 SDLoc DL(N);
19037 assert(N->getNumValues() == 2 && "Expected MVEEXT with 2 elements");
19038 assert((VT == MVT::v4i32 || VT == MVT::v8i16) && "Unexpected MVEEXT type");
19039
19040 EVT ExtVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19041 *DAG.getContext());
19042 auto Extend = [&](SDValue V) {
19043 SDValue VVT = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, V);
19044 return N->getOpcode() == ARMISD::MVESEXT
19045 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, VVT,
19046 DAG.getValueType(ExtVT))
19047 : DAG.getZeroExtendInReg(VVT, DL, ExtVT);
19048 };
19049
19050 // MVEEXT(VDUP) -> SIGN_EXTEND_INREG(VDUP)
19051 if (N->getOperand(0).getOpcode() == ARMISD::VDUP) {
19052 SDValue Ext = Extend(N->getOperand(0));
19053 return DAG.getMergeValues({Ext, Ext}, DL);
19054 }
19055
19056 // MVEEXT(shuffle) -> SIGN_EXTEND_INREG/ZERO_EXTEND_INREG
19057 if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N->getOperand(0))) {
19058 ArrayRef<int> Mask = SVN->getMask();
19059 assert(Mask.size() == 2 * VT.getVectorNumElements());
19060 assert(Mask.size() == SVN->getValueType(0).getVectorNumElements());
19061 unsigned Rev = VT == MVT::v4i32 ? ARMISD::VREV32 : ARMISD::VREV16;
19062 SDValue Op0 = SVN->getOperand(0);
19063 SDValue Op1 = SVN->getOperand(1);
19064
19065 auto CheckInregMask = [&](int Start, int Offset) {
19066 for (int Idx = 0, E = VT.getVectorNumElements(); Idx < E; ++Idx)
19067 if (Mask[Start + Idx] >= 0 && Mask[Start + Idx] != Idx * 2 + Offset)
19068 return false;
19069 return true;
19070 };
19071 SDValue V0 = SDValue(N, 0);
19072 SDValue V1 = SDValue(N, 1);
19073 if (CheckInregMask(0, 0))
19074 V0 = Extend(Op0);
19075 else if (CheckInregMask(0, 1))
19076 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19077 else if (CheckInregMask(0, Mask.size()))
19078 V0 = Extend(Op1);
19079 else if (CheckInregMask(0, Mask.size() + 1))
19080 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19081
19082 if (CheckInregMask(VT.getVectorNumElements(), Mask.size()))
19083 V1 = Extend(Op1);
19084 else if (CheckInregMask(VT.getVectorNumElements(), Mask.size() + 1))
19085 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19086 else if (CheckInregMask(VT.getVectorNumElements(), 0))
19087 V1 = Extend(Op0);
19088 else if (CheckInregMask(VT.getVectorNumElements(), 1))
19089 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19090
19091 if (V0.getNode() != N || V1.getNode() != N)
19092 return DAG.getMergeValues({V0, V1}, DL);
19093 }
19094
19095 // MVEEXT(load) -> extload, extload
19096 if (N->getOperand(0)->getOpcode() == ISD::LOAD)
19098 return L;
19099
19100 if (!DCI.isAfterLegalizeDAG())
19101 return SDValue();
19102
19103 // Lower to a stack store and reload:
19104 // VSTRW.32 a, stack; VLDRH.32 stack; VLDRH.32 stack+8;
19105 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19106 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19107 int NumOuts = N->getNumValues();
19108 assert((NumOuts == 2 || NumOuts == 4) &&
19109 "Expected 2 or 4 outputs to an MVEEXT");
19110 EVT LoadVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19111 *DAG.getContext());
19112 if (N->getNumOperands() == 4)
19113 LoadVT = LoadVT.getHalfNumVectorElementsVT(*DAG.getContext());
19114
19115 MachinePointerInfo MPI =
19117 SDValue Chain = DAG.getStore(DAG.getEntryNode(), DL, N->getOperand(0),
19118 StackPtr, MPI, Align(4));
19119
19121 for (int I = 0; I < NumOuts; I++) {
19122 SDValue Ptr = DAG.getNode(
19123 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19124 DAG.getConstant(I * 16 / NumOuts, DL, StackPtr.getValueType()));
19126 DAG.getMachineFunction(), SPFI, I * 16 / NumOuts);
19127 SDValue Load = DAG.getExtLoad(
19128 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD, DL,
19129 VT, Chain, Ptr, MPI, LoadVT, Align(4));
19130 Loads.push_back(Load);
19131 }
19132
19133 return DAG.getMergeValues(Loads, DL);
19134}
19135
19137 DAGCombinerInfo &DCI) const {
19138 switch (N->getOpcode()) {
19139 default: break;
19140 case ISD::SELECT_CC:
19141 case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
19142 case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
19143 case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
19144 case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
19145 case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
19146 case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget);
19147 case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget);
19148 case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget);
19149 case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
19150 case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
19151 case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
19152 case ISD::BRCOND:
19153 case ISD::BR_CC: return PerformHWLoopCombine(N, DCI, Subtarget);
19154 case ARMISD::ADDC:
19155 case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
19156 case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI, Subtarget);
19157 case ARMISD::BFI: return PerformBFICombine(N, DCI.DAG);
19158 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
19159 case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG);
19160 case ARMISD::VMOVhr: return PerformVMOVhrCombine(N, DCI);
19161 case ARMISD::VMOVrh: return PerformVMOVrhCombine(N, DCI.DAG);
19162 case ISD::STORE: return PerformSTORECombine(N, DCI, Subtarget);
19163 case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI, Subtarget);
19166 return PerformExtractEltCombine(N, DCI, Subtarget);
19170 case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI, Subtarget);
19171 case ARMISD::VDUP: return PerformVDUPCombine(N, DCI.DAG, Subtarget);
19172 case ISD::FP_TO_SINT:
19173 case ISD::FP_TO_UINT:
19174 return PerformVCVTCombine(N, DCI.DAG, Subtarget);
19175 case ISD::FADD:
19176 return PerformFADDCombine(N, DCI.DAG, Subtarget);
19177 case ISD::FMUL:
19178 return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget);
19180 return PerformIntrinsicCombine(N, DCI);
19181 case ISD::SHL:
19182 case ISD::SRA:
19183 case ISD::SRL:
19184 return PerformShiftCombine(N, DCI, Subtarget);
19185 case ISD::SIGN_EXTEND:
19186 case ISD::ZERO_EXTEND:
19187 case ISD::ANY_EXTEND:
19188 return PerformExtendCombine(N, DCI.DAG, Subtarget);
19189 case ISD::FP_EXTEND:
19190 return PerformFPExtendCombine(N, DCI.DAG, Subtarget);
19191 case ISD::SMIN:
19192 case ISD::UMIN:
19193 case ISD::SMAX:
19194 case ISD::UMAX:
19195 return PerformMinMaxCombine(N, DCI.DAG, Subtarget);
19196 case ARMISD::CMOV:
19197 return PerformCMOVCombine(N, DCI.DAG);
19198 case ARMISD::BRCOND:
19199 return PerformBRCONDCombine(N, DCI.DAG);
19200 case ARMISD::CMPZ:
19201 return PerformCMPZCombine(N, DCI.DAG);
19202 case ARMISD::CSINC:
19203 case ARMISD::CSINV:
19204 case ARMISD::CSNEG:
19205 return PerformCSETCombine(N, DCI.DAG);
19206 case ISD::LOAD:
19207 return PerformLOADCombine(N, DCI, Subtarget);
19208 case ARMISD::VLD1DUP:
19209 case ARMISD::VLD2DUP:
19210 case ARMISD::VLD3DUP:
19211 case ARMISD::VLD4DUP:
19212 return PerformVLDCombine(N, DCI);
19214 return PerformARMBUILD_VECTORCombine(N, DCI);
19215 case ISD::BITCAST:
19216 return PerformBITCASTCombine(N, DCI, Subtarget);
19217 case ARMISD::PREDICATE_CAST:
19218 return PerformPREDICATE_CASTCombine(N, DCI);
19219 case ARMISD::VECTOR_REG_CAST:
19220 return PerformVECTOR_REG_CASTCombine(N, DCI.DAG, Subtarget);
19221 case ARMISD::MVETRUNC:
19222 return PerformMVETruncCombine(N, DCI);
19223 case ARMISD::MVESEXT:
19224 case ARMISD::MVEZEXT:
19225 return PerformMVEExtCombine(N, DCI);
19226 case ARMISD::VCMP:
19227 return PerformVCMPCombine(N, DCI.DAG, Subtarget);
19228 case ISD::VECREDUCE_ADD:
19229 return PerformVECREDUCE_ADDCombine(N, DCI.DAG, Subtarget);
19230 case ARMISD::VADDVs:
19231 case ARMISD::VADDVu:
19232 case ARMISD::VADDLVs:
19233 case ARMISD::VADDLVu:
19234 case ARMISD::VADDLVAs:
19235 case ARMISD::VADDLVAu:
19236 case ARMISD::VMLAVs:
19237 case ARMISD::VMLAVu:
19238 case ARMISD::VMLALVs:
19239 case ARMISD::VMLALVu:
19240 case ARMISD::VMLALVAs:
19241 case ARMISD::VMLALVAu:
19242 return PerformReduceShuffleCombine(N, DCI.DAG);
19243 case ARMISD::VMOVN:
19244 return PerformVMOVNCombine(N, DCI);
19245 case ARMISD::VQMOVNs:
19246 case ARMISD::VQMOVNu:
19247 return PerformVQMOVNCombine(N, DCI);
19248 case ARMISD::VQDMULH:
19249 return PerformVQDMULHCombine(N, DCI);
19250 case ARMISD::ASRL:
19251 case ARMISD::LSRL:
19252 case ARMISD::LSLL:
19253 return PerformLongShiftCombine(N, DCI.DAG);
19254 case ARMISD::SMULWB: {
19255 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19256 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19257 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19258 return SDValue();
19259 break;
19260 }
19261 case ARMISD::SMULWT: {
19262 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19263 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19264 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19265 return SDValue();
19266 break;
19267 }
19268 case ARMISD::SMLALBB:
19269 case ARMISD::QADD16b:
19270 case ARMISD::QSUB16b:
19271 case ARMISD::UQADD16b:
19272 case ARMISD::UQSUB16b: {
19273 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19274 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19275 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19276 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19277 return SDValue();
19278 break;
19279 }
19280 case ARMISD::SMLALBT: {
19281 unsigned LowWidth = N->getOperand(0).getValueType().getSizeInBits();
19282 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19283 unsigned HighWidth = N->getOperand(1).getValueType().getSizeInBits();
19284 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19285 if ((SimplifyDemandedBits(N->getOperand(0), LowMask, DCI)) ||
19286 (SimplifyDemandedBits(N->getOperand(1), HighMask, DCI)))
19287 return SDValue();
19288 break;
19289 }
19290 case ARMISD::SMLALTB: {
19291 unsigned HighWidth = N->getOperand(0).getValueType().getSizeInBits();
19292 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19293 unsigned LowWidth = N->getOperand(1).getValueType().getSizeInBits();
19294 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19295 if ((SimplifyDemandedBits(N->getOperand(0), HighMask, DCI)) ||
19296 (SimplifyDemandedBits(N->getOperand(1), LowMask, DCI)))
19297 return SDValue();
19298 break;
19299 }
19300 case ARMISD::SMLALTT: {
19301 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19302 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19303 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19304 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19305 return SDValue();
19306 break;
19307 }
19308 case ARMISD::QADD8b:
19309 case ARMISD::QSUB8b:
19310 case ARMISD::UQADD8b:
19311 case ARMISD::UQSUB8b: {
19312 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19313 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
19314 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19315 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19316 return SDValue();
19317 break;
19318 }
19319 case ARMISD::VBSP:
19320 if (N->getOperand(1) == N->getOperand(2))
19321 return N->getOperand(1);
19322 return SDValue();
19325 switch (N->getConstantOperandVal(1)) {
19326 case Intrinsic::arm_neon_vld1:
19327 case Intrinsic::arm_neon_vld1x2:
19328 case Intrinsic::arm_neon_vld1x3:
19329 case Intrinsic::arm_neon_vld1x4:
19330 case Intrinsic::arm_neon_vld2:
19331 case Intrinsic::arm_neon_vld3:
19332 case Intrinsic::arm_neon_vld4:
19333 case Intrinsic::arm_neon_vld2lane:
19334 case Intrinsic::arm_neon_vld3lane:
19335 case Intrinsic::arm_neon_vld4lane:
19336 case Intrinsic::arm_neon_vld2dup:
19337 case Intrinsic::arm_neon_vld3dup:
19338 case Intrinsic::arm_neon_vld4dup:
19339 case Intrinsic::arm_neon_vst1:
19340 case Intrinsic::arm_neon_vst1x2:
19341 case Intrinsic::arm_neon_vst1x3:
19342 case Intrinsic::arm_neon_vst1x4:
19343 case Intrinsic::arm_neon_vst2:
19344 case Intrinsic::arm_neon_vst3:
19345 case Intrinsic::arm_neon_vst4:
19346 case Intrinsic::arm_neon_vst2lane:
19347 case Intrinsic::arm_neon_vst3lane:
19348 case Intrinsic::arm_neon_vst4lane:
19349 return PerformVLDCombine(N, DCI);
19350 case Intrinsic::arm_mve_vld2q:
19351 case Intrinsic::arm_mve_vld4q:
19352 case Intrinsic::arm_mve_vst2q:
19353 case Intrinsic::arm_mve_vst4q:
19354 return PerformMVEVLDCombine(N, DCI);
19355 default: break;
19356 }
19357 break;
19358 }
19359 return SDValue();
19360}
19361
19363 EVT VT) const {
19364 return (VT == MVT::f32) && (Opc == ISD::LOAD || Opc == ISD::STORE);
19365}
19366
19368 Align Alignment,
19370 unsigned *Fast) const {
19371 // Depends what it gets converted into if the type is weird.
19372 if (!VT.isSimple())
19373 return false;
19374
19375 // The AllowsUnaligned flag models the SCTLR.A setting in ARM cpus
19376 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
19377 auto Ty = VT.getSimpleVT().SimpleTy;
19378
19379 if (Ty == MVT::i8 || Ty == MVT::i16 || Ty == MVT::i32) {
19380 // Unaligned access can use (for example) LRDB, LRDH, LDR
19381 if (AllowsUnaligned) {
19382 if (Fast)
19383 *Fast = Subtarget->hasV7Ops();
19384 return true;
19385 }
19386 }
19387
19388 if (Ty == MVT::f64 || Ty == MVT::v2f64) {
19389 // For any little-endian targets with neon, we can support unaligned ld/st
19390 // of D and Q (e.g. {D0,D1}) registers by using vld1.i8/vst1.i8.
19391 // A big-endian target may also explicitly support unaligned accesses
19392 if (Subtarget->hasNEON() && (AllowsUnaligned || Subtarget->isLittle())) {
19393 if (Fast)
19394 *Fast = 1;
19395 return true;
19396 }
19397 }
19398
19399 if (!Subtarget->hasMVEIntegerOps())
19400 return false;
19401
19402 // These are for predicates
19403 if ((Ty == MVT::v16i1 || Ty == MVT::v8i1 || Ty == MVT::v4i1 ||
19404 Ty == MVT::v2i1)) {
19405 if (Fast)
19406 *Fast = 1;
19407 return true;
19408 }
19409
19410 // These are for truncated stores/narrowing loads. They are fine so long as
19411 // the alignment is at least the size of the item being loaded
19412 if ((Ty == MVT::v4i8 || Ty == MVT::v8i8 || Ty == MVT::v4i16) &&
19413 Alignment >= VT.getScalarSizeInBits() / 8) {
19414 if (Fast)
19415 *Fast = true;
19416 return true;
19417 }
19418
19419 // In little-endian MVE, the store instructions VSTRB.U8, VSTRH.U16 and
19420 // VSTRW.U32 all store the vector register in exactly the same format, and
19421 // differ only in the range of their immediate offset field and the required
19422 // alignment. So there is always a store that can be used, regardless of
19423 // actual type.
19424 //
19425 // For big endian, that is not the case. But can still emit a (VSTRB.U8;
19426 // VREV64.8) pair and get the same effect. This will likely be better than
19427 // aligning the vector through the stack.
19428 if (Ty == MVT::v16i8 || Ty == MVT::v8i16 || Ty == MVT::v8f16 ||
19429 Ty == MVT::v4i32 || Ty == MVT::v4f32 || Ty == MVT::v2i64 ||
19430 Ty == MVT::v2f64) {
19431 if (Fast)
19432 *Fast = 1;
19433 return true;
19434 }
19435
19436 return false;
19437}
19438
19440 LLVMContext &Context, const MemOp &Op,
19441 const AttributeList &FuncAttributes) const {
19442 // See if we can use NEON instructions for this...
19443 if ((Op.isMemcpyOrMemmove() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
19444 !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
19445 unsigned Fast;
19446 if (Op.size() >= 16 &&
19447 (Op.isAligned(Align(16)) ||
19448 (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
19450 Fast))) {
19451 return MVT::v2f64;
19452 } else if (Op.size() >= 8 &&
19453 (Op.isAligned(Align(8)) ||
19455 MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
19456 Fast))) {
19457 return MVT::f64;
19458 }
19459 }
19460
19461 // Let the target-independent logic figure it out.
19462 return MVT::Other;
19463}
19464
19465// 64-bit integers are split into their high and low parts and held in two
19466// different registers, so the trunc is free since the low register can just
19467// be used.
19468bool ARMTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
19469 if (!SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
19470 return false;
19471 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
19472 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
19473 return (SrcBits == 64 && DestBits == 32);
19474}
19475
19477 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
19478 !DstVT.isInteger())
19479 return false;
19480 unsigned SrcBits = SrcVT.getSizeInBits();
19481 unsigned DestBits = DstVT.getSizeInBits();
19482 return (SrcBits == 64 && DestBits == 32);
19483}
19484
19486 if (Val.getOpcode() != ISD::LOAD)
19487 return false;
19488
19489 EVT VT1 = Val.getValueType();
19490 if (!VT1.isSimple() || !VT1.isInteger() ||
19491 !VT2.isSimple() || !VT2.isInteger())
19492 return false;
19493
19494 switch (VT1.getSimpleVT().SimpleTy) {
19495 default: break;
19496 case MVT::i1:
19497 case MVT::i8:
19498 case MVT::i16:
19499 // 8-bit and 16-bit loads implicitly zero-extend to 32-bits.
19500 return true;
19501 }
19502
19503 return false;
19504}
19505
19507 if (!VT.isSimple())
19508 return false;
19509
19510 // There are quite a few FP16 instructions (e.g. VNMLA, VNMLS, etc.) that
19511 // negate values directly (fneg is free). So, we don't want to let the DAG
19512 // combiner rewrite fneg into xors and some other instructions. For f16 and
19513 // FullFP16 argument passing, some bitcast nodes may be introduced,
19514 // triggering this DAG combine rewrite, so we are avoiding that with this.
19515 switch (VT.getSimpleVT().SimpleTy) {
19516 default: break;
19517 case MVT::f16:
19518 return Subtarget->hasFullFP16();
19519 }
19520
19521 return false;
19522}
19523
19525 if (!Subtarget->hasMVEIntegerOps())
19526 return nullptr;
19527 Type *SVIType = SVI->getType();
19528 Type *ScalarType = SVIType->getScalarType();
19529
19530 if (ScalarType->isFloatTy())
19531 return Type::getInt32Ty(SVIType->getContext());
19532 if (ScalarType->isHalfTy())
19533 return Type::getInt16Ty(SVIType->getContext());
19534 return nullptr;
19535}
19536
19538 EVT VT = ExtVal.getValueType();
19539
19540 if (!isTypeLegal(VT))
19541 return false;
19542
19543 if (auto *Ld = dyn_cast<MaskedLoadSDNode>(ExtVal.getOperand(0))) {
19544 if (Ld->isExpandingLoad())
19545 return false;
19546 }
19547
19548 if (Subtarget->hasMVEIntegerOps())
19549 return true;
19550
19551 // Don't create a loadext if we can fold the extension into a wide/long
19552 // instruction.
19553 // If there's more than one user instruction, the loadext is desirable no
19554 // matter what. There can be two uses by the same instruction.
19555 if (ExtVal->use_empty() ||
19556 !ExtVal->user_begin()->isOnlyUserOf(ExtVal.getNode()))
19557 return true;
19558
19559 SDNode *U = *ExtVal->user_begin();
19560 if ((U->getOpcode() == ISD::ADD || U->getOpcode() == ISD::SUB ||
19561 U->getOpcode() == ISD::SHL || U->getOpcode() == ARMISD::VSHLIMM))
19562 return false;
19563
19564 return true;
19565}
19566
19568 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
19569 return false;
19570
19571 if (!isTypeLegal(EVT::getEVT(Ty1)))
19572 return false;
19573
19574 assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");
19575
19576 // Assuming the caller doesn't have a zeroext or signext return parameter,
19577 // truncation all the way down to i1 is valid.
19578 return true;
19579}
19580
19581/// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
19582/// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
19583/// expanded to FMAs when this method returns true, otherwise fmuladd is
19584/// expanded to fmul + fadd.
19585///
19586/// ARM supports both fused and unfused multiply-add operations; we already
19587/// lower a pair of fmul and fadd to the latter so it's not clear that there
19588/// would be a gain or that the gain would be worthwhile enough to risk
19589/// correctness bugs.
19590///
19591/// For MVE, we set this to true as it helps simplify the need for some
19592/// patterns (and we don't have the non-fused floating point instruction).
19593bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
19594 EVT VT) const {
19595 if (Subtarget->useSoftFloat())
19596 return false;
19597
19598 if (!VT.isSimple())
19599 return false;
19600
19601 switch (VT.getSimpleVT().SimpleTy) {
19602 case MVT::v4f32:
19603 case MVT::v8f16:
19604 return Subtarget->hasMVEFloatOps();
19605 case MVT::f16:
19606 return Subtarget->useFPVFMx16();
19607 case MVT::f32:
19608 return Subtarget->useFPVFMx();
19609 case MVT::f64:
19610 return Subtarget->useFPVFMx64();
19611 default:
19612 break;
19613 }
19614
19615 return false;
19616}
19617
19618static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
19619 if (V < 0)
19620 return false;
19621
19622 unsigned Scale = 1;
19623 switch (VT.getSimpleVT().SimpleTy) {
19624 case MVT::i1:
19625 case MVT::i8:
19626 // Scale == 1;
19627 break;
19628 case MVT::i16:
19629 // Scale == 2;
19630 Scale = 2;
19631 break;
19632 default:
19633 // On thumb1 we load most things (i32, i64, floats, etc) with a LDR
19634 // Scale == 4;
19635 Scale = 4;
19636 break;
19637 }
19638
19639 if ((V & (Scale - 1)) != 0)
19640 return false;
19641 return isUInt<5>(V / Scale);
19642}
19643
19644static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
19645 const ARMSubtarget *Subtarget) {
19646 if (!VT.isInteger() && !VT.isFloatingPoint())
19647 return false;
19648 if (VT.isVector() && Subtarget->hasNEON())
19649 return false;
19650 if (VT.isVector() && VT.isFloatingPoint() && Subtarget->hasMVEIntegerOps() &&
19651 !Subtarget->hasMVEFloatOps())
19652 return false;
19653
19654 bool IsNeg = false;
19655 if (V < 0) {
19656 IsNeg = true;
19657 V = -V;
19658 }
19659
19660 unsigned NumBytes = std::max((unsigned)VT.getSizeInBits() / 8, 1U);
19661
19662 // MVE: size * imm7
19663 if (VT.isVector() && Subtarget->hasMVEIntegerOps()) {
19664 switch (VT.getSimpleVT().getVectorElementType().SimpleTy) {
19665 case MVT::i32:
19666 case MVT::f32:
19667 return isShiftedUInt<7,2>(V);
19668 case MVT::i16:
19669 case MVT::f16:
19670 return isShiftedUInt<7,1>(V);
19671 case MVT::i8:
19672 return isUInt<7>(V);
19673 default:
19674 return false;
19675 }
19676 }
19677
19678 // half VLDR: 2 * imm8
19679 if (VT.isFloatingPoint() && NumBytes == 2 && Subtarget->hasFPRegs16())
19680 return isShiftedUInt<8, 1>(V);
19681 // VLDR and LDRD: 4 * imm8
19682 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
19683 return isShiftedUInt<8, 2>(V);
19684
19685 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
19686 // + imm12 or - imm8
19687 if (IsNeg)
19688 return isUInt<8>(V);
19689 return isUInt<12>(V);
19690 }
19691
19692 return false;
19693}
19694
19695/// isLegalAddressImmediate - Return true if the integer value can be used
19696/// as the offset of the target addressing mode for load / store of the
19697/// given type.
19698static bool isLegalAddressImmediate(int64_t V, EVT VT,
19699 const ARMSubtarget *Subtarget) {
19700 if (V == 0)
19701 return true;
19702
19703 if (!VT.isSimple())
19704 return false;
19705
19706 if (Subtarget->isThumb1Only())
19707 return isLegalT1AddressImmediate(V, VT);
19708 else if (Subtarget->isThumb2())
19709 return isLegalT2AddressImmediate(V, VT, Subtarget);
19710
19711 // ARM mode.
19712 if (V < 0)
19713 V = - V;
19714 switch (VT.getSimpleVT().SimpleTy) {
19715 default: return false;
19716 case MVT::i1:
19717 case MVT::i8:
19718 case MVT::i32:
19719 // +- imm12
19720 return isUInt<12>(V);
19721 case MVT::i16:
19722 // +- imm8
19723 return isUInt<8>(V);
19724 case MVT::f32:
19725 case MVT::f64:
19726 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
19727 return false;
19728 return isShiftedUInt<8, 2>(V);
19729 }
19730}
19731
19733 EVT VT) const {
19734 int Scale = AM.Scale;
19735 if (Scale < 0)
19736 return false;
19737
19738 switch (VT.getSimpleVT().SimpleTy) {
19739 default: return false;
19740 case MVT::i1:
19741 case MVT::i8:
19742 case MVT::i16:
19743 case MVT::i32:
19744 if (Scale == 1)
19745 return true;
19746 // r + r << imm
19747 Scale = Scale & ~1;
19748 return Scale == 2 || Scale == 4 || Scale == 8;
19749 case MVT::i64:
19750 // FIXME: What are we trying to model here? ldrd doesn't have an r + r
19751 // version in Thumb mode.
19752 // r + r
19753 if (Scale == 1)
19754 return true;
19755 // r * 2 (this can be lowered to r + r).
19756 if (!AM.HasBaseReg && Scale == 2)
19757 return true;
19758 return false;
19759 case MVT::isVoid:
19760 // Note, we allow "void" uses (basically, uses that aren't loads or
19761 // stores), because arm allows folding a scale into many arithmetic
19762 // operations. This should be made more precise and revisited later.
19763
19764 // Allow r << imm, but the imm has to be a multiple of two.
19765 if (Scale & 1) return false;
19766 return isPowerOf2_32(Scale);
19767 }
19768}
19769
19771 EVT VT) const {
19772 const int Scale = AM.Scale;
19773
19774 // Negative scales are not supported in Thumb1.
19775 if (Scale < 0)
19776 return false;
19777
19778 // Thumb1 addressing modes do not support register scaling excepting the
19779 // following cases:
19780 // 1. Scale == 1 means no scaling.
19781 // 2. Scale == 2 this can be lowered to r + r if there is no base register.
19782 return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
19783}
19784
19785/// isLegalAddressingMode - Return true if the addressing mode represented
19786/// by AM is legal for this target, for a load/store of the specified type.
19788 const AddrMode &AM, Type *Ty,
19789 unsigned AS, Instruction *I) const {
19790 EVT VT = getValueType(DL, Ty, true);
19791 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget))
19792 return false;
19793
19794 // Can never fold addr of global into load/store.
19795 if (AM.BaseGV)
19796 return false;
19797
19798 switch (AM.Scale) {
19799 case 0: // no scale reg, must be "r+i" or "r", or "i".
19800 break;
19801 default:
19802 // ARM doesn't support any R+R*scale+imm addr modes.
19803 if (AM.BaseOffs)
19804 return false;
19805
19806 if (!VT.isSimple())
19807 return false;
19808
19809 if (Subtarget->isThumb1Only())
19810 return isLegalT1ScaledAddressingMode(AM, VT);
19811
19812 if (Subtarget->isThumb2())
19813 return isLegalT2ScaledAddressingMode(AM, VT);
19814
19815 int Scale = AM.Scale;
19816 switch (VT.getSimpleVT().SimpleTy) {
19817 default: return false;
19818 case MVT::i1:
19819 case MVT::i8:
19820 case MVT::i32:
19821 if (Scale < 0) Scale = -Scale;
19822 if (Scale == 1)
19823 return true;
19824 // r + r << imm
19825 return isPowerOf2_32(Scale & ~1);
19826 case MVT::i16:
19827 case MVT::i64:
19828 // r +/- r
19829 if (Scale == 1 || (AM.HasBaseReg && Scale == -1))
19830 return true;
19831 // r * 2 (this can be lowered to r + r).
19832 if (!AM.HasBaseReg && Scale == 2)
19833 return true;
19834 return false;
19835
19836 case MVT::isVoid:
19837 // Note, we allow "void" uses (basically, uses that aren't loads or
19838 // stores), because arm allows folding a scale into many arithmetic
19839 // operations. This should be made more precise and revisited later.
19840
19841 // Allow r << imm, but the imm has to be a multiple of two.
19842 if (Scale & 1) return false;
19843 return isPowerOf2_32(Scale);
19844 }
19845 }
19846 return true;
19847}
19848
19849/// isLegalICmpImmediate - Return true if the specified immediate is legal
19850/// icmp immediate, that is the target has icmp instructions which can compare
19851/// a register against the immediate without having to materialize the
19852/// immediate into a register.
19854 // Thumb2 and ARM modes can use cmn for negative immediates.
19855 if (!Subtarget->isThumb())
19856 return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
19858 if (Subtarget->isThumb2())
19859 return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
19861 // Thumb1 doesn't have cmn, and only 8-bit immediates.
19862 return Imm >= 0 && Imm <= 255;
19863}
19864
19865/// isLegalAddImmediate - Return true if the specified immediate is a legal add
19866/// *or sub* immediate, that is the target has add or sub instructions which can
19867/// add a register with the immediate without having to materialize the
19868/// immediate into a register.
19870 // Same encoding for add/sub, just flip the sign.
19871 uint64_t AbsImm = AbsoluteValue(Imm);
19872 if (!Subtarget->isThumb())
19873 return ARM_AM::getSOImmVal(AbsImm) != -1;
19874 if (Subtarget->isThumb2())
19875 return ARM_AM::getT2SOImmVal(AbsImm) != -1;
19876 // Thumb1 only has 8-bit unsigned immediate.
19877 return AbsImm <= 255;
19878}
19879
19880// Return false to prevent folding
19881// (mul (add r, c0), c1) -> (add (mul r, c1), c0*c1) in DAGCombine,
19882// if the folding leads to worse code.
19884 SDValue ConstNode) const {
19885 // Let the DAGCombiner decide for vector types and large types.
19886 const EVT VT = AddNode.getValueType();
19887 if (VT.isVector() || VT.getScalarSizeInBits() > 32)
19888 return true;
19889
19890 // It is worse if c0 is legal add immediate, while c1*c0 is not
19891 // and has to be composed by at least two instructions.
19892 const ConstantSDNode *C0Node = cast<ConstantSDNode>(AddNode.getOperand(1));
19893 const ConstantSDNode *C1Node = cast<ConstantSDNode>(ConstNode);
19894 const int64_t C0 = C0Node->getSExtValue();
19895 APInt CA = C0Node->getAPIntValue() * C1Node->getAPIntValue();
19897 return true;
19898 if (ConstantMaterializationCost((unsigned)CA.getZExtValue(), Subtarget) > 1)
19899 return false;
19900
19901 // Default to true and let the DAGCombiner decide.
19902 return true;
19903}
19904
19906 bool isSEXTLoad, SDValue &Base,
19907 SDValue &Offset, bool &isInc,
19908 SelectionDAG &DAG) {
19909 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19910 return false;
19911
19912 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
19913 // AddressingMode 3
19914 Base = Ptr->getOperand(0);
19916 int RHSC = (int)RHS->getZExtValue();
19917 if (RHSC < 0 && RHSC > -256) {
19918 assert(Ptr->getOpcode() == ISD::ADD);
19919 isInc = false;
19920 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19921 return true;
19922 }
19923 }
19924 isInc = (Ptr->getOpcode() == ISD::ADD);
19925 Offset = Ptr->getOperand(1);
19926 return true;
19927 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
19928 // AddressingMode 2
19930 int RHSC = (int)RHS->getZExtValue();
19931 if (RHSC < 0 && RHSC > -0x1000) {
19932 assert(Ptr->getOpcode() == ISD::ADD);
19933 isInc = false;
19934 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19935 Base = Ptr->getOperand(0);
19936 return true;
19937 }
19938 }
19939
19940 if (Ptr->getOpcode() == ISD::ADD) {
19941 isInc = true;
19942 ARM_AM::ShiftOpc ShOpcVal=
19944 if (ShOpcVal != ARM_AM::no_shift) {
19945 Base = Ptr->getOperand(1);
19946 Offset = Ptr->getOperand(0);
19947 } else {
19948 Base = Ptr->getOperand(0);
19949 Offset = Ptr->getOperand(1);
19950 }
19951 return true;
19952 }
19953
19954 isInc = (Ptr->getOpcode() == ISD::ADD);
19955 Base = Ptr->getOperand(0);
19956 Offset = Ptr->getOperand(1);
19957 return true;
19958 }
19959
19960 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
19961 return false;
19962}
19963
19965 bool isSEXTLoad, SDValue &Base,
19966 SDValue &Offset, bool &isInc,
19967 SelectionDAG &DAG) {
19968 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19969 return false;
19970
19971 Base = Ptr->getOperand(0);
19973 int RHSC = (int)RHS->getZExtValue();
19974 if (RHSC < 0 && RHSC > -0x100) { // 8 bits.
19975 assert(Ptr->getOpcode() == ISD::ADD);
19976 isInc = false;
19977 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19978 return true;
19979 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero.
19980 isInc = Ptr->getOpcode() == ISD::ADD;
19981 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
19982 return true;
19983 }
19984 }
19985
19986 return false;
19987}
19988
19989static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment,
19990 bool isSEXTLoad, bool IsMasked, bool isLE,
19992 bool &isInc, SelectionDAG &DAG) {
19993 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19994 return false;
19995 if (!isa<ConstantSDNode>(Ptr->getOperand(1)))
19996 return false;
19997
19998 // We allow LE non-masked loads to change the type (for example use a vldrb.8
19999 // as opposed to a vldrw.32). This can allow extra addressing modes or
20000 // alignments for what is otherwise an equivalent instruction.
20001 bool CanChangeType = isLE && !IsMasked;
20002
20004 int RHSC = (int)RHS->getZExtValue();
20005
20006 auto IsInRange = [&](int RHSC, int Limit, int Scale) {
20007 if (RHSC < 0 && RHSC > -Limit * Scale && RHSC % Scale == 0) {
20008 assert(Ptr->getOpcode() == ISD::ADD);
20009 isInc = false;
20010 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20011 return true;
20012 } else if (RHSC > 0 && RHSC < Limit * Scale && RHSC % Scale == 0) {
20013 isInc = Ptr->getOpcode() == ISD::ADD;
20014 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
20015 return true;
20016 }
20017 return false;
20018 };
20019
20020 // Try to find a matching instruction based on s/zext, Alignment, Offset and
20021 // (in BE/masked) type.
20022 Base = Ptr->getOperand(0);
20023 if (VT == MVT::v4i16) {
20024 if (Alignment >= 2 && IsInRange(RHSC, 0x80, 2))
20025 return true;
20026 } else if (VT == MVT::v4i8 || VT == MVT::v8i8) {
20027 if (IsInRange(RHSC, 0x80, 1))
20028 return true;
20029 } else if (Alignment >= 4 &&
20030 (CanChangeType || VT == MVT::v4i32 || VT == MVT::v4f32) &&
20031 IsInRange(RHSC, 0x80, 4))
20032 return true;
20033 else if (Alignment >= 2 &&
20034 (CanChangeType || VT == MVT::v8i16 || VT == MVT::v8f16) &&
20035 IsInRange(RHSC, 0x80, 2))
20036 return true;
20037 else if ((CanChangeType || VT == MVT::v16i8) && IsInRange(RHSC, 0x80, 1))
20038 return true;
20039 return false;
20040}
20041
20042/// getPreIndexedAddressParts - returns true by value, base pointer and
20043/// offset pointer and addressing mode by reference if the node's address
20044/// can be legally represented as pre-indexed load / store address.
20045bool
20047 SDValue &Offset,
20049 SelectionDAG &DAG) const {
20050 if (Subtarget->isThumb1Only())
20051 return false;
20052
20053 EVT VT;
20054 SDValue Ptr;
20055 Align Alignment;
20056 unsigned AS = 0;
20057 bool isSEXTLoad = false;
20058 bool IsMasked = false;
20059 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20060 Ptr = LD->getBasePtr();
20061 VT = LD->getMemoryVT();
20062 Alignment = LD->getAlign();
20063 AS = LD->getAddressSpace();
20064 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20065 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20066 Ptr = ST->getBasePtr();
20067 VT = ST->getMemoryVT();
20068 Alignment = ST->getAlign();
20069 AS = ST->getAddressSpace();
20070 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20071 Ptr = LD->getBasePtr();
20072 VT = LD->getMemoryVT();
20073 Alignment = LD->getAlign();
20074 AS = LD->getAddressSpace();
20075 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20076 IsMasked = true;
20078 Ptr = ST->getBasePtr();
20079 VT = ST->getMemoryVT();
20080 Alignment = ST->getAlign();
20081 AS = ST->getAddressSpace();
20082 IsMasked = true;
20083 } else
20084 return false;
20085
20086 unsigned Fast = 0;
20087 if (!allowsMisalignedMemoryAccesses(VT, AS, Alignment,
20089 // Only generate post-increment or pre-increment forms when a real
20090 // hardware instruction exists for them. Do not emit postinc/preinc
20091 // if the operation will end up as a libcall.
20092 return false;
20093 }
20094
20095 bool isInc;
20096 bool isLegal = false;
20097 if (VT.isVector())
20098 isLegal = Subtarget->hasMVEIntegerOps() &&
20100 Ptr.getNode(), VT, Alignment, isSEXTLoad, IsMasked,
20101 Subtarget->isLittle(), Base, Offset, isInc, DAG);
20102 else {
20103 if (Subtarget->isThumb2())
20104 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20105 Offset, isInc, DAG);
20106 else
20107 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20108 Offset, isInc, DAG);
20109 }
20110 if (!isLegal)
20111 return false;
20112
20113 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
20114 return true;
20115}
20116
20117/// getPostIndexedAddressParts - returns true by value, base pointer and
20118/// offset pointer and addressing mode by reference if this node can be
20119/// combined with a load / store to form a post-indexed load / store.
20121 SDValue &Base,
20122 SDValue &Offset,
20124 SelectionDAG &DAG) const {
20125 EVT VT;
20126 SDValue Ptr;
20127 Align Alignment;
20128 bool isSEXTLoad = false, isNonExt;
20129 bool IsMasked = false;
20130 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20131 VT = LD->getMemoryVT();
20132 Ptr = LD->getBasePtr();
20133 Alignment = LD->getAlign();
20134 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20135 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20136 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20137 VT = ST->getMemoryVT();
20138 Ptr = ST->getBasePtr();
20139 Alignment = ST->getAlign();
20140 isNonExt = !ST->isTruncatingStore();
20141 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20142 VT = LD->getMemoryVT();
20143 Ptr = LD->getBasePtr();
20144 Alignment = LD->getAlign();
20145 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20146 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20147 IsMasked = true;
20149 VT = ST->getMemoryVT();
20150 Ptr = ST->getBasePtr();
20151 Alignment = ST->getAlign();
20152 isNonExt = !ST->isTruncatingStore();
20153 IsMasked = true;
20154 } else
20155 return false;
20156
20157 if (Subtarget->isThumb1Only()) {
20158 // Thumb-1 can do a limited post-inc load or store as an updating LDM. It
20159 // must be non-extending/truncating, i32, with an offset of 4.
20160 assert(Op->getValueType(0) == MVT::i32 && "Non-i32 post-inc op?!");
20161 if (Op->getOpcode() != ISD::ADD || !isNonExt)
20162 return false;
20163 auto *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1));
20164 if (!RHS || RHS->getZExtValue() != 4)
20165 return false;
20166 if (Alignment < Align(4))
20167 return false;
20168
20169 Offset = Op->getOperand(1);
20170 Base = Op->getOperand(0);
20171 AM = ISD::POST_INC;
20172 return true;
20173 }
20174
20175 bool isInc;
20176 bool isLegal = false;
20177 if (VT.isVector())
20178 isLegal = Subtarget->hasMVEIntegerOps() &&
20179 getMVEIndexedAddressParts(Op, VT, Alignment, isSEXTLoad, IsMasked,
20180 Subtarget->isLittle(), Base, Offset,
20181 isInc, DAG);
20182 else {
20183 if (Subtarget->isThumb2())
20184 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20185 isInc, DAG);
20186 else
20187 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20188 isInc, DAG);
20189 }
20190 if (!isLegal)
20191 return false;
20192
20193 if (Ptr != Base) {
20194 // Swap base ptr and offset to catch more post-index load / store when
20195 // it's legal. In Thumb2 mode, offset must be an immediate.
20196 if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
20197 !Subtarget->isThumb2())
20199
20200 // Post-indexed load / store update the base pointer.
20201 if (Ptr != Base)
20202 return false;
20203 }
20204
20205 AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
20206 return true;
20207}
20208
20211 const APInt &DemandedElts,
20212 const SelectionDAG &DAG,
20213 unsigned Depth) const {
20214 unsigned BitWidth = Known.getBitWidth();
20215 Known.resetAll();
20216 switch (Op.getOpcode()) {
20217 default: break;
20218 case ARMISD::ADDC:
20219 case ARMISD::ADDE:
20220 case ARMISD::SUBC:
20221 case ARMISD::SUBE:
20222 // Special cases when we convert a carry to a boolean.
20223 if (Op.getResNo() == 0) {
20224 SDValue LHS = Op.getOperand(0);
20225 SDValue RHS = Op.getOperand(1);
20226 // (ADDE 0, 0, C) will give us a single bit.
20227 if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
20228 isNullConstant(RHS)) {
20230 return;
20231 }
20232 }
20233 break;
20234 case ARMISD::CMOV: {
20235 // Bits are known zero/one if known on the LHS and RHS.
20236 Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
20237 if (Known.isUnknown())
20238 return;
20239
20240 KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
20241 Known = Known.intersectWith(KnownRHS);
20242 return;
20243 }
20245 Intrinsic::ID IntID =
20246 static_cast<Intrinsic::ID>(Op->getConstantOperandVal(1));
20247 switch (IntID) {
20248 default: return;
20249 case Intrinsic::arm_ldaex:
20250 case Intrinsic::arm_ldrex: {
20251 EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
20252 unsigned MemBits = VT.getScalarSizeInBits();
20253 Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20254 return;
20255 }
20256 }
20257 }
20258 case ARMISD::BFI: {
20259 // Conservatively, we can recurse down the first operand
20260 // and just mask out all affected bits.
20261 Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20262
20263 // The operand to BFI is already a mask suitable for removing the bits it
20264 // sets.
20265 const APInt &Mask = Op.getConstantOperandAPInt(2);
20266 Known.Zero &= Mask;
20267 Known.One &= Mask;
20268 return;
20269 }
20270 case ARMISD::VGETLANEs:
20271 case ARMISD::VGETLANEu: {
20272 const SDValue &SrcSV = Op.getOperand(0);
20273 EVT VecVT = SrcSV.getValueType();
20274 assert(VecVT.isVector() && "VGETLANE expected a vector type");
20275 const unsigned NumSrcElts = VecVT.getVectorNumElements();
20276 ConstantSDNode *Pos = cast<ConstantSDNode>(Op.getOperand(1).getNode());
20277 assert(Pos->getAPIntValue().ult(NumSrcElts) &&
20278 "VGETLANE index out of bounds");
20279 unsigned Idx = Pos->getZExtValue();
20280 APInt DemandedElt = APInt::getOneBitSet(NumSrcElts, Idx);
20281 Known = DAG.computeKnownBits(SrcSV, DemandedElt, Depth + 1);
20282
20283 EVT VT = Op.getValueType();
20284 const unsigned DstSz = VT.getScalarSizeInBits();
20285 const unsigned SrcSz = VecVT.getVectorElementType().getSizeInBits();
20286 (void)SrcSz;
20287 assert(SrcSz == Known.getBitWidth());
20288 assert(DstSz > SrcSz);
20289 if (Op.getOpcode() == ARMISD::VGETLANEs)
20290 Known = Known.sext(DstSz);
20291 else {
20292 Known = Known.zext(DstSz);
20293 }
20294 assert(DstSz == Known.getBitWidth());
20295 break;
20296 }
20297 case ARMISD::VMOVrh: {
20298 KnownBits KnownOp = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20299 assert(KnownOp.getBitWidth() == 16);
20300 Known = KnownOp.zext(32);
20301 break;
20302 }
20303 case ARMISD::CSINC:
20304 case ARMISD::CSINV:
20305 case ARMISD::CSNEG: {
20306 KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20307 KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
20308
20309 // The result is either:
20310 // CSINC: KnownOp0 or KnownOp1 + 1
20311 // CSINV: KnownOp0 or ~KnownOp1
20312 // CSNEG: KnownOp0 or KnownOp1 * -1
20313 if (Op.getOpcode() == ARMISD::CSINC)
20314 KnownOp1 =
20315 KnownBits::add(KnownOp1, KnownBits::makeConstant(APInt(32, 1)));
20316 else if (Op.getOpcode() == ARMISD::CSINV)
20317 std::swap(KnownOp1.Zero, KnownOp1.One);
20318 else if (Op.getOpcode() == ARMISD::CSNEG)
20319 KnownOp1 = KnownBits::mul(KnownOp1,
20321
20322 Known = KnownOp0.intersectWith(KnownOp1);
20323 break;
20324 }
20325 case ARMISD::VORRIMM:
20326 case ARMISD::VBICIMM: {
20327 unsigned Encoded = Op.getConstantOperandVal(1);
20328 unsigned DecEltBits = 0;
20329 uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
20330
20331 unsigned EltBits = Op.getScalarValueSizeInBits();
20332 if (EltBits != DecEltBits) {
20333 // Be conservative: only update Known when EltBits == DecEltBits.
20334 // This is believed to always be true for VORRIMM/VBICIMM today, but if
20335 // that changes in the future, doing nothing here is safer than risking
20336 // subtle bugs.
20337 break;
20338 }
20339
20340 KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20341 bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
20342 APInt Imm(DecEltBits, DecodedVal);
20343
20344 Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
20345 Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
20346 break;
20347 }
20348 }
20349}
20350
20351static bool isLegalLogicalImmediate(unsigned Imm,
20352 const ARMSubtarget *Subtarget) {
20353 if (!Subtarget->isThumb())
20354 return ARM_AM::getSOImmVal(Imm) != -1;
20355 if (Subtarget->isThumb2())
20356 return ARM_AM::getT2SOImmVal(Imm) != -1;
20357 // Thumb1 only has 8-bit unsigned immediate.
20358 return Imm <= 255;
20359}
20360
20361/// Refine i32 AND/OR/XOR with a constant RHS using demanded bits: replace the
20362/// immediate with an equivalent constant that ARM/Thumb can encode as a
20363/// logical immediate (or that selects better lowering), without changing the
20364/// computed result on those demanded bits.
20365static bool optimizeLogicalImm(SDValue Op, unsigned Imm,
20366 const APInt &DemandedBits,
20367 const ARMSubtarget *Subtarget,
20369
20370 if (Imm == 0 || Imm == ~0U)
20371 return false;
20372
20373 unsigned Opc = Op.getOpcode();
20374 unsigned Demanded = DemandedBits.getZExtValue();
20375 EVT VT = Op.getValueType();
20376
20377 unsigned ShrunkImm = Imm & Demanded;
20378 unsigned ExpandedImm = Imm | ~Demanded;
20379
20380 auto IsLegalImm = [ShrunkImm, ExpandedImm](unsigned CandidateImm) -> bool {
20381 return (ShrunkImm & CandidateImm) == ShrunkImm &&
20382 (~ExpandedImm & CandidateImm) == 0;
20383 };
20384 auto UseImm = [Imm, Opc, Op, VT, &TLO](unsigned NewImm) -> bool {
20385 if (NewImm == Imm)
20386 return true;
20387 SDLoc DL(Op);
20388 SDValue NewC = TLO.DAG.getConstant(NewImm, DL, VT);
20389 SDValue NewOp =
20390 TLO.DAG.getNode(Opc, DL, VT, Op.getOperand(0), NewC, Op->getFlags());
20391 return TLO.CombineTo(Op, NewOp);
20392 };
20393
20394 // Shrunk immediate is 0: AND becomes zero; OR/XOR with 0 leaves the other
20395 // operand (still valid on demanded bits).
20396 if (ShrunkImm == 0) {
20397 ++NumOptimizedImms;
20398 return UseImm(ShrunkImm);
20399 }
20400
20401 // If the immediate is all ones: for AND this removes the operation; for
20402 // OR/XOR it remains a transform valid on demanded bits. (Target-independent
20403 // shrink may not fold this, so keep it to avoid obscure combine loops.)
20404 if (ExpandedImm == ~0U) {
20405 ++NumOptimizedImms;
20406 return UseImm(ExpandedImm);
20407 }
20408
20409 // Thumb1: prefer 0xFF / 0xFFFF when they fit the demanded-bit envelope so
20410 // lowering can match uxtb / uxth (AND immediates only; OR/XOR do not use
20411 // that). Run this before strict ShrunkImm: a tight 8-bit ShrunkImm can be
20412 // legal while 0xFF still matches the envelope and yields better isel (uxtb).
20413 if (Opc == ISD::AND && Subtarget->hasV6Ops()) {
20414 if (IsLegalImm(0xFF)) {
20415 ++NumOptimizedImms;
20416 return UseImm(0xFF);
20417 }
20418
20419 if (IsLegalImm(0xFFFF)) {
20420 ++NumOptimizedImms;
20421 return UseImm(0xFFFF);
20422 }
20423 }
20424
20425 // Don't optimize if it is legal.
20426 if (isLegalLogicalImmediate(Imm, Subtarget))
20427 return false;
20428
20429 // FIXME: Check for BIC being legal causes infinite loop due to target
20430 // independent DAG combine undoing this.
20431
20432 // Prefer strict shrink when ShrunkImm encodes for this target, before
20433 // complement expansion.
20434 if (isLegalLogicalImmediate(ShrunkImm, Subtarget)) {
20435 ++NumOptimizedImms;
20436 return UseImm(ShrunkImm);
20437 }
20438
20439 // Complement expansion: if all undemanded bits are already one, ExpandedImm
20440 // is Imm with every non-demanded bit set. When (~ExpandedImm) < 256, the
20441 // complement fits in an 8-bit unsigned value, i.e. bits 8–31 of ExpandedImm
20442 // are all ones; only the low byte may differ from ~0. Use that expanded
20443 // constant so isel sees a mask shape that fits logical-immediate patterns.
20444 if ((~ExpandedImm) < 256) {
20445 ++NumOptimizedImms;
20446 return UseImm(ExpandedImm);
20447 }
20448
20449 // FIXME: The check for v6 is because this interferes with some ubfx
20450 // optimizations.
20451 if (Opc == ISD::AND && isLegalLogicalImmediate(~ExpandedImm, Subtarget) &&
20452 !Subtarget->hasV6Ops()) {
20453 ++NumOptimizedImms;
20454 return UseImm(ExpandedImm);
20455 }
20456
20457 // Potential improvements:
20458 //
20459 // We could try to recognize lsls+lsrs or lsrs+lsls pairs here.
20460 // We could try to prefer Thumb1 immediates which can be lowered to a
20461 // two-instruction sequence.
20462
20463 return false;
20464}
20465
20467 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
20468 TargetLoweringOpt &TLO) const {
20469 // Delay this optimization to as late as possible.
20470 if (!TLO.LegalOps)
20471 return false;
20472
20473 EVT VT = Op.getValueType();
20474
20475 // Ignore vectors.
20476 if (VT.isVector())
20477 return false;
20478
20479 unsigned Size = VT.getSizeInBits();
20480
20481 if (Size != 32)
20482 return false;
20483
20484 // Exit early if we demand all bits.
20485 if (DemandedBits.isAllOnes())
20486 return false;
20487
20488 switch (Op.getOpcode()) {
20489 default:
20490 return false;
20491 case ISD::AND:
20492 case ISD::OR:
20493 case ISD::XOR:
20494 break;
20495 }
20496 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20497 if (!C)
20498 return false;
20499 unsigned Imm = C->getZExtValue();
20500 return optimizeLogicalImm(Op, Imm, DemandedBits, Subtarget, TLO);
20501}
20502
20504 SDValue Op, const APInt &OriginalDemandedBits,
20505 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
20506 unsigned Depth) const {
20507 unsigned Opc = Op.getOpcode();
20508
20509 switch (Opc) {
20510 case ARMISD::ASRL:
20511 case ARMISD::LSRL: {
20512 // If this is result 0 and the other result is unused, see if the demand
20513 // bits allow us to shrink this long shift into a standard small shift in
20514 // the opposite direction.
20515 if (Op.getResNo() == 0 && !Op->hasAnyUseOfValue(1) &&
20516 isa<ConstantSDNode>(Op->getOperand(2))) {
20517 unsigned ShAmt = Op->getConstantOperandVal(2);
20518 if (ShAmt < 32 && OriginalDemandedBits.isSubsetOf(APInt::getAllOnes(32)
20519 << (32 - ShAmt)))
20520 return TLO.CombineTo(
20521 Op, TLO.DAG.getNode(
20522 ISD::SHL, SDLoc(Op), MVT::i32, Op.getOperand(1),
20523 TLO.DAG.getConstant(32 - ShAmt, SDLoc(Op), MVT::i32)));
20524 }
20525 break;
20526 }
20527 case ARMISD::VBICIMM: {
20528 SDValue Op0 = Op.getOperand(0);
20529 unsigned ModImm = Op.getConstantOperandVal(1);
20530 unsigned EltBits = 0;
20531 uint64_t Mask = ARM_AM::decodeVMOVModImm(ModImm, EltBits);
20532 if ((OriginalDemandedBits & Mask) == 0)
20533 return TLO.CombineTo(Op, Op0);
20534 }
20535 }
20536
20538 Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
20539}
20540
20541//===----------------------------------------------------------------------===//
20542// ARM Inline Assembly Support
20543//===----------------------------------------------------------------------===//
20544
20545const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
20546 // At this point, we have to lower this constraint to something else, so we
20547 // lower it to an "r" or "w". However, by doing this we will force the result
20548 // to be in register, while the X constraint is much more permissive.
20549 //
20550 // Although we are correct (we are free to emit anything, without
20551 // constraints), we might break use cases that would expect us to be more
20552 // efficient and emit something else.
20553 if (!Subtarget->hasVFP2Base())
20554 return "r";
20555 if (ConstraintVT.isFloatingPoint())
20556 return "w";
20557 if (ConstraintVT.isVector() && Subtarget->hasNEON() &&
20558 (ConstraintVT.getSizeInBits() == 64 ||
20559 ConstraintVT.getSizeInBits() == 128))
20560 return "w";
20561
20562 return "r";
20563}
20564
20565/// getConstraintType - Given a constraint letter, return the type of
20566/// constraint it is for this target.
20569 unsigned S = Constraint.size();
20570 if (S == 1) {
20571 switch (Constraint[0]) {
20572 default: break;
20573 case 'l': return C_RegisterClass;
20574 case 'w': return C_RegisterClass;
20575 case 'h': return C_RegisterClass;
20576 case 'x': return C_RegisterClass;
20577 case 't': return C_RegisterClass;
20578 case 'j': return C_Immediate; // Constant for movw.
20579 // An address with a single base register. Due to the way we
20580 // currently handle addresses it is the same as an 'r' memory constraint.
20581 case 'Q': return C_Memory;
20582 }
20583 } else if (S == 2) {
20584 switch (Constraint[0]) {
20585 default: break;
20586 case 'T': return C_RegisterClass;
20587 // All 'U+' constraints are addresses.
20588 case 'U': return C_Memory;
20589 }
20590 }
20591 return TargetLowering::getConstraintType(Constraint);
20592}
20593
20594/// Examine constraint type and operand type and determine a weight value.
20595/// This object must already have been set up with the operand type
20596/// and the current alternative constraint selected.
20599 AsmOperandInfo &info, const char *constraint) const {
20601 Value *CallOperandVal = info.CallOperandVal;
20602 // If we don't have a value, we can't do a match,
20603 // but allow it at the lowest weight.
20604 if (!CallOperandVal)
20605 return CW_Default;
20606 Type *type = CallOperandVal->getType();
20607 // Look at the constraint type.
20608 switch (*constraint) {
20609 default:
20611 break;
20612 case 'l':
20613 if (type->isIntegerTy()) {
20614 if (Subtarget->isThumb())
20615 weight = CW_SpecificReg;
20616 else
20617 weight = CW_Register;
20618 }
20619 break;
20620 case 'w':
20621 if (type->isFloatingPointTy())
20622 weight = CW_Register;
20623 break;
20624 }
20625 return weight;
20626}
20627
20628static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
20629 if (PR == 0 || VT == MVT::Other)
20630 return false;
20631 if (ARM::SPRRegClass.contains(PR))
20632 return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32;
20633 if (ARM::DPRRegClass.contains(PR))
20634 return VT != MVT::f64 && !VT.is64BitVector();
20635 return false;
20636}
20637
20638using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
20639
20641 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
20642 switch (Constraint.size()) {
20643 case 1:
20644 // GCC ARM Constraint Letters
20645 switch (Constraint[0]) {
20646 case 'l': // Low regs or general regs.
20647 if (Subtarget->isThumb())
20648 return RCPair(0U, &ARM::tGPRRegClass);
20649 return RCPair(0U, &ARM::GPRRegClass);
20650 case 'h': // High regs or no regs.
20651 if (Subtarget->isThumb())
20652 return RCPair(0U, &ARM::hGPRRegClass);
20653 break;
20654 case 'r':
20655 if (Subtarget->isThumb1Only())
20656 return RCPair(0U, &ARM::tGPRRegClass);
20657 return RCPair(0U, &ARM::GPRRegClass);
20658 case 'w':
20659 if (VT == MVT::Other)
20660 break;
20661 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20662 return RCPair(0U, &ARM::SPRRegClass);
20663 if (VT.getSizeInBits() == 64)
20664 return RCPair(0U, &ARM::DPRRegClass);
20665 if (VT.getSizeInBits() == 128)
20666 return RCPair(0U, &ARM::QPRRegClass);
20667 break;
20668 case 'x':
20669 if (VT == MVT::Other)
20670 break;
20671 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20672 return RCPair(0U, &ARM::SPR_8RegClass);
20673 if (VT.getSizeInBits() == 64)
20674 return RCPair(0U, &ARM::DPR_8RegClass);
20675 if (VT.getSizeInBits() == 128)
20676 return RCPair(0U, &ARM::QPR_8RegClass);
20677 break;
20678 case 't':
20679 if (VT == MVT::Other)
20680 break;
20681 if (VT == MVT::f32 || VT == MVT::i32 || VT == MVT::f16 || VT == MVT::bf16)
20682 return RCPair(0U, &ARM::SPRRegClass);
20683 if (VT.getSizeInBits() == 64)
20684 return RCPair(0U, &ARM::DPR_VFP2RegClass);
20685 if (VT.getSizeInBits() == 128)
20686 return RCPair(0U, &ARM::QPR_VFP2RegClass);
20687 break;
20688 }
20689 break;
20690
20691 case 2:
20692 if (Constraint[0] == 'T') {
20693 switch (Constraint[1]) {
20694 default:
20695 break;
20696 case 'e':
20697 return RCPair(0U, &ARM::tGPREvenRegClass);
20698 case 'o':
20699 return RCPair(0U, &ARM::tGPROddRegClass);
20700 }
20701 }
20702 break;
20703
20704 default:
20705 break;
20706 }
20707
20708 if (StringRef("{cc}").equals_insensitive(Constraint))
20709 return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
20710
20711 // r14 is an alias of lr.
20712 if (StringRef("{r14}").equals_insensitive(Constraint))
20713 return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32));
20714
20715 auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
20716 if (isIncompatibleReg(RCP.first, VT))
20717 return {0, nullptr};
20718 return RCP;
20719}
20720
20721/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
20722/// vector. If it is invalid, don't add anything to Ops.
20724 StringRef Constraint,
20725 std::vector<SDValue> &Ops,
20726 SelectionDAG &DAG) const {
20727 SDValue Result;
20728
20729 // Currently only support length 1 constraints.
20730 if (Constraint.size() != 1)
20731 return;
20732
20733 char ConstraintLetter = Constraint[0];
20734 switch (ConstraintLetter) {
20735 default: break;
20736 case 'j':
20737 case 'I': case 'J': case 'K': case 'L':
20738 case 'M': case 'N': case 'O':
20740 if (!C)
20741 return;
20742
20743 int64_t CVal64 = C->getSExtValue();
20744 int CVal = (int) CVal64;
20745 // None of these constraints allow values larger than 32 bits. Check
20746 // that the value fits in an int.
20747 if (CVal != CVal64)
20748 return;
20749
20750 switch (ConstraintLetter) {
20751 case 'j':
20752 // Constant suitable for movw, must be between 0 and
20753 // 65535.
20754 if (Subtarget->hasV6T2Ops() || (Subtarget->hasV8MBaselineOps()))
20755 if (CVal >= 0 && CVal <= 65535)
20756 break;
20757 return;
20758 case 'I':
20759 if (Subtarget->isThumb1Only()) {
20760 // This must be a constant between 0 and 255, for ADD
20761 // immediates.
20762 if (CVal >= 0 && CVal <= 255)
20763 break;
20764 } else if (Subtarget->isThumb2()) {
20765 // A constant that can be used as an immediate value in a
20766 // data-processing instruction.
20767 if (ARM_AM::getT2SOImmVal(CVal) != -1)
20768 break;
20769 } else {
20770 // A constant that can be used as an immediate value in a
20771 // data-processing instruction.
20772 if (ARM_AM::getSOImmVal(CVal) != -1)
20773 break;
20774 }
20775 return;
20776
20777 case 'J':
20778 if (Subtarget->isThumb1Only()) {
20779 // This must be a constant between -255 and -1, for negated ADD
20780 // immediates. This can be used in GCC with an "n" modifier that
20781 // prints the negated value, for use with SUB instructions. It is
20782 // not useful otherwise but is implemented for compatibility.
20783 if (CVal >= -255 && CVal <= -1)
20784 break;
20785 } else {
20786 // This must be a constant between -4095 and 4095. This is suitable
20787 // for use as the immediate offset field in LDR and STR instructions
20788 // such as LDR r0,[r1,#offset].
20789 if (CVal >= -4095 && CVal <= 4095)
20790 break;
20791 }
20792 return;
20793
20794 case 'K':
20795 if (Subtarget->isThumb1Only()) {
20796 // A 32-bit value where only one byte has a nonzero value. Exclude
20797 // zero to match GCC. This constraint is used by GCC internally for
20798 // constants that can be loaded with a move/shift combination.
20799 // It is not useful otherwise but is implemented for compatibility.
20800 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal))
20801 break;
20802 } else if (Subtarget->isThumb2()) {
20803 // A constant whose bitwise inverse can be used as an immediate
20804 // value in a data-processing instruction. This can be used in GCC
20805 // with a "B" modifier that prints the inverted value, for use with
20806 // BIC and MVN instructions. It is not useful otherwise but is
20807 // implemented for compatibility.
20808 if (ARM_AM::getT2SOImmVal(~CVal) != -1)
20809 break;
20810 } else {
20811 // A constant whose bitwise inverse can be used as an immediate
20812 // value in a data-processing instruction. This can be used in GCC
20813 // with a "B" modifier that prints the inverted value, for use with
20814 // BIC and MVN instructions. It is not useful otherwise but is
20815 // implemented for compatibility.
20816 if (ARM_AM::getSOImmVal(~CVal) != -1)
20817 break;
20818 }
20819 return;
20820
20821 case 'L':
20822 if (Subtarget->isThumb1Only()) {
20823 // This must be a constant between -7 and 7,
20824 // for 3-operand ADD/SUB immediate instructions.
20825 if (CVal >= -7 && CVal < 7)
20826 break;
20827 } else if (Subtarget->isThumb2()) {
20828 // A constant whose negation can be used as an immediate value in a
20829 // data-processing instruction. This can be used in GCC with an "n"
20830 // modifier that prints the negated value, for use with SUB
20831 // instructions. It is not useful otherwise but is implemented for
20832 // compatibility.
20833 if (ARM_AM::getT2SOImmVal(-CVal) != -1)
20834 break;
20835 } else {
20836 // A constant whose negation can be used as an immediate value in a
20837 // data-processing instruction. This can be used in GCC with an "n"
20838 // modifier that prints the negated value, for use with SUB
20839 // instructions. It is not useful otherwise but is implemented for
20840 // compatibility.
20841 if (ARM_AM::getSOImmVal(-CVal) != -1)
20842 break;
20843 }
20844 return;
20845
20846 case 'M':
20847 if (Subtarget->isThumb1Only()) {
20848 // This must be a multiple of 4 between 0 and 1020, for
20849 // ADD sp + immediate.
20850 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0))
20851 break;
20852 } else {
20853 // A power of two or a constant between 0 and 32. This is used in
20854 // GCC for the shift amount on shifted register operands, but it is
20855 // useful in general for any shift amounts.
20856 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0))
20857 break;
20858 }
20859 return;
20860
20861 case 'N':
20862 if (Subtarget->isThumb1Only()) {
20863 // This must be a constant between 0 and 31, for shift amounts.
20864 if (CVal >= 0 && CVal <= 31)
20865 break;
20866 }
20867 return;
20868
20869 case 'O':
20870 if (Subtarget->isThumb1Only()) {
20871 // This must be a multiple of 4 between -508 and 508, for
20872 // ADD/SUB sp = sp + immediate.
20873 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0))
20874 break;
20875 }
20876 return;
20877 }
20878 Result = DAG.getSignedTargetConstant(CVal, SDLoc(Op), Op.getValueType());
20879 break;
20880 }
20881
20882 if (Result.getNode()) {
20883 Ops.push_back(Result);
20884 return;
20885 }
20886 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
20887}
20888
20889static RTLIB::Libcall getDivRemLibcall(
20890 const SDNode *N, MVT::SimpleValueType SVT) {
20891 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20892 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20893 "Unhandled Opcode in getDivRemLibcall");
20894 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20895 N->getOpcode() == ISD::SREM;
20896 RTLIB::Libcall LC;
20897 switch (SVT) {
20898 default: llvm_unreachable("Unexpected request for libcall!");
20899 case MVT::i8: LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break;
20900 case MVT::i16: LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break;
20901 case MVT::i32: LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break;
20902 case MVT::i64: LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break;
20903 }
20904 return LC;
20905}
20906
20908 const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
20909 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20910 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20911 "Unhandled Opcode in getDivRemArgList");
20912 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20913 N->getOpcode() == ISD::SREM;
20915 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
20916 EVT ArgVT = N->getOperand(i).getValueType();
20917 Type *ArgTy = ArgVT.getTypeForEVT(*Context);
20918 TargetLowering::ArgListEntry Entry(N->getOperand(i), ArgTy);
20919 Entry.IsSExt = isSigned;
20920 Entry.IsZExt = !isSigned;
20921 Args.push_back(Entry);
20922 }
20923 if (Subtarget->getTargetTriple().isOSWindows() && Args.size() >= 2)
20924 std::swap(Args[0], Args[1]);
20925 return Args;
20926}
20927
20928SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
20929 assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
20930 Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
20931 Subtarget->isTargetFuchsia() || Subtarget->isTargetWindows()) &&
20932 "Register-based DivRem lowering only");
20933 unsigned Opcode = Op->getOpcode();
20934 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
20935 "Invalid opcode for Div/Rem lowering");
20936 bool isSigned = (Opcode == ISD::SDIVREM);
20937 EVT VT = Op->getValueType(0);
20938 SDLoc dl(Op);
20939
20940 if (VT == MVT::i64 && isa<ConstantSDNode>(Op.getOperand(1))) {
20942 if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i32, DAG)) {
20943 SDValue Res0 =
20944 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[0], Result[1]);
20945 SDValue Res1 =
20946 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[2], Result[3]);
20947 return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
20948 {Res0, Res1});
20949 }
20950 }
20951
20952 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
20953
20954 // If the target has hardware divide, use divide + multiply + subtract:
20955 // div = a / b
20956 // rem = a - b * div
20957 // return {div, rem}
20958 // This should be lowered into UDIV/SDIV + MLS later on.
20959 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
20960 : Subtarget->hasDivideInARMMode();
20961 if (hasDivide && Op->getValueType(0).isSimple() &&
20962 Op->getSimpleValueType(0) == MVT::i32) {
20963 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
20964 const SDValue Dividend = Op->getOperand(0);
20965 const SDValue Divisor = Op->getOperand(1);
20966 SDValue Div = DAG.getNode(DivOpcode, dl, VT, Dividend, Divisor);
20967 SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Div, Divisor);
20968 SDValue Rem = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
20969
20970 SDValue Values[2] = {Div, Rem};
20971 return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VT, VT), Values);
20972 }
20973
20974 RTLIB::Libcall LC = getDivRemLibcall(Op.getNode(),
20975 VT.getSimpleVT().SimpleTy);
20976 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
20977
20978 SDValue InChain = DAG.getEntryNode();
20979
20981 DAG.getContext(),
20982 Subtarget);
20983
20984 SDValue Callee =
20985 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
20986
20987 Type *RetTy = StructType::get(Ty, Ty);
20988
20989 if (getTM().getTargetTriple().isOSWindows())
20990 InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
20991
20992 TargetLowering::CallLoweringInfo CLI(DAG);
20993 CLI.setDebugLoc(dl)
20994 .setChain(InChain)
20995 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
20996 Callee, std::move(Args))
20997 .setInRegister()
21000
21001 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
21002 return CallInfo.first;
21003}
21004
21005// Lowers REM using divmod helpers
21006// see RTABI section 4.2/4.3
21007SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
21008 EVT VT = N->getValueType(0);
21009
21010 if (VT == MVT::i64 && isa<ConstantSDNode>(N->getOperand(1))) {
21012 if (expandDIVREMByConstant(N, Result, MVT::i32, DAG))
21013 return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), N->getValueType(0),
21014 Result[0], Result[1]);
21015 }
21016
21017 // Build return types (div and rem)
21018 std::vector<Type*> RetTyParams;
21019 Type *RetTyElement;
21020
21021 switch (VT.getSimpleVT().SimpleTy) {
21022 default: llvm_unreachable("Unexpected request for libcall!");
21023 case MVT::i8: RetTyElement = Type::getInt8Ty(*DAG.getContext()); break;
21024 case MVT::i16: RetTyElement = Type::getInt16Ty(*DAG.getContext()); break;
21025 case MVT::i32: RetTyElement = Type::getInt32Ty(*DAG.getContext()); break;
21026 case MVT::i64: RetTyElement = Type::getInt64Ty(*DAG.getContext()); break;
21027 }
21028
21029 RetTyParams.push_back(RetTyElement);
21030 RetTyParams.push_back(RetTyElement);
21031 ArrayRef<Type*> ret = ArrayRef<Type*>(RetTyParams);
21032 Type *RetTy = StructType::get(*DAG.getContext(), ret);
21033
21034 RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
21035 SimpleTy);
21036 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21037 SDValue InChain = DAG.getEntryNode();
21039 Subtarget);
21040 bool isSigned = N->getOpcode() == ISD::SREM;
21041
21042 SDValue Callee =
21043 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21044
21045 if (getTM().getTargetTriple().isOSWindows())
21046 InChain = WinDBZCheckDenominator(DAG, N, InChain);
21047
21048 // Lower call
21049 CallLoweringInfo CLI(DAG);
21050 CLI.setChain(InChain)
21051 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21052 Callee, std::move(Args))
21055 .setDebugLoc(SDLoc(N));
21056 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
21057
21058 // Return second (rem) result operand (first contains div)
21059 SDNode *ResNode = CallResult.first.getNode();
21060 assert(ResNode->getNumOperands() == 2 && "divmod should return two operands");
21061 return ResNode->getOperand(1);
21062}
21063
21064SDValue
21065ARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
21066 assert(getTM().getTargetTriple().isOSWindows() &&
21067 "unsupported target platform");
21068 SDLoc DL(Op);
21069
21070 // Get the inputs.
21071 SDValue Chain = Op.getOperand(0);
21072 SDValue Size = Op.getOperand(1);
21073
21075 "no-stack-arg-probe")) {
21076 MaybeAlign Align =
21077 cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
21078 SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21079 Chain = SP.getValue(1);
21080 SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
21081 if (Align)
21082 SP = DAG.getNode(ISD::AND, DL, MVT::i32, SP.getValue(0),
21083 DAG.getSignedConstant(-Align->value(), DL, MVT::i32));
21084 Chain = DAG.getCopyToReg(Chain, DL, ARM::SP, SP);
21085 SDValue Ops[2] = { SP, Chain };
21086 return DAG.getMergeValues(Ops, DL);
21087 }
21088
21089 SDValue Words = DAG.getNode(ISD::SRL, DL, MVT::i32, Size,
21090 DAG.getConstant(2, DL, MVT::i32));
21091
21092 SDValue Glue;
21093 Chain = DAG.getCopyToReg(Chain, DL, ARM::R4, Words, Glue);
21094 Glue = Chain.getValue(1);
21095
21096 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
21097 Chain = DAG.getNode(ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Glue);
21098
21099 SDValue NewSP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21100 Chain = NewSP.getValue(1);
21101
21102 SDValue Ops[2] = { NewSP, Chain };
21103 return DAG.getMergeValues(Ops, DL);
21104}
21105
21106SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
21107 bool IsStrict = Op->isStrictFPOpcode();
21108 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21109 const unsigned DstSz = Op.getValueType().getSizeInBits();
21110 const unsigned SrcSz = SrcVal.getValueType().getSizeInBits();
21111 assert(DstSz > SrcSz && DstSz <= 64 && SrcSz >= 16 &&
21112 "Unexpected type for custom-lowering FP_EXTEND");
21113
21114 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21115 "With both FP DP and 16, any FP conversion is legal!");
21116
21117 assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
21118 "With FP16, 16 to 32 conversion is legal!");
21119
21120 // Converting from 32 -> 64 is valid if we have FP64.
21121 if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
21122 // FIXME: Remove this when we have strict fp instruction selection patterns
21123 if (IsStrict) {
21124 SDLoc Loc(Op);
21125 SDValue Result = DAG.getNode(ISD::FP_EXTEND,
21126 Loc, Op.getValueType(), SrcVal);
21127 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
21128 }
21129 return Op;
21130 }
21131
21132 // Either we are converting from 16 -> 64, without FP16 and/or
21133 // FP.double-precision or without Armv8-fp. So we must do it in two
21134 // steps.
21135 // Or we are converting from 32 -> 64 without fp.double-precision or 16 -> 32
21136 // without FP16. So we must do a function call.
21137 SDLoc Loc(Op);
21138 RTLIB::Libcall LC;
21139 MakeLibCallOptions CallOptions;
21140 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21141 for (unsigned Sz = SrcSz; Sz <= 32 && Sz < DstSz; Sz *= 2) {
21142 bool Supported = (Sz == 16 ? Subtarget->hasFP16() : Subtarget->hasFP64());
21143 MVT SrcVT = (Sz == 16 ? MVT::f16 : MVT::f32);
21144 MVT DstVT = (Sz == 16 ? MVT::f32 : MVT::f64);
21145 if (Supported) {
21146 if (IsStrict) {
21147 SrcVal = DAG.getNode(ISD::STRICT_FP_EXTEND, Loc,
21148 {DstVT, MVT::Other}, {Chain, SrcVal});
21149 Chain = SrcVal.getValue(1);
21150 } else {
21151 SrcVal = DAG.getNode(ISD::FP_EXTEND, Loc, DstVT, SrcVal);
21152 }
21153 } else {
21154 LC = RTLIB::getFPEXT(SrcVT, DstVT);
21155 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21156 "Unexpected type for custom-lowering FP_EXTEND");
21157 std::tie(SrcVal, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21158 Loc, Chain);
21159 }
21160 }
21161
21162 return IsStrict ? DAG.getMergeValues({SrcVal, Chain}, Loc) : SrcVal;
21163}
21164
21165SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
21166 bool IsStrict = Op->isStrictFPOpcode();
21167
21168 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21169 EVT SrcVT = SrcVal.getValueType();
21170 EVT DstVT = Op.getValueType();
21171
21172 if (DstVT == MVT::bf16) {
21173 if (Subtarget->hasBF16() && SrcVT == MVT::f32)
21174 return Op;
21175 return SDValue();
21176 }
21177
21178 const unsigned DstSz = Op.getValueType().getSizeInBits();
21179 const unsigned SrcSz = SrcVT.getSizeInBits();
21180 (void)DstSz;
21181 assert(DstSz < SrcSz && SrcSz <= 64 && DstSz >= 16 &&
21182 "Unexpected type for custom-lowering FP_ROUND");
21183
21184 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21185 "With both FP DP and 16, any FP conversion is legal!");
21186
21187 SDLoc Loc(Op);
21188
21189 // Instruction from 32 -> 16 if hasFP16 is valid
21190 if (SrcSz == 32 && Subtarget->hasFP16())
21191 return Op;
21192
21193 // Lib call from 32 -> 16 / 64 -> [32, 16]
21194 RTLIB::Libcall LC = RTLIB::getFPROUND(SrcVT, DstVT);
21195 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21196 "Unexpected type for custom-lowering FP_ROUND");
21197 MakeLibCallOptions CallOptions;
21198 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21199 SDValue Result;
21200 std::tie(Result, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21201 Loc, Chain);
21202 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
21203}
21204
21205bool
21207 // The ARM target isn't yet aware of offsets.
21208 return false;
21209}
21210
21212 if (v == 0xffffffff)
21213 return false;
21214
21215 // there can be 1's on either or both "outsides", all the "inside"
21216 // bits must be 0's
21217 return isShiftedMask_32(~v);
21218}
21219
21220/// isFPImmLegal - Returns true if the target can instruction select the
21221/// specified FP immediate natively. If false, the legalizer will
21222/// materialize the FP immediate as a load from a constant pool.
21224 bool ForCodeSize) const {
21225 if (!Subtarget->hasVFP3Base())
21226 return false;
21227 if (VT == MVT::f16 && Subtarget->hasFullFP16())
21228 return ARM_AM::getFP16Imm(Imm) != -1;
21229 if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
21231 return true;
21232 if (VT == MVT::f32)
21233 return ARM_AM::getFP32Imm(Imm) != -1;
21234 if (VT == MVT::f64 && Subtarget->hasFP64())
21235 return ARM_AM::getFP64Imm(Imm) != -1;
21236 return false;
21237}
21238
21239/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
21240/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
21241/// specified in the intrinsic calls.
21244 MachineFunction &MF, unsigned Intrinsic) const {
21245 IntrinsicInfo Info;
21246 switch (Intrinsic) {
21247 case Intrinsic::arm_neon_vld1:
21248 case Intrinsic::arm_neon_vld2:
21249 case Intrinsic::arm_neon_vld3:
21250 case Intrinsic::arm_neon_vld4:
21251 case Intrinsic::arm_neon_vld2lane:
21252 case Intrinsic::arm_neon_vld3lane:
21253 case Intrinsic::arm_neon_vld4lane:
21254 case Intrinsic::arm_neon_vld2dup:
21255 case Intrinsic::arm_neon_vld3dup:
21256 case Intrinsic::arm_neon_vld4dup: {
21257 Info.opc = ISD::INTRINSIC_W_CHAIN;
21258 // Conservatively set memVT to the entire set of vectors loaded.
21259 auto &DL = I.getDataLayout();
21260 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21261 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21262 Info.ptrVal = I.getArgOperand(0);
21263 Info.offset = 0;
21264 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21265 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21266 // volatile loads with NEON intrinsics not supported
21267 Info.flags = MachineMemOperand::MOLoad;
21268 Infos.push_back(Info);
21269 return;
21270 }
21271 case Intrinsic::arm_neon_vld1x2:
21272 case Intrinsic::arm_neon_vld1x3:
21273 case Intrinsic::arm_neon_vld1x4: {
21274 Info.opc = ISD::INTRINSIC_W_CHAIN;
21275 // Conservatively set memVT to the entire set of vectors loaded.
21276 auto &DL = I.getDataLayout();
21277 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21278 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21279 Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
21280 Info.offset = 0;
21281 Info.align = I.getParamAlign(I.arg_size() - 1).valueOrOne();
21282 // volatile loads with NEON intrinsics not supported
21283 Info.flags = MachineMemOperand::MOLoad;
21284 Infos.push_back(Info);
21285 return;
21286 }
21287 case Intrinsic::arm_neon_vst1:
21288 case Intrinsic::arm_neon_vst2:
21289 case Intrinsic::arm_neon_vst3:
21290 case Intrinsic::arm_neon_vst4:
21291 case Intrinsic::arm_neon_vst2lane:
21292 case Intrinsic::arm_neon_vst3lane:
21293 case Intrinsic::arm_neon_vst4lane: {
21294 Info.opc = ISD::INTRINSIC_VOID;
21295 // Conservatively set memVT to the entire set of vectors stored.
21296 auto &DL = I.getDataLayout();
21297 unsigned NumElts = 0;
21298 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21299 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21300 if (!ArgTy->isVectorTy())
21301 break;
21302 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21303 }
21304 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21305 Info.ptrVal = I.getArgOperand(0);
21306 Info.offset = 0;
21307 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21308 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21309 // volatile stores with NEON intrinsics not supported
21310 Info.flags = MachineMemOperand::MOStore;
21311 Infos.push_back(Info);
21312 return;
21313 }
21314 case Intrinsic::arm_neon_vst1x2:
21315 case Intrinsic::arm_neon_vst1x3:
21316 case Intrinsic::arm_neon_vst1x4: {
21317 Info.opc = ISD::INTRINSIC_VOID;
21318 // Conservatively set memVT to the entire set of vectors stored.
21319 auto &DL = I.getDataLayout();
21320 unsigned NumElts = 0;
21321 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21322 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21323 if (!ArgTy->isVectorTy())
21324 break;
21325 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21326 }
21327 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21328 Info.ptrVal = I.getArgOperand(0);
21329 Info.offset = 0;
21330 Info.align = I.getParamAlign(0).valueOrOne();
21331 // volatile stores with NEON intrinsics not supported
21332 Info.flags = MachineMemOperand::MOStore;
21333 Infos.push_back(Info);
21334 return;
21335 }
21336 case Intrinsic::arm_mve_vld2q:
21337 case Intrinsic::arm_mve_vld4q: {
21338 Info.opc = ISD::INTRINSIC_W_CHAIN;
21339 // Conservatively set memVT to the entire set of vectors loaded.
21340 Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
21341 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
21342 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21343 Info.ptrVal = I.getArgOperand(0);
21344 Info.offset = 0;
21345 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21346 // volatile loads with MVE intrinsics not supported
21347 Info.flags = MachineMemOperand::MOLoad;
21348 Infos.push_back(Info);
21349 return;
21350 }
21351 case Intrinsic::arm_mve_vst2q:
21352 case Intrinsic::arm_mve_vst4q: {
21353 Info.opc = ISD::INTRINSIC_VOID;
21354 // Conservatively set memVT to the entire set of vectors stored.
21355 Type *VecTy = I.getArgOperand(1)->getType();
21356 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vst2q ? 2 : 4;
21357 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21358 Info.ptrVal = I.getArgOperand(0);
21359 Info.offset = 0;
21360 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21361 // volatile stores with MVE intrinsics not supported
21362 Info.flags = MachineMemOperand::MOStore;
21363 Infos.push_back(Info);
21364 return;
21365 }
21366 case Intrinsic::arm_mve_vldr_gather_base:
21367 case Intrinsic::arm_mve_vldr_gather_base_predicated: {
21368 Info.opc = ISD::INTRINSIC_W_CHAIN;
21369 Info.ptrVal = nullptr;
21370 Info.memVT = MVT::getVT(I.getType());
21371 Info.align = Align(1);
21372 Info.flags |= MachineMemOperand::MOLoad;
21373 Infos.push_back(Info);
21374 return;
21375 }
21376 case Intrinsic::arm_mve_vldr_gather_base_wb:
21377 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: {
21378 Info.opc = ISD::INTRINSIC_W_CHAIN;
21379 Info.ptrVal = nullptr;
21380 Info.memVT = MVT::getVT(I.getType()->getContainedType(0));
21381 Info.align = Align(1);
21382 Info.flags |= MachineMemOperand::MOLoad;
21383 Infos.push_back(Info);
21384 return;
21385 }
21386 case Intrinsic::arm_mve_vldr_gather_offset:
21387 case Intrinsic::arm_mve_vldr_gather_offset_predicated: {
21388 Info.opc = ISD::INTRINSIC_W_CHAIN;
21389 Info.ptrVal = nullptr;
21390 MVT DataVT = MVT::getVT(I.getType());
21391 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
21392 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21393 DataVT.getVectorNumElements());
21394 Info.align = Align(1);
21395 Info.flags |= MachineMemOperand::MOLoad;
21396 Infos.push_back(Info);
21397 return;
21398 }
21399 case Intrinsic::arm_mve_vstr_scatter_base:
21400 case Intrinsic::arm_mve_vstr_scatter_base_predicated: {
21401 Info.opc = ISD::INTRINSIC_VOID;
21402 Info.ptrVal = nullptr;
21403 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21404 Info.align = Align(1);
21405 Info.flags |= MachineMemOperand::MOStore;
21406 Infos.push_back(Info);
21407 return;
21408 }
21409 case Intrinsic::arm_mve_vstr_scatter_base_wb:
21410 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated: {
21411 Info.opc = ISD::INTRINSIC_W_CHAIN;
21412 Info.ptrVal = nullptr;
21413 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21414 Info.align = Align(1);
21415 Info.flags |= MachineMemOperand::MOStore;
21416 Infos.push_back(Info);
21417 return;
21418 }
21419 case Intrinsic::arm_mve_vstr_scatter_offset:
21420 case Intrinsic::arm_mve_vstr_scatter_offset_predicated: {
21421 Info.opc = ISD::INTRINSIC_VOID;
21422 Info.ptrVal = nullptr;
21423 MVT DataVT = MVT::getVT(I.getArgOperand(2)->getType());
21424 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
21425 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21426 DataVT.getVectorNumElements());
21427 Info.align = Align(1);
21428 Info.flags |= MachineMemOperand::MOStore;
21429 Infos.push_back(Info);
21430 return;
21431 }
21432 case Intrinsic::arm_ldaex:
21433 case Intrinsic::arm_ldrex: {
21434 auto &DL = I.getDataLayout();
21435 Type *ValTy = I.getParamElementType(0);
21436 Info.opc = ISD::INTRINSIC_W_CHAIN;
21437 Info.memVT = MVT::getVT(ValTy);
21438 Info.ptrVal = I.getArgOperand(0);
21439 Info.offset = 0;
21440 Info.align = DL.getABITypeAlign(ValTy);
21442 Infos.push_back(Info);
21443 return;
21444 }
21445 case Intrinsic::arm_stlex:
21446 case Intrinsic::arm_strex: {
21447 auto &DL = I.getDataLayout();
21448 Type *ValTy = I.getParamElementType(1);
21449 Info.opc = ISD::INTRINSIC_W_CHAIN;
21450 Info.memVT = MVT::getVT(ValTy);
21451 Info.ptrVal = I.getArgOperand(1);
21452 Info.offset = 0;
21453 Info.align = DL.getABITypeAlign(ValTy);
21455 Infos.push_back(Info);
21456 return;
21457 }
21458 case Intrinsic::arm_stlexd:
21459 case Intrinsic::arm_strexd:
21460 Info.opc = ISD::INTRINSIC_W_CHAIN;
21461 Info.memVT = MVT::i64;
21462 Info.ptrVal = I.getArgOperand(2);
21463 Info.offset = 0;
21464 Info.align = Align(8);
21466 Infos.push_back(Info);
21467 return;
21468
21469 case Intrinsic::arm_ldaexd:
21470 case Intrinsic::arm_ldrexd:
21471 Info.opc = ISD::INTRINSIC_W_CHAIN;
21472 Info.memVT = MVT::i64;
21473 Info.ptrVal = I.getArgOperand(0);
21474 Info.offset = 0;
21475 Info.align = Align(8);
21477 Infos.push_back(Info);
21478 return;
21479
21480 default:
21481 break;
21482 }
21483}
21484
21485/// Returns true if it is beneficial to convert a load of a constant
21486/// to just the constant itself.
21488 Type *Ty) const {
21489 assert(Ty->isIntegerTy());
21490
21491 unsigned Bits = Ty->getPrimitiveSizeInBits();
21492 if (Bits == 0 || Bits > 32)
21493 return false;
21494 return true;
21495}
21496
21499 unsigned Index) const {
21502
21503 if (Index == 0 || Index == ResVT.getVectorNumElements())
21506}
21507
21509 ARM_MB::MemBOpt Domain) const {
21510 // First, if the target has no DMB, see what fallback we can use.
21511 if (!Subtarget->hasDataBarrier()) {
21512 // Some ARMv6 cpus can support data barriers with an mcr instruction.
21513 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
21514 // here.
21515 if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
21516 Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
21517 Builder.getInt32(0), Builder.getInt32(7),
21518 Builder.getInt32(10), Builder.getInt32(5)};
21519 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_mcr, args);
21520 }
21521 // Instead of using barriers, atomic accesses on these subtargets use
21522 // libcalls.
21523 llvm_unreachable("makeDMB on a target so old that it has no barriers");
21524 } else {
21525 // Only a full system barrier exists in the M-class architectures.
21526 Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
21527 Constant *CDomain = Builder.getInt32(Domain);
21528 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_dmb, CDomain);
21529 }
21530}
21531
21532// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
21534 Instruction *Inst,
21535 AtomicOrdering Ord) const {
21536 switch (Ord) {
21539 llvm_unreachable("Invalid fence: unordered/non-atomic");
21542 return nullptr; // Nothing to do
21544 if (!Inst->hasAtomicStore())
21545 return nullptr; // Nothing to do
21546 [[fallthrough]];
21549 if (Subtarget->preferISHSTBarriers())
21550 return makeDMB(Builder, ARM_MB::ISHST);
21551 // FIXME: add a comment with a link to documentation justifying this.
21552 else
21553 return makeDMB(Builder, ARM_MB::ISH);
21554 }
21555 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
21556}
21557
21559 Instruction *Inst,
21560 AtomicOrdering Ord) const {
21561 switch (Ord) {
21564 llvm_unreachable("Invalid fence: unordered/not-atomic");
21567 return nullptr; // Nothing to do
21571 return makeDMB(Builder, ARM_MB::ISH);
21572 }
21573 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
21574}
21575
21576// Loads and stores less than 64-bits are already atomic; ones above that
21577// are doomed anyway, so defer to the default libcall and blame the OS when
21578// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21579// anything for those.
21582 bool has64BitAtomicStore;
21583 if (Subtarget->isMClass())
21584 has64BitAtomicStore = false;
21585 else if (Subtarget->isThumb())
21586 has64BitAtomicStore = Subtarget->hasV7Ops();
21587 else
21588 has64BitAtomicStore = Subtarget->hasV6Ops();
21589
21590 unsigned Size = SI->getValueOperand()->getType()->getPrimitiveSizeInBits();
21591 return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind::Expand
21593}
21594
21595// Loads and stores less than 64-bits are already atomic; ones above that
21596// are doomed anyway, so defer to the default libcall and blame the OS when
21597// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21598// anything for those.
21599// FIXME: ldrd and strd are atomic if the CPU has LPAE (e.g. A15 has that
21600// guarantee, see DDI0406C ARM architecture reference manual,
21601// sections A8.8.72-74 LDRD)
21604 bool has64BitAtomicLoad;
21605 if (Subtarget->isMClass())
21606 has64BitAtomicLoad = false;
21607 else if (Subtarget->isThumb())
21608 has64BitAtomicLoad = Subtarget->hasV7Ops();
21609 else
21610 has64BitAtomicLoad = Subtarget->hasV6Ops();
21611
21612 unsigned Size = LI->getType()->getPrimitiveSizeInBits();
21613 return (Size == 64 && has64BitAtomicLoad) ? AtomicExpansionKind::LLOnly
21615}
21616
21617// For the real atomic operations, we have ldrex/strex up to 32 bits,
21618// and up to 64 bits on the non-M profiles
21621 if (AI->isFloatingPointOperation())
21623
21624 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
21625 bool hasAtomicRMW;
21626 if (Subtarget->isMClass())
21627 hasAtomicRMW = Subtarget->hasV8MBaselineOps();
21628 else if (Subtarget->isThumb())
21629 hasAtomicRMW = Subtarget->hasV7Ops();
21630 else
21631 hasAtomicRMW = Subtarget->hasV6Ops();
21632 if (Size <= (Subtarget->isMClass() ? 32U : 64U) && hasAtomicRMW) {
21633 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21634 // implement atomicrmw without spilling. If the target address is also on
21635 // the stack and close enough to the spill slot, this can lead to a
21636 // situation where the monitor always gets cleared and the atomic operation
21637 // can never succeed. So at -O0 lower this operation to a CAS loop.
21638 if (getTargetMachine().getOptLevel() == CodeGenOptLevel::None)
21641 }
21643}
21644
21645// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
21646// bits, and up to 64 bits on the non-M profiles.
21649 const AtomicCmpXchgInst *AI) const {
21650 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21651 // implement cmpxchg without spilling. If the address being exchanged is also
21652 // on the stack and close enough to the spill slot, this can lead to a
21653 // situation where the monitor always gets cleared and the atomic operation
21654 // can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
21655 unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
21656 bool HasAtomicCmpXchg;
21657 if (Subtarget->isMClass())
21658 HasAtomicCmpXchg = Subtarget->hasV8MBaselineOps();
21659 else if (Subtarget->isThumb())
21660 HasAtomicCmpXchg = Subtarget->hasV7Ops();
21661 else
21662 HasAtomicCmpXchg = Subtarget->hasV6Ops();
21663 if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None &&
21664 HasAtomicCmpXchg && Size <= (Subtarget->isMClass() ? 32U : 64U))
21667}
21668
21670 const Instruction *I) const {
21671 return InsertFencesForAtomic;
21672}
21673
21675 // ROPI/RWPI are not supported currently.
21676 return !Subtarget->isROPI() && !Subtarget->isRWPI();
21677}
21678
21680 Module &M, const LibcallLoweringInfo &Libcalls) const {
21681 // MSVC CRT provides functionalities for stack protection.
21682 RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21683 Libcalls.getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21684
21685 RTLIB::LibcallImpl SecurityCookieVar =
21686 Libcalls.getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
21687 if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
21688 SecurityCookieVar != RTLIB::Unsupported) {
21689 // MSVC CRT has a global variable holding security cookie.
21690 M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
21691 PointerType::getUnqual(M.getContext()));
21692
21693 // MSVC CRT has a function to validate security cookie.
21694 FunctionCallee SecurityCheckCookie =
21695 M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall),
21696 Type::getVoidTy(M.getContext()),
21697 PointerType::getUnqual(M.getContext()));
21698 if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee()))
21699 F->addParamAttr(0, Attribute::AttrKind::InReg);
21700 }
21701
21703}
21704
21706 unsigned &Cost) const {
21707 // If we do not have NEON, vector types are not natively supported.
21708 if (!Subtarget->hasNEON())
21709 return false;
21710
21711 // Floating point values and vector values map to the same register file.
21712 // Therefore, although we could do a store extract of a vector type, this is
21713 // better to leave at float as we have more freedom in the addressing mode for
21714 // those.
21715 if (VectorTy->isFPOrFPVectorTy())
21716 return false;
21717
21718 // If the index is unknown at compile time, this is very expensive to lower
21719 // and it is not possible to combine the store with the extract.
21720 if (!isa<ConstantInt>(Idx))
21721 return false;
21722
21723 assert(VectorTy->isVectorTy() && "VectorTy is not a vector type");
21724 unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
21725 // We can do a store + vector extract on any vector that fits perfectly in a D
21726 // or Q register.
21727 if (BitWidth == 64 || BitWidth == 128) {
21728 Cost = 0;
21729 return true;
21730 }
21731 return false;
21732}
21733
21735 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
21736 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
21737 unsigned Opcode = Op.getOpcode();
21738 switch (Opcode) {
21739 case ARMISD::VORRIMM:
21740 case ARMISD::VBICIMM:
21741 return false;
21742 }
21744 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
21745}
21746
21748 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21749}
21750
21752 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21753}
21754
21756 const Instruction &AndI) const {
21757 if (!Subtarget->hasV7Ops())
21758 return false;
21759
21760 // Sink the `and` instruction only if the mask would fit into a modified
21761 // immediate operand.
21763 if (!Mask || Mask->getValue().getBitWidth() > 32u)
21764 return false;
21765 auto MaskVal = unsigned(Mask->getValue().getZExtValue());
21766 return (Subtarget->isThumb2() ? ARM_AM::getT2SOImmVal(MaskVal)
21767 : ARM_AM::getSOImmVal(MaskVal)) != -1;
21768}
21769
21772 SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const {
21773 if (Subtarget->hasMinSize() && !getTM().getTargetTriple().isOSWindows())
21776 ExpansionFactor);
21777}
21778
21780 Value *Addr,
21781 AtomicOrdering Ord) const {
21782 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21783 bool IsAcquire = isAcquireOrStronger(Ord);
21784
21785 // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd
21786 // intrinsic must return {i32, i32} and we have to recombine them into a
21787 // single i64 here.
21788 if (ValueTy->getPrimitiveSizeInBits() == 64) {
21790 IsAcquire ? Intrinsic::arm_ldaexd : Intrinsic::arm_ldrexd;
21791
21792 Value *LoHi =
21793 Builder.CreateIntrinsic(Int, Addr, /*FMFSource=*/nullptr, "lohi");
21794
21795 Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
21796 Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
21797 if (!Subtarget->isLittle())
21798 std::swap (Lo, Hi);
21799 Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
21800 Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
21801 return Builder.CreateOr(
21802 Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 32)), "val64");
21803 }
21804
21805 Type *Tys[] = { Addr->getType() };
21806 Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex;
21807 CallInst *CI = Builder.CreateIntrinsicWithoutFolding(Int, Tys, Addr);
21808
21809 CI->addParamAttr(
21810 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy));
21811 return Builder.CreateTruncOrBitCast(CI, ValueTy);
21812}
21813
21815 IRBuilderBase &Builder) const {
21816 if (!Subtarget->hasV7Ops())
21817 return;
21818 Builder.CreateIntrinsic(Intrinsic::arm_clrex, {});
21819}
21820
21822 Value *Val, Value *Addr,
21823 AtomicOrdering Ord) const {
21824 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21825 bool IsRelease = isReleaseOrStronger(Ord);
21826
21827 // Since the intrinsics must have legal type, the i64 intrinsics take two
21828 // parameters: "i32, i32". We must marshal Val into the appropriate form
21829 // before the call.
21830 if (Val->getType()->getPrimitiveSizeInBits() == 64) {
21832 IsRelease ? Intrinsic::arm_stlexd : Intrinsic::arm_strexd;
21833 Type *Int32Ty = Type::getInt32Ty(M->getContext());
21834
21835 Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
21836 Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
21837 if (!Subtarget->isLittle())
21838 std::swap(Lo, Hi);
21839 return Builder.CreateIntrinsic(Int, {Lo, Hi, Addr});
21840 }
21841
21842 Intrinsic::ID Int = IsRelease ? Intrinsic::arm_stlex : Intrinsic::arm_strex;
21843 Type *Tys[] = { Addr->getType() };
21845
21846 CallInst *CI = Builder.CreateCall(
21847 Strex, {Builder.CreateZExtOrBitCast(
21848 Val, Strex->getFunctionType()->getParamType(0)),
21849 Addr});
21850 CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType,
21851 Val->getType()));
21852 return CI;
21853}
21854
21855
21857 return Subtarget->isMClass();
21858}
21859
21860/// A helper function for determining the number of interleaved accesses we
21861/// will generate when lowering accesses of the given type.
21862unsigned
21864 const DataLayout &DL) const {
21865 return (DL.getTypeSizeInBits(VecTy) + 127) / 128;
21866}
21867
21869 unsigned Factor, FixedVectorType *VecTy, Align Alignment,
21870 const DataLayout &DL) const {
21871
21872 unsigned VecSize = DL.getTypeSizeInBits(VecTy);
21873 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
21874
21875 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
21876 return false;
21877
21878 // Ensure the vector doesn't have f16 elements. Even though we could do an
21879 // i16 vldN, we can't hold the f16 vectors and will end up converting via
21880 // f32.
21881 if (Subtarget->hasNEON() && VecTy->getElementType()->isHalfTy())
21882 return false;
21883 if (Subtarget->hasMVEIntegerOps() && Factor == 3)
21884 return false;
21885
21886 // Ensure the number of vector elements is greater than 1.
21887 if (VecTy->getNumElements() < 2)
21888 return false;
21889
21890 // Ensure the element type is legal.
21891 if (ElSize != 8 && ElSize != 16 && ElSize != 32)
21892 return false;
21893 // And the alignment if high enough under MVE.
21894 if (Subtarget->hasMVEIntegerOps() && Alignment < ElSize / 8)
21895 return false;
21896
21897 // Ensure the total vector size is 64 or a multiple of 128. Types larger than
21898 // 128 will be split into multiple interleaved accesses.
21899 if (Subtarget->hasNEON() && VecSize == 64)
21900 return true;
21901 return VecSize % 128 == 0;
21902}
21903
21905 if (Subtarget->hasNEON())
21906 return 4;
21907 if (Subtarget->hasMVEIntegerOps())
21910}
21911
21912/// Lower an interleaved load into a vldN intrinsic.
21913///
21914/// E.g. Lower an interleaved load (Factor = 2):
21915/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr, align 4
21916/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
21917/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
21918///
21919/// Into:
21920/// %vld2 = { <4 x i32>, <4 x i32> } call llvm.arm.neon.vld2(%ptr, 4)
21921/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 0
21922/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 1
21925 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
21926 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
21927 "Invalid interleave factor");
21928 assert(!Shuffles.empty() && "Empty shufflevector input");
21929 assert(Shuffles.size() == Indices.size() &&
21930 "Unmatched number of shufflevectors and indices");
21931
21932 auto *LI = dyn_cast<LoadInst>(Load);
21933 if (!LI)
21934 return false;
21935 assert(!Mask && GapMask.popcount() == Factor && "Unexpected mask on a load");
21936
21937 auto *VecTy = cast<FixedVectorType>(Shuffles[0]->getType());
21938 Type *EltTy = VecTy->getElementType();
21939
21940 const DataLayout &DL = LI->getDataLayout();
21941 Align Alignment = LI->getAlign();
21942
21943 // Skip if we do not have NEON and skip illegal vector types. We can
21944 // "legalize" wide vector types into multiple interleaved accesses as long as
21945 // the vector types are divisible by 128.
21946 if (!isLegalInterleavedAccessType(Factor, VecTy, Alignment, DL))
21947 return false;
21948
21949 unsigned NumLoads = getNumInterleavedAccesses(VecTy, DL);
21950
21951 // A pointer vector can not be the return type of the ldN intrinsics. Need to
21952 // load integer vectors first and then convert to pointer vectors.
21953 if (EltTy->isPointerTy())
21954 VecTy = FixedVectorType::get(DL.getIntPtrType(EltTy), VecTy);
21955
21956 IRBuilder<> Builder(LI);
21957
21958 // The base address of the load.
21959 Value *BaseAddr = LI->getPointerOperand();
21960
21961 if (NumLoads > 1) {
21962 // If we're going to generate more than one load, reset the sub-vector type
21963 // to something legal.
21964 VecTy = FixedVectorType::get(VecTy->getElementType(),
21965 VecTy->getNumElements() / NumLoads);
21966 }
21967
21968 assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!");
21969
21970 auto createLoadIntrinsic = [&](Value *BaseAddr) {
21971 if (Subtarget->hasNEON()) {
21972 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21973 Type *Tys[] = {VecTy, PtrTy};
21974 static const Intrinsic::ID LoadInts[3] = {Intrinsic::arm_neon_vld2,
21975 Intrinsic::arm_neon_vld3,
21976 Intrinsic::arm_neon_vld4};
21977
21979 Ops.push_back(BaseAddr);
21980 Ops.push_back(Builder.getInt32(LI->getAlign().value()));
21981
21982 return Builder.CreateIntrinsic(LoadInts[Factor - 2], Tys, Ops,
21983 /*FMFSource=*/nullptr, "vldN");
21984 } else {
21985 assert((Factor == 2 || Factor == 4) &&
21986 "expected interleave factor of 2 or 4 for MVE");
21987 Intrinsic::ID LoadInts =
21988 Factor == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
21989 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21990 Type *Tys[] = {VecTy, PtrTy};
21991
21993 Ops.push_back(BaseAddr);
21994 return Builder.CreateIntrinsic(LoadInts, Tys, Ops, /*FMFSource=*/nullptr,
21995 "vldN");
21996 }
21997 };
21998
21999 // Holds sub-vectors extracted from the load intrinsic return values. The
22000 // sub-vectors are associated with the shufflevector instructions they will
22001 // replace.
22003
22004 for (unsigned LoadCount = 0; LoadCount < NumLoads; ++LoadCount) {
22005 // If we're generating more than one load, compute the base address of
22006 // subsequent loads as an offset from the previous.
22007 if (LoadCount > 0)
22008 BaseAddr = Builder.CreateConstGEP1_32(VecTy->getElementType(), BaseAddr,
22009 VecTy->getNumElements() * Factor);
22010
22011 Value *VldN = createLoadIntrinsic(BaseAddr);
22012
22013 // Replace uses of each shufflevector with the corresponding vector loaded
22014 // by ldN.
22015 for (unsigned i = 0; i < Shuffles.size(); i++) {
22016 ShuffleVectorInst *SV = Shuffles[i];
22017 unsigned Index = Indices[i];
22018
22019 Value *SubVec = Builder.CreateExtractValue(VldN, Index);
22020
22021 // Convert the integer vector to pointer vector if the element is pointer.
22022 if (EltTy->isPointerTy())
22023 SubVec = Builder.CreateIntToPtr(
22024 SubVec,
22025 FixedVectorType::get(SV->getType()->getElementType(), VecTy));
22026
22027 SubVecs[SV].push_back(SubVec);
22028 }
22029 }
22030
22031 // Replace uses of the shufflevector instructions with the sub-vectors
22032 // returned by the load intrinsic. If a shufflevector instruction is
22033 // associated with more than one sub-vector, those sub-vectors will be
22034 // concatenated into a single wide vector.
22035 for (ShuffleVectorInst *SVI : Shuffles) {
22036 auto &SubVec = SubVecs[SVI];
22037 auto *WideVec =
22038 SubVec.size() > 1 ? concatenateVectors(Builder, SubVec) : SubVec[0];
22039 SVI->replaceAllUsesWith(WideVec);
22040 }
22041
22042 return true;
22043}
22044
22045/// Lower an interleaved store into a vstN intrinsic.
22046///
22047/// E.g. Lower an interleaved store (Factor = 3):
22048/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
22049/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
22050/// store <12 x i32> %i.vec, <12 x i32>* %ptr, align 4
22051///
22052/// Into:
22053/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
22054/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
22055/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
22056/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22057///
22058/// Note that the new shufflevectors will be removed and we'll only generate one
22059/// vst3 instruction in CodeGen.
22060///
22061/// Example for a more general valid mask (Factor 3). Lower:
22062/// %i.vec = shuffle <32 x i32> %v0, <32 x i32> %v1,
22063/// <4, 32, 16, 5, 33, 17, 6, 34, 18, 7, 35, 19>
22064/// store <12 x i32> %i.vec, <12 x i32>* %ptr
22065///
22066/// Into:
22067/// %sub.v0 = shuffle <32 x i32> %v0, <32 x i32> v1, <4, 5, 6, 7>
22068/// %sub.v1 = shuffle <32 x i32> %v0, <32 x i32> v1, <32, 33, 34, 35>
22069/// %sub.v2 = shuffle <32 x i32> %v0, <32 x i32> v1, <16, 17, 18, 19>
22070/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22072 Value *LaneMask,
22073 ShuffleVectorInst *SVI,
22074 unsigned Factor,
22075 const APInt &GapMask) const {
22076 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22077 "Invalid interleave factor");
22078 auto *SI = dyn_cast<StoreInst>(Store);
22079 if (!SI)
22080 return false;
22081 assert(!LaneMask && GapMask.popcount() == Factor &&
22082 "Unexpected mask on store");
22083
22084 auto *VecTy = cast<FixedVectorType>(SVI->getType());
22085 assert(VecTy->getNumElements() % Factor == 0 && "Invalid interleaved store");
22086
22087 unsigned LaneLen = VecTy->getNumElements() / Factor;
22088 Type *EltTy = VecTy->getElementType();
22089 auto *SubVecTy = FixedVectorType::get(EltTy, LaneLen);
22090
22091 const DataLayout &DL = SI->getDataLayout();
22092 Align Alignment = SI->getAlign();
22093
22094 // Skip if we do not have NEON and skip illegal vector types. We can
22095 // "legalize" wide vector types into multiple interleaved accesses as long as
22096 // the vector types are divisible by 128.
22097 if (!isLegalInterleavedAccessType(Factor, SubVecTy, Alignment, DL))
22098 return false;
22099
22100 unsigned NumStores = getNumInterleavedAccesses(SubVecTy, DL);
22101
22102 Value *Op0 = SVI->getOperand(0);
22103 Value *Op1 = SVI->getOperand(1);
22104 IRBuilder<> Builder(SI);
22105
22106 // StN intrinsics don't support pointer vectors as arguments. Convert pointer
22107 // vectors to integer vectors.
22108 if (EltTy->isPointerTy()) {
22109 Type *IntTy = DL.getIntPtrType(EltTy);
22110
22111 // Convert to the corresponding integer vector.
22112 auto *IntVecTy =
22114 Op0 = Builder.CreatePtrToInt(Op0, IntVecTy);
22115 Op1 = Builder.CreatePtrToInt(Op1, IntVecTy);
22116
22117 SubVecTy = FixedVectorType::get(IntTy, LaneLen);
22118 }
22119
22120 // The base address of the store.
22121 Value *BaseAddr = SI->getPointerOperand();
22122
22123 if (NumStores > 1) {
22124 // If we're going to generate more than one store, reset the lane length
22125 // and sub-vector type to something legal.
22126 LaneLen /= NumStores;
22127 SubVecTy = FixedVectorType::get(SubVecTy->getElementType(), LaneLen);
22128 }
22129
22130 assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!");
22131
22132 auto Mask = SVI->getShuffleMask();
22133
22134 auto createStoreIntrinsic = [&](Value *BaseAddr,
22135 SmallVectorImpl<Value *> &Shuffles) {
22136 if (Subtarget->hasNEON()) {
22137 static const Intrinsic::ID StoreInts[3] = {Intrinsic::arm_neon_vst2,
22138 Intrinsic::arm_neon_vst3,
22139 Intrinsic::arm_neon_vst4};
22140 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22141 Type *Tys[] = {PtrTy, SubVecTy};
22142
22144 Ops.push_back(BaseAddr);
22145 append_range(Ops, Shuffles);
22146 Ops.push_back(Builder.getInt32(SI->getAlign().value()));
22147 Builder.CreateIntrinsic(StoreInts[Factor - 2], Tys, Ops);
22148 } else {
22149 assert((Factor == 2 || Factor == 4) &&
22150 "expected interleave factor of 2 or 4 for MVE");
22151 Intrinsic::ID StoreInts =
22152 Factor == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
22153 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22154 Type *Tys[] = {PtrTy, SubVecTy};
22155
22157 Ops.push_back(BaseAddr);
22158 append_range(Ops, Shuffles);
22159 for (unsigned F = 0; F < Factor; F++) {
22160 Ops.push_back(Builder.getInt32(F));
22161 Builder.CreateIntrinsic(StoreInts, Tys, Ops);
22162 Ops.pop_back();
22163 }
22164 }
22165 };
22166
22167 for (unsigned StoreCount = 0; StoreCount < NumStores; ++StoreCount) {
22168 // If we generating more than one store, we compute the base address of
22169 // subsequent stores as an offset from the previous.
22170 if (StoreCount > 0)
22171 BaseAddr = Builder.CreateConstGEP1_32(SubVecTy->getElementType(),
22172 BaseAddr, LaneLen * Factor);
22173
22174 SmallVector<Value *, 4> Shuffles;
22175
22176 // Split the shufflevector operands into sub vectors for the new vstN call.
22177 for (unsigned i = 0; i < Factor; i++) {
22178 unsigned IdxI = StoreCount * LaneLen * Factor + i;
22179 if (Mask[IdxI] >= 0) {
22180 Shuffles.push_back(Builder.CreateShuffleVector(
22181 Op0, Op1, createSequentialMask(Mask[IdxI], LaneLen, 0)));
22182 } else {
22183 unsigned StartMask = 0;
22184 for (unsigned j = 1; j < LaneLen; j++) {
22185 unsigned IdxJ = StoreCount * LaneLen * Factor + j;
22186 if (Mask[IdxJ * Factor + IdxI] >= 0) {
22187 StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
22188 break;
22189 }
22190 }
22191 // Note: If all elements in a chunk are undefs, StartMask=0!
22192 // Note: Filling undef gaps with random elements is ok, since
22193 // those elements were being written anyway (with undefs).
22194 // In the case of all undefs we're defaulting to using elems from 0
22195 // Note: StartMask cannot be negative, it's checked in
22196 // isReInterleaveMask
22197 Shuffles.push_back(Builder.CreateShuffleVector(
22198 Op0, Op1, createSequentialMask(StartMask, LaneLen, 0)));
22199 }
22200 }
22201
22202 createStoreIntrinsic(BaseAddr, Shuffles);
22203 }
22204 return true;
22205}
22206
22214
22216 uint64_t &Members) {
22217 if (auto *ST = dyn_cast<StructType>(Ty)) {
22218 for (unsigned i = 0; i < ST->getNumElements(); ++i) {
22219 uint64_t SubMembers = 0;
22220 if (!isHomogeneousAggregate(ST->getElementType(i), Base, SubMembers))
22221 return false;
22222 Members += SubMembers;
22223 }
22224 } else if (auto *AT = dyn_cast<ArrayType>(Ty)) {
22225 uint64_t SubMembers = 0;
22226 if (!isHomogeneousAggregate(AT->getElementType(), Base, SubMembers))
22227 return false;
22228 Members += SubMembers * AT->getNumElements();
22229 } else if (Ty->isFloatTy()) {
22230 if (Base != HA_UNKNOWN && Base != HA_FLOAT)
22231 return false;
22232 Members = 1;
22233 Base = HA_FLOAT;
22234 } else if (Ty->isDoubleTy()) {
22235 if (Base != HA_UNKNOWN && Base != HA_DOUBLE)
22236 return false;
22237 Members = 1;
22238 Base = HA_DOUBLE;
22239 } else if (auto *VT = dyn_cast<VectorType>(Ty)) {
22240 Members = 1;
22241 switch (Base) {
22242 case HA_FLOAT:
22243 case HA_DOUBLE:
22244 return false;
22245 case HA_VECT64:
22246 return VT->getPrimitiveSizeInBits().getFixedValue() == 64;
22247 case HA_VECT128:
22248 return VT->getPrimitiveSizeInBits().getFixedValue() == 128;
22249 case HA_UNKNOWN:
22250 switch (VT->getPrimitiveSizeInBits().getFixedValue()) {
22251 case 64:
22252 Base = HA_VECT64;
22253 return true;
22254 case 128:
22255 Base = HA_VECT128;
22256 return true;
22257 default:
22258 return false;
22259 }
22260 }
22261 }
22262
22263 return (Members > 0 && Members <= 4);
22264}
22265
22266/// Return the correct alignment for the current calling convention.
22268 Type *ArgTy, const DataLayout &DL) const {
22269 const Align ABITypeAlign = DL.getABITypeAlign(ArgTy);
22270 if (!ArgTy->isVectorTy())
22271 return ABITypeAlign;
22272
22273 // Avoid over-aligning vector parameters. It would require realigning the
22274 // stack and waste space for no real benefit.
22275 MaybeAlign StackAlign = DL.getStackAlignment();
22276 assert(StackAlign && "data layout string is missing stack alignment");
22277 return std::min(ABITypeAlign, *StackAlign);
22278}
22279
22280/// Return true if a type is an AAPCS-VFP homogeneous aggregate or one of
22281/// [N x i32] or [N x i64]. This allows front-ends to skip emitting padding when
22282/// passing according to AAPCS rules.
22284 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
22285 const DataLayout &DL) const {
22286 if (getEffectiveCallingConv(CallConv, isVarArg) !=
22288 return false;
22289
22291 uint64_t Members = 0;
22292 bool IsHA = isHomogeneousAggregate(Ty, Base, Members);
22293 LLVM_DEBUG(dbgs() << "isHA: " << IsHA << " "; Ty->dump());
22294
22295 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
22296 return IsHA || IsIntArray;
22297}
22298
22300 ExceptionHandling EH, const Constant *PersonalityFn) const {
22301 // Platforms which do not use SjLj EH may return values in these registers
22302 // via the personality function.
22303 return EH == ExceptionHandling::SjLj ? Register() : ARM::R0;
22304}
22305
22307 ExceptionHandling EH, const Constant *PersonalityFn) const {
22308 // Platforms which do not use SjLj EH may return values in these registers
22309 // via the personality function.
22310 return EH == ExceptionHandling::SjLj ? Register() : ARM::R1;
22311}
22312
22313void ARMTargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
22314 // Update IsSplitCSR in ARMFunctionInfo.
22315 ARMFunctionInfo *AFI = Entry->getParent()->getInfo<ARMFunctionInfo>();
22316 AFI->setIsSplitCSR(true);
22317}
22318
22319void ARMTargetLowering::insertCopiesSplitCSR(
22320 MachineBasicBlock *Entry,
22321 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
22322 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
22323 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
22324 if (!IStart)
22325 return;
22326
22327 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
22328 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
22329 MachineBasicBlock::iterator MBBI = Entry->begin();
22330 for (const MCPhysReg *I = IStart; *I; ++I) {
22331 const TargetRegisterClass *RC = nullptr;
22332 if (ARM::GPRRegClass.contains(*I))
22333 RC = &ARM::GPRRegClass;
22334 else if (ARM::DPRRegClass.contains(*I))
22335 RC = &ARM::DPRRegClass;
22336 else
22337 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
22338
22339 Register NewVR = MRI->createVirtualRegister(RC);
22340 // Create copy from CSR to a virtual register.
22341 // FIXME: this currently does not emit CFI pseudo-instructions, it works
22342 // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
22343 // nounwind. If we want to generalize this later, we may need to emit
22344 // CFI pseudo-instructions.
22345 assert(Entry->getParent()->getFunction().hasFnAttribute(
22346 Attribute::NoUnwind) &&
22347 "Function should be nounwind in insertCopiesSplitCSR!");
22348 Entry->addLiveIn(*I);
22349 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
22350 .addReg(*I);
22351
22352 // Insert the copy-back instructions right before the terminator.
22353 for (auto *Exit : Exits)
22354 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
22355 TII->get(TargetOpcode::COPY), *I)
22356 .addReg(NewVR);
22357 }
22358}
22359
22364
22366 return Subtarget->hasMVEIntegerOps();
22367}
22368
22371 auto *VTy = dyn_cast<FixedVectorType>(Ty);
22372 if (!VTy)
22373 return false;
22374
22375 auto *ScalarTy = VTy->getScalarType();
22376 unsigned NumElements = VTy->getNumElements();
22377
22378 unsigned VTyWidth = VTy->getScalarSizeInBits() * NumElements;
22379 if (VTyWidth < 128 || !llvm::isPowerOf2_32(VTyWidth))
22380 return false;
22381
22382 // Both VCADD and VCMUL/VCMLA support the same types, F16 and F32
22383 if (ScalarTy->isHalfTy() || ScalarTy->isFloatTy())
22384 return Subtarget->hasMVEFloatOps();
22385
22387 return false;
22388
22389 return Subtarget->hasMVEIntegerOps() &&
22390 (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
22391 ScalarTy->isIntegerTy(32));
22392}
22393
22395 static const MCPhysReg RCRegs[] = {ARM::FPSCR_RM};
22396 return RCRegs;
22397}
22398
22401 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
22402 Value *Accumulator) const {
22403
22405
22406 unsigned TyWidth = Ty->getScalarSizeInBits() * Ty->getNumElements();
22407
22408 assert(TyWidth >= 128 && "Width of vector type must be at least 128 bits");
22409
22410 if (TyWidth > 128) {
22411 int Stride = Ty->getNumElements() / 2;
22412 auto SplitSeq = llvm::seq<int>(0, Ty->getNumElements());
22413 auto SplitSeqVec = llvm::to_vector(SplitSeq);
22414 ArrayRef<int> LowerSplitMask(&SplitSeqVec[0], Stride);
22415 ArrayRef<int> UpperSplitMask(&SplitSeqVec[Stride], Stride);
22416
22417 auto *LowerSplitA = B.CreateShuffleVector(InputA, LowerSplitMask);
22418 auto *LowerSplitB = B.CreateShuffleVector(InputB, LowerSplitMask);
22419 auto *UpperSplitA = B.CreateShuffleVector(InputA, UpperSplitMask);
22420 auto *UpperSplitB = B.CreateShuffleVector(InputB, UpperSplitMask);
22421 Value *LowerSplitAcc = nullptr;
22422 Value *UpperSplitAcc = nullptr;
22423
22424 if (Accumulator) {
22425 LowerSplitAcc = B.CreateShuffleVector(Accumulator, LowerSplitMask);
22426 UpperSplitAcc = B.CreateShuffleVector(Accumulator, UpperSplitMask);
22427 }
22428
22429 auto *LowerSplitInt = createComplexDeinterleavingIR(
22430 B, OperationType, Rotation, LowerSplitA, LowerSplitB, LowerSplitAcc);
22431 auto *UpperSplitInt = createComplexDeinterleavingIR(
22432 B, OperationType, Rotation, UpperSplitA, UpperSplitB, UpperSplitAcc);
22433
22434 ArrayRef<int> JoinMask(&SplitSeqVec[0], Ty->getNumElements());
22435 return B.CreateShuffleVector(LowerSplitInt, UpperSplitInt, JoinMask);
22436 }
22437
22438 auto *IntTy = Type::getInt32Ty(B.getContext());
22439
22440 ConstantInt *ConstRotation = nullptr;
22441 if (OperationType == ComplexDeinterleavingOperation::CMulPartial) {
22442 ConstRotation = ConstantInt::get(IntTy, (int)Rotation);
22443
22444 if (Accumulator)
22445 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmlaq, Ty,
22446 {ConstRotation, Accumulator, InputB, InputA});
22447 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmulq, Ty,
22448 {ConstRotation, InputB, InputA});
22449 }
22450
22451 if (OperationType == ComplexDeinterleavingOperation::CAdd) {
22452 // 1 means the value is not halved.
22453 auto *ConstHalving = ConstantInt::get(IntTy, 1);
22454
22456 ConstRotation = ConstantInt::get(IntTy, 0);
22458 ConstRotation = ConstantInt::get(IntTy, 1);
22459
22460 if (!ConstRotation)
22461 return nullptr; // Invalid rotation for arm_mve_vcaddq
22462
22463 return B.CreateIntrinsic(Intrinsic::arm_mve_vcaddq, Ty,
22464 {ConstHalving, ConstRotation, InputA, InputB});
22465 }
22466
22467 return nullptr;
22468}
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)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, 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...
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
unsigned Imm
unsigned uint64_t
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 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 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,...
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 bool isVTRNMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
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 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 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 isVZIPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
static SDValue PerformORCombineToSMULWBT(SDNode *OR, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static 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,...
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 bool isVUZPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
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 TargetLowering::ArgListTy getDivRemArgList(const SDNode *N, LLVMContext *Context, 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 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 unsigned SelectPairHalf(unsigned Elements, ArrayRef< int > Mask, unsigned Index)
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 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 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,...
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 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.
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:857
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
PowerPC Reduce CR logical Operation
R600 Clause Merge
const SmallVectorImpl< MachineOperand > & Cond
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")))
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:484
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:5974
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...
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
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize=false) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
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...
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,...
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:43
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
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:258
unsigned size() const
Definition DenseMap.h:207
bool empty() const
Definition DenseMap.h:206
iterator begin()
Definition DenseMap.h:172
iterator end()
Definition DenseMap.h:176
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:356
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:730
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:114
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2908
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:68
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.
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)
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 & 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.
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
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.
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 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 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 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.
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
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
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.
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.
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.
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:538
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:777
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
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
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
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:200
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:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:830
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:261
@ 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:514
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:236
@ 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:168
@ FGETSIGN
INT = FGETSIGN(FP) - Return the sign bit of the specified floating point value as an integer 0/1 valu...
Definition ISDOpcodes.h:541
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:603
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:790
@ 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:264
@ 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:864
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:521
@ 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:220
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition ISDOpcodes.h:172
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:891
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:587
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:418
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:750
@ 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:280
@ 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:254
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:439
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:799
@ SET_ROUNDING
Set rounding mode.
Definition ISDOpcodes.h:986
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:855
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:718
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:488
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:668
@ 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:838
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:353
@ BR_JT
BR_JT - Jumptable branch.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:375
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:807
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition ISDOpcodes.h:247
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition ISDOpcodes.h:230
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:349
@ CTLS
Count leading redundant sign bits.
Definition ISDOpcodes.h:803
@ 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:981
@ STRICT_FP_TO_FP16
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:707
@ 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:772
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:652
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:617
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
Definition ISDOpcodes.h:139
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:579
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:224
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:861
@ 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:822
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:357
@ 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:899
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:730
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:989
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:816
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:329
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:487
@ STRICT_FROUNDEVEN
Definition ISDOpcodes.h:467
@ 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:110
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:481
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:503
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:480
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:937
@ 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:508
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:742
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:738
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:713
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:428
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:568
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ 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:798
@ 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:970
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
Definition ISDOpcodes.h:122
@ STRICT_FNEARBYINT
Definition ISDOpcodes.h:459
@ 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:956
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition ISDOpcodes.h:162
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:867
@ 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:844
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:537
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:366
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
Definition ISDOpcodes.h:725
@ SADDO_CARRY
Carry-using overflow-aware nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:339
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:213
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:559
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.
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.
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.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
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
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.
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.
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:144
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 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
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
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
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:587
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
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
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.
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
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
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:106
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 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...