LLVM 23.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 <cstdlib>
109#include <iterator>
110#include <limits>
111#include <optional>
112#include <tuple>
113#include <utility>
114#include <vector>
115
116using namespace llvm;
117
118#define DEBUG_TYPE "arm-isel"
119
120STATISTIC(NumTailCalls, "Number of tail calls");
121STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
122STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
123STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
124STATISTIC(NumConstpoolPromoted,
125 "Number of constants with their storage promoted into constant pools");
126
127static cl::opt<bool>
128ARMInterworking("arm-interworking", cl::Hidden,
129 cl::desc("Enable / disable ARM interworking (for debugging only)"),
130 cl::init(true));
131
133 "arm-promote-constant", cl::Hidden,
134 cl::desc("Enable / disable promotion of unnamed_addr constants into "
135 "constant pools"),
136 cl::init(false)); // FIXME: set to true by default once PR32780 is fixed
138 "arm-promote-constant-max-size", cl::Hidden,
139 cl::desc("Maximum size of constant to promote into a constant pool"),
140 cl::init(64));
142 "arm-promote-constant-max-total", cl::Hidden,
143 cl::desc("Maximum size of ALL constants to promote into a constant pool"),
144 cl::init(128));
145
147MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden,
148 cl::desc("Maximum interleave factor for MVE VLDn to generate."),
149 cl::init(2));
150
152 "arm-max-base-updates-to-check", cl::Hidden,
153 cl::desc("Maximum number of base-updates to check generating postindex."),
154 cl::init(64));
155
156/// Value type used for "flags" operands / results (either CPSR or FPSCR_NZCV).
157constexpr MVT FlagsVT = MVT::i32;
158
159// The APCS parameter registers.
160static const MCPhysReg GPRArgRegs[] = {
161 ARM::R0, ARM::R1, ARM::R2, ARM::R3
162};
163
165 SelectionDAG &DAG, const SDLoc &DL) {
167 assert(Arg.ArgVT.bitsLT(MVT::i32));
168 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
169 SDValue Ext =
171 MVT::i32, Trunc);
172 return Ext;
173}
174
175void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
176 if (VT != PromotedLdStVT) {
178 AddPromotedToType (ISD::LOAD, VT, PromotedLdStVT);
179
181 AddPromotedToType (ISD::STORE, VT, PromotedLdStVT);
182 }
183
184 MVT ElemTy = VT.getVectorElementType();
185 if (ElemTy != MVT::f64)
189 if (ElemTy == MVT::i32) {
194 } else {
199 }
208 if (VT.isInteger()) {
212 }
213
214 // Neon does not support vector divide/remainder operations.
223
224 if (!VT.isFloatingPoint() && VT != MVT::v2i64 && VT != MVT::v1i64)
225 for (auto Opcode : {ISD::ABS, ISD::ABDS, ISD::ABDU, ISD::SMIN, ISD::SMAX,
227 setOperationAction(Opcode, VT, Legal);
228 if (!VT.isFloatingPoint())
229 for (auto Opcode : {ISD::SADDSAT, ISD::UADDSAT, ISD::SSUBSAT, ISD::USUBSAT})
230 setOperationAction(Opcode, VT, Legal);
231}
232
233void ARMTargetLowering::addDRTypeForNEON(MVT VT) {
234 addRegisterClass(VT, &ARM::DPRRegClass);
235 addTypeForNEON(VT, MVT::f64);
236}
237
238void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
239 addRegisterClass(VT, &ARM::DPairRegClass);
240 addTypeForNEON(VT, MVT::v2f64);
241}
242
243void ARMTargetLowering::setAllExpand(MVT VT) {
244 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
246
247 // We support these really simple operations even on types where all
248 // the actual arithmetic has to be broken down into simpler
249 // operations or turned into library calls.
254}
255
256void ARMTargetLowering::addAllExtLoads(const MVT From, const MVT To,
257 LegalizeAction Action) {
258 setLoadExtAction(ISD::EXTLOAD, From, To, Action);
259 setLoadExtAction(ISD::ZEXTLOAD, From, To, Action);
260 setLoadExtAction(ISD::SEXTLOAD, From, To, Action);
261}
262
263void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
264 const MVT IntTypes[] = { MVT::v16i8, MVT::v8i16, MVT::v4i32 };
265
266 for (auto VT : IntTypes) {
267 addRegisterClass(VT, &ARM::MQPRRegClass);
298
299 // No native support for these.
309
310 // Vector reductions
320
321 if (!HasMVEFP) {
326 } else {
329 }
330
331 // Pre and Post inc are supported on loads and stores
332 for (unsigned im = (unsigned)ISD::PRE_INC;
333 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
338 }
339 }
340
341 const MVT FloatTypes[] = { MVT::v8f16, MVT::v4f32 };
342 for (auto VT : FloatTypes) {
343 addRegisterClass(VT, &ARM::MQPRRegClass);
344 if (!HasMVEFP)
345 setAllExpand(VT);
346
347 // These are legal or custom whether we have MVE.fp or not
360
361 // Pre and Post inc are supported on loads and stores
362 for (unsigned im = (unsigned)ISD::PRE_INC;
363 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
368 }
369
370 if (HasMVEFP) {
378 }
383
384 // No native support for these.
399 }
400 }
401
402 // Custom Expand smaller than legal vector reductions to prevent false zero
403 // items being added.
412
413 // We 'support' these types up to bitcast/load/store level, regardless of
414 // MVE integer-only / float support. Only doing FP data processing on the FP
415 // vector types is inhibited at integer-only level.
416 const MVT LongTypes[] = { MVT::v2i64, MVT::v2f64 };
417 for (auto VT : LongTypes) {
418 addRegisterClass(VT, &ARM::MQPRRegClass);
419 setAllExpand(VT);
425 }
427
428 // We can do bitwise operations on v2i64 vectors
429 setOperationAction(ISD::AND, MVT::v2i64, Legal);
430 setOperationAction(ISD::OR, MVT::v2i64, Legal);
431 setOperationAction(ISD::XOR, MVT::v2i64, Legal);
432
433 // It is legal to extload from v4i8 to v4i16 or v4i32.
434 addAllExtLoads(MVT::v8i16, MVT::v8i8, Legal);
435 addAllExtLoads(MVT::v4i32, MVT::v4i16, Legal);
436 addAllExtLoads(MVT::v4i32, MVT::v4i8, Legal);
437
438 // It is legal to sign extend from v4i8/v4i16 to v4i32 or v8i8 to v8i16.
444
445 // Some truncating stores are legal too.
446 setTruncStoreAction(MVT::v4i32, MVT::v4i16, Legal);
447 setTruncStoreAction(MVT::v4i32, MVT::v4i8, Legal);
448 setTruncStoreAction(MVT::v8i16, MVT::v8i8, Legal);
449
450 // Pre and Post inc on these are legal, given the correct extends
451 for (unsigned im = (unsigned)ISD::PRE_INC;
452 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
453 for (auto VT : {MVT::v8i8, MVT::v4i8, MVT::v4i16}) {
458 }
459 }
460
461 // Predicate types
462 const MVT pTypes[] = {MVT::v16i1, MVT::v8i1, MVT::v4i1, MVT::v2i1};
463 for (auto VT : pTypes) {
464 addRegisterClass(VT, &ARM::VCCRRegClass);
479
480 if (!HasMVEFP) {
485 }
486 }
490 setOperationAction(ISD::OR, MVT::v2i1, Expand);
496
505}
506
508 return static_cast<const ARMBaseTargetMachine &>(getTargetMachine());
509}
510
512 const ARMSubtarget &STI)
513 : TargetLowering(TM_, STI), Subtarget(&STI),
514 RegInfo(Subtarget->getRegisterInfo()),
515 Itins(Subtarget->getInstrItineraryData()) {
516 const auto &TM = static_cast<const ARMBaseTargetMachine &>(TM_);
517
520
521 const Triple &TT = TM.getTargetTriple();
522
523 if (Subtarget->isThumb1Only())
524 addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
525 else
526 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
527
528 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only() &&
529 Subtarget->hasFPRegs()) {
530 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
531 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
532
533 if (!Subtarget->hasVFP2Base()) {
534 setAllExpand(MVT::f32);
535 } else {
538
541 setOperationAction(Op, MVT::f32, Legal);
542 }
543 if (!Subtarget->hasFP64()) {
544 setAllExpand(MVT::f64);
545 } else {
548 setOperationAction(Op, MVT::f64, Legal);
549
551 }
552 }
553
554 if (Subtarget->hasFullFP16()) {
557 setOperationAction(Op, MVT::f16, Legal);
558
559 addRegisterClass(MVT::f16, &ARM::HPRRegClass);
562
567 }
568
569 if (Subtarget->hasBF16()) {
570 addRegisterClass(MVT::bf16, &ARM::HPRRegClass);
571 setAllExpand(MVT::bf16);
572 if (!Subtarget->hasFullFP16())
576 } else {
581 }
582
584 for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
585 setTruncStoreAction(VT, InnerVT, Expand);
586 addAllExtLoads(VT, InnerVT, Expand);
587 }
588
591
593 }
594
595 if (!Subtarget->isThumb1Only() && !Subtarget->hasV8_1MMainlineOps())
597
598 if (!Subtarget->hasV8_1MMainlineOps())
600
601 if (!Subtarget->isThumb1Only())
603
606
609
610 if (Subtarget->hasMVEIntegerOps())
611 addMVEVectorTypes(Subtarget->hasMVEFloatOps());
612
613 // Combine low-overhead loop intrinsics so that we can lower i1 types.
614 if (Subtarget->hasLOB()) {
616 }
617
618 if (Subtarget->hasNEON()) {
619 addDRTypeForNEON(MVT::v2f32);
620 addDRTypeForNEON(MVT::v8i8);
621 addDRTypeForNEON(MVT::v4i16);
622 addDRTypeForNEON(MVT::v2i32);
623 addDRTypeForNEON(MVT::v1i64);
624
625 addQRTypeForNEON(MVT::v4f32);
626 addQRTypeForNEON(MVT::v2f64);
627 addQRTypeForNEON(MVT::v16i8);
628 addQRTypeForNEON(MVT::v8i16);
629 addQRTypeForNEON(MVT::v4i32);
630 addQRTypeForNEON(MVT::v2i64);
631
632 if (Subtarget->hasFullFP16()) {
633 addQRTypeForNEON(MVT::v8f16);
634 addDRTypeForNEON(MVT::v4f16);
635 }
636
637 if (Subtarget->hasBF16()) {
638 addQRTypeForNEON(MVT::v8bf16);
639 addDRTypeForNEON(MVT::v4bf16);
640 }
641 }
642
643 if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) {
644 // v2f64 is legal so that QR subregs can be extracted as f64 elements, but
645 // none of Neon, MVE or VFP supports any arithmetic operations on it.
646 setOperationAction(ISD::FADD, MVT::v2f64, Expand);
647 setOperationAction(ISD::FSUB, MVT::v2f64, Expand);
648 setOperationAction(ISD::FMUL, MVT::v2f64, Expand);
649 // FIXME: Code duplication: FDIV and FREM are expanded always, see
650 // ARMTargetLowering::addTypeForNEON method for details.
651 setOperationAction(ISD::FDIV, MVT::v2f64, Expand);
652 setOperationAction(ISD::FREM, MVT::v2f64, Expand);
653 // FIXME: Create unittest.
654 // In another words, find a way when "copysign" appears in DAG with vector
655 // operands.
657 // FIXME: Code duplication: SETCC has custom operation action, see
658 // ARMTargetLowering::addTypeForNEON method for details.
660 // FIXME: Create unittest for FNEG and for FABS.
661 setOperationAction(ISD::FNEG, MVT::v2f64, Expand);
662 setOperationAction(ISD::FABS, MVT::v2f64, Expand);
664 setOperationAction(ISD::FSIN, MVT::v2f64, Expand);
665 setOperationAction(ISD::FCOS, MVT::v2f64, Expand);
666 setOperationAction(ISD::FTAN, MVT::v2f64, Expand);
667 setOperationAction(ISD::FPOW, MVT::v2f64, Expand);
668 setOperationAction(ISD::FLOG, MVT::v2f64, Expand);
671 setOperationAction(ISD::FEXP, MVT::v2f64, Expand);
680 setOperationAction(ISD::FMA, MVT::v2f64, Expand);
681 }
682
683 if (Subtarget->hasNEON()) {
684 // The same with v4f32. But keep in mind that vadd, vsub, vmul are natively
685 // supported for v4f32.
687 setOperationAction(ISD::FSIN, MVT::v4f32, Expand);
688 setOperationAction(ISD::FCOS, MVT::v4f32, Expand);
689 setOperationAction(ISD::FTAN, MVT::v4f32, Expand);
690 setOperationAction(ISD::FPOW, MVT::v4f32, Expand);
691 setOperationAction(ISD::FLOG, MVT::v4f32, Expand);
694 setOperationAction(ISD::FEXP, MVT::v4f32, Expand);
703
704 // Mark v2f32 intrinsics.
706 setOperationAction(ISD::FSIN, MVT::v2f32, Expand);
707 setOperationAction(ISD::FCOS, MVT::v2f32, Expand);
708 setOperationAction(ISD::FTAN, MVT::v2f32, Expand);
709 setOperationAction(ISD::FPOW, MVT::v2f32, Expand);
710 setOperationAction(ISD::FLOG, MVT::v2f32, Expand);
713 setOperationAction(ISD::FEXP, MVT::v2f32, Expand);
722
725 setOperationAction(Op, MVT::v4f16, Expand);
726 setOperationAction(Op, MVT::v8f16, Expand);
727 }
728
729 // Neon does not support some operations on v1i64 and v2i64 types.
730 setOperationAction(ISD::MUL, MVT::v1i64, Expand);
731 // Custom handling for some quad-vector types to detect VMULL.
732 setOperationAction(ISD::MUL, MVT::v8i16, Custom);
733 setOperationAction(ISD::MUL, MVT::v4i32, Custom);
734 setOperationAction(ISD::MUL, MVT::v2i64, Custom);
735 // Custom handling for some vector types to avoid expensive expansions
736 setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
738 setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
740 // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
741 // a destination type that is wider than the source, and nor does
742 // it have a FP_TO_[SU]INT instruction with a narrower destination than
743 // source.
752
755
756 // NEON does not have single instruction CTPOP for vectors with element
757 // types wider than 8-bits. However, custom lowering can leverage the
758 // v8i8/v16i8 vcnt instruction.
765
766 setOperationAction(ISD::CTLZ, MVT::v1i64, Expand);
767 setOperationAction(ISD::CTLZ, MVT::v2i64, Expand);
768
769 // NEON does not have single instruction CTTZ for vectors.
771 setOperationAction(ISD::CTTZ, MVT::v4i16, Custom);
772 setOperationAction(ISD::CTTZ, MVT::v2i32, Custom);
773 setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
774
775 setOperationAction(ISD::CTTZ, MVT::v16i8, Custom);
776 setOperationAction(ISD::CTTZ, MVT::v8i16, Custom);
777 setOperationAction(ISD::CTTZ, MVT::v4i32, Custom);
778 setOperationAction(ISD::CTTZ, MVT::v2i64, Custom);
779
784
789
793 }
794
795 // NEON only has FMA instructions as of VFP4.
796 if (!Subtarget->hasVFP4Base()) {
797 setOperationAction(ISD::FMA, MVT::v2f32, Expand);
798 setOperationAction(ISD::FMA, MVT::v4f32, Expand);
799 }
800
803
804 // It is legal to extload from v4i8 to v4i16 or v4i32.
805 for (MVT Ty : {MVT::v8i8, MVT::v4i8, MVT::v2i8, MVT::v4i16, MVT::v2i16,
806 MVT::v2i32}) {
811 }
812 }
813
814 for (auto VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v16i8, MVT::v8i16,
815 MVT::v4i32}) {
820 }
821 }
822
823 if (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) {
830 }
831 if (Subtarget->hasMVEIntegerOps()) {
834 ISD::SETCC});
835 }
836 if (Subtarget->hasMVEFloatOps()) {
838 }
839
840 if (!Subtarget->hasFP64()) {
841 // When targeting a floating-point unit with only single-precision
842 // operations, f64 is legal for the few double-precision instructions which
843 // are present However, no double-precision operations other than moves,
844 // loads and stores are provided by the hardware.
881 }
882
885
886 if (!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) {
889 if (Subtarget->hasFullFP16()) {
892 }
893 } else {
895 }
896
897 if (!Subtarget->hasFP16()) {
900 } else {
903 }
904
905 computeRegisterProperties(Subtarget->getRegisterInfo());
906
907 // ARM does not have floating-point extending loads.
908 for (MVT VT : MVT::fp_valuetypes()) {
909 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
910 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
911 setLoadExtAction(ISD::EXTLOAD, VT, MVT::bf16, Expand);
912 }
913
914 // ... or truncating stores
915 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
916 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
917 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
918 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
919 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
920
921 // ARM does not have i1 sign extending load.
922 for (MVT VT : MVT::integer_valuetypes())
924
925 // ARM supports all 4 flavors of integer indexed load / store.
926 if (!Subtarget->isThumb1Only()) {
927 for (unsigned im = (unsigned)ISD::PRE_INC;
929 setIndexedLoadAction(im, MVT::i1, Legal);
930 setIndexedLoadAction(im, MVT::i8, Legal);
931 setIndexedLoadAction(im, MVT::i16, Legal);
932 setIndexedLoadAction(im, MVT::i32, Legal);
933 setIndexedStoreAction(im, MVT::i1, Legal);
934 setIndexedStoreAction(im, MVT::i8, Legal);
935 setIndexedStoreAction(im, MVT::i16, Legal);
936 setIndexedStoreAction(im, MVT::i32, Legal);
937 }
938 } else {
939 // Thumb-1 has limited post-inc load/store support - LDM r0!, {r1}.
942 }
943
944 // Custom loads/stores to possible use __aeabi_uread/write*
945 if (TT.isTargetAEABI() && !Subtarget->allowsUnalignedMem()) {
950 }
951
956
957 if (!Subtarget->isThumb1Only()) {
960 }
961
966 if (Subtarget->hasDSP()) {
975 }
976 if (Subtarget->hasBaseDSP()) {
979 }
980
981 // i64 operation support.
984 if (Subtarget->isThumb1Only()) {
987 }
988 if (Subtarget->isThumb1Only() || !Subtarget->hasV6Ops()
989 || (Subtarget->isThumb2() && !Subtarget->hasDSP()))
991
1001
1002 // MVE lowers 64 bit shifts to lsll and lsrl
1003 // assuming that ISD::SRL and SRA of i64 are already marked custom
1004 if (Subtarget->hasMVEIntegerOps())
1006
1007 // Expand to __aeabi_l{lsl,lsr,asr} calls for Thumb1.
1008 if (Subtarget->isThumb1Only()) {
1012 }
1013
1014 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops())
1016
1017 // ARM does not have ROTL.
1022 }
1024 // TODO: These two should be set to LibCall, but this currently breaks
1025 // the Linux kernel build. See #101786.
1028 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
1031 }
1032
1033 // @llvm.readcyclecounter requires the Performance Monitors extension.
1034 // Default to the 0 expansion on unsupported platforms.
1035 // FIXME: Technically there are older ARM CPUs that have
1036 // implementation-specific ways of obtaining this information.
1037 if (Subtarget->hasPerfMon())
1039
1040 // Only ARMv6 has BSWAP.
1041 if (!Subtarget->hasV6Ops())
1043
1044 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
1045 : Subtarget->hasDivideInARMMode();
1046 if (!hasDivide) {
1047 // These are expanded into libcalls if the cpu doesn't have HW divider.
1050 }
1051
1052 if (TT.isOSWindows() && !Subtarget->hasDivideInThumbMode()) {
1055
1058 }
1059
1062
1063 // Register based DivRem for AEABI (RTABI 4.2)
1064 if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
1065 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isOSWindows()) {
1068 HasStandaloneRem = false;
1069
1074 } else {
1077 }
1078
1083
1084 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1086
1087 // Use the default implementation.
1089 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1091 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1094
1095 if (TT.isOSWindows())
1097 else
1099
1100 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
1101 // the default expansion.
1102 InsertFencesForAtomic = false;
1103 if (Subtarget->hasAnyDataBarrier() &&
1104 (!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps())) {
1105 // ATOMIC_FENCE needs custom lowering; the others should have been expanded
1106 // to ldrex/strex loops already.
1108 if (!Subtarget->isThumb() || !Subtarget->isMClass())
1110
1111 // On v8, we have particularly efficient implementations of atomic fences
1112 // if they can be combined with nearby atomic loads and stores.
1113 if (!Subtarget->hasAcquireRelease() ||
1114 getTargetMachine().getOptLevel() == CodeGenOptLevel::None) {
1115 // Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
1116 InsertFencesForAtomic = true;
1117 }
1118 } else {
1119 // If there's anything we can use as a barrier, go through custom lowering
1120 // for ATOMIC_FENCE.
1121 // If target has DMB in thumb, Fences can be inserted.
1122 if (Subtarget->hasDataBarrier())
1123 InsertFencesForAtomic = true;
1124
1126 Subtarget->hasAnyDataBarrier() ? Custom : Expand);
1127
1128 // Set them all for libcall, which will force libcalls.
1141 // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the
1142 // Unordered/Monotonic case.
1143 if (!InsertFencesForAtomic) {
1146 }
1147 }
1148
1149 // Compute supported atomic widths.
1150 if (TT.isOSLinux() || (!Subtarget->isMClass() && Subtarget->hasV6Ops())) {
1151 // For targets where __sync_* routines are reliably available, we use them
1152 // if necessary.
1153 //
1154 // ARM Linux always supports 64-bit atomics through kernel-assisted atomic
1155 // routines (kernel 3.1 or later). FIXME: Not with compiler-rt?
1156 //
1157 // ARMv6 targets have native instructions in ARM mode. For Thumb mode,
1158 // such targets should provide __sync_* routines, which use the ARM mode
1159 // instructions. (ARMv6 doesn't have dmb, but it has an equivalent
1160 // encoding; see ARMISD::MEMBARRIER_MCR.)
1162 } else if ((Subtarget->isMClass() && Subtarget->hasV8MBaselineOps()) ||
1163 Subtarget->hasForced32BitAtomics()) {
1164 // Cortex-M (besides Cortex-M0) have 32-bit atomics.
1166 } else {
1167 // We can't assume anything about other targets; just use libatomic
1168 // routines.
1170 }
1171
1173
1175
1176 // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
1177 if (!Subtarget->hasV6Ops()) {
1180 }
1182
1183 if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() &&
1184 !Subtarget->isThumb1Only()) {
1185 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
1186 // iff target supports vfp2.
1196 }
1197
1198 // We want to custom lower some of our intrinsics.
1203
1213 if (Subtarget->hasFullFP16()) {
1217 }
1218
1220
1223 if (Subtarget->hasFullFP16())
1227 setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1228
1229 // We don't support sin/cos/fmod/copysign/pow
1238 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
1239 !Subtarget->isThumb1Only()) {
1242 }
1245
1246 if (!Subtarget->hasVFP4Base()) {
1249 }
1250
1251 // Various VFP goodness
1252 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
1253 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1254 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
1259 }
1260
1261 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
1262 if (!Subtarget->hasFP16()) {
1267 }
1268
1269 // Strict floating-point comparisons need custom lowering.
1276 }
1277
1278 // FP-ARMv8 implements a lot of rounding-like FP operations.
1279 if (Subtarget->hasFPARMv8Base()) {
1280 for (auto Op :
1287 setOperationAction(Op, MVT::f32, Legal);
1288
1289 if (Subtarget->hasFP64())
1290 setOperationAction(Op, MVT::f64, Legal);
1291 }
1292
1293 if (Subtarget->hasNEON()) {
1298 }
1299 }
1300
1301 // FP16 often need to be promoted to call lib functions
1302 // clang-format off
1303 if (Subtarget->hasFullFP16()) {
1307
1308 for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1322 setOperationAction(Op, MVT::f16, Promote);
1323 }
1324
1325 // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1326 // because the result type is integer.
1328 setOperationAction(Op, MVT::f16, Custom);
1329
1335 setOperationAction(Op, MVT::f16, Legal);
1336 }
1337 // clang-format on
1338 }
1339
1340 if (Subtarget->hasNEON()) {
1341 // vmin and vmax aren't available in a scalar form, so we can use
1342 // a NEON instruction with an undef lane instead.
1351
1352 if (Subtarget->hasV8Ops()) {
1357 setOperationAction(Op, MVT::v2f32, Legal);
1358 setOperationAction(Op, MVT::v4f32, Legal);
1359 }
1360 }
1361
1362 if (Subtarget->hasFullFP16()) {
1367
1372
1377 setOperationAction(Op, MVT::v4f16, Legal);
1378 setOperationAction(Op, MVT::v8f16, Legal);
1379 }
1380 }
1381 }
1382
1383 // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined. MinGW has
1384 // it, but it's just a wrapper around ldexp.
1385 if (TT.isOSWindows()) {
1387 if (isOperationExpand(Op, MVT::f32))
1388 setOperationAction(Op, MVT::f32, Promote);
1389 }
1390
1391 // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
1392 // isn't legal.
1394 if (isOperationExpand(Op, MVT::f16))
1395 setOperationAction(Op, MVT::f16, Promote);
1396
1397 // We have target-specific dag combine patterns for the following nodes:
1398 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
1401
1402 if (Subtarget->hasMVEIntegerOps())
1404
1405 if (Subtarget->hasV6Ops())
1407 if (Subtarget->isThumb1Only())
1409 // Attempt to lower smin/smax to ssat/usat
1410 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) ||
1411 Subtarget->isThumb2()) {
1413 }
1414
1416
1417 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1418 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
1420 else
1422
1423 //// temporary - rewrite interface to use type
1426 MaxStoresPerMemcpy = 4; // For @llvm.memcpy -> sequence of stores
1428 MaxStoresPerMemmove = 4; // For @llvm.memmove -> sequence of stores
1430
1431 // On ARM arguments smaller than 4 bytes are extended, so all arguments
1432 // are at least 4 bytes aligned.
1434
1435 // Prefer likely predicted branches to selects on out-of-order cores.
1436 PredictableSelectIsExpensive = Subtarget->getSchedModel().isOutOfOrder();
1437
1438 setPrefLoopAlignment(Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1440 Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1441
1442 setMinFunctionAlignment(Subtarget->isThumb() ? Align(2) : Align(4));
1443
1444 IsStrictFPEnabled = true;
1445}
1446
1448 return Subtarget->useSoftFloat();
1449}
1450
1452 return !Subtarget->isThumb1Only() && VT.getSizeInBits() <= 32;
1453}
1454
1455// FIXME: It might make sense to define the representative register class as the
1456// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
1457// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
1458// SPR's representative would be DPR_VFP2. This should work well if register
1459// pressure tracking were modified such that a register use would increment the
1460// pressure of the register class's representative and all of it's super
1461// classes' representatives transitively. We have not implemented this because
1462// of the difficulty prior to coalescing of modeling operand register classes
1463// due to the common occurrence of cross class copies and subregister insertions
1464// and extractions.
1465std::pair<const TargetRegisterClass *, uint8_t>
1467 MVT VT) const {
1468 const TargetRegisterClass *RRC = nullptr;
1469 uint8_t Cost = 1;
1470 switch (VT.SimpleTy) {
1471 default:
1473 // Use DPR as representative register class for all floating point
1474 // and vector types. Since there are 32 SPR registers and 32 DPR registers so
1475 // the cost is 1 for both f32 and f64.
1476 case MVT::f32: case MVT::f64: case MVT::v8i8: case MVT::v4i16:
1477 case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
1478 RRC = &ARM::DPRRegClass;
1479 // When NEON is used for SP, only half of the register file is available
1480 // because operations that define both SP and DP results will be constrained
1481 // to the VFP2 class (D0-D15). We currently model this constraint prior to
1482 // coalescing by double-counting the SP regs. See the FIXME above.
1483 if (Subtarget->useNEONForSinglePrecisionFP())
1484 Cost = 2;
1485 break;
1486 case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
1487 case MVT::v4f32: case MVT::v2f64:
1488 RRC = &ARM::DPRRegClass;
1489 Cost = 2;
1490 break;
1491 case MVT::v4i64:
1492 RRC = &ARM::DPRRegClass;
1493 Cost = 4;
1494 break;
1495 case MVT::v8i64:
1496 RRC = &ARM::DPRRegClass;
1497 Cost = 8;
1498 break;
1499 }
1500 return std::make_pair(RRC, Cost);
1501}
1502
1504 EVT VT) const {
1505 if (!VT.isVector())
1506 return getPointerTy(DL);
1507
1508 // MVE has a predicate register.
1509 if (Subtarget->hasMVEIntegerOps())
1510 return EVT::getVectorVT(C, MVT::i1, VT.getVectorElementCount());
1511
1513}
1514
1515/// getRegClassFor - Return the register class that should be used for the
1516/// specified value type.
1517const TargetRegisterClass *
1518ARMTargetLowering::getRegClassFor(MVT VT, bool isDivergent) const {
1519 (void)isDivergent;
1520 // Map v4i64 to QQ registers but do not make the type legal. Similarly map
1521 // v8i64 to QQQQ registers. v4i64 and v8i64 are only used for REG_SEQUENCE to
1522 // load / store 4 to 8 consecutive NEON D registers, or 2 to 4 consecutive
1523 // MVE Q registers.
1524 if (Subtarget->hasNEON()) {
1525 if (VT == MVT::v4i64)
1526 return &ARM::QQPRRegClass;
1527 if (VT == MVT::v8i64)
1528 return &ARM::QQQQPRRegClass;
1529 }
1530 if (Subtarget->hasMVEIntegerOps()) {
1531 if (VT == MVT::v4i64)
1532 return &ARM::MQQPRRegClass;
1533 if (VT == MVT::v8i64)
1534 return &ARM::MQQQQPRRegClass;
1535 }
1537}
1538
1539// memcpy, and other memory intrinsics, typically tries to use LDM/STM if the
1540// source/dest is aligned and the copy size is large enough. We therefore want
1541// to align such objects passed to memory intrinsics.
1543 Align &PrefAlign) const {
1544 if (!isa<MemIntrinsic>(CI))
1545 return false;
1546 MinSize = 8;
1547 // On ARM11 onwards (excluding M class) 8-byte aligned LDM is typically 1
1548 // cycle faster than 4-byte aligned LDM.
1549 PrefAlign =
1550 (Subtarget->hasV6Ops() && !Subtarget->isMClass() ? Align(8) : Align(4));
1551 return true;
1552}
1553
1554// Create a fast isel object.
1556 FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo,
1557 const LibcallLoweringInfo *libcallLowering) const {
1558 return ARM::createFastISel(funcInfo, libInfo, libcallLowering);
1559}
1560
1562 unsigned NumVals = N->getNumValues();
1563 if (!NumVals)
1564 return Sched::RegPressure;
1565
1566 for (unsigned i = 0; i != NumVals; ++i) {
1567 EVT VT = N->getValueType(i);
1568 if (VT == MVT::Glue || VT == MVT::Other)
1569 continue;
1570 if (VT.isFloatingPoint() || VT.isVector())
1571 return Sched::ILP;
1572 }
1573
1574 if (!N->isMachineOpcode())
1575 return Sched::RegPressure;
1576
1577 // Load are scheduled for latency even if there instruction itinerary
1578 // is not available.
1579 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
1580 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1581
1582 if (MCID.getNumDefs() == 0)
1583 return Sched::RegPressure;
1584 if (!Itins->isEmpty() &&
1585 Itins->getOperandCycle(MCID.getSchedClass(), 0) > 2U)
1586 return Sched::ILP;
1587
1588 return Sched::RegPressure;
1589}
1590
1591//===----------------------------------------------------------------------===//
1592// Lowering Code
1593//===----------------------------------------------------------------------===//
1594
1595static bool isSRL16(const SDValue &Op) {
1596 if (Op.getOpcode() != ISD::SRL)
1597 return false;
1598 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1599 return Const->getZExtValue() == 16;
1600 return false;
1601}
1602
1603static bool isSRA16(const SDValue &Op) {
1604 if (Op.getOpcode() != ISD::SRA)
1605 return false;
1606 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1607 return Const->getZExtValue() == 16;
1608 return false;
1609}
1610
1611static bool isSHL16(const SDValue &Op) {
1612 if (Op.getOpcode() != ISD::SHL)
1613 return false;
1614 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1615 return Const->getZExtValue() == 16;
1616 return false;
1617}
1618
1619// Check for a signed 16-bit value. We special case SRA because it makes it
1620// more simple when also looking for SRAs that aren't sign extending a
1621// smaller value. Without the check, we'd need to take extra care with
1622// checking order for some operations.
1623static bool isS16(const SDValue &Op, SelectionDAG &DAG) {
1624 if (isSRA16(Op))
1625 return isSHL16(Op.getOperand(0));
1626 return DAG.ComputeNumSignBits(Op) == 17;
1627}
1628
1629/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
1631 switch (CC) {
1632 default: llvm_unreachable("Unknown condition code!");
1633 case ISD::SETNE: return ARMCC::NE;
1634 case ISD::SETEQ: return ARMCC::EQ;
1635 case ISD::SETGT: return ARMCC::GT;
1636 case ISD::SETGE: return ARMCC::GE;
1637 case ISD::SETLT: return ARMCC::LT;
1638 case ISD::SETLE: return ARMCC::LE;
1639 case ISD::SETUGT: return ARMCC::HI;
1640 case ISD::SETUGE: return ARMCC::HS;
1641 case ISD::SETULT: return ARMCC::LO;
1642 case ISD::SETULE: return ARMCC::LS;
1643 }
1644}
1645
1646/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
1648 ARMCC::CondCodes &CondCode2) {
1649 CondCode2 = ARMCC::AL;
1650 switch (CC) {
1651 default: llvm_unreachable("Unknown FP condition!");
1652 case ISD::SETEQ:
1653 case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
1654 case ISD::SETGT:
1655 case ISD::SETOGT: CondCode = ARMCC::GT; break;
1656 case ISD::SETGE:
1657 case ISD::SETOGE: CondCode = ARMCC::GE; break;
1658 case ISD::SETOLT: CondCode = ARMCC::MI; break;
1659 case ISD::SETOLE: CondCode = ARMCC::LS; break;
1660 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
1661 case ISD::SETO: CondCode = ARMCC::VC; break;
1662 case ISD::SETUO: CondCode = ARMCC::VS; break;
1663 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
1664 case ISD::SETUGT: CondCode = ARMCC::HI; break;
1665 case ISD::SETUGE: CondCode = ARMCC::PL; break;
1666 case ISD::SETLT:
1667 case ISD::SETULT: CondCode = ARMCC::LT; break;
1668 case ISD::SETLE:
1669 case ISD::SETULE: CondCode = ARMCC::LE; break;
1670 case ISD::SETNE:
1671 case ISD::SETUNE: CondCode = ARMCC::NE; break;
1672 }
1673}
1674
1675//===----------------------------------------------------------------------===//
1676// Calling Convention Implementation
1677//===----------------------------------------------------------------------===//
1678
1679/// getEffectiveCallingConv - Get the effective calling convention, taking into
1680/// account presence of floating point hardware and calling convention
1681/// limitations, such as support for variadic functions.
1683ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
1684 bool isVarArg) const {
1685 switch (CC) {
1686 default:
1687 report_fatal_error("Unsupported calling convention");
1690 case CallingConv::GHC:
1692 return CC;
1698 case CallingConv::Swift:
1701 case CallingConv::C:
1702 case CallingConv::Tail:
1703 if (!getTM().isAAPCS_ABI())
1704 return CallingConv::ARM_APCS;
1705 else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1706 getTargetMachine().Options.FloatABIType == FloatABI::Hard &&
1707 !isVarArg)
1709 else
1711 case CallingConv::Fast:
1713 if (!getTM().isAAPCS_ABI()) {
1714 if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() && !isVarArg)
1715 return CallingConv::Fast;
1716 return CallingConv::ARM_APCS;
1717 } else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1718 !isVarArg)
1720 else
1722 }
1723}
1724
1726 bool isVarArg) const {
1727 return CCAssignFnForNode(CC, false, isVarArg);
1728}
1729
1731 bool isVarArg) const {
1732 return CCAssignFnForNode(CC, true, isVarArg);
1733}
1734
1735/// CCAssignFnForNode - Selects the correct CCAssignFn for the given
1736/// CallingConvention.
1737CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
1738 bool Return,
1739 bool isVarArg) const {
1740 switch (getEffectiveCallingConv(CC, isVarArg)) {
1741 default:
1742 report_fatal_error("Unsupported calling convention");
1744 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1746 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1748 return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1749 case CallingConv::Fast:
1750 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1751 case CallingConv::GHC:
1752 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1754 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1756 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1758 return (Return ? RetCC_ARM_AAPCS : CC_ARM_Win32_CFGuard_Check);
1759 }
1760}
1761
1762SDValue ARMTargetLowering::MoveToHPR(const SDLoc &dl, SelectionDAG &DAG,
1763 MVT LocVT, MVT ValVT, SDValue Val) const {
1764 Val = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocVT.getSizeInBits()),
1765 Val);
1766 if (Subtarget->hasFullFP16()) {
1767 Val = DAG.getNode(ARMISD::VMOVhr, dl, ValVT, Val);
1768 } else {
1769 Val = DAG.getNode(ISD::TRUNCATE, dl,
1770 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1771 Val = DAG.getNode(ISD::BITCAST, dl, ValVT, Val);
1772 }
1773 return Val;
1774}
1775
1776SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
1777 MVT LocVT, MVT ValVT,
1778 SDValue Val) const {
1779 if (Subtarget->hasFullFP16()) {
1780 Val = DAG.getNode(ARMISD::VMOVrh, dl,
1781 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1782 } else {
1783 Val = DAG.getNode(ISD::BITCAST, dl,
1784 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1785 Val = DAG.getNode(ISD::ZERO_EXTEND, dl,
1786 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1787 }
1788 return DAG.getNode(ISD::BITCAST, dl, LocVT, Val);
1789}
1790
1791/// LowerCallResult - Lower the result values of a call into the
1792/// appropriate copies out of appropriate physical registers.
1793SDValue ARMTargetLowering::LowerCallResult(
1794 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
1795 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1796 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
1797 SDValue ThisVal, bool isCmseNSCall) const {
1798 // Assign locations to each value returned by this call.
1800 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1801 *DAG.getContext());
1802 CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, isVarArg));
1803
1804 // Copy all of the result registers out of their specified physreg.
1805 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1806 CCValAssign VA = RVLocs[i];
1807
1808 // Pass 'this' value directly from the argument to return value, to avoid
1809 // reg unit interference
1810 if (i == 0 && isThisReturn) {
1811 assert(!VA.needsCustom() && VA.getLocVT() == MVT::i32 &&
1812 "unexpected return calling convention register assignment");
1813 InVals.push_back(ThisVal);
1814 continue;
1815 }
1816
1817 SDValue Val;
1818 if (VA.needsCustom() &&
1819 (VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2f64)) {
1820 // Handle f64 or half of a v2f64.
1821 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1822 InGlue);
1823 Chain = Lo.getValue(1);
1824 InGlue = Lo.getValue(2);
1825 VA = RVLocs[++i]; // skip ahead to next loc
1826 SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1827 InGlue);
1828 Chain = Hi.getValue(1);
1829 InGlue = Hi.getValue(2);
1830 if (!Subtarget->isLittle())
1831 std::swap (Lo, Hi);
1832 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1833
1834 if (VA.getLocVT() == MVT::v2f64) {
1835 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
1836 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1837 DAG.getConstant(0, dl, MVT::i32));
1838
1839 VA = RVLocs[++i]; // skip ahead to next loc
1840 Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1841 Chain = Lo.getValue(1);
1842 InGlue = Lo.getValue(2);
1843 VA = RVLocs[++i]; // skip ahead to next loc
1844 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1845 Chain = Hi.getValue(1);
1846 InGlue = Hi.getValue(2);
1847 if (!Subtarget->isLittle())
1848 std::swap (Lo, Hi);
1849 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1850 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1851 DAG.getConstant(1, dl, MVT::i32));
1852 }
1853 } else {
1854 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(),
1855 InGlue);
1856 Chain = Val.getValue(1);
1857 InGlue = Val.getValue(2);
1858 }
1859
1860 switch (VA.getLocInfo()) {
1861 default: llvm_unreachable("Unknown loc info!");
1862 case CCValAssign::Full: break;
1863 case CCValAssign::BCvt:
1864 Val = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), Val);
1865 break;
1866 }
1867
1868 // f16 arguments have their size extended to 4 bytes and passed as if they
1869 // had been copied to the LSBs of a 32-bit register.
1870 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
1871 if (VA.needsCustom() &&
1872 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
1873 Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
1874
1875 // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
1876 // is less than 32 bits must be sign- or zero-extended after the call for
1877 // security reasons. Although the ABI mandates an extension done by the
1878 // callee, the latter cannot be trusted to follow the rules of the ABI.
1879 const ISD::InputArg &Arg = Ins[VA.getValNo()];
1880 if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
1881 VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
1882 Val = handleCMSEValue(Val, Arg, DAG, dl);
1883
1884 InVals.push_back(Val);
1885 }
1886
1887 return Chain;
1888}
1889
1890std::pair<SDValue, MachinePointerInfo> ARMTargetLowering::computeAddrForCallArg(
1891 const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA, SDValue StackPtr,
1892 bool IsTailCall, int SPDiff) const {
1893 SDValue DstAddr;
1894 MachinePointerInfo DstInfo;
1895 int32_t Offset = VA.getLocMemOffset();
1896 MachineFunction &MF = DAG.getMachineFunction();
1897
1898 if (IsTailCall) {
1899 Offset += SPDiff;
1900 auto PtrVT = getPointerTy(DAG.getDataLayout());
1901 int Size = VA.getLocVT().getFixedSizeInBits() / 8;
1902 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
1903 DstAddr = DAG.getFrameIndex(FI, PtrVT);
1904 DstInfo =
1906 } else {
1907 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1908 DstAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
1909 StackPtr, PtrOff);
1910 DstInfo =
1912 }
1913
1914 return std::make_pair(DstAddr, DstInfo);
1915}
1916
1917// Returns the type of copying which is required to set up a byval argument to
1918// a tail-called function. This isn't needed for non-tail calls, because they
1919// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
1920// avoid clobbering another argument (CopyViaTemp), and sometimes can be
1921// optimised to zero copies when forwarding an argument from the caller's
1922// caller (NoCopy).
1923ARMTargetLowering::ByValCopyKind ARMTargetLowering::ByValNeedsCopyForTailCall(
1924 SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
1925 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1926 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
1927
1928 // Globals are always safe to copy from.
1930 return CopyOnce;
1931
1932 // Can only analyse frame index nodes, conservatively assume we need a
1933 // temporary.
1934 auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
1935 auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
1936 if (!SrcFrameIdxNode || !DstFrameIdxNode)
1937 return CopyViaTemp;
1938
1939 int SrcFI = SrcFrameIdxNode->getIndex();
1940 int DstFI = DstFrameIdxNode->getIndex();
1941 assert(MFI.isFixedObjectIndex(DstFI) &&
1942 "byval passed in non-fixed stack slot");
1943
1944 int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
1945 int64_t DstOffset = MFI.getObjectOffset(DstFI);
1946
1947 // If the source is in the local frame, then the copy to the argument memory
1948 // is always valid.
1949 bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
1950 if (!FixedSrc ||
1951 (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
1952 return CopyOnce;
1953
1954 // In the case of byval arguments split between registers and the stack,
1955 // computeAddrForCallArg returns a FrameIndex which corresponds only to the
1956 // stack portion, but the Src SDValue will refer to the full value, including
1957 // the local stack memory that the register portion gets stored into. We only
1958 // need to compare them for equality, so normalise on the full value version.
1959 uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
1960 DstOffset -= RegSize;
1961
1962 // If the value is already in the correct location, then no copying is
1963 // needed. If not, then we need to copy via a temporary.
1964 if (SrcOffset == DstOffset)
1965 return NoCopy;
1966 else
1967 return CopyViaTemp;
1968}
1969
1970void ARMTargetLowering::PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG,
1971 SDValue Chain, SDValue &Arg,
1972 RegsToPassVector &RegsToPass,
1973 CCValAssign &VA, CCValAssign &NextVA,
1974 SDValue &StackPtr,
1975 SmallVectorImpl<SDValue> &MemOpChains,
1976 bool IsTailCall,
1977 int SPDiff) const {
1978 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
1979 DAG.getVTList(MVT::i32, MVT::i32), Arg);
1980 unsigned id = Subtarget->isLittle() ? 0 : 1;
1981 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
1982
1983 if (NextVA.isRegLoc())
1984 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
1985 else {
1986 assert(NextVA.isMemLoc());
1987 if (!StackPtr.getNode())
1988 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP,
1990
1991 SDValue DstAddr;
1992 MachinePointerInfo DstInfo;
1993 std::tie(DstAddr, DstInfo) =
1994 computeAddrForCallArg(dl, DAG, NextVA, StackPtr, IsTailCall, SPDiff);
1995 MemOpChains.push_back(
1996 DAG.getStore(Chain, dl, fmrrd.getValue(1 - id), DstAddr, DstInfo));
1997 }
1998}
1999
2000static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
2001 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
2003}
2004
2005/// LowerCall - Lowering a call into a callseq_start <-
2006/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
2007/// nodes.
2008SDValue
2009ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2010 SmallVectorImpl<SDValue> &InVals) const {
2011 SelectionDAG &DAG = CLI.DAG;
2012 SDLoc &dl = CLI.DL;
2013 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2014 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2015 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2016 SDValue Chain = CLI.Chain;
2017 SDValue Callee = CLI.Callee;
2018 bool &isTailCall = CLI.IsTailCall;
2019 CallingConv::ID CallConv = CLI.CallConv;
2020 bool doesNotRet = CLI.DoesNotReturn;
2021 bool isVarArg = CLI.IsVarArg;
2022 const CallBase *CB = CLI.CB;
2023
2024 MachineFunction &MF = DAG.getMachineFunction();
2025 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2026 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2027 MachineFunction::CallSiteInfo CSInfo;
2028 bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
2029 bool isThisReturn = false;
2030 bool isCmseNSCall = false;
2031 bool isSibCall = false;
2032 bool PreferIndirect = false;
2033 bool GuardWithBTI = false;
2034
2035 // Analyze operands of the call, assigning locations to each operand.
2037 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
2038 *DAG.getContext());
2039 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, isVarArg));
2040
2041 // Lower 'returns_twice' calls to a pseudo-instruction.
2042 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) &&
2043 !Subtarget->noBTIAtReturnTwice())
2044 GuardWithBTI = AFI->branchTargetEnforcement();
2045
2046 // Set type id for call site info.
2047 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
2048
2049 // Determine whether this is a non-secure function call.
2050 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
2051 isCmseNSCall = true;
2052
2053 // Disable tail calls if they're not supported.
2054 if (!Subtarget->supportsTailCall())
2055 isTailCall = false;
2056
2057 // For both the non-secure calls and the returns from a CMSE entry function,
2058 // the function needs to do some extra work after the call, or before the
2059 // return, respectively, thus it cannot end with a tail call
2060 if (isCmseNSCall || AFI->isCmseNSEntryFunction())
2061 isTailCall = false;
2062
2063 if (isa<GlobalAddressSDNode>(Callee)) {
2064 // If we're optimizing for minimum size and the function is called three or
2065 // more times in this block, we can improve codesize by calling indirectly
2066 // as BLXr has a 16-bit encoding.
2067 auto *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
2068 if (CLI.CB) {
2069 auto *BB = CLI.CB->getParent();
2070 PreferIndirect = Subtarget->isThumb() && Subtarget->hasMinSize() &&
2071 count_if(GV->users(), [&BB](const User *U) {
2072 return isa<Instruction>(U) &&
2073 cast<Instruction>(U)->getParent() == BB;
2074 }) > 2;
2075 }
2076 }
2077 if (isTailCall) {
2078 // Check if it's really possible to do a tail call.
2079 isTailCall =
2080 IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
2081
2082 if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
2083 CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
2084 isSibCall = true;
2085
2086 // We don't support GuaranteedTailCallOpt for ARM, only automatically
2087 // detected sibcalls.
2088 if (isTailCall)
2089 ++NumTailCalls;
2090 }
2091
2092 if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
2093 report_fatal_error("failed to perform tail call elimination on a call "
2094 "site marked musttail");
2095
2096 // Get a count of how many bytes are to be pushed on the stack.
2097 unsigned NumBytes = CCInfo.getStackSize();
2098
2099 // SPDiff is the byte offset of the call's argument area from the callee's.
2100 // Stores to callee stack arguments will be placed in FixedStackSlots offset
2101 // by this amount for a tail call. In a sibling call it must be 0 because the
2102 // caller will deallocate the entire stack and the callee still expects its
2103 // arguments to begin at SP+0. Completely unused for non-tail calls.
2104 int SPDiff = 0;
2105
2106 if (isTailCall && !isSibCall) {
2107 auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
2108 unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
2109
2110 // Since callee will pop argument stack as a tail call, we must keep the
2111 // popped size 16-byte aligned.
2112 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
2113 assert(StackAlign && "data layout string is missing stack alignment");
2114 NumBytes = alignTo(NumBytes, *StackAlign);
2115
2116 // SPDiff will be negative if this tail call requires more space than we
2117 // would automatically have in our incoming argument space. Positive if we
2118 // can actually shrink the stack.
2119 SPDiff = NumReusableBytes - NumBytes;
2120
2121 // If this call requires more stack than we have available from
2122 // LowerFormalArguments, tell FrameLowering to reserve space for it.
2123 if (SPDiff < 0 && AFI->getArgRegsSaveSize() < (unsigned)-SPDiff)
2124 AFI->setArgRegsSaveSize(-SPDiff);
2125 }
2126
2127 if (isSibCall) {
2128 // For sibling tail calls, memory operands are available in our caller's stack.
2129 NumBytes = 0;
2130 } else {
2131 // Adjust the stack pointer for the new arguments...
2132 // These operations are automatically eliminated by the prolog/epilog pass
2133 Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
2134 }
2135
2137 DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy(DAG.getDataLayout()));
2138
2139 RegsToPassVector RegsToPass;
2140 SmallVector<SDValue, 8> MemOpChains;
2141
2142 // If we are doing a tail-call, any byval arguments will be written to stack
2143 // space which was used for incoming arguments. If any the values being used
2144 // are incoming byval arguments to this function, then they might be
2145 // overwritten by the stores of the outgoing arguments. To avoid this, we
2146 // need to make a temporary copy of them in local stack space, then copy back
2147 // to the argument area.
2148 DenseMap<unsigned, SDValue> ByValTemporaries;
2149 SDValue ByValTempChain;
2150 if (isTailCall) {
2151 SmallVector<SDValue, 8> ByValCopyChains;
2152 for (const CCValAssign &VA : ArgLocs) {
2153 unsigned ArgIdx = VA.getValNo();
2154 SDValue Src = OutVals[ArgIdx];
2155 ISD::ArgFlagsTy Flags = Outs[ArgIdx].Flags;
2156
2157 if (!Flags.isByVal())
2158 continue;
2159
2160 SDValue Dst;
2161 MachinePointerInfo DstInfo;
2162 std::tie(Dst, DstInfo) =
2163 computeAddrForCallArg(dl, DAG, VA, SDValue(), true, SPDiff);
2164 ByValCopyKind Copy = ByValNeedsCopyForTailCall(DAG, Src, Dst, Flags);
2165
2166 if (Copy == NoCopy) {
2167 // If the argument is already at the correct offset on the stack
2168 // (because we are forwarding a byval argument from our caller), we
2169 // don't need any copying.
2170 continue;
2171 } else if (Copy == CopyOnce) {
2172 // If the argument is in our local stack frame, no other argument
2173 // preparation can clobber it, so we can copy it to the final location
2174 // later.
2175 ByValTemporaries[ArgIdx] = Src;
2176 } else {
2177 assert(Copy == CopyViaTemp && "unexpected enum value");
2178 // If we might be copying this argument from the outgoing argument
2179 // stack area, we need to copy via a temporary in the local stack
2180 // frame.
2181 int TempFrameIdx = MFI.CreateStackObject(
2182 Flags.getByValSize(), Flags.getNonZeroByValAlign(), false);
2183 SDValue Temp =
2184 DAG.getFrameIndex(TempFrameIdx, getPointerTy(DAG.getDataLayout()));
2185
2186 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
2187 SDValue AlignNode =
2188 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2189
2190 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2191 SDValue Ops[] = {Chain, Temp, Src, SizeNode, AlignNode};
2192 ByValCopyChains.push_back(
2193 DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs, Ops));
2194 ByValTemporaries[ArgIdx] = Temp;
2195 }
2196 }
2197 if (!ByValCopyChains.empty())
2198 ByValTempChain =
2199 DAG.getNode(ISD::TokenFactor, dl, MVT::Other, ByValCopyChains);
2200 }
2201
2202 // During a tail call, stores to the argument area must happen after all of
2203 // the function's incoming arguments have been loaded because they may alias.
2204 // This is done by folding in a TokenFactor from LowerFormalArguments, but
2205 // there's no point in doing so repeatedly so this tracks whether that's
2206 // happened yet.
2207 bool AfterFormalArgLoads = false;
2208
2209 // Walk the register/memloc assignments, inserting copies/loads. In the case
2210 // of tail call optimization, arguments are handled later.
2211 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size();
2212 i != e;
2213 ++i, ++realArgIdx) {
2214 CCValAssign &VA = ArgLocs[i];
2215 SDValue Arg = OutVals[realArgIdx];
2216 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
2217 bool isByVal = Flags.isByVal();
2218
2219 // Promote the value if needed.
2220 switch (VA.getLocInfo()) {
2221 default: llvm_unreachable("Unknown loc info!");
2222 case CCValAssign::Full: break;
2223 case CCValAssign::SExt:
2224 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
2225 break;
2226 case CCValAssign::ZExt:
2227 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
2228 break;
2229 case CCValAssign::AExt:
2230 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
2231 break;
2232 case CCValAssign::BCvt:
2233 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2234 break;
2235 }
2236
2237 if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
2238 Chain = DAG.getStackArgumentTokenFactor(Chain);
2239 if (ByValTempChain) {
2240 // In case of large byval copies, re-using the stackframe for tail-calls
2241 // can lead to overwriting incoming arguments on the stack. Force
2242 // loading these stack arguments before the copy to avoid that.
2243 SmallVector<SDValue, 8> IncomingLoad;
2244 for (unsigned I = 0; I < OutVals.size(); ++I) {
2245 if (Outs[I].Flags.isByVal())
2246 continue;
2247
2248 SDValue OutVal = OutVals[I];
2249 LoadSDNode *OutLN = dyn_cast_or_null<LoadSDNode>(OutVal);
2250 if (!OutLN)
2251 continue;
2252
2253 FrameIndexSDNode *FIN =
2255 if (!FIN)
2256 continue;
2257
2258 if (!MFI.isFixedObjectIndex(FIN->getIndex()))
2259 continue;
2260
2261 for (const CCValAssign &VA : ArgLocs) {
2262 if (VA.isMemLoc())
2263 IncomingLoad.push_back(OutVal.getValue(1));
2264 }
2265 }
2266
2267 // Update the chain to force loads for potentially clobbered argument
2268 // loads to happen before the byval copy.
2269 if (!IncomingLoad.empty()) {
2270 IncomingLoad.push_back(Chain);
2271 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, IncomingLoad);
2272 }
2273
2274 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chain,
2275 ByValTempChain);
2276 }
2277 AfterFormalArgLoads = true;
2278 }
2279
2280 // f16 arguments have their size extended to 4 bytes and passed as if they
2281 // had been copied to the LSBs of a 32-bit register.
2282 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
2283 if (VA.needsCustom() &&
2284 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16)) {
2285 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2286 } else {
2287 // f16 arguments could have been extended prior to argument lowering.
2288 // Mask them arguments if this is a CMSE nonsecure call.
2289 auto ArgVT = Outs[realArgIdx].ArgVT;
2290 if (isCmseNSCall && (ArgVT == MVT::f16)) {
2291 auto LocBits = VA.getLocVT().getSizeInBits();
2292 auto MaskValue = APInt::getLowBitsSet(LocBits, ArgVT.getSizeInBits());
2293 SDValue Mask =
2294 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2295 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2296 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2297 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2298 }
2299 }
2300
2301 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
2302 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
2303 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2304 DAG.getConstant(0, dl, MVT::i32));
2305 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2306 DAG.getConstant(1, dl, MVT::i32));
2307
2308 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
2309 StackPtr, MemOpChains, isTailCall, SPDiff);
2310
2311 VA = ArgLocs[++i]; // skip ahead to next loc
2312 if (VA.isRegLoc()) {
2313 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
2314 StackPtr, MemOpChains, isTailCall, SPDiff);
2315 } else {
2316 assert(VA.isMemLoc());
2317 SDValue DstAddr;
2318 MachinePointerInfo DstInfo;
2319 std::tie(DstAddr, DstInfo) =
2320 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2321 MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
2322 }
2323 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
2324 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
2325 StackPtr, MemOpChains, isTailCall, SPDiff);
2326 } else if (VA.isRegLoc()) {
2327 if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
2328 Outs[0].VT == MVT::i32) {
2329 assert(VA.getLocVT() == MVT::i32 &&
2330 "unexpected calling convention register assignment");
2331 assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
2332 "unexpected use of 'returned'");
2333 isThisReturn = true;
2334 }
2335 const TargetOptions &Options = DAG.getTarget().Options;
2336 if (Options.EmitCallSiteInfo)
2337 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
2338 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2339 } else if (isByVal) {
2340 assert(VA.isMemLoc());
2341 unsigned offset = 0;
2342
2343 // True if this byval aggregate will be split between registers
2344 // and memory.
2345 unsigned ByValArgsCount = CCInfo.getInRegsParamsCount();
2346 unsigned CurByValIdx = CCInfo.getInRegsParamsProcessed();
2347
2348 SDValue ByValSrc;
2349 bool NeedsStackCopy;
2350 if (auto It = ByValTemporaries.find(realArgIdx);
2351 It != ByValTemporaries.end()) {
2352 ByValSrc = It->second;
2353 NeedsStackCopy = true;
2354 } else {
2355 ByValSrc = Arg;
2356 NeedsStackCopy = !isTailCall;
2357 }
2358
2359 // If part of the argument is in registers, load them.
2360 if (CurByValIdx < ByValArgsCount) {
2361 unsigned RegBegin, RegEnd;
2362 CCInfo.getInRegsParamInfo(CurByValIdx, RegBegin, RegEnd);
2363
2364 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2365 unsigned int i, j;
2366 for (i = 0, j = RegBegin; j < RegEnd; i++, j++) {
2367 SDValue Const = DAG.getConstant(4*i, dl, MVT::i32);
2368 SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, Const);
2369 SDValue Load =
2370 DAG.getLoad(PtrVT, dl, Chain, AddArg, MachinePointerInfo(),
2371 DAG.InferPtrAlign(AddArg));
2372 MemOpChains.push_back(Load.getValue(1));
2373 RegsToPass.push_back(std::make_pair(j, Load));
2374 }
2375
2376 // If parameter size outsides register area, "offset" value
2377 // helps us to calculate stack slot for remained part properly.
2378 offset = RegEnd - RegBegin;
2379
2380 CCInfo.nextInRegsParam();
2381 }
2382
2383 // If the memory part of the argument isn't already in the correct place
2384 // (which can happen with tail calls), copy it into the argument area.
2385 if (NeedsStackCopy && Flags.getByValSize() > 4 * offset) {
2386 auto PtrVT = getPointerTy(DAG.getDataLayout());
2387 SDValue Dst;
2388 MachinePointerInfo DstInfo;
2389 std::tie(Dst, DstInfo) =
2390 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2391 SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
2392 SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
2393 SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
2394 MVT::i32);
2395 SDValue AlignNode =
2396 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2397
2398 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2399 SDValue Ops[] = { Chain, Dst, Src, SizeNode, AlignNode};
2400 MemOpChains.push_back(DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs,
2401 Ops));
2402 }
2403 } else {
2404 assert(VA.isMemLoc());
2405 SDValue DstAddr;
2406 MachinePointerInfo DstInfo;
2407 std::tie(DstAddr, DstInfo) =
2408 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2409
2410 SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
2411 MemOpChains.push_back(Store);
2412 }
2413 }
2414
2415 if (!MemOpChains.empty())
2416 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
2417
2418 // Build a sequence of copy-to-reg nodes chained together with token chain
2419 // and flag operands which copy the outgoing args into the appropriate regs.
2420 SDValue InGlue;
2421 for (const auto &[Reg, N] : RegsToPass) {
2422 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
2423 InGlue = Chain.getValue(1);
2424 }
2425
2426 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2427 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2428 // node so that legalize doesn't hack it.
2429 bool isDirect = false;
2430
2431 const TargetMachine &TM = getTargetMachine();
2432 const Triple &TT = TM.getTargetTriple();
2433 const GlobalValue *GVal = nullptr;
2434 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
2435 GVal = G->getGlobal();
2436 bool isStub = !TM.shouldAssumeDSOLocal(GVal) && TT.isOSBinFormatMachO();
2437
2438 bool isARMFunc = !Subtarget->isThumb() || (isStub && !Subtarget->isMClass());
2439 bool isLocalARMFunc = false;
2440 auto PtrVt = getPointerTy(DAG.getDataLayout());
2441
2442 if (Subtarget->genLongCalls()) {
2443 assert((!isPositionIndependent() || TT.isOSWindows()) &&
2444 "long-calls codegen is not position independent!");
2445 // Handle a global address or an external symbol. If it's not one of
2446 // those, the target's already in a register, so we don't need to do
2447 // anything extra.
2448 if (isa<GlobalAddressSDNode>(Callee)) {
2449 if (Subtarget->genExecuteOnly()) {
2450 if (Subtarget->useMovt())
2451 ++NumMovwMovt;
2452 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2453 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2454 } else {
2455 // Create a constant pool entry for the callee address
2456 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2457 ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(
2458 GVal, ARMPCLabelIndex, ARMCP::CPValue, 0);
2459
2460 // Get the address of the callee into a register
2461 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2462 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2463 Callee = DAG.getLoad(
2464 PtrVt, dl, DAG.getEntryNode(), Addr,
2466 }
2467 } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
2468 const char *Sym = S->getSymbol();
2469
2470 if (Subtarget->genExecuteOnly()) {
2471 if (Subtarget->useMovt())
2472 ++NumMovwMovt;
2473 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2474 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2475 } else {
2476 // Create a constant pool entry for the callee address
2477 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2478 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2479 *DAG.getContext(), Sym, ARMPCLabelIndex, 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 }
2489 } else if (isa<GlobalAddressSDNode>(Callee)) {
2490 if (!PreferIndirect) {
2491 isDirect = true;
2492 bool isDef = GVal->isStrongDefinitionForLinker();
2493
2494 // ARM call to a local ARM function is predicable.
2495 isLocalARMFunc = !Subtarget->isThumb() && (isDef || !ARMInterworking);
2496 // tBX takes a register source operand.
2497 if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2498 assert(TT.isOSBinFormatMachO() && "WrapperPIC use on non-MachO?");
2499 Callee = DAG.getNode(
2500 ARMISD::WrapperPIC, dl, PtrVt,
2501 DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, ARMII::MO_NONLAZY));
2502 Callee = DAG.getLoad(
2503 PtrVt, dl, DAG.getEntryNode(), Callee,
2507 } else if (Subtarget->isTargetCOFF()) {
2508 assert(Subtarget->isTargetWindows() &&
2509 "Windows is the only supported COFF target");
2510 unsigned TargetFlags = ARMII::MO_NO_FLAG;
2511 if (GVal->hasDLLImportStorageClass())
2512 TargetFlags = ARMII::MO_DLLIMPORT;
2513 else if (!TM.shouldAssumeDSOLocal(GVal))
2514 TargetFlags = ARMII::MO_COFFSTUB;
2515 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, /*offset=*/0,
2516 TargetFlags);
2517 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
2518 Callee =
2519 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
2520 DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
2522 } else {
2523 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, 0);
2524 }
2525 }
2526 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2527 isDirect = true;
2528 // tBX takes a register source operand.
2529 const char *Sym = S->getSymbol();
2530 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2531 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2532 ARMConstantPoolValue *CPV =
2534 ARMPCLabelIndex, 4);
2535 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2536 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2537 Callee = DAG.getLoad(
2538 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2540 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2541 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, Callee, PICLabel);
2542 } else {
2543 Callee = DAG.getTargetExternalSymbol(Sym, PtrVt, 0);
2544 }
2545 }
2546
2547 if (isCmseNSCall) {
2548 assert(!isARMFunc && !isDirect &&
2549 "Cannot handle call to ARM function or direct call");
2550 if (NumBytes > 0) {
2551 DAG.getContext()->diagnose(
2552 DiagnosticInfoUnsupported(DAG.getMachineFunction().getFunction(),
2553 "call to non-secure function would require "
2554 "passing arguments on stack",
2555 dl.getDebugLoc()));
2556 }
2557 if (isStructRet) {
2558 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2560 "call to non-secure function would return value through pointer",
2561 dl.getDebugLoc()));
2562 }
2563 }
2564
2565 // FIXME: handle tail calls differently.
2566 unsigned CallOpc;
2567 if (Subtarget->isThumb()) {
2568 if (GuardWithBTI)
2569 CallOpc = ARMISD::t2CALL_BTI;
2570 else if (isCmseNSCall)
2571 CallOpc = ARMISD::tSECALL;
2572 else if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
2573 CallOpc = ARMISD::CALL_NOLINK;
2574 else
2575 CallOpc = ARMISD::CALL;
2576 } else {
2577 if (!isDirect && !Subtarget->hasV5TOps())
2578 CallOpc = ARMISD::CALL_NOLINK;
2579 else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
2580 // Emit regular call when code size is the priority
2581 !Subtarget->hasMinSize())
2582 // "mov lr, pc; b _foo" to avoid confusing the RSP
2583 CallOpc = ARMISD::CALL_NOLINK;
2584 else
2585 CallOpc = isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL;
2586 }
2587
2588 // We don't usually want to end the call-sequence here because we would tidy
2589 // the frame up *after* the call, however in the ABI-changing tail-call case
2590 // we've carefully laid out the parameters so that when sp is reset they'll be
2591 // in the correct location.
2592 if (isTailCall && !isSibCall) {
2593 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
2594 InGlue = Chain.getValue(1);
2595 }
2596
2597 std::vector<SDValue> Ops;
2598 Ops.push_back(Chain);
2599 Ops.push_back(Callee);
2600
2601 if (isTailCall) {
2602 Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
2603 }
2604
2605 // Add argument registers to the end of the list so that they are known live
2606 // into the call.
2607 for (const auto &[Reg, N] : RegsToPass)
2608 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2609
2610 // Add a register mask operand representing the call-preserved registers.
2611 const uint32_t *Mask;
2612 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
2613 if (isThisReturn) {
2614 // For 'this' returns, use the R0-preserving mask if applicable
2615 Mask = ARI->getThisReturnPreservedMask(MF, CallConv);
2616 if (!Mask) {
2617 // Set isThisReturn to false if the calling convention is not one that
2618 // allows 'returned' to be modeled in this way, so LowerCallResult does
2619 // not try to pass 'this' straight through
2620 isThisReturn = false;
2621 Mask = ARI->getCallPreservedMask(MF, CallConv);
2622 }
2623 } else
2624 Mask = ARI->getCallPreservedMask(MF, CallConv);
2625
2626 assert(Mask && "Missing call preserved mask for calling convention");
2627 Ops.push_back(DAG.getRegisterMask(Mask));
2628
2629 if (InGlue.getNode())
2630 Ops.push_back(InGlue);
2631
2632 if (isTailCall) {
2634 SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
2635 if (CLI.CFIType)
2636 Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2637 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2638 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2639 return Ret;
2640 }
2641
2642 // Returns a chain and a flag for retval copy to use.
2643 Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
2644 if (CLI.CFIType)
2645 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2646 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2647 InGlue = Chain.getValue(1);
2648 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
2649
2650 // If we're guaranteeing tail-calls will be honoured, the callee must
2651 // pop its own argument stack on return. But this call is *not* a tail call so
2652 // we need to undo that after it returns to restore the status-quo.
2653 bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
2654 uint64_t CalleePopBytes =
2655 canGuaranteeTCO(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : -1U;
2656
2657 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, CalleePopBytes, InGlue, dl);
2658 if (!Ins.empty())
2659 InGlue = Chain.getValue(1);
2660
2661 // Handle result values, copying them out of physregs into vregs that we
2662 // return.
2663 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2664 InVals, isThisReturn,
2665 isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
2666}
2667
2668/// HandleByVal - Every parameter *after* a byval parameter is passed
2669/// on the stack. Remember the next parameter register to allocate,
2670/// and then confiscate the rest of the parameter registers to insure
2671/// this.
2672void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size,
2673 Align Alignment) const {
2674 // Byval (as with any stack) slots are always at least 4 byte aligned.
2675 Alignment = std::max(Alignment, Align(4));
2676
2677 MCRegister Reg = State->AllocateReg(GPRArgRegs);
2678 if (!Reg)
2679 return;
2680
2681 unsigned AlignInRegs = Alignment.value() / 4;
2682 unsigned Waste = (ARM::R4 - Reg) % AlignInRegs;
2683 for (unsigned i = 0; i < Waste; ++i)
2684 Reg = State->AllocateReg(GPRArgRegs);
2685
2686 if (!Reg)
2687 return;
2688
2689 unsigned Excess = 4 * (ARM::R4 - Reg);
2690
2691 // Special case when NSAA != SP and parameter size greater than size of
2692 // all remained GPR regs. In that case we can't split parameter, we must
2693 // send it to stack. We also must set NCRN to R4, so waste all
2694 // remained registers.
2695 const unsigned NSAAOffset = State->getStackSize();
2696 if (NSAAOffset != 0 && Size > Excess) {
2697 while (State->AllocateReg(GPRArgRegs))
2698 ;
2699 return;
2700 }
2701
2702 // First register for byval parameter is the first register that wasn't
2703 // allocated before this method call, so it would be "reg".
2704 // If parameter is small enough to be saved in range [reg, r4), then
2705 // the end (first after last) register would be reg + param-size-in-regs,
2706 // else parameter would be splitted between registers and stack,
2707 // end register would be r4 in this case.
2708 unsigned ByValRegBegin = Reg;
2709 unsigned ByValRegEnd = std::min<unsigned>(Reg + Size / 4, ARM::R4);
2710 State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd);
2711 // Note, first register is allocated in the beginning of function already,
2712 // allocate remained amount of registers we need.
2713 for (unsigned i = Reg + 1; i != ByValRegEnd; ++i)
2714 State->AllocateReg(GPRArgRegs);
2715 // A byval parameter that is split between registers and memory needs its
2716 // size truncated here.
2717 // In the case where the entire structure fits in registers, we set the
2718 // size in memory to zero.
2719 Size = std::max<int>(Size - Excess, 0);
2720}
2721
2722/// IsEligibleForTailCallOptimization - Check whether the call is eligible
2723/// for tail call optimization. Targets which want to do tail call
2724/// optimization should implement this function. Note that this function also
2725/// processes musttail calls, so when this function returns false on a valid
2726/// musttail call, a fatal backend error occurs.
2727bool ARMTargetLowering::IsEligibleForTailCallOptimization(
2729 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
2730 CallingConv::ID CalleeCC = CLI.CallConv;
2731 SDValue Callee = CLI.Callee;
2732 bool isVarArg = CLI.IsVarArg;
2733 const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2734 const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2735 const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2736 const SelectionDAG &DAG = CLI.DAG;
2737 MachineFunction &MF = DAG.getMachineFunction();
2738 const Function &CallerF = MF.getFunction();
2739 CallingConv::ID CallerCC = CallerF.getCallingConv();
2740
2741 assert(Subtarget->supportsTailCall());
2742
2743 // Indirect tail-calls require a register to hold the target address. That
2744 // register must be:
2745 // * Allocatable (i.e. r0-r7 if the target is Thumb1).
2746 // * Not callee-saved, so must be one of r0-r3 or r12.
2747 // * Not used to hold an argument to the tail-called function, which might be
2748 // in r0-r3.
2749 // * Not used to hold the return address authentication code, which is in r12
2750 // if enabled.
2751 // Sometimes, no register matches all of these conditions, so we can't do a
2752 // tail-call.
2753 if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) {
2754 SmallSet<MCPhysReg, 5> AddressRegisters = {ARM::R0, ARM::R1, ARM::R2,
2755 ARM::R3};
2756 if (!(Subtarget->isThumb1Only() ||
2757 MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)))
2758 AddressRegisters.insert(ARM::R12);
2759 for (const CCValAssign &AL : ArgLocs)
2760 if (AL.isRegLoc())
2761 AddressRegisters.erase(AL.getLocReg());
2762 if (AddressRegisters.empty()) {
2763 LLVM_DEBUG(dbgs() << "false (no reg to hold function pointer)\n");
2764 return false;
2765 }
2766 }
2767
2768 // Look for obvious safe cases to perform tail call optimization that do not
2769 // require ABI changes. This is what gcc calls sibcall.
2770
2771 // Exception-handling functions need a special set of instructions to indicate
2772 // a return to the hardware. Tail-calling another function would probably
2773 // break this.
2774 if (CallerF.hasFnAttribute("interrupt")) {
2775 LLVM_DEBUG(dbgs() << "false (interrupt attribute)\n");
2776 return false;
2777 }
2778
2779 if (canGuaranteeTCO(CalleeCC,
2780 getTargetMachine().Options.GuaranteedTailCallOpt)) {
2781 LLVM_DEBUG(dbgs() << (CalleeCC == CallerCC ? "true" : "false")
2782 << " (guaranteed tail-call CC)\n");
2783 return CalleeCC == CallerCC;
2784 }
2785
2786 // Also avoid sibcall optimization if either caller or callee uses struct
2787 // return semantics.
2788 bool isCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
2789 bool isCallerStructRet = MF.getFunction().hasStructRetAttr();
2790 if (isCalleeStructRet != isCallerStructRet) {
2791 LLVM_DEBUG(dbgs() << "false (struct-ret)\n");
2792 return false;
2793 }
2794
2795 // Externally-defined functions with weak linkage should not be
2796 // tail-called on ARM when the OS does not support dynamic
2797 // pre-emption of symbols, as the AAELF spec requires normal calls
2798 // to undefined weak functions to be replaced with a NOP or jump to the
2799 // next instruction. The behaviour of branch instructions in this
2800 // situation (as used for tail calls) is implementation-defined, so we
2801 // cannot rely on the linker replacing the tail call with a return.
2802 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2803 const GlobalValue *GV = G->getGlobal();
2804 const Triple &TT = getTargetMachine().getTargetTriple();
2805 if (GV->hasExternalWeakLinkage() &&
2806 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
2807 TT.isOSBinFormatMachO())) {
2808 LLVM_DEBUG(dbgs() << "false (external weak linkage)\n");
2809 return false;
2810 }
2811 }
2812
2813 // Check that the call results are passed in the same way.
2814 LLVMContext &C = *DAG.getContext();
2816 getEffectiveCallingConv(CalleeCC, isVarArg),
2817 getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
2818 CCAssignFnForReturn(CalleeCC, isVarArg),
2819 CCAssignFnForReturn(CallerCC, CallerF.isVarArg()))) {
2820 LLVM_DEBUG(dbgs() << "false (incompatible results)\n");
2821 return false;
2822 }
2823 // The callee has to preserve all registers the caller needs to preserve.
2824 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
2825 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
2826 if (CalleeCC != CallerCC) {
2827 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
2828 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) {
2829 LLVM_DEBUG(dbgs() << "false (not all registers preserved)\n");
2830 return false;
2831 }
2832 }
2833
2834 // If Caller's vararg argument has been split between registers and stack, do
2835 // not perform tail call, since part of the argument is in caller's local
2836 // frame.
2837 const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
2838 if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
2839 LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
2840 return false;
2841 }
2842
2843 // If the callee takes no arguments then go on to check the results of the
2844 // call.
2845 const MachineRegisterInfo &MRI = MF.getRegInfo();
2846 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals)) {
2847 LLVM_DEBUG(dbgs() << "false (parameters in CSRs do not match)\n");
2848 return false;
2849 }
2850
2851 // If the stack arguments for this call do not fit into our own save area then
2852 // the call cannot be made tail.
2853 if (CCInfo.getStackSize() > AFI_Caller->getArgumentStackSize())
2854 return false;
2855
2856 LLVM_DEBUG(dbgs() << "true\n");
2857 return true;
2858}
2859
2860bool
2861ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2862 MachineFunction &MF, bool isVarArg,
2864 LLVMContext &Context, const Type *RetTy) const {
2866 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
2867 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2868}
2869
2871 const SDLoc &DL, SelectionDAG &DAG) {
2872 const MachineFunction &MF = DAG.getMachineFunction();
2873 const Function &F = MF.getFunction();
2874
2875 StringRef IntKind = F.getFnAttribute("interrupt").getValueAsString();
2876
2877 // See ARM ARM v7 B1.8.3. On exception entry LR is set to a possibly offset
2878 // version of the "preferred return address". These offsets affect the return
2879 // instruction if this is a return from PL1 without hypervisor extensions.
2880 // IRQ/FIQ: +4 "subs pc, lr, #4"
2881 // SWI: 0 "subs pc, lr, #0"
2882 // ABORT: +4 "subs pc, lr, #4"
2883 // UNDEF: +4/+2 "subs pc, lr, #0"
2884 // UNDEF varies depending on where the exception came from ARM or Thumb
2885 // mode. Alongside GCC, we throw our hands up in disgust and pretend it's 0.
2886
2887 int64_t LROffset;
2888 if (IntKind == "" || IntKind == "IRQ" || IntKind == "FIQ" ||
2889 IntKind == "ABORT")
2890 LROffset = 4;
2891 else if (IntKind == "SWI" || IntKind == "UNDEF")
2892 LROffset = 0;
2893 else
2894 report_fatal_error("Unsupported interrupt attribute. If present, value "
2895 "must be one of: IRQ, FIQ, SWI, ABORT or UNDEF");
2896
2897 RetOps.insert(RetOps.begin() + 1,
2898 DAG.getConstant(LROffset, DL, MVT::i32, false));
2899
2900 return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
2901}
2902
2903SDValue
2904ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2905 bool isVarArg,
2907 const SmallVectorImpl<SDValue> &OutVals,
2908 const SDLoc &dl, SelectionDAG &DAG) const {
2909 // CCValAssign - represent the assignment of the return value to a location.
2911
2912 // CCState - Info about the registers and stack slots.
2913 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
2914 *DAG.getContext());
2915
2916 // Analyze outgoing return values.
2917 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2918
2919 SDValue Glue;
2921 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
2922 bool isLittleEndian = Subtarget->isLittle();
2923
2924 MachineFunction &MF = DAG.getMachineFunction();
2925 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2926 AFI->setReturnRegsCount(RVLocs.size());
2927
2928 // Report error if cmse entry function returns structure through first ptr arg.
2929 if (AFI->isCmseNSEntryFunction() && MF.getFunction().hasStructRetAttr()) {
2930 // Note: using an empty SDLoc(), as the first line of the function is a
2931 // better place to report than the last line.
2932 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2934 "secure entry function would return value through pointer",
2935 SDLoc().getDebugLoc()));
2936 }
2937
2938 // Copy the result values into the output registers.
2939 for (unsigned i = 0, realRVLocIdx = 0;
2940 i != RVLocs.size();
2941 ++i, ++realRVLocIdx) {
2942 CCValAssign &VA = RVLocs[i];
2943 assert(VA.isRegLoc() && "Can only return in registers!");
2944
2945 SDValue Arg = OutVals[realRVLocIdx];
2946 bool ReturnF16 = false;
2947
2948 if (Subtarget->hasFullFP16() && getTM().isTargetHardFloat()) {
2949 // Half-precision return values can be returned like this:
2950 //
2951 // t11 f16 = fadd ...
2952 // t12: i16 = bitcast t11
2953 // t13: i32 = zero_extend t12
2954 // t14: f32 = bitcast t13 <~~~~~~~ Arg
2955 //
2956 // to avoid code generation for bitcasts, we simply set Arg to the node
2957 // that produces the f16 value, t11 in this case.
2958 //
2959 if (Arg.getValueType() == MVT::f32 && Arg.getOpcode() == ISD::BITCAST) {
2960 SDValue ZE = Arg.getOperand(0);
2961 if (ZE.getOpcode() == ISD::ZERO_EXTEND && ZE.getValueType() == MVT::i32) {
2962 SDValue BC = ZE.getOperand(0);
2963 if (BC.getOpcode() == ISD::BITCAST && BC.getValueType() == MVT::i16) {
2964 Arg = BC.getOperand(0);
2965 ReturnF16 = true;
2966 }
2967 }
2968 }
2969 }
2970
2971 switch (VA.getLocInfo()) {
2972 default: llvm_unreachable("Unknown loc info!");
2973 case CCValAssign::Full: break;
2974 case CCValAssign::BCvt:
2975 if (!ReturnF16)
2976 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2977 break;
2978 }
2979
2980 // Mask f16 arguments if this is a CMSE nonsecure entry.
2981 auto RetVT = Outs[realRVLocIdx].ArgVT;
2982 if (AFI->isCmseNSEntryFunction() && (RetVT == MVT::f16)) {
2983 if (VA.needsCustom() && VA.getValVT() == MVT::f16) {
2984 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2985 } else {
2986 auto LocBits = VA.getLocVT().getSizeInBits();
2987 auto MaskValue = APInt::getLowBitsSet(LocBits, RetVT.getSizeInBits());
2988 SDValue Mask =
2989 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2990 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2991 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2992 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2993 }
2994 }
2995
2996 if (VA.needsCustom() &&
2997 (VA.getLocVT() == MVT::v2f64 || VA.getLocVT() == MVT::f64)) {
2998 if (VA.getLocVT() == MVT::v2f64) {
2999 // Extract the first half and return it in two registers.
3000 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3001 DAG.getConstant(0, dl, MVT::i32));
3002 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
3003 DAG.getVTList(MVT::i32, MVT::i32), Half);
3004
3005 Chain =
3006 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3007 HalfGPRs.getValue(isLittleEndian ? 0 : 1), Glue);
3008 Glue = Chain.getValue(1);
3009 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3010 VA = RVLocs[++i]; // skip ahead to next loc
3011 Chain =
3012 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3013 HalfGPRs.getValue(isLittleEndian ? 1 : 0), Glue);
3014 Glue = Chain.getValue(1);
3015 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3016 VA = RVLocs[++i]; // skip ahead to next loc
3017
3018 // Extract the 2nd half and fall through to handle it as an f64 value.
3019 Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3020 DAG.getConstant(1, dl, MVT::i32));
3021 }
3022 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
3023 // available.
3024 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
3025 DAG.getVTList(MVT::i32, MVT::i32), Arg);
3026 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3027 fmrrd.getValue(isLittleEndian ? 0 : 1), Glue);
3028 Glue = Chain.getValue(1);
3029 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3030 VA = RVLocs[++i]; // skip ahead to next loc
3031 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3032 fmrrd.getValue(isLittleEndian ? 1 : 0), Glue);
3033 } else
3034 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
3035
3036 // Guarantee that all emitted copies are
3037 // stuck together, avoiding something bad.
3038 Glue = Chain.getValue(1);
3039 RetOps.push_back(DAG.getRegister(
3040 VA.getLocReg(), ReturnF16 ? Arg.getValueType() : VA.getLocVT()));
3041 }
3042 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
3043 const MCPhysReg *I =
3044 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3045 if (I) {
3046 for (; *I; ++I) {
3047 if (ARM::GPRRegClass.contains(*I))
3048 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3049 else if (ARM::DPRRegClass.contains(*I))
3051 else
3052 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3053 }
3054 }
3055
3056 // Update chain and glue.
3057 RetOps[0] = Chain;
3058 if (Glue.getNode())
3059 RetOps.push_back(Glue);
3060
3061 // CPUs which aren't M-class use a special sequence to return from
3062 // exceptions (roughly, any instruction setting pc and cpsr simultaneously,
3063 // though we use "subs pc, lr, #N").
3064 //
3065 // M-class CPUs actually use a normal return sequence with a special
3066 // (hardware-provided) value in LR, so the normal code path works.
3067 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt") &&
3068 !Subtarget->isMClass()) {
3069 if (Subtarget->isThumb1Only())
3070 report_fatal_error("interrupt attribute is not supported in Thumb1");
3071 return LowerInterruptReturn(RetOps, dl, DAG);
3072 }
3073
3074 unsigned RetNode =
3075 AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
3076 return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
3077}
3078
3079bool ARMTargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
3080 if (N->getNumValues() != 1)
3081 return false;
3082 if (!N->hasNUsesOfValue(1, 0))
3083 return false;
3084
3085 SDValue TCChain = Chain;
3086 SDNode *Copy = *N->user_begin();
3087 if (Copy->getOpcode() == ISD::CopyToReg) {
3088 // If the copy has a glue operand, we conservatively assume it isn't safe to
3089 // perform a tail call.
3090 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3091 return false;
3092 TCChain = Copy->getOperand(0);
3093 } else if (Copy->getOpcode() == ARMISD::VMOVRRD) {
3094 SDNode *VMov = Copy;
3095 // f64 returned in a pair of GPRs.
3096 SmallPtrSet<SDNode*, 2> Copies;
3097 for (SDNode *U : VMov->users()) {
3098 if (U->getOpcode() != ISD::CopyToReg)
3099 return false;
3100 Copies.insert(U);
3101 }
3102 if (Copies.size() > 2)
3103 return false;
3104
3105 for (SDNode *U : VMov->users()) {
3106 SDValue UseChain = U->getOperand(0);
3107 if (Copies.count(UseChain.getNode()))
3108 // Second CopyToReg
3109 Copy = U;
3110 else {
3111 // We are at the top of this chain.
3112 // If the copy has a glue operand, we conservatively assume it
3113 // isn't safe to perform a tail call.
3114 if (U->getOperand(U->getNumOperands() - 1).getValueType() == MVT::Glue)
3115 return false;
3116 // First CopyToReg
3117 TCChain = UseChain;
3118 }
3119 }
3120 } else if (Copy->getOpcode() == ISD::BITCAST) {
3121 // f32 returned in a single GPR.
3122 if (!Copy->hasOneUse())
3123 return false;
3124 Copy = *Copy->user_begin();
3125 if (Copy->getOpcode() != ISD::CopyToReg || !Copy->hasNUsesOfValue(1, 0))
3126 return false;
3127 // If the copy has a glue operand, we conservatively assume it isn't safe to
3128 // perform a tail call.
3129 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3130 return false;
3131 TCChain = Copy->getOperand(0);
3132 } else {
3133 return false;
3134 }
3135
3136 bool HasRet = false;
3137 for (const SDNode *U : Copy->users()) {
3138 if (U->getOpcode() != ARMISD::RET_GLUE &&
3139 U->getOpcode() != ARMISD::INTRET_GLUE)
3140 return false;
3141 HasRet = true;
3142 }
3143
3144 if (!HasRet)
3145 return false;
3146
3147 Chain = TCChain;
3148 return true;
3149}
3150
3151bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
3152 if (!Subtarget->supportsTailCall())
3153 return false;
3154
3155 if (!CI->isTailCall())
3156 return false;
3157
3158 return true;
3159}
3160
3161// Trying to write a 64 bit value so need to split into two 32 bit values first,
3162// and pass the lower and high parts through.
3164 SDLoc DL(Op);
3165 SDValue WriteValue = Op->getOperand(2);
3166
3167 // This function is only supposed to be called for i64 type argument.
3168 assert(WriteValue.getValueType() == MVT::i64
3169 && "LowerWRITE_REGISTER called for non-i64 type argument.");
3170
3171 SDValue Lo, Hi;
3172 std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32);
3173 SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi };
3174 return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops);
3175}
3176
3177// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3178// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
3179// one of the above mentioned nodes. It has to be wrapped because otherwise
3180// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3181// be used to form addressing mode. These wrapped nodes will be selected
3182// into MOVi.
3183SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
3184 SelectionDAG &DAG) const {
3185 EVT PtrVT = Op.getValueType();
3186 // FIXME there is no actual debug info here
3187 SDLoc dl(Op);
3188 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3189 SDValue Res;
3190
3191 // When generating execute-only code Constant Pools must be promoted to the
3192 // global data section. It's a bit ugly that we can't share them across basic
3193 // blocks, but this way we guarantee that execute-only behaves correct with
3194 // position-independent addressing modes.
3195 if (Subtarget->genExecuteOnly()) {
3196 auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
3197 auto *T = CP->getType();
3198 auto C = const_cast<Constant*>(CP->getConstVal());
3199 auto M = DAG.getMachineFunction().getFunction().getParent();
3200 auto GV = new GlobalVariable(
3201 *M, T, /*isConstant=*/true, GlobalVariable::InternalLinkage, C,
3202 Twine(DAG.getDataLayout().getInternalSymbolPrefix()) + "CP" +
3203 Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
3204 Twine(AFI->createPICLabelUId()));
3205 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3206 return LowerGlobalAddress(GA, DAG);
3207 }
3208
3209 // The 16-bit ADR instruction can only encode offsets that are multiples of 4,
3210 // so we need to align to at least 4 bytes when we don't have 32-bit ADR.
3211 Align CPAlign = CP->getAlign();
3212 if (Subtarget->isThumb1Only())
3213 CPAlign = std::max(CPAlign, Align(4));
3215 Res =
3216 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CPAlign);
3217 else
3218 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CPAlign);
3219 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
3220}
3221
3223 // If we don't have a 32-bit pc-relative branch instruction then the jump
3224 // table consists of block addresses. Usually this is inline, but for
3225 // execute-only it must be placed out-of-line.
3226 if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
3229}
3230
3231SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
3232 SelectionDAG &DAG) const {
3235 unsigned ARMPCLabelIndex = 0;
3236 SDLoc DL(Op);
3237 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3238 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
3239 SDValue CPAddr;
3240 bool IsPositionIndependent = isPositionIndependent() || Subtarget->isROPI();
3241 if (!IsPositionIndependent) {
3242 CPAddr = DAG.getTargetConstantPool(BA, PtrVT, Align(4));
3243 } else {
3244 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3245 ARMPCLabelIndex = AFI->createPICLabelUId();
3247 ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex,
3248 ARMCP::CPBlockAddress, PCAdj);
3249 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3250 }
3251 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
3252 SDValue Result = DAG.getLoad(
3253 PtrVT, DL, DAG.getEntryNode(), CPAddr,
3255 if (!IsPositionIndependent)
3256 return Result;
3257 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, DL, MVT::i32);
3258 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
3259}
3260
3261/// Convert a TLS address reference into the correct sequence of loads
3262/// and calls to compute the variable's address for Darwin, and return an
3263/// SDValue containing the final node.
3264
3265/// Darwin only has one TLS scheme which must be capable of dealing with the
3266/// fully general situation, in the worst case. This means:
3267/// + "extern __thread" declaration.
3268/// + Defined in a possibly unknown dynamic library.
3269///
3270/// The general system is that each __thread variable has a [3 x i32] descriptor
3271/// which contains information used by the runtime to calculate the address. The
3272/// only part of this the compiler needs to know about is the first word, which
3273/// contains a function pointer that must be called with the address of the
3274/// entire descriptor in "r0".
3275///
3276/// Since this descriptor may be in a different unit, in general access must
3277/// proceed along the usual ARM rules. A common sequence to produce is:
3278///
3279/// movw rT1, :lower16:_var$non_lazy_ptr
3280/// movt rT1, :upper16:_var$non_lazy_ptr
3281/// ldr r0, [rT1]
3282/// ldr rT2, [r0]
3283/// blx rT2
3284/// [...address now in r0...]
3285SDValue
3286ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
3287 SelectionDAG &DAG) const {
3288 assert(getTargetMachine().getTargetTriple().isOSDarwin() &&
3289 "This function expects a Darwin target");
3290 SDLoc DL(Op);
3291
3292 // First step is to get the address of the actua global symbol. This is where
3293 // the TLS descriptor lives.
3294 SDValue DescAddr = LowerGlobalAddressDarwin(Op, DAG);
3295
3296 // The first entry in the descriptor is a function pointer that we must call
3297 // to obtain the address of the variable.
3298 SDValue Chain = DAG.getEntryNode();
3299 SDValue FuncTLVGet = DAG.getLoad(
3300 MVT::i32, DL, Chain, DescAddr,
3304 Chain = FuncTLVGet.getValue(1);
3305
3306 MachineFunction &F = DAG.getMachineFunction();
3307 MachineFrameInfo &MFI = F.getFrameInfo();
3308 MFI.setAdjustsStack(true);
3309
3310 // TLS calls preserve all registers except those that absolutely must be
3311 // trashed: R0 (it takes an argument), LR (it's a call) and CPSR (let's not be
3312 // silly).
3313 auto TRI =
3315 auto ARI = static_cast<const ARMRegisterInfo *>(TRI);
3316 const uint32_t *Mask = ARI->getTLSCallPreservedMask(DAG.getMachineFunction());
3317
3318 // Finally, we can make the call. This is just a degenerate version of a
3319 // normal AArch64 call node: r0 takes the address of the descriptor, and
3320 // returns the address of the variable in this thread.
3321 Chain = DAG.getCopyToReg(Chain, DL, ARM::R0, DescAddr, SDValue());
3322 Chain =
3323 DAG.getNode(ARMISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
3324 Chain, FuncTLVGet, DAG.getRegister(ARM::R0, MVT::i32),
3325 DAG.getRegisterMask(Mask), Chain.getValue(1));
3326 return DAG.getCopyFromReg(Chain, DL, ARM::R0, MVT::i32, Chain.getValue(1));
3327}
3328
3329SDValue
3330ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
3331 SelectionDAG &DAG) const {
3332 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3333 "Windows specific TLS lowering");
3334
3335 SDValue Chain = DAG.getEntryNode();
3336 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3337 SDLoc DL(Op);
3338
3339 // Load the current TEB (thread environment block)
3340 SDValue Ops[] = {Chain,
3341 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
3342 DAG.getTargetConstant(15, DL, MVT::i32),
3343 DAG.getTargetConstant(0, DL, MVT::i32),
3344 DAG.getTargetConstant(13, DL, MVT::i32),
3345 DAG.getTargetConstant(0, DL, MVT::i32),
3346 DAG.getTargetConstant(2, DL, MVT::i32)};
3347 SDValue CurrentTEB = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
3348 DAG.getVTList(MVT::i32, MVT::Other), Ops);
3349
3350 SDValue TEB = CurrentTEB.getValue(0);
3351 Chain = CurrentTEB.getValue(1);
3352
3353 // Load the ThreadLocalStoragePointer from the TEB
3354 // A pointer to the TLS array is located at offset 0x2c from the TEB.
3355 SDValue TLSArray =
3356 DAG.getNode(ISD::ADD, DL, PtrVT, TEB, DAG.getIntPtrConstant(0x2c, DL));
3357 TLSArray = DAG.getLoad(PtrVT, DL, Chain, TLSArray, MachinePointerInfo());
3358
3359 // The pointer to the thread's TLS data area is at the TLS Index scaled by 4
3360 // offset into the TLSArray.
3361
3362 // Load the TLS index from the C runtime
3363 SDValue TLSIndex =
3364 DAG.getTargetExternalSymbol("_tls_index", PtrVT, ARMII::MO_NO_FLAG);
3365 TLSIndex = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, TLSIndex);
3366 TLSIndex = DAG.getLoad(PtrVT, DL, Chain, TLSIndex, MachinePointerInfo());
3367
3368 SDValue Slot = DAG.getNode(ISD::SHL, DL, PtrVT, TLSIndex,
3369 DAG.getConstant(2, DL, MVT::i32));
3370 SDValue TLS = DAG.getLoad(PtrVT, DL, Chain,
3371 DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
3372 MachinePointerInfo());
3373
3374 // Get the offset of the start of the .tls section (section base)
3375 const auto *GA = cast<GlobalAddressSDNode>(Op);
3376 auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
3377 SDValue Offset = DAG.getLoad(
3378 PtrVT, DL, Chain,
3379 DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
3380 DAG.getTargetConstantPool(CPV, PtrVT, Align(4))),
3382
3383 return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
3384}
3385
3386// Lower ISD::GlobalTLSAddress using the "general dynamic" model
3387SDValue
3388ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
3389 SelectionDAG &DAG) const {
3390 SDLoc dl(GA);
3391 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3392 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3393 MachineFunction &MF = DAG.getMachineFunction();
3394 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3395 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3396 ARMConstantPoolValue *CPV =
3397 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3398 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
3399 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3400 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
3401 Argument = DAG.getLoad(
3402 PtrVT, dl, DAG.getEntryNode(), Argument,
3404 SDValue Chain = Argument.getValue(1);
3405
3406 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3407 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
3408
3409 // call __tls_get_addr.
3411 Args.emplace_back(Argument, Type::getInt32Ty(*DAG.getContext()));
3412
3413 // FIXME: is there useful debug info available here?
3414 TargetLowering::CallLoweringInfo CLI(DAG);
3415 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3417 DAG.getExternalSymbol("__tls_get_addr", PtrVT), std::move(Args));
3418
3419 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3420 return CallResult.first;
3421}
3422
3423// Lower ISD::GlobalTLSAddress using the "initial exec" or
3424// "local exec" model.
3425SDValue
3426ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
3427 SelectionDAG &DAG,
3428 TLSModel::Model model) const {
3429 const GlobalValue *GV = GA->getGlobal();
3430 SDLoc dl(GA);
3432 SDValue Chain = DAG.getEntryNode();
3433 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3434 // Get the Thread Pointer
3435 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3436
3437 if (model == TLSModel::InitialExec) {
3438 MachineFunction &MF = DAG.getMachineFunction();
3439 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3440 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3441 // Initial exec model.
3442 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3443 ARMConstantPoolValue *CPV =
3444 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3446 true);
3447 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3448 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3449 Offset = DAG.getLoad(
3450 PtrVT, dl, Chain, Offset,
3452 Chain = Offset.getValue(1);
3453
3454 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3455 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
3456
3457 Offset = DAG.getLoad(
3458 PtrVT, dl, Chain, Offset,
3460 } else {
3461 // local exec model
3462 assert(model == TLSModel::LocalExec);
3463 ARMConstantPoolValue *CPV =
3465 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3466 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3467 Offset = DAG.getLoad(
3468 PtrVT, dl, Chain, Offset,
3470 }
3471
3472 // The address of the thread local variable is the add of the thread
3473 // pointer with the offset of the variable.
3474 return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
3475}
3476
3477SDValue
3478ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
3479 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
3480 if (DAG.getTarget().useEmulatedTLS())
3481 return LowerToTLSEmulatedModel(GA, DAG);
3482
3483 const Triple &TT = getTargetMachine().getTargetTriple();
3484 if (TT.isOSDarwin())
3485 return LowerGlobalTLSAddressDarwin(Op, DAG);
3486
3487 if (TT.isOSWindows())
3488 return LowerGlobalTLSAddressWindows(Op, DAG);
3489
3490 // TODO: implement the "local dynamic" model
3491 assert(TT.isOSBinFormatELF() && "Only ELF implemented here");
3493
3494 switch (model) {
3497 return LowerToTLSGeneralDynamicModel(GA, DAG);
3500 return LowerToTLSExecModels(GA, DAG, model);
3501 }
3502 llvm_unreachable("bogus TLS model");
3503}
3504
3505/// Return true if all users of V are within function F, looking through
3506/// ConstantExprs.
3507static bool allUsersAreInFunction(const Value *V, const Function *F) {
3508 SmallVector<const User*,4> Worklist(V->users());
3509 while (!Worklist.empty()) {
3510 auto *U = Worklist.pop_back_val();
3511 if (isa<ConstantExpr>(U)) {
3512 append_range(Worklist, U->users());
3513 continue;
3514 }
3515
3516 auto *I = dyn_cast<Instruction>(U);
3517 if (!I || I->getParent()->getParent() != F)
3518 return false;
3519 }
3520 return true;
3521}
3522
3524 const GlobalValue *GV, SelectionDAG &DAG,
3525 EVT PtrVT, const SDLoc &dl) {
3526 // If we're creating a pool entry for a constant global with unnamed address,
3527 // and the global is small enough, we can emit it inline into the constant pool
3528 // to save ourselves an indirection.
3529 //
3530 // This is a win if the constant is only used in one function (so it doesn't
3531 // need to be duplicated) or duplicating the constant wouldn't increase code
3532 // size (implying the constant is no larger than 4 bytes).
3533 const Function &F = DAG.getMachineFunction().getFunction();
3534
3535 // We rely on this decision to inline being idempotent and unrelated to the
3536 // use-site. We know that if we inline a variable at one use site, we'll
3537 // inline it elsewhere too (and reuse the constant pool entry). Fast-isel
3538 // doesn't know about this optimization, so bail out if it's enabled else
3539 // we could decide to inline here (and thus never emit the GV) but require
3540 // the GV from fast-isel generated code.
3543 return SDValue();
3544
3545 auto *GVar = dyn_cast<GlobalVariable>(GV);
3546 if (!GVar || !GVar->hasInitializer() ||
3547 !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
3548 !GVar->hasLocalLinkage())
3549 return SDValue();
3550
3551 // If we inline a value that contains relocations, we move the relocations
3552 // from .data to .text. This is not allowed in position-independent code.
3553 auto *Init = GVar->getInitializer();
3554 if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3555 Init->needsDynamicRelocation())
3556 return SDValue();
3557
3558 // The constant islands pass can only really deal with alignment requests
3559 // <= 4 bytes and cannot pad constants itself. Therefore we cannot promote
3560 // any type wanting greater alignment requirements than 4 bytes. We also
3561 // can only promote constants that are multiples of 4 bytes in size or
3562 // are paddable to a multiple of 4. Currently we only try and pad constants
3563 // that are strings for simplicity.
3564 auto *CDAInit = dyn_cast<ConstantDataArray>(Init);
3565 unsigned Size = DAG.getDataLayout().getTypeAllocSize(Init->getType());
3566 Align PrefAlign = DAG.getDataLayout().getPreferredAlign(GVar);
3567 unsigned RequiredPadding = 4 - (Size % 4);
3568 bool PaddingPossible =
3569 RequiredPadding == 4 || (CDAInit && CDAInit->isString());
3570 if (!PaddingPossible || PrefAlign > 4 || Size > ConstpoolPromotionMaxSize ||
3571 Size == 0)
3572 return SDValue();
3573
3574 unsigned PaddedSize = Size + ((RequiredPadding == 4) ? 0 : RequiredPadding);
3576 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3577
3578 // We can't bloat the constant pool too much, else the ConstantIslands pass
3579 // may fail to converge. If we haven't promoted this global yet (it may have
3580 // multiple uses), and promoting it would increase the constant pool size (Sz
3581 // > 4), ensure we have space to do so up to MaxTotal.
3582 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar) && Size > 4)
3583 if (AFI->getPromotedConstpoolIncrease() + PaddedSize - 4 >=
3585 return SDValue();
3586
3587 // This is only valid if all users are in a single function; we can't clone
3588 // the constant in general. The LLVM IR unnamed_addr allows merging
3589 // constants, but not cloning them.
3590 //
3591 // We could potentially allow cloning if we could prove all uses of the
3592 // constant in the current function don't care about the address, like
3593 // printf format strings. But that isn't implemented for now.
3594 if (!allUsersAreInFunction(GVar, &F))
3595 return SDValue();
3596
3597 // We're going to inline this global. Pad it out if needed.
3598 if (RequiredPadding != 4) {
3599 StringRef S = CDAInit->getAsString();
3600
3602 std::copy(S.bytes_begin(), S.bytes_end(), V.begin());
3603 while (RequiredPadding--)
3604 V.push_back(0);
3606 }
3607
3608 auto CPVal = ARMConstantPoolConstant::Create(GVar, Init);
3609 SDValue CPAddr = DAG.getTargetConstantPool(CPVal, PtrVT, Align(4));
3610 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar)) {
3613 PaddedSize - 4);
3614 }
3615 ++NumConstpoolPromoted;
3616 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3617}
3618
3620 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
3621 if (!(GV = GA->getAliaseeObject()))
3622 return false;
3623 if (const auto *V = dyn_cast<GlobalVariable>(GV))
3624 return V->isConstant();
3625 return isa<Function>(GV);
3626}
3627
3628SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3629 SelectionDAG &DAG) const {
3630 switch (Subtarget->getTargetTriple().getObjectFormat()) {
3631 default: llvm_unreachable("unknown object format");
3632 case Triple::COFF:
3633 return LowerGlobalAddressWindows(Op, DAG);
3634 case Triple::ELF:
3635 return LowerGlobalAddressELF(Op, DAG);
3636 case Triple::MachO:
3637 return LowerGlobalAddressDarwin(Op, DAG);
3638 }
3639}
3640
3641SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
3642 SelectionDAG &DAG) const {
3643 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3644 SDLoc dl(Op);
3645 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3646 bool IsRO = isReadOnly(GV);
3647
3648 // promoteToConstantPool only if not generating XO text section
3649 if (GV->isDSOLocal() && !Subtarget->genExecuteOnly())
3650 if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
3651 return V;
3652
3653 if (isPositionIndependent()) {
3654 // Weak symbols need GOT indirection even when hidden/DSO-local.
3655 // The assembler eagerly resolves PC-relative expressions when the
3656 // symbol and reference are in the same section, which prevents the
3657 // linker from overriding a weak definition with a non-weak one.
3658 bool UseGOT = !GV->isDSOLocal() || GV->isWeakForLinker();
3659 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
3660 UseGOT ? ARMII::MO_GOT : 0);
3661 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3662 if (UseGOT)
3663 Result =
3664 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3666 return Result;
3667 } else if (Subtarget->isROPI() && IsRO) {
3668 // PC-relative.
3669 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3670 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3671 return Result;
3672 } else if (Subtarget->isRWPI() && !IsRO) {
3673 // SB-relative.
3674 SDValue RelAddr;
3675 if (Subtarget->useMovt()) {
3676 ++NumMovwMovt;
3677 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_SBREL);
3678 RelAddr = DAG.getNode(ARMISD::Wrapper, dl, PtrVT, G);
3679 } else { // use literal pool for address constant
3680 ARMConstantPoolValue *CPV =
3682 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3683 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3684 RelAddr = DAG.getLoad(
3685 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3687 }
3688 SDValue SB = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::R9, PtrVT);
3689 SDValue Result = DAG.getNode(ISD::ADD, dl, PtrVT, SB, RelAddr);
3690 return Result;
3691 }
3692
3693 // If we have T2 ops, we can materialize the address directly via movt/movw
3694 // pair. This is always cheaper. If need to generate Execute Only code, and we
3695 // only have Thumb1 available, we can't use a constant pool and are forced to
3696 // use immediate relocations.
3697 if (Subtarget->useMovt() || Subtarget->genExecuteOnly()) {
3698 if (Subtarget->useMovt())
3699 ++NumMovwMovt;
3700 // FIXME: Once remat is capable of dealing with instructions with register
3701 // operands, expand this into two nodes.
3702 return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
3703 DAG.getTargetGlobalAddress(GV, dl, PtrVT));
3704 } else {
3705 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
3706 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3707 return DAG.getLoad(
3708 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3710 }
3711}
3712
3713SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3714 SelectionDAG &DAG) const {
3715 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3716 "ROPI/RWPI not currently supported for Darwin");
3717 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3718 SDLoc dl(Op);
3719 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3720
3721 if (Subtarget->useMovt())
3722 ++NumMovwMovt;
3723
3724 // FIXME: Once remat is capable of dealing with instructions with register
3725 // operands, expand this into multiple nodes
3726 unsigned Wrapper =
3727 isPositionIndependent() ? ARMISD::WrapperPIC : ARMISD::Wrapper;
3728
3729 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
3730 SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
3731
3732 if (Subtarget->isGVIndirectSymbol(GV))
3733 Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3735 return Result;
3736}
3737
3738SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op,
3739 SelectionDAG &DAG) const {
3740 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3741 "non-Windows COFF is not supported");
3742 assert(Subtarget->useMovt() &&
3743 "Windows on ARM expects to use movw/movt");
3744 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3745 "ROPI/RWPI not currently supported for Windows");
3746
3747 const TargetMachine &TM = getTargetMachine();
3748 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3749 ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG;
3750 if (GV->hasDLLImportStorageClass())
3751 TargetFlags = ARMII::MO_DLLIMPORT;
3752 else if (!TM.shouldAssumeDSOLocal(GV))
3753 TargetFlags = ARMII::MO_COFFSTUB;
3754 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3756 SDLoc DL(Op);
3757
3758 ++NumMovwMovt;
3759
3760 // FIXME: Once remat is capable of dealing with instructions with register
3761 // operands, expand this into two nodes.
3762 Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT,
3763 DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*offset=*/0,
3764 TargetFlags));
3765 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
3766 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
3768 return Result;
3769}
3770
3771SDValue
3772ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const {
3773 SDLoc dl(Op);
3774 SDValue Val = DAG.getConstant(0, dl, MVT::i32);
3775 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl,
3776 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
3777 Op.getOperand(1), Val);
3778}
3779
3780SDValue
3781ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
3782 SDLoc dl(Op);
3783 return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
3784 Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
3785}
3786
3787SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
3788 SelectionDAG &DAG) const {
3789 SDLoc dl(Op);
3790 return DAG.getNode(ARMISD::EH_SJLJ_SETUP_DISPATCH, dl, MVT::Other,
3791 Op.getOperand(0));
3792}
3793
3794SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3795 SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3796 unsigned IntNo =
3797 Op.getConstantOperandVal(Op.getOperand(0).getValueType() == MVT::Other);
3798 switch (IntNo) {
3799 default:
3800 return SDValue(); // Don't custom lower most intrinsics.
3801 case Intrinsic::arm_gnu_eabi_mcount: {
3802 MachineFunction &MF = DAG.getMachineFunction();
3803 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3804 SDLoc dl(Op);
3805 SDValue Chain = Op.getOperand(0);
3806 // call "\01__gnu_mcount_nc"
3807 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3808 const uint32_t *Mask =
3810 assert(Mask && "Missing call preserved mask for calling convention");
3811 // Mark LR an implicit live-in.
3812 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3813 SDValue ReturnAddress =
3814 DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3815 constexpr EVT ResultTys[] = {MVT::Other, MVT::Glue};
3816 SDValue Callee =
3817 DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3819 if (Subtarget->isThumb())
3820 return SDValue(
3821 DAG.getMachineNode(
3822 ARM::tBL_PUSHLR, dl, ResultTys,
3823 {ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3824 DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3825 0);
3826 return SDValue(
3827 DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3828 {ReturnAddress, Callee, RegisterMask, Chain}),
3829 0);
3830 }
3831 }
3832}
3833
3834SDValue
3835ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
3836 const ARMSubtarget *Subtarget) const {
3837 unsigned IntNo = Op.getConstantOperandVal(0);
3838 SDLoc dl(Op);
3839 switch (IntNo) {
3840 default: return SDValue(); // Don't custom lower most intrinsics.
3841 case Intrinsic::localaddress: {
3842 const MachineFunction &MF = DAG.getMachineFunction();
3843 const auto *RegInfo = Subtarget->getRegisterInfo();
3844 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
3845 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
3846 Op.getSimpleValueType());
3847 }
3848 case Intrinsic::eh_recoverfp: {
3849 SDValue FnOp = Op.getOperand(1);
3850 GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
3851 auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
3852 if (!Fn)
3854 "llvm.eh.recoverfp must take a function as the first argument");
3855 const auto *RegInfo = Subtarget->getRegisterInfo();
3856 Register BaseReg = RegInfo->getBaseRegister();
3857 MachineFunction &MF = DAG.getMachineFunction();
3858 MachineBasicBlock &MBB = *MF.begin();
3859 if (!MBB.isLiveIn(BaseReg))
3860 MBB.addLiveIn(BaseReg);
3861 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3862 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, BaseReg, PtrVT);
3863 }
3864 case Intrinsic::thread_pointer: {
3865 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3866 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3867 }
3868 case Intrinsic::arm_cls: {
3869 // Note: arm_cls and arm_cls64 intrinsics are expanded directly here
3870 // in LowerINTRINSIC_WO_CHAIN since there's no native scalar CLS
3871 // instruction.
3872 const SDValue &Operand = Op.getOperand(1);
3873 const EVT VTy = Op.getValueType();
3874 return DAG.getNode(ISD::CTLS, dl, VTy, Operand);
3875 }
3876 case Intrinsic::arm_cls64: {
3877 // arm_cls64 returns i32 but takes i64 input.
3878 // Use ISD::CTLS for i64 and truncate the result.
3879 SDValue CTLS64 = DAG.getNode(ISD::CTLS, dl, MVT::i64, Op.getOperand(1));
3880 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, CTLS64);
3881 }
3882 case Intrinsic::arm_neon_vcls:
3883 case Intrinsic::arm_mve_vcls: {
3884 // Lower vector CLS intrinsics to ISD::CTLS.
3885 // Vector CTLS is Legal when NEON/MVE is available (set elsewhere).
3886 const EVT VTy = Op.getValueType();
3887 return DAG.getNode(ISD::CTLS, dl, VTy, Op.getOperand(1));
3888 }
3889 case Intrinsic::eh_sjlj_lsda: {
3890 MachineFunction &MF = DAG.getMachineFunction();
3891 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3892 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3893 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3894 SDValue CPAddr;
3895 bool IsPositionIndependent = isPositionIndependent();
3896 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
3897 ARMConstantPoolValue *CPV =
3898 ARMConstantPoolConstant::Create(&MF.getFunction(), ARMPCLabelIndex,
3899 ARMCP::CPLSDA, PCAdj);
3900 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3901 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3902 SDValue Result = DAG.getLoad(
3903 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3905
3906 if (IsPositionIndependent) {
3907 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3908 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
3909 }
3910 return Result;
3911 }
3912 case Intrinsic::arm_neon_vabs:
3913 return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(),
3914 Op.getOperand(1));
3915 case Intrinsic::arm_neon_vabds:
3916 if (Op.getValueType().isInteger())
3917 return DAG.getNode(ISD::ABDS, SDLoc(Op), Op.getValueType(),
3918 Op.getOperand(1), Op.getOperand(2));
3919 return SDValue();
3920 case Intrinsic::arm_neon_vabdu:
3921 return DAG.getNode(ISD::ABDU, SDLoc(Op), Op.getValueType(),
3922 Op.getOperand(1), Op.getOperand(2));
3923 case Intrinsic::arm_neon_vmulls:
3924 case Intrinsic::arm_neon_vmullu: {
3925 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
3926 ? ARMISD::VMULLs : ARMISD::VMULLu;
3927 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3928 Op.getOperand(1), Op.getOperand(2));
3929 }
3930 case Intrinsic::arm_neon_vminnm:
3931 case Intrinsic::arm_neon_vmaxnm: {
3932 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminnm)
3933 ? ISD::FMINNUM : ISD::FMAXNUM;
3934 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3935 Op.getOperand(1), Op.getOperand(2));
3936 }
3937 case Intrinsic::arm_neon_vminu:
3938 case Intrinsic::arm_neon_vmaxu: {
3939 if (Op.getValueType().isFloatingPoint())
3940 return SDValue();
3941 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminu)
3942 ? ISD::UMIN : ISD::UMAX;
3943 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3944 Op.getOperand(1), Op.getOperand(2));
3945 }
3946 case Intrinsic::arm_neon_vmins:
3947 case Intrinsic::arm_neon_vmaxs: {
3948 // v{min,max}s is overloaded between signed integers and floats.
3949 if (!Op.getValueType().isFloatingPoint()) {
3950 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3951 ? ISD::SMIN : ISD::SMAX;
3952 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3953 Op.getOperand(1), Op.getOperand(2));
3954 }
3955 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3956 ? ISD::FMINIMUM : ISD::FMAXIMUM;
3957 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3958 Op.getOperand(1), Op.getOperand(2));
3959 }
3960 case Intrinsic::arm_neon_vtbl1:
3961 return DAG.getNode(ARMISD::VTBL1, SDLoc(Op), Op.getValueType(),
3962 Op.getOperand(1), Op.getOperand(2));
3963 case Intrinsic::arm_neon_vtbl2:
3964 return DAG.getNode(ARMISD::VTBL2, SDLoc(Op), Op.getValueType(),
3965 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3966 case Intrinsic::arm_mve_pred_i2v:
3967 case Intrinsic::arm_mve_pred_v2i:
3968 return DAG.getNode(ARMISD::PREDICATE_CAST, SDLoc(Op), Op.getValueType(),
3969 Op.getOperand(1));
3970 case Intrinsic::arm_mve_vreinterpretq:
3971 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(Op), Op.getValueType(),
3972 Op.getOperand(1));
3973 case Intrinsic::arm_mve_lsll:
3974 return DAG.getNode(ARMISD::LSLL, SDLoc(Op), Op->getVTList(),
3975 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3976 case Intrinsic::arm_mve_asrl:
3977 return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
3978 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3979 case Intrinsic::arm_mve_vsli:
3980 return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
3981 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3982 case Intrinsic::arm_mve_vsri:
3983 return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
3984 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3985 }
3986}
3987
3989 const ARMSubtarget *Subtarget) {
3990 SDLoc dl(Op);
3991 auto SSID = static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
3992 if (SSID == SyncScope::SingleThread)
3993 return Op;
3994
3995 if (!Subtarget->hasDataBarrier()) {
3996 // Some ARMv6 cpus can support data barriers with an mcr instruction.
3997 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
3998 // here.
3999 assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() &&
4000 "Unexpected ISD::ATOMIC_FENCE encountered. Should be libcall!");
4001 return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0),
4002 DAG.getConstant(0, dl, MVT::i32));
4003 }
4004
4005 AtomicOrdering Ord =
4006 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
4008 if (Subtarget->isMClass()) {
4009 // Only a full system barrier exists in the M-class architectures.
4011 } else if (Subtarget->preferISHSTBarriers() &&
4012 Ord == AtomicOrdering::Release) {
4013 // Swift happens to implement ISHST barriers in a way that's compatible with
4014 // Release semantics but weaker than ISH so we'd be fools not to use
4015 // it. Beware: other processors probably don't!
4017 }
4018
4019 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
4020 DAG.getConstant(Intrinsic::arm_dmb, dl, MVT::i32),
4021 DAG.getConstant(Domain, dl, MVT::i32));
4022}
4023
4025 const ARMSubtarget *Subtarget) {
4026 // ARM pre v5TE and Thumb1 does not have preload instructions.
4027 if (!(Subtarget->isThumb2() ||
4028 (!Subtarget->isThumb1Only() && Subtarget->hasV5TEOps())))
4029 // Just preserve the chain.
4030 return Op.getOperand(0);
4031
4032 SDLoc dl(Op);
4033 unsigned isRead = ~Op.getConstantOperandVal(2) & 1;
4034 if (!isRead &&
4035 (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
4036 // ARMv7 with MP extension has PLDW.
4037 return Op.getOperand(0);
4038
4039 unsigned isData = Op.getConstantOperandVal(4);
4040 if (Subtarget->isThumb()) {
4041 // Invert the bits.
4042 isRead = ~isRead & 1;
4043 isData = ~isData & 1;
4044 }
4045
4046 return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
4047 Op.getOperand(1), DAG.getConstant(isRead, dl, MVT::i32),
4048 DAG.getConstant(isData, dl, MVT::i32));
4049}
4050
4053 ARMFunctionInfo *FuncInfo = MF.getInfo<ARMFunctionInfo>();
4054
4055 // vastart just stores the address of the VarArgsFrameIndex slot into the
4056 // memory location argument.
4057 SDLoc dl(Op);
4059 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4060 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4061 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
4062 MachinePointerInfo(SV));
4063}
4064
4065SDValue ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA,
4066 CCValAssign &NextVA,
4067 SDValue &Root,
4068 SelectionDAG &DAG,
4069 const SDLoc &dl) const {
4070 MachineFunction &MF = DAG.getMachineFunction();
4071 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4072
4073 const TargetRegisterClass *RC;
4074 if (AFI->isThumb1OnlyFunction())
4075 RC = &ARM::tGPRRegClass;
4076 else
4077 RC = &ARM::GPRRegClass;
4078
4079 // Transform the arguments stored in physical registers into virtual ones.
4080 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4081 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4082
4083 SDValue ArgValue2;
4084 if (NextVA.isMemLoc()) {
4085 MachineFrameInfo &MFI = MF.getFrameInfo();
4086 int FI = MFI.CreateFixedObject(4, NextVA.getLocMemOffset(), true);
4087
4088 // Create load node to retrieve arguments from the stack.
4089 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4090 ArgValue2 = DAG.getLoad(
4091 MVT::i32, dl, Root, FIN,
4093 } else {
4094 Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
4095 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4096 }
4097 if (!Subtarget->isLittle())
4098 std::swap (ArgValue, ArgValue2);
4099 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
4100}
4101
4102// The remaining GPRs hold either the beginning of variable-argument
4103// data, or the beginning of an aggregate passed by value (usually
4104// byval). Either way, we allocate stack slots adjacent to the data
4105// provided by our caller, and store the unallocated registers there.
4106// If this is a variadic function, the va_list pointer will begin with
4107// these values; otherwise, this reassembles a (byval) structure that
4108// was split between registers and memory.
4109// Return: The frame index registers were stored into.
4110int ARMTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG,
4111 const SDLoc &dl, SDValue &Chain,
4112 const Value *OrigArg,
4113 unsigned InRegsParamRecordIdx,
4114 int ArgOffset, unsigned ArgSize) const {
4115 // Currently, two use-cases possible:
4116 // Case #1. Non-var-args function, and we meet first byval parameter.
4117 // Setup first unallocated register as first byval register;
4118 // eat all remained registers
4119 // (these two actions are performed by HandleByVal method).
4120 // Then, here, we initialize stack frame with
4121 // "store-reg" instructions.
4122 // Case #2. Var-args function, that doesn't contain byval parameters.
4123 // The same: eat all remained unallocated registers,
4124 // initialize stack frame.
4125
4126 MachineFunction &MF = DAG.getMachineFunction();
4127 MachineFrameInfo &MFI = MF.getFrameInfo();
4128 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4129 unsigned RBegin, REnd;
4130 if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) {
4131 CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, RBegin, REnd);
4132 } else {
4133 unsigned RBeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4134 RBegin = RBeginIdx == 4 ? (unsigned)ARM::R4 : GPRArgRegs[RBeginIdx];
4135 REnd = ARM::R4;
4136 }
4137
4138 if (REnd != RBegin)
4139 ArgOffset = -4 * (ARM::R4 - RBegin);
4140
4141 auto PtrVT = getPointerTy(DAG.getDataLayout());
4142 int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, false);
4143 SDValue FIN = DAG.getFrameIndex(FrameIndex, PtrVT);
4144
4146 const TargetRegisterClass *RC =
4147 AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
4148
4149 for (unsigned Reg = RBegin, i = 0; Reg < REnd; ++Reg, ++i) {
4150 Register VReg = MF.addLiveIn(Reg, RC);
4151 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
4152 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
4153 MachinePointerInfo(OrigArg, 4 * i));
4154 MemOps.push_back(Store);
4155 FIN = DAG.getNode(ISD::ADD, dl, PtrVT, FIN, DAG.getConstant(4, dl, PtrVT));
4156 }
4157
4158 if (!MemOps.empty())
4159 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
4160 return FrameIndex;
4161}
4162
4163// Setup stack frame, the va_list pointer will start from.
4164void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
4165 const SDLoc &dl, SDValue &Chain,
4166 unsigned ArgOffset,
4167 unsigned TotalArgRegsSaveSize,
4168 bool ForceMutable) const {
4169 MachineFunction &MF = DAG.getMachineFunction();
4170 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4171
4172 // Try to store any remaining integer argument regs
4173 // to their spots on the stack so that they may be loaded by dereferencing
4174 // the result of va_next.
4175 // If there is no regs to be stored, just point address after last
4176 // argument passed via stack.
4177 int FrameIndex = StoreByValRegs(
4178 CCInfo, DAG, dl, Chain, nullptr, CCInfo.getInRegsParamsCount(),
4179 CCInfo.getStackSize(), std::max(4U, TotalArgRegsSaveSize));
4180 AFI->setVarArgsFrameIndex(FrameIndex);
4181}
4182
4183bool ARMTargetLowering::splitValueIntoRegisterParts(
4184 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
4185 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
4186 EVT ValueVT = Val.getValueType();
4187 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4188 unsigned ValueBits = ValueVT.getSizeInBits();
4189 unsigned PartBits = PartVT.getSizeInBits();
4190 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(ValueBits), Val);
4191 Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::getIntegerVT(PartBits), Val);
4192 Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
4193 Parts[0] = Val;
4194 return true;
4195 }
4196 return false;
4197}
4198
4199SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
4200 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
4201 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
4202 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4203 unsigned ValueBits = ValueVT.getSizeInBits();
4204 unsigned PartBits = PartVT.getSizeInBits();
4205 SDValue Val = Parts[0];
4206
4207 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(PartBits), Val);
4208 Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::getIntegerVT(ValueBits), Val);
4209 Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
4210 return Val;
4211 }
4212 return SDValue();
4213}
4214
4215SDValue ARMTargetLowering::LowerFormalArguments(
4216 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
4217 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
4218 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
4219 MachineFunction &MF = DAG.getMachineFunction();
4220 MachineFrameInfo &MFI = MF.getFrameInfo();
4221
4222 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4223
4224 // Assign locations to all of the incoming arguments.
4226 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
4227 *DAG.getContext());
4228 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4229
4231 unsigned CurArgIdx = 0;
4232
4233 // Initially ArgRegsSaveSize is zero.
4234 // Then we increase this value each time we meet byval parameter.
4235 // We also increase this value in case of varargs function.
4236 AFI->setArgRegsSaveSize(0);
4237
4238 // Calculate the amount of stack space that we need to allocate to store
4239 // byval and variadic arguments that are passed in registers.
4240 // We need to know this before we allocate the first byval or variadic
4241 // argument, as they will be allocated a stack slot below the CFA (Canonical
4242 // Frame Address, the stack pointer at entry to the function).
4243 unsigned ArgRegBegin = ARM::R4;
4244 for (const CCValAssign &VA : ArgLocs) {
4245 if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
4246 break;
4247
4248 unsigned Index = VA.getValNo();
4249 ISD::ArgFlagsTy Flags = Ins[Index].Flags;
4250 if (!Flags.isByVal())
4251 continue;
4252
4253 assert(VA.isMemLoc() && "unexpected byval pointer in reg");
4254 unsigned RBegin, REnd;
4255 CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
4256 ArgRegBegin = std::min(ArgRegBegin, RBegin);
4257
4258 CCInfo.nextInRegsParam();
4259 }
4260 CCInfo.rewindByValRegsInfo();
4261
4262 int lastInsIndex = -1;
4263 if (isVarArg && MFI.hasVAStart()) {
4264 unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4265 if (RegIdx != std::size(GPRArgRegs))
4266 ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
4267 }
4268
4269 unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
4270 AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
4271 auto PtrVT = getPointerTy(DAG.getDataLayout());
4272
4273 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4274 CCValAssign &VA = ArgLocs[i];
4275 if (Ins[VA.getValNo()].isOrigArg()) {
4276 std::advance(CurOrigArg,
4277 Ins[VA.getValNo()].getOrigArgIndex() - CurArgIdx);
4278 CurArgIdx = Ins[VA.getValNo()].getOrigArgIndex();
4279 }
4280 // Arguments stored in registers.
4281 if (VA.isRegLoc()) {
4282 EVT RegVT = VA.getLocVT();
4283 SDValue ArgValue;
4284
4285 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4286 // f64 and vector types are split up into multiple registers or
4287 // combinations of registers and stack slots.
4288 SDValue ArgValue1 =
4289 GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4290 VA = ArgLocs[++i]; // skip ahead to next loc
4291 SDValue ArgValue2;
4292 if (VA.isMemLoc()) {
4293 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), true);
4294 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4295 ArgValue2 = DAG.getLoad(
4296 MVT::f64, dl, Chain, FIN,
4298 } else {
4299 ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4300 }
4301 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
4302 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4303 ArgValue1, DAG.getIntPtrConstant(0, dl));
4304 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4305 ArgValue2, DAG.getIntPtrConstant(1, dl));
4306 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
4307 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4308 } else {
4309 const TargetRegisterClass *RC;
4310
4311 if (RegVT == MVT::f16 || RegVT == MVT::bf16)
4312 RC = &ARM::HPRRegClass;
4313 else if (RegVT == MVT::f32)
4314 RC = &ARM::SPRRegClass;
4315 else if (RegVT == MVT::f64 || RegVT == MVT::v4f16 ||
4316 RegVT == MVT::v4bf16)
4317 RC = &ARM::DPRRegClass;
4318 else if (RegVT == MVT::v2f64 || RegVT == MVT::v8f16 ||
4319 RegVT == MVT::v8bf16)
4320 RC = &ARM::QPRRegClass;
4321 else if (RegVT == MVT::i32)
4322 RC = AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass
4323 : &ARM::GPRRegClass;
4324 else
4325 llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
4326
4327 // Transform the arguments in physical registers into virtual ones.
4328 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4329 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
4330
4331 // If this value is passed in r0 and has the returned attribute (e.g.
4332 // C++ 'structors), record this fact for later use.
4333 if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
4334 AFI->setPreservesR0();
4335 }
4336 }
4337
4338 // If this is an 8 or 16-bit value, it is really passed promoted
4339 // to 32 bits. Insert an assert[sz]ext to capture this, then
4340 // truncate to the right size.
4341 switch (VA.getLocInfo()) {
4342 default: llvm_unreachable("Unknown loc info!");
4343 case CCValAssign::Full: break;
4344 case CCValAssign::BCvt:
4345 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4346 break;
4347 }
4348
4349 // f16 arguments have their size extended to 4 bytes and passed as if they
4350 // had been copied to the LSBs of a 32-bit register.
4351 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
4352 if (VA.needsCustom() &&
4353 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4354 ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4355
4356 // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4357 // less than 32 bits must be sign- or zero-extended in the callee for
4358 // security reasons. Although the ABI mandates an extension done by the
4359 // caller, the latter cannot be trusted to follow the rules of the ABI.
4360 const ISD::InputArg &Arg = Ins[VA.getValNo()];
4361 if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4362 RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4363 ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4364
4365 InVals.push_back(ArgValue);
4366 } else { // VA.isRegLoc()
4367 // Only arguments passed on the stack should make it here.
4368 assert(VA.isMemLoc());
4369 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
4370
4371 int index = VA.getValNo();
4372
4373 // Some Ins[] entries become multiple ArgLoc[] entries.
4374 // Process them only once.
4375 if (index != lastInsIndex)
4376 {
4377 ISD::ArgFlagsTy Flags = Ins[index].Flags;
4378 // FIXME: For now, all byval parameter objects are marked mutable.
4379 // This can be changed with more analysis.
4380 // In case of tail call optimization mark all arguments mutable.
4381 // Since they could be overwritten by lowering of arguments in case of
4382 // a tail call.
4383 if (Flags.isByVal()) {
4384 assert(Ins[index].isOrigArg() &&
4385 "Byval arguments cannot be implicit");
4386 unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed();
4387
4388 int FrameIndex = StoreByValRegs(
4389 CCInfo, DAG, dl, Chain, &*CurOrigArg, CurByValIndex,
4390 VA.getLocMemOffset(), Flags.getByValSize());
4391 InVals.push_back(DAG.getFrameIndex(FrameIndex, PtrVT));
4392 CCInfo.nextInRegsParam();
4393 } else if (VA.needsCustom() && (VA.getValVT() == MVT::f16 ||
4394 VA.getValVT() == MVT::bf16)) {
4395 // f16 and bf16 values are passed in the least-significant half of
4396 // a 4 byte stack slot. This is done as-if the extension was done
4397 // in a 32-bit register, so the actual bytes used for the value
4398 // differ between little and big endian.
4399 assert(VA.getLocVT().getSizeInBits() == 32);
4400 unsigned FIOffset = VA.getLocMemOffset();
4401 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits() / 8,
4402 FIOffset, true);
4403
4404 SDValue Addr = DAG.getFrameIndex(FI, PtrVT);
4405 if (DAG.getDataLayout().isBigEndian())
4406 Addr = DAG.getObjectPtrOffset(dl, Addr, TypeSize::getFixed(2));
4407
4408 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, Addr,
4410 DAG.getMachineFunction(), FI)));
4411
4412 } else {
4413 unsigned FIOffset = VA.getLocMemOffset();
4414 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
4415 FIOffset, true);
4416
4417 // Create load nodes to retrieve arguments from the stack.
4418 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4419 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
4421 DAG.getMachineFunction(), FI)));
4422 }
4423 lastInsIndex = index;
4424 }
4425 }
4426 }
4427
4428 // varargs
4429 if (isVarArg && MFI.hasVAStart()) {
4430 VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getStackSize(),
4431 TotalArgRegsSaveSize);
4432 if (AFI->isCmseNSEntryFunction()) {
4433 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4435 "secure entry function must not be variadic", dl.getDebugLoc()));
4436 }
4437 }
4438
4439 unsigned StackArgSize = CCInfo.getStackSize();
4440 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4441 if (canGuaranteeTCO(CallConv, TailCallOpt)) {
4442 // The only way to guarantee a tail call is if the callee restores its
4443 // argument area, but it must also keep the stack aligned when doing so.
4444 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
4445 assert(StackAlign && "data layout string is missing stack alignment");
4446 StackArgSize = alignTo(StackArgSize, *StackAlign);
4447
4448 AFI->setArgumentStackToRestore(StackArgSize);
4449 }
4450 AFI->setArgumentStackSize(StackArgSize);
4451
4452 if (CCInfo.getStackSize() > 0 && AFI->isCmseNSEntryFunction()) {
4453 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4455 "secure entry function requires arguments on stack", dl.getDebugLoc()));
4456 }
4457
4458 return Chain;
4459}
4460
4461/// isFloatingPointZero - Return true if this is +0.0.
4464 return CFP->getValueAPF().isPosZero();
4465 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
4466 // Maybe this has already been legalized into the constant pool?
4467 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
4468 SDValue WrapperOp = Op.getOperand(1).getOperand(0);
4470 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
4471 return CFP->getValueAPF().isPosZero();
4472 }
4473 } else if (Op->getOpcode() == ISD::BITCAST &&
4474 Op->getValueType(0) == MVT::f64) {
4475 // Handle (ISD::BITCAST (ARMISD::VMOVIMM (ISD::TargetConstant 0)) MVT::f64)
4476 // created by LowerConstantFP().
4477 SDValue BitcastOp = Op->getOperand(0);
4478 if (BitcastOp->getOpcode() == ARMISD::VMOVIMM &&
4479 isNullConstant(BitcastOp->getOperand(0)))
4480 return true;
4481 }
4482 return false;
4483}
4484
4486 // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
4487 if (Op->getFlags().hasNoSignedWrap())
4488 return true;
4489
4490 // We can still figure out if the second operand is safe to use
4491 // in a CMN instruction by checking if it is known to be not the minimum
4492 // signed value. If it is not, then we can safely use CMN.
4493 // Note: We can eventually remove this check and simply rely on
4494 // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
4495 // consistently sets them appropriately when making said nodes.
4496
4497 KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
4498 return !KnownSrc.getSignedMinValue().isMinSignedValue();
4499}
4500
4502 return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
4503 (isIntEqualitySetCC(CC) ||
4504 (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
4505 (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
4506}
4507
4508/// Returns how profitable it is to fold a comparison's operand's shift and/or
4509/// extension operations into the comparison instruction's second operand
4510/// (so_reg_imm / so_reg_reg for ARM, t2_so_reg for Thumb-2).
4512 // Thumb-1 CMP does not support shifted second operands.
4513 if (ST.isThumb1Only() || !Op.hasOneUse())
4514 return 0;
4515
4516 unsigned Opc = Op.getOpcode();
4517 if (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) {
4518 if (auto *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
4519 return ShiftAmt->getZExtValue() <= 31 ? 1 : 0;
4520 // Register-controlled shift: only ARM-mode CMP/CMN (so_reg_reg) supports
4521 // this; Thumb-2 t2_so_reg requires an immediate shift amount.
4522 return ST.isThumb() ? 0 : 1;
4523 }
4524
4525 if (Opc == ISD::ROTR) {
4526 // Rotr constants will be normalized via mod 32, or & 31,
4527 // so we do not have to bounds check.
4528 if (isa<ConstantSDNode>(Op.getOperand(1)))
4529 return 1;
4530 return ST.isThumb() ? 0 : 1;
4531 }
4532
4533 return 0;
4534}
4535
4536/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4537/// the given operands.
4538SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4539 SDValue &ARMcc, SelectionDAG &DAG,
4540 const SDLoc &dl) const {
4541 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4542 unsigned C = RHSC->getZExtValue();
4543 if (!isLegalICmpImmediate((int32_t)C)) {
4544 // Constant does not fit, try adjusting it by one.
4545 switch (CC) {
4546 default: break;
4547 case ISD::SETLT:
4548 case ISD::SETGE:
4549 if (C != 0x80000000 && isLegalICmpImmediate(C-1)) {
4550 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4551 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4552 }
4553 break;
4554 case ISD::SETULT:
4555 case ISD::SETUGE:
4556 if (C != 0 && isLegalICmpImmediate(C-1)) {
4557 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4558 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4559 }
4560 break;
4561 case ISD::SETLE:
4562 case ISD::SETGT:
4563 if (C != 0x7fffffff && isLegalICmpImmediate(C+1)) {
4564 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4565 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4566 }
4567 break;
4568 case ISD::SETULE:
4569 case ISD::SETUGT:
4570 if (C != 0xffffffff && isLegalICmpImmediate(C+1)) {
4571 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4572 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4573 }
4574 break;
4575 }
4576 }
4577 }
4578
4579 // Thumb1 has very limited immediate modes, so turning an "and" into a
4580 // shift can save multiple instructions.
4581 //
4582 // If we have (x & C1), and C1 is an appropriate mask, we can transform it
4583 // into "((x << n) >> n)". But that isn't necessarily profitable on its
4584 // own. If it's the operand to an unsigned comparison with an immediate,
4585 // we can eliminate one of the shifts: we transform
4586 // "((x << n) >> n) == C2" to "(x << n) == (C2 << n)".
4587 //
4588 // We avoid transforming cases which aren't profitable due to encoding
4589 // details:
4590 //
4591 // 1. C2 fits into the immediate field of a cmp, and the transformed version
4592 // would not; in that case, we're essentially trading one immediate load for
4593 // another.
4594 // 2. C1 is 255 or 65535, so we can use uxtb or uxth.
4595 // 3. C2 is zero; we have other code for this special case.
4596 //
4597 // FIXME: Figure out profitability for Thumb2; we usually can't save an
4598 // instruction, since the AND is always one instruction anyway, but we could
4599 // use narrow instructions in some cases.
4600 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::AND &&
4601 LHS->hasOneUse() && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4602 LHS.getValueType() == MVT::i32 && isa<ConstantSDNode>(RHS) &&
4603 !isSignedIntSetCC(CC)) {
4604 unsigned Mask = LHS.getConstantOperandVal(1);
4605 auto *RHSC = cast<ConstantSDNode>(RHS.getNode());
4606 uint64_t RHSV = RHSC->getZExtValue();
4607 if (isMask_32(Mask) && (RHSV & ~Mask) == 0 && Mask != 255 && Mask != 65535) {
4608 unsigned ShiftBits = llvm::countl_zero(Mask);
4609 if (RHSV && (RHSV > 255 || (RHSV << ShiftBits) <= 255)) {
4610 SDValue ShiftAmt = DAG.getConstant(ShiftBits, dl, MVT::i32);
4611 LHS = DAG.getNode(ISD::SHL, dl, MVT::i32, LHS.getOperand(0), ShiftAmt);
4612 RHS = DAG.getConstant(RHSV << ShiftBits, dl, MVT::i32);
4613 }
4614 }
4615 }
4616
4617 // The specific comparison "(x<<c) > 0x80000000U" can be optimized to a
4618 // single "lsls x, c+1". The shift sets the "C" and "Z" flags the same
4619 // way a cmp would.
4620 // FIXME: Add support for ARM/Thumb2; this would need isel patterns, and
4621 // some tweaks to the heuristics for the previous and->shift transform.
4622 // FIXME: Optimize cases where the LHS isn't a shift.
4623 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::SHL &&
4624 isa<ConstantSDNode>(RHS) && RHS->getAsZExtVal() == 0x80000000U &&
4625 CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4626 LHS.getConstantOperandVal(1) < 31) {
4627 unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
4628 SDValue Shift =
4629 DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
4630 LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
4631 ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
4632 return Shift.getValue(1);
4633 }
4634
4636
4637 unsigned CompareType;
4638 switch (CondCode) {
4639 default:
4640 CompareType = ARMISD::CMP;
4641 break;
4642 case ARMCC::EQ:
4643 case ARMCC::NE:
4644 // Uses only Z Flag
4645 CompareType = ARMISD::CMPZ;
4646 break;
4647 }
4648
4649 // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
4650 // the codebase.
4651
4652 // TODO: When we have a solution to the vselect predicate not allowing pl/mi
4653 // all the time, allow those cases to be cmn too no matter what.
4654 if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
4655 CompareType = ARMISD::CMN;
4656 RHS = RHS.getOperand(1);
4657 } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
4658 CompareType = ARMISD::CMN;
4659 LHS = LHS.getOperand(1);
4661 }
4662
4663 // Prefer folding shifts / CMN into the cmp/cmn second operand (so_reg /
4664 // t2_so_reg). When both sides compete, pick the higher
4665 // getCmpOperandFoldingProfit. Only when RHS is not a legal icmp
4666 // immediate: otherwise keep the canonical (reg, imm) form.
4667 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getNode());
4668 if (!C || !isLegalICmpImmediate(C->getSExtValue())) {
4669 if (getCmpOperandFoldingProfit(LHS, *Subtarget) >
4670 getCmpOperandFoldingProfit(RHS, *Subtarget)) {
4671 std::swap(LHS, RHS);
4672 if (CompareType == ARMISD::CMP)
4674 }
4675 }
4676
4677 // If the RHS is a constant zero then the V (overflow) flag will never be
4678 // set. This can allow us to simplify GE to PL or LT to MI, which can be
4679 // simpler for other passes (like the peephole optimiser) to deal with.
4680 if (isNullConstant(RHS)) {
4681 switch (CondCode) {
4682 default:
4683 break;
4684 case ARMCC::GE:
4686 break;
4687 case ARMCC::LT:
4689 break;
4690 }
4691 }
4692
4693 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
4694 return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
4695}
4696
4697/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
4698SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4699 SelectionDAG &DAG, const SDLoc &dl,
4700 bool Signaling) const {
4701 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
4702 SDValue Flags;
4704 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP, dl, FlagsVT,
4705 LHS, RHS);
4706 else
4707 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
4708 FlagsVT, LHS);
4709 return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
4710}
4711
4712// This function returns three things: the arithmetic computation itself
4713// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4714// comparison and the condition code define the case in which the arithmetic
4715// computation *does not* overflow.
4716std::pair<SDValue, SDValue>
4717ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4718 SDValue &ARMcc) const {
4719 assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4720
4721 SDValue Value, OverflowCmp;
4722 SDValue LHS = Op.getOperand(0);
4723 SDValue RHS = Op.getOperand(1);
4724 SDLoc dl(Op);
4725
4726 // FIXME: We are currently always generating CMPs because we don't support
4727 // generating CMN through the backend. This is not as good as the natural
4728 // CMP case because it causes a register dependency and cannot be folded
4729 // later.
4730
4731 switch (Op.getOpcode()) {
4732 default:
4733 llvm_unreachable("Unknown overflow instruction!");
4734 case ISD::SADDO:
4735 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4736 Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4737 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4738 break;
4739 case ISD::UADDO:
4740 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4741 // We use ADDC here to correspond to its use in LowerALUO.
4742 // We do not use it in the USUBO case as Value may not be used.
4743 Value = DAG.getNode(ARMISD::ADDC, dl,
4744 DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4745 .getValue(0);
4746 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4747 break;
4748 case ISD::SSUBO:
4749 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4750 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4751 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4752 break;
4753 case ISD::USUBO:
4754 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4755 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4756 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4757 break;
4758 case ISD::UMULO:
4759 // We generate a UMUL_LOHI and then check if the high word is 0.
4760 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4761 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4762 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4763 LHS, RHS);
4764 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4765 DAG.getConstant(0, dl, MVT::i32));
4766 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4767 break;
4768 case ISD::SMULO:
4769 // We generate a SMUL_LOHI and then check if all the bits of the high word
4770 // are the same as the sign bit of the low word.
4771 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4772 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4773 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4774 LHS, RHS);
4775 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4776 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4777 Value.getValue(0),
4778 DAG.getConstant(31, dl, MVT::i32)));
4779 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4780 break;
4781 } // switch (...)
4782
4783 return std::make_pair(Value, OverflowCmp);
4784}
4785
4787 SDLoc DL(Value);
4788 EVT VT = Value.getValueType();
4789
4790 if (Invert)
4791 Value = DAG.getNode(ISD::SUB, DL, MVT::i32,
4792 DAG.getConstant(1, DL, MVT::i32), Value);
4793
4794 SDValue Cmp = DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(VT, MVT::i32),
4795 Value, DAG.getConstant(1, DL, VT));
4796 return Cmp.getValue(1);
4797}
4798
4800 bool Invert) {
4801 SDLoc DL(Flags);
4802
4803 if (Invert) {
4804 // Convert flags to boolean with ADDE 0,0,Carry then compute 1 - bool.
4805 SDValue BoolCarry = DAG.getNode(
4806 ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4807 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT), Flags);
4808 return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, VT), BoolCarry);
4809 }
4810
4811 // Now convert the carry flag into a boolean carry. We do this
4812 // using ARMISD::ADDE 0, 0, Carry
4813 return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4814 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT),
4815 Flags);
4816}
4817
4818// Value is 1 if 'V' bit is 1, else 0
4820 SDLoc DL(Flags);
4821 SDValue Zero = DAG.getConstant(0, DL, VT);
4822 SDValue One = DAG.getConstant(1, DL, VT);
4823 SDValue ARMcc = DAG.getConstant(ARMCC::VS, DL, MVT::i32);
4824 return DAG.getNode(ARMISD::CMOV, DL, VT, Zero, One, ARMcc, Flags);
4825}
4826
4827SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
4828 // Let legalize expand this if it isn't a legal type yet.
4829 if (!isTypeLegal(Op.getValueType()))
4830 return SDValue();
4831
4832 SDValue LHS = Op.getOperand(0);
4833 SDValue RHS = Op.getOperand(1);
4834 SDLoc dl(Op);
4835
4836 EVT VT = Op.getValueType();
4837 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4838 SDValue Value;
4839 SDValue Overflow;
4840 switch (Op.getOpcode()) {
4841 case ISD::UADDO:
4842 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4843 // Convert the carry flag into a boolean value.
4844 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, false);
4845 break;
4846 case ISD::USUBO:
4847 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4848 // Convert the carry flag into a boolean value.
4849 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, true);
4850 break;
4851 default: {
4852 // Handle other operations with getARMXALUOOp
4853 SDValue OverflowCmp, ARMcc;
4854 std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4855 // We use 0 and 1 as false and true values.
4856 // ARMcc represents the "no overflow" condition (e.g., VC for signed ops).
4857 // CMOV operand order is (FalseVal, TrueVal), so we put 1 in FalseVal
4858 // position to get Overflow=1 when the "no overflow" condition is false.
4859 Overflow =
4860 DAG.getNode(ARMISD::CMOV, dl, MVT::i32,
4861 DAG.getConstant(1, dl, MVT::i32), // FalseVal: overflow
4862 DAG.getConstant(0, dl, MVT::i32), // TrueVal: no overflow
4863 ARMcc, OverflowCmp);
4864 break;
4865 }
4866 }
4867
4868 return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4869}
4870
4872 const ARMSubtarget *Subtarget) {
4873 EVT VT = Op.getValueType();
4874 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || Subtarget->isThumb1Only())
4875 return SDValue();
4876 if (!VT.isSimple())
4877 return SDValue();
4878
4879 unsigned NewOpcode;
4880 switch (VT.getSimpleVT().SimpleTy) {
4881 default:
4882 return SDValue();
4883 case MVT::i8:
4884 switch (Op->getOpcode()) {
4885 case ISD::UADDSAT:
4886 NewOpcode = ARMISD::UQADD8b;
4887 break;
4888 case ISD::SADDSAT:
4889 NewOpcode = ARMISD::QADD8b;
4890 break;
4891 case ISD::USUBSAT:
4892 NewOpcode = ARMISD::UQSUB8b;
4893 break;
4894 case ISD::SSUBSAT:
4895 NewOpcode = ARMISD::QSUB8b;
4896 break;
4897 }
4898 break;
4899 case MVT::i16:
4900 switch (Op->getOpcode()) {
4901 case ISD::UADDSAT:
4902 NewOpcode = ARMISD::UQADD16b;
4903 break;
4904 case ISD::SADDSAT:
4905 NewOpcode = ARMISD::QADD16b;
4906 break;
4907 case ISD::USUBSAT:
4908 NewOpcode = ARMISD::UQSUB16b;
4909 break;
4910 case ISD::SSUBSAT:
4911 NewOpcode = ARMISD::QSUB16b;
4912 break;
4913 }
4914 break;
4915 }
4916
4917 SDLoc dl(Op);
4918 SDValue Add =
4919 DAG.getNode(NewOpcode, dl, MVT::i32,
4920 DAG.getSExtOrTrunc(Op->getOperand(0), dl, MVT::i32),
4921 DAG.getSExtOrTrunc(Op->getOperand(1), dl, MVT::i32));
4922 return DAG.getNode(ISD::TRUNCATE, dl, VT, Add);
4923}
4924
4925SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
4926 SDValue Cond = Op.getOperand(0);
4927 SDValue SelectTrue = Op.getOperand(1);
4928 SDValue SelectFalse = Op.getOperand(2);
4929 SDLoc dl(Op);
4930 unsigned Opc = Cond.getOpcode();
4931
4932 if (Cond.getResNo() == 1 &&
4933 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
4934 Opc == ISD::USUBO)) {
4935 if (!isTypeLegal(Cond->getValueType(0)))
4936 return SDValue();
4937
4938 SDValue Value, OverflowCmp;
4939 SDValue ARMcc;
4940 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
4941 EVT VT = Op.getValueType();
4942
4943 return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
4944 }
4945
4946 // Convert:
4947 //
4948 // (select (cmov 1, 0, cond), t, f) -> (cmov t, f, cond)
4949 // (select (cmov 0, 1, cond), t, f) -> (cmov f, t, cond)
4950 //
4951 if (Cond.getOpcode() == ARMISD::CMOV && Cond.hasOneUse()) {
4952 const ConstantSDNode *CMOVTrue =
4953 dyn_cast<ConstantSDNode>(Cond.getOperand(0));
4954 const ConstantSDNode *CMOVFalse =
4955 dyn_cast<ConstantSDNode>(Cond.getOperand(1));
4956
4957 if (CMOVTrue && CMOVFalse) {
4958 unsigned CMOVTrueVal = CMOVTrue->getZExtValue();
4959 unsigned CMOVFalseVal = CMOVFalse->getZExtValue();
4960
4961 SDValue True;
4962 SDValue False;
4963 if (CMOVTrueVal == 1 && CMOVFalseVal == 0) {
4964 True = SelectTrue;
4965 False = SelectFalse;
4966 } else if (CMOVTrueVal == 0 && CMOVFalseVal == 1) {
4967 True = SelectFalse;
4968 False = SelectTrue;
4969 }
4970
4971 if (True.getNode() && False.getNode())
4972 return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
4973 Cond.getOperand(3), DAG);
4974 }
4975 }
4976
4977 return DAG.getSelectCC(dl, Cond,
4978 DAG.getConstant(0, dl, Cond.getValueType()),
4979 SelectTrue, SelectFalse, ISD::SETNE);
4980}
4981
4983 bool &swpCmpOps, bool &swpVselOps) {
4984 // Start by selecting the GE condition code for opcodes that return true for
4985 // 'equality'
4986 if (CC == ISD::SETUGE || CC == ISD::SETOGE || CC == ISD::SETOLE ||
4987 CC == ISD::SETULE || CC == ISD::SETGE || CC == ISD::SETLE)
4988 CondCode = ARMCC::GE;
4989
4990 // and GT for opcodes that return false for 'equality'.
4991 else if (CC == ISD::SETUGT || CC == ISD::SETOGT || CC == ISD::SETOLT ||
4992 CC == ISD::SETULT || CC == ISD::SETGT || CC == ISD::SETLT)
4993 CondCode = ARMCC::GT;
4994
4995 // Since we are constrained to GE/GT, if the opcode contains 'less', we need
4996 // to swap the compare operands.
4997 if (CC == ISD::SETOLE || CC == ISD::SETULE || CC == ISD::SETOLT ||
4998 CC == ISD::SETULT || CC == ISD::SETLE || CC == ISD::SETLT)
4999 swpCmpOps = true;
5000
5001 // Both GT and GE are ordered comparisons, and return false for 'unordered'.
5002 // If we have an unordered opcode, we need to swap the operands to the VSEL
5003 // instruction (effectively negating the condition).
5004 //
5005 // This also has the effect of swapping which one of 'less' or 'greater'
5006 // returns true, so we also swap the compare operands. It also switches
5007 // whether we return true for 'equality', so we compensate by picking the
5008 // opposite condition code to our original choice.
5009 if (CC == ISD::SETULE || CC == ISD::SETULT || CC == ISD::SETUGE ||
5010 CC == ISD::SETUGT) {
5011 swpCmpOps = !swpCmpOps;
5012 swpVselOps = !swpVselOps;
5013 CondCode = CondCode == ARMCC::GT ? ARMCC::GE : ARMCC::GT;
5014 }
5015
5016 // 'ordered' is 'anything but unordered', so use the VS condition code and
5017 // swap the VSEL operands.
5018 if (CC == ISD::SETO) {
5019 CondCode = ARMCC::VS;
5020 swpVselOps = true;
5021 }
5022
5023 // 'unordered or not equal' is 'anything but equal', so use the EQ condition
5024 // code and swap the VSEL operands. Also do this if we don't care about the
5025 // unordered case.
5026 if (CC == ISD::SETUNE || CC == ISD::SETNE) {
5027 CondCode = ARMCC::EQ;
5028 swpVselOps = true;
5029 }
5030}
5031
5032SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
5033 SDValue TrueVal, SDValue ARMcc,
5034 SDValue Flags, SelectionDAG &DAG) const {
5035 if (!Subtarget->hasFP64() && VT == MVT::f64) {
5036 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5037 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
5038 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5039 DAG.getVTList(MVT::i32, MVT::i32), TrueVal);
5040
5041 SDValue TrueLow = TrueVal.getValue(0);
5042 SDValue TrueHigh = TrueVal.getValue(1);
5043 SDValue FalseLow = FalseVal.getValue(0);
5044 SDValue FalseHigh = FalseVal.getValue(1);
5045
5046 SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
5047 ARMcc, Flags);
5048 SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
5049 ARMcc, Flags);
5050
5051 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
5052 }
5053 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
5054}
5055
5056static bool isGTorGE(ISD::CondCode CC) {
5057 return CC == ISD::SETGT || CC == ISD::SETGE;
5058}
5059
5060static bool isLTorLE(ISD::CondCode CC) {
5061 return CC == ISD::SETLT || CC == ISD::SETLE;
5062}
5063
5064// See if a conditional (LHS CC RHS ? TrueVal : FalseVal) is lower-saturating.
5065// All of these conditions (and their <= and >= counterparts) will do:
5066// x < k ? k : x
5067// x > k ? x : k
5068// k < x ? x : k
5069// k > x ? k : x
5070static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
5071 const SDValue TrueVal, const SDValue FalseVal,
5072 const ISD::CondCode CC, const SDValue K) {
5073 return (isGTorGE(CC) &&
5074 ((K == LHS && K == TrueVal) || (K == RHS && K == FalseVal))) ||
5075 (isLTorLE(CC) &&
5076 ((K == RHS && K == TrueVal) || (K == LHS && K == FalseVal)));
5077}
5078
5079// Check if two chained conditionals could be converted into SSAT or USAT.
5080//
5081// SSAT can replace a set of two conditional selectors that bound a number to an
5082// interval of type [k, ~k] when k + 1 is a power of 2. Here are some examples:
5083//
5084// x < -k ? -k : (x > k ? k : x)
5085// x < -k ? -k : (x < k ? x : k)
5086// x > -k ? (x > k ? k : x) : -k
5087// x < k ? (x < -k ? -k : x) : k
5088// etc.
5089//
5090// LLVM canonicalizes these to either a min(max()) or a max(min())
5091// pattern. This function tries to match one of these and will return a SSAT
5092// node if successful.
5093//
5094// USAT works similarly to SSAT but bounds on the interval [0, k] where k + 1
5095// is a power of 2.
5097 EVT VT = Op.getValueType();
5098 SDValue V1 = Op.getOperand(0);
5099 SDValue K1 = Op.getOperand(1);
5100 SDValue TrueVal1 = Op.getOperand(2);
5101 SDValue FalseVal1 = Op.getOperand(3);
5102 ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5103
5104 const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
5105 if (Op2.getOpcode() != ISD::SELECT_CC)
5106 return SDValue();
5107
5108 SDValue V2 = Op2.getOperand(0);
5109 SDValue K2 = Op2.getOperand(1);
5110 SDValue TrueVal2 = Op2.getOperand(2);
5111 SDValue FalseVal2 = Op2.getOperand(3);
5112 ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
5113
5114 SDValue V1Tmp = V1;
5115 SDValue V2Tmp = V2;
5116
5117 // Check that the registers and the constants match a max(min()) or min(max())
5118 // pattern
5119 if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
5120 K2 != FalseVal2 ||
5121 !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
5122 return SDValue();
5123
5124 // Check that the constant in the lower-bound check is
5125 // the opposite of the constant in the upper-bound check
5126 // in 1's complement.
5128 return SDValue();
5129
5130 int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
5131 int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
5132 int64_t PosVal = std::max(Val1, Val2);
5133 int64_t NegVal = std::min(Val1, Val2);
5134
5135 if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
5136 !isPowerOf2_64(PosVal + 1))
5137 return SDValue();
5138
5139 // Handle the difference between USAT (unsigned) and SSAT (signed)
5140 // saturation
5141 // At this point, PosVal is guaranteed to be positive
5142 uint64_t K = PosVal;
5143 SDLoc dl(Op);
5144 if (Val1 == ~Val2)
5145 return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
5146 DAG.getConstant(llvm::countr_one(K), dl, VT));
5147 if (NegVal == 0)
5148 return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
5149 DAG.getConstant(llvm::countr_one(K), dl, VT));
5150
5151 return SDValue();
5152}
5153
5154// Check if a condition of the type x < k ? k : x can be converted into a
5155// bit operation instead of conditional moves.
5156// Currently this is allowed given:
5157// - The conditions and values match up
5158// - k is 0 or -1 (all ones)
5159// This function will not check the last condition, thats up to the caller
5160// It returns true if the transformation can be made, and in such case
5161// returns x in V, and k in SatK.
5163 SDValue &SatK)
5164{
5165 SDValue LHS = Op.getOperand(0);
5166 SDValue RHS = Op.getOperand(1);
5167 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5168 SDValue TrueVal = Op.getOperand(2);
5169 SDValue FalseVal = Op.getOperand(3);
5170
5172 ? &RHS
5173 : nullptr;
5174
5175 // No constant operation in comparison, early out
5176 if (!K)
5177 return false;
5178
5179 SDValue KTmp = isa<ConstantSDNode>(TrueVal) ? TrueVal : FalseVal;
5180 V = (KTmp == TrueVal) ? FalseVal : TrueVal;
5181 SDValue VTmp = (K && *K == LHS) ? RHS : LHS;
5182
5183 // If the constant on left and right side, or variable on left and right,
5184 // does not match, early out
5185 if (*K != KTmp || V != VTmp)
5186 return false;
5187
5188 if (isLowerSaturate(LHS, RHS, TrueVal, FalseVal, CC, *K)) {
5189 SatK = *K;
5190 return true;
5191 }
5192
5193 return false;
5194}
5195
5196bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
5197 if (VT == MVT::f32)
5198 return !Subtarget->hasVFP2Base();
5199 if (VT == MVT::f64)
5200 return !Subtarget->hasFP64();
5201 if (VT == MVT::f16)
5202 return !Subtarget->hasFullFP16();
5203 return false;
5204}
5205
5206static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
5207 SDValue FalseVal, const ARMSubtarget *Subtarget) {
5208 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5209 ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
5210 if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
5211 return SDValue();
5212
5213 unsigned TVal = CTVal->getZExtValue();
5214 unsigned FVal = CFVal->getZExtValue();
5215
5216 Opcode = 0;
5217 InvertCond = false;
5218 if (TVal == ~FVal) {
5219 Opcode = ARMISD::CSINV;
5220 } else if (TVal == ~FVal + 1) {
5221 Opcode = ARMISD::CSNEG;
5222 } else if (TVal + 1 == FVal) {
5223 Opcode = ARMISD::CSINC;
5224 } else if (TVal == FVal + 1) {
5225 Opcode = ARMISD::CSINC;
5226 std::swap(TrueVal, FalseVal);
5227 std::swap(TVal, FVal);
5228 InvertCond = !InvertCond;
5229 } else {
5230 return SDValue();
5231 }
5232
5233 // If one of the constants is cheaper than another, materialise the
5234 // cheaper one and let the csel generate the other.
5235 if (Opcode != ARMISD::CSINC &&
5236 HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
5237 std::swap(TrueVal, FalseVal);
5238 std::swap(TVal, FVal);
5239 InvertCond = !InvertCond;
5240 }
5241
5242 // Attempt to use ZR checking TVal is 0, possibly inverting the condition
5243 // to get there. CSINC not is invertable like the other two (~(~a) == a,
5244 // -(-a) == a, but (a+1)+1 != a).
5245 if (FVal == 0 && Opcode != ARMISD::CSINC) {
5246 std::swap(TrueVal, FalseVal);
5247 std::swap(TVal, FVal);
5248 InvertCond = !InvertCond;
5249 }
5250
5251 return TrueVal;
5252}
5253
5254SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
5255 EVT VT = Op.getValueType();
5256 SDLoc dl(Op);
5257
5258 // Try to convert two saturating conditional selects into a single SSAT
5259 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
5260 if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
5261 return SatValue;
5262
5263 // Try to convert expressions of the form x < k ? k : x (and similar forms)
5264 // into more efficient bit operations, which is possible when k is 0 or -1
5265 // On ARM and Thumb-2 which have flexible operand 2 this will result in
5266 // single instructions. On Thumb the shift and the bit operation will be two
5267 // instructions.
5268 // Only allow this transformation on full-width (32-bit) operations
5269 SDValue LowerSatConstant;
5270 SDValue SatValue;
5271 if (VT == MVT::i32 &&
5272 isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
5273 SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
5274 DAG.getConstant(31, dl, VT));
5275 if (isNullConstant(LowerSatConstant)) {
5276 SDValue NotShiftV = DAG.getNode(ISD::XOR, dl, VT, ShiftV,
5277 DAG.getAllOnesConstant(dl, VT));
5278 return DAG.getNode(ISD::AND, dl, VT, SatValue, NotShiftV);
5279 } else if (isAllOnesConstant(LowerSatConstant))
5280 return DAG.getNode(ISD::OR, dl, VT, SatValue, ShiftV);
5281 }
5282
5283 SDValue LHS = Op.getOperand(0);
5284 SDValue RHS = Op.getOperand(1);
5285 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5286 SDValue TrueVal = Op.getOperand(2);
5287 SDValue FalseVal = Op.getOperand(3);
5288 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5289 ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
5290 if (Op.getValueType().isInteger()) {
5291
5292 // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
5293 // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
5294 // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
5295 // Both require less instructions than compare and conditional select.
5296 if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
5297 RHSC->isZero() && CFVal && CFVal->isZero() &&
5298 LHS.getValueType() == RHS.getValueType()) {
5299 EVT VT = LHS.getValueType();
5300 SDValue Shift =
5301 DAG.getNode(ISD::SRA, dl, VT, LHS,
5302 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5303
5304 if (CC == ISD::SETGT)
5305 Shift = DAG.getNOT(dl, Shift, VT);
5306
5307 return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
5308 }
5309
5310 // (SELECT_CC setlt, x, 0, 1, 0) -> SRL(x, bw-1)
5311 if (CC == ISD::SETLT && isNullConstant(RHS) && isOneConstant(TrueVal) &&
5312 isNullConstant(FalseVal) && LHS.getValueType() == VT)
5313 return DAG.getNode(ISD::SRL, dl, VT, LHS,
5314 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5315 }
5316
5317 if (LHS.getValueType() == MVT::i32) {
5318 unsigned Opcode;
5319 bool InvertCond;
5320 if (SDValue Op =
5321 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
5322 if (InvertCond)
5323 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5324
5325 SDValue ARMcc;
5326 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5327 EVT VT = Op.getValueType();
5328 return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
5329 }
5330 }
5331
5332 if (isUnsupportedFloatingType(LHS.getValueType())) {
5333 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5334
5335 // If softenSetCCOperands only returned one value, we should compare it to
5336 // zero.
5337 if (!RHS.getNode()) {
5338 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5339 CC = ISD::SETNE;
5340 }
5341 }
5342
5343 if (LHS.getValueType() == MVT::i32) {
5344 // Try to generate VSEL on ARMv8.
5345 // The VSEL instruction can't use all the usual ARM condition
5346 // codes: it only has two bits to select the condition code, so it's
5347 // constrained to use only GE, GT, VS and EQ.
5348 //
5349 // To implement all the various ISD::SETXXX opcodes, we sometimes need to
5350 // swap the operands of the previous compare instruction (effectively
5351 // inverting the compare condition, swapping 'less' and 'greater') and
5352 // sometimes need to swap the operands to the VSEL (which inverts the
5353 // condition in the sense of firing whenever the previous condition didn't)
5354 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
5355 TrueVal.getValueType() == MVT::f32 ||
5356 TrueVal.getValueType() == MVT::f64)) {
5358 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
5359 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
5360 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5361 std::swap(TrueVal, FalseVal);
5362 }
5363 }
5364
5365 SDValue ARMcc;
5366 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5367 // Choose GE over PL, which vsel does now support
5368 if (ARMcc->getAsZExtVal() == ARMCC::PL)
5369 ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
5370 return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5371 }
5372
5373 ARMCC::CondCodes CondCode, CondCode2;
5374 FPCCToARMCC(CC, CondCode, CondCode2);
5375
5376 // Normalize the fp compare. If RHS is zero we prefer to keep it there so we
5377 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
5378 // must use VSEL (limited condition codes), due to not having conditional f16
5379 // moves.
5380 if (Subtarget->hasFPARMv8Base() &&
5381 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
5382 (TrueVal.getValueType() == MVT::f16 ||
5383 TrueVal.getValueType() == MVT::f32 ||
5384 TrueVal.getValueType() == MVT::f64)) {
5385 bool swpCmpOps = false;
5386 bool swpVselOps = false;
5387 checkVSELConstraints(CC, CondCode, swpCmpOps, swpVselOps);
5388
5389 if (CondCode == ARMCC::GT || CondCode == ARMCC::GE ||
5390 CondCode == ARMCC::VS || CondCode == ARMCC::EQ) {
5391 if (swpCmpOps)
5392 std::swap(LHS, RHS);
5393 if (swpVselOps)
5394 std::swap(TrueVal, FalseVal);
5395 }
5396 }
5397
5398 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5399 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5400 SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5401 if (CondCode2 != ARMCC::AL) {
5402 SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
5403 Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
5404 }
5405 return Result;
5406}
5407
5408/// canChangeToInt - Given the fp compare operand, return true if it is suitable
5409/// to morph to an integer compare sequence.
5410static bool canChangeToInt(SDValue Op, bool &SeenZero,
5411 const ARMSubtarget *Subtarget) {
5412 SDNode *N = Op.getNode();
5413 if (!N->hasOneUse())
5414 // Otherwise it requires moving the value from fp to integer registers.
5415 return false;
5416 if (!N->getNumValues())
5417 return false;
5418 EVT VT = Op.getValueType();
5419 if (VT != MVT::f32 && !Subtarget->isFPBrccSlow())
5420 // f32 case is generally profitable. f64 case only makes sense when vcmpe +
5421 // vmrs are very slow, e.g. cortex-a8.
5422 return false;
5423
5424 if (isFloatingPointZero(Op)) {
5425 SeenZero = true;
5426 return true;
5427 }
5428 return ISD::isNormalLoad(N);
5429}
5430
5433 return DAG.getConstant(0, SDLoc(Op), MVT::i32);
5434
5436 return DAG.getLoad(MVT::i32, SDLoc(Op), Ld->getChain(), Ld->getBasePtr(),
5437 Ld->getPointerInfo(), Ld->getAlign(),
5438 Ld->getMemOperand()->getFlags());
5439
5440 llvm_unreachable("Unknown VFP cmp argument!");
5441}
5442
5444 SDValue &RetVal1, SDValue &RetVal2) {
5445 SDLoc dl(Op);
5446
5447 if (isFloatingPointZero(Op)) {
5448 RetVal1 = DAG.getConstant(0, dl, MVT::i32);
5449 RetVal2 = DAG.getConstant(0, dl, MVT::i32);
5450 return;
5451 }
5452
5453 if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Op)) {
5454 SDValue Ptr = Ld->getBasePtr();
5455 RetVal1 =
5456 DAG.getLoad(MVT::i32, dl, Ld->getChain(), Ptr, Ld->getPointerInfo(),
5457 Ld->getAlign(), Ld->getMemOperand()->getFlags());
5458
5459 EVT PtrType = Ptr.getValueType();
5460 SDValue NewPtr = DAG.getNode(ISD::ADD, dl,
5461 PtrType, Ptr, DAG.getConstant(4, dl, PtrType));
5462 RetVal2 = DAG.getLoad(MVT::i32, dl, Ld->getChain(), NewPtr,
5463 Ld->getPointerInfo().getWithOffset(4),
5464 commonAlignment(Ld->getAlign(), 4),
5465 Ld->getMemOperand()->getFlags());
5466 return;
5467 }
5468
5469 llvm_unreachable("Unknown VFP cmp argument!");
5470}
5471
5472/// OptimizeVFPBrcond - With nnan and without daz, it's legal to optimize some
5473/// f32 and even f64 comparisons to integer ones.
5474SDValue
5475ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
5476 SDValue Chain = Op.getOperand(0);
5477 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5478 SDValue LHS = Op.getOperand(2);
5479 SDValue RHS = Op.getOperand(3);
5480 SDValue Dest = Op.getOperand(4);
5481 SDLoc dl(Op);
5482
5483 bool LHSSeenZero = false;
5484 bool LHSOk = canChangeToInt(LHS, LHSSeenZero, Subtarget);
5485 bool RHSSeenZero = false;
5486 bool RHSOk = canChangeToInt(RHS, RHSSeenZero, Subtarget);
5487 if (LHSOk && RHSOk && (LHSSeenZero || RHSSeenZero)) {
5488 // If unsafe fp math optimization is enabled and there are no other uses of
5489 // the CMP operands, and the condition code is EQ or NE, we can optimize it
5490 // to an integer comparison.
5491 if (CC == ISD::SETOEQ)
5492 CC = ISD::SETEQ;
5493 else if (CC == ISD::SETUNE)
5494 CC = ISD::SETNE;
5495
5496 SDValue Mask = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5497 SDValue ARMcc;
5498 if (LHS.getValueType() == MVT::f32) {
5499 LHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5500 bitcastf32Toi32(LHS, DAG), Mask);
5501 RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5502 bitcastf32Toi32(RHS, DAG), Mask);
5503 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5504 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5505 Cmp);
5506 }
5507
5508 SDValue LHS1, LHS2;
5509 SDValue RHS1, RHS2;
5510 expandf64Toi32(LHS, DAG, LHS1, LHS2);
5511 expandf64Toi32(RHS, DAG, RHS1, RHS2);
5512 LHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, LHS2, Mask);
5513 RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
5515 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5516 SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
5517 return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
5518 }
5519
5520 return SDValue();
5521}
5522
5523// Generate CMP + CMOV for integer abs.
5524SDValue ARMTargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
5525 SDLoc DL(Op);
5526
5527 SDValue Neg = DAG.getNegative(Op.getOperand(0), DL, MVT::i32);
5528
5529 // Generate CMP & CMOV.
5530 SDValue Cmp = DAG.getNode(ARMISD::CMP, DL, FlagsVT, Op.getOperand(0),
5531 DAG.getConstant(0, DL, MVT::i32));
5532 return DAG.getNode(ARMISD::CMOV, DL, MVT::i32, Op.getOperand(0), Neg,
5533 DAG.getConstant(ARMCC::MI, DL, MVT::i32), Cmp);
5534}
5535
5537 ARMCC::CondCodes CondCode =
5538 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();
5539 CondCode = ARMCC::getOppositeCondition(CondCode);
5540 return DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5541}
5542
5543SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5544 SDValue Chain = Op.getOperand(0);
5545 SDValue Cond = Op.getOperand(1);
5546 SDValue Dest = Op.getOperand(2);
5547 SDLoc dl(Op);
5548
5549 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5550 // instruction.
5551 unsigned Opc = Cond.getOpcode();
5552 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5553 !Subtarget->isThumb1Only();
5554 if (Cond.getResNo() == 1 &&
5555 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5556 Opc == ISD::USUBO || OptimizeMul)) {
5557 // Only lower legal XALUO ops.
5558 if (!isTypeLegal(Cond->getValueType(0)))
5559 return SDValue();
5560
5561 // The actual operation with overflow check.
5562 SDValue Value, OverflowCmp;
5563 SDValue ARMcc;
5564 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5565
5566 // Reverse the condition code.
5567 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5568
5569 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5570 OverflowCmp);
5571 }
5572
5573 return SDValue();
5574}
5575
5576SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5577 SDValue Chain = Op.getOperand(0);
5578 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5579 SDValue LHS = Op.getOperand(2);
5580 SDValue RHS = Op.getOperand(3);
5581 SDValue Dest = Op.getOperand(4);
5582 SDLoc dl(Op);
5583
5584 if (isUnsupportedFloatingType(LHS.getValueType())) {
5585 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5586
5587 // If softenSetCCOperands only returned one value, we should compare it to
5588 // zero.
5589 if (!RHS.getNode()) {
5590 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5591 CC = ISD::SETNE;
5592 }
5593 }
5594
5595 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5596 // instruction.
5597 unsigned Opc = LHS.getOpcode();
5598 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5599 !Subtarget->isThumb1Only();
5600 if (LHS.getResNo() == 1 && (isOneConstant(RHS) || isNullConstant(RHS)) &&
5601 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5602 Opc == ISD::USUBO || OptimizeMul) &&
5603 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5604 // Only lower legal XALUO ops.
5605 if (!isTypeLegal(LHS->getValueType(0)))
5606 return SDValue();
5607
5608 // The actual operation with overflow check.
5609 SDValue Value, OverflowCmp;
5610 SDValue ARMcc;
5611 std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5612
5613 if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5614 // Reverse the condition code.
5615 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5616 }
5617
5618 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5619 OverflowCmp);
5620 }
5621
5622 if (LHS.getValueType() == MVT::i32) {
5623 SDValue ARMcc;
5624 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5625 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
5626 }
5627
5628 SDNodeFlags Flags = Op->getFlags();
5629 if (Flags.hasNoNaNs() &&
5630 DAG.getDenormalMode(MVT::f32) == DenormalMode::getIEEE() &&
5631 DAG.getDenormalMode(MVT::f64) == DenormalMode::getIEEE() &&
5632 (CC == ISD::SETEQ || CC == ISD::SETOEQ || CC == ISD::SETNE ||
5633 CC == ISD::SETUNE)) {
5634 if (SDValue Result = OptimizeVFPBrcond(Op, DAG))
5635 return Result;
5636 }
5637
5638 ARMCC::CondCodes CondCode, CondCode2;
5639 FPCCToARMCC(CC, CondCode, CondCode2);
5640
5641 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5642 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5643 SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
5644 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5645 if (CondCode2 != ARMCC::AL) {
5646 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
5647 SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
5648 Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5649 }
5650 return Res;
5651}
5652
5653SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
5654 SDValue Chain = Op.getOperand(0);
5655 SDValue Table = Op.getOperand(1);
5656 SDValue Index = Op.getOperand(2);
5657 SDLoc dl(Op);
5658
5659 EVT PTy = getPointerTy(DAG.getDataLayout());
5660 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
5661 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
5662 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
5663 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
5664 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
5665 if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
5666 // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
5667 // which does another jump to the destination. This also makes it easier
5668 // to translate it to TBB / TBH later (Thumb2 only).
5669 // FIXME: This might not work if the function is extremely large.
5670 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,
5671 Addr, Op.getOperand(2), JTI);
5672 }
5673 if (isPositionIndependent() || Subtarget->isROPI()) {
5674 Addr =
5675 DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
5677 Chain = Addr.getValue(1);
5678 Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
5679 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5680 } else {
5681 Addr =
5682 DAG.getLoad(PTy, dl, Chain, Addr,
5684 Chain = Addr.getValue(1);
5685 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5686 }
5687}
5688
5690 EVT VT = Op.getValueType();
5691 SDLoc dl(Op);
5692
5693 if (Op.getValueType().getVectorElementType() == MVT::i32) {
5694 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::f32)
5695 return Op;
5696 return DAG.UnrollVectorOp(Op.getNode());
5697 }
5698
5699 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5700
5701 EVT NewTy;
5702 const EVT OpTy = Op.getOperand(0).getValueType();
5703 if (OpTy == MVT::v4f32)
5704 NewTy = MVT::v4i32;
5705 else if (OpTy == MVT::v4f16 && HasFullFP16)
5706 NewTy = MVT::v4i16;
5707 else if (OpTy == MVT::v8f16 && HasFullFP16)
5708 NewTy = MVT::v8i16;
5709 else
5710 llvm_unreachable("Invalid type for custom lowering!");
5711
5712 if (VT != MVT::v4i16 && VT != MVT::v8i16)
5713 return DAG.UnrollVectorOp(Op.getNode());
5714
5715 Op = DAG.getNode(Op.getOpcode(), dl, NewTy, Op.getOperand(0));
5716 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
5717}
5718
5719SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
5720 EVT VT = Op.getValueType();
5721 if (VT.isVector())
5722 return LowerVectorFP_TO_INT(Op, DAG);
5723
5724 bool IsStrict = Op->isStrictFPOpcode();
5725 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5726
5727 if (isUnsupportedFloatingType(SrcVal.getValueType())) {
5728 RTLIB::Libcall LC;
5729 if (Op.getOpcode() == ISD::FP_TO_SINT ||
5730 Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
5731 LC = RTLIB::getFPTOSINT(SrcVal.getValueType(),
5732 Op.getValueType());
5733 else
5734 LC = RTLIB::getFPTOUINT(SrcVal.getValueType(),
5735 Op.getValueType());
5736 SDLoc Loc(Op);
5737 MakeLibCallOptions CallOptions;
5738 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5740 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5741 CallOptions, Loc, Chain);
5742 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5743 }
5744
5745 // FIXME: Remove this when we have strict fp instruction selection patterns
5746 if (IsStrict) {
5747 SDLoc Loc(Op);
5748 SDValue Result =
5751 Loc, Op.getValueType(), SrcVal);
5752 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
5753 }
5754
5755 return Op;
5756}
5757
5759 const ARMSubtarget *Subtarget) {
5760 EVT VT = Op.getValueType();
5761 EVT ToVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
5762 EVT FromVT = Op.getOperand(0).getValueType();
5763
5764 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f32)
5765 return Op;
5766 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f64 &&
5767 Subtarget->hasFP64())
5768 return Op;
5769 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f16 &&
5770 Subtarget->hasFullFP16())
5771 return Op;
5772 if (VT == MVT::v4i32 && ToVT == MVT::i32 && FromVT == MVT::v4f32 &&
5773 Subtarget->hasMVEFloatOps())
5774 return Op;
5775 if (VT == MVT::v8i16 && ToVT == MVT::i16 && FromVT == MVT::v8f16 &&
5776 Subtarget->hasMVEFloatOps())
5777 return Op;
5778
5779 if (FromVT != MVT::v4f32 && FromVT != MVT::v8f16)
5780 return SDValue();
5781
5782 SDLoc DL(Op);
5783 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
5784 unsigned BW = ToVT.getScalarSizeInBits() - IsSigned;
5785 SDValue CVT = DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
5786 DAG.getValueType(VT.getScalarType()));
5787 SDValue Max = DAG.getNode(IsSigned ? ISD::SMIN : ISD::UMIN, DL, VT, CVT,
5788 DAG.getConstant((1 << BW) - 1, DL, VT));
5789 if (IsSigned)
5790 Max = DAG.getNode(ISD::SMAX, DL, VT, Max,
5791 DAG.getSignedConstant(-(1 << BW), DL, VT));
5792 return Max;
5793}
5794
5796 EVT VT = Op.getValueType();
5797 SDLoc dl(Op);
5798
5799 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::i32) {
5800 if (VT.getVectorElementType() == MVT::f32)
5801 return Op;
5802 return DAG.UnrollVectorOp(Op.getNode());
5803 }
5804
5805 assert((Op.getOperand(0).getValueType() == MVT::v4i16 ||
5806 Op.getOperand(0).getValueType() == MVT::v8i16) &&
5807 "Invalid type for custom lowering!");
5808
5809 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5810
5811 EVT DestVecType;
5812 if (VT == MVT::v4f32)
5813 DestVecType = MVT::v4i32;
5814 else if (VT == MVT::v4f16 && HasFullFP16)
5815 DestVecType = MVT::v4i16;
5816 else if (VT == MVT::v8f16 && HasFullFP16)
5817 DestVecType = MVT::v8i16;
5818 else
5819 return DAG.UnrollVectorOp(Op.getNode());
5820
5821 unsigned CastOpc;
5822 unsigned Opc;
5823 switch (Op.getOpcode()) {
5824 default: llvm_unreachable("Invalid opcode!");
5825 case ISD::SINT_TO_FP:
5826 CastOpc = ISD::SIGN_EXTEND;
5828 break;
5829 case ISD::UINT_TO_FP:
5830 CastOpc = ISD::ZERO_EXTEND;
5832 break;
5833 }
5834
5835 Op = DAG.getNode(CastOpc, dl, DestVecType, Op.getOperand(0));
5836 return DAG.getNode(Opc, dl, VT, Op);
5837}
5838
5839SDValue ARMTargetLowering::LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const {
5840 EVT VT = Op.getValueType();
5841 if (VT.isVector())
5842 return LowerVectorINT_TO_FP(Op, DAG);
5843 if (isUnsupportedFloatingType(VT)) {
5844 RTLIB::Libcall LC;
5845 if (Op.getOpcode() == ISD::SINT_TO_FP)
5846 LC = RTLIB::getSINTTOFP(Op.getOperand(0).getValueType(),
5847 Op.getValueType());
5848 else
5849 LC = RTLIB::getUINTTOFP(Op.getOperand(0).getValueType(),
5850 Op.getValueType());
5851 MakeLibCallOptions CallOptions;
5852 return makeLibCall(DAG, LC, Op.getValueType(), Op.getOperand(0),
5853 CallOptions, SDLoc(Op)).first;
5854 }
5855
5856 return Op;
5857}
5858
5859SDValue ARMTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
5860 // Implement fcopysign with a fabs and a conditional fneg.
5861 SDValue Tmp0 = Op.getOperand(0);
5862 SDValue Tmp1 = Op.getOperand(1);
5863 SDLoc dl(Op);
5864 EVT VT = Op.getValueType();
5865 EVT SrcVT = Tmp1.getValueType();
5866 bool InGPR = Tmp0.getOpcode() == ISD::BITCAST ||
5867 Tmp0.getOpcode() == ARMISD::VMOVDRR;
5868 bool UseNEON = !InGPR && Subtarget->hasNEON();
5869
5870 if (UseNEON) {
5871 // Use VBSL to copy the sign bit.
5872 unsigned EncodedVal = ARM_AM::createVMOVModImm(0x6, 0x80);
5873 SDValue Mask = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v2i32,
5874 DAG.getTargetConstant(EncodedVal, dl, MVT::i32));
5875 EVT OpVT = (VT == MVT::f32) ? MVT::v2i32 : MVT::v1i64;
5876 if (VT == MVT::f64)
5877 Mask = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5878 DAG.getNode(ISD::BITCAST, dl, OpVT, Mask),
5879 DAG.getConstant(32, dl, MVT::i32));
5880 else /*if (VT == MVT::f32)*/
5881 Tmp0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp0);
5882 if (SrcVT == MVT::f32) {
5883 Tmp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp1);
5884 if (VT == MVT::f64)
5885 Tmp1 = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5886 DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1),
5887 DAG.getConstant(32, dl, MVT::i32));
5888 } else if (VT == MVT::f32)
5889 Tmp1 = DAG.getNode(ARMISD::VSHRuIMM, dl, MVT::v1i64,
5890 DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, Tmp1),
5891 DAG.getConstant(32, dl, MVT::i32));
5892 Tmp0 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp0);
5893 Tmp1 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1);
5894
5896 dl, MVT::i32);
5897 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v8i8, AllOnes);
5898 SDValue MaskNot = DAG.getNode(ISD::XOR, dl, OpVT, Mask,
5899 DAG.getNode(ISD::BITCAST, dl, OpVT, AllOnes));
5900
5901 SDValue Res = DAG.getNode(ISD::OR, dl, OpVT,
5902 DAG.getNode(ISD::AND, dl, OpVT, Tmp1, Mask),
5903 DAG.getNode(ISD::AND, dl, OpVT, Tmp0, MaskNot));
5904 if (VT == MVT::f32) {
5905 Res = DAG.getNode(ISD::BITCAST, dl, MVT::v2f32, Res);
5906 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
5907 DAG.getConstant(0, dl, MVT::i32));
5908 } else {
5909 Res = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Res);
5910 }
5911
5912 return Res;
5913 }
5914
5915 // Bitcast operand 1 to i32.
5916 if (SrcVT == MVT::f64)
5917 Tmp1 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5918 Tmp1).getValue(1);
5919 Tmp1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp1);
5920
5921 // Or in the signbit with integer operations.
5922 SDValue Mask1 = DAG.getConstant(0x80000000, dl, MVT::i32);
5923 SDValue Mask2 = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5924 Tmp1 = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp1, Mask1);
5925 if (VT == MVT::f32) {
5926 Tmp0 = DAG.getNode(ISD::AND, dl, MVT::i32,
5927 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp0), Mask2);
5928 return DAG.getNode(ISD::BITCAST, dl, MVT::f32,
5929 DAG.getNode(ISD::OR, dl, MVT::i32, Tmp0, Tmp1));
5930 }
5931
5932 // f64: Or the high part with signbit and then combine two parts.
5933 Tmp0 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5934 Tmp0);
5935 SDValue Lo = Tmp0.getValue(0);
5936 SDValue Hi = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp0.getValue(1), Mask2);
5937 Hi = DAG.getNode(ISD::OR, dl, MVT::i32, Hi, Tmp1);
5938 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
5939}
5940
5941SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
5942 MachineFunction &MF = DAG.getMachineFunction();
5943 MachineFrameInfo &MFI = MF.getFrameInfo();
5944 MFI.setReturnAddressIsTaken(true);
5945
5946 EVT VT = Op.getValueType();
5947 SDLoc dl(Op);
5948 unsigned Depth = Op.getConstantOperandVal(0);
5949 if (Depth) {
5950 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
5951 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
5952 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
5953 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
5954 MachinePointerInfo());
5955 }
5956
5957 // Return LR, which contains the return address. Mark it an implicit live-in.
5958 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
5959 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
5960}
5961
5962SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
5963 const ARMBaseRegisterInfo &ARI =
5964 *static_cast<const ARMBaseRegisterInfo*>(RegInfo);
5965 MachineFunction &MF = DAG.getMachineFunction();
5966 MachineFrameInfo &MFI = MF.getFrameInfo();
5967 MFI.setFrameAddressIsTaken(true);
5968
5969 EVT VT = Op.getValueType();
5970 SDLoc dl(Op); // FIXME probably not meaningful
5971 unsigned Depth = Op.getConstantOperandVal(0);
5972 Register FrameReg = ARI.getFrameRegister(MF);
5973 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
5974 while (Depth--)
5975 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
5976 MachinePointerInfo());
5977 return FrameAddr;
5978}
5979
5980// FIXME? Maybe this could be a TableGen attribute on some registers and
5981// this table could be generated automatically from RegInfo.
5982Register ARMTargetLowering::getRegisterByName(const char* RegName, LLT VT,
5983 const MachineFunction &MF) const {
5984 return StringSwitch<Register>(RegName)
5985 .Case("sp", ARM::SP)
5986 .Default(Register());
5987}
5988
5989// Result is 64 bit value so split into two 32 bit values and return as a
5990// pair of values.
5992 SelectionDAG &DAG) {
5993 SDLoc DL(N);
5994
5995 // This function is only supposed to be called for i64 type destination.
5996 assert(N->getValueType(0) == MVT::i64
5997 && "ExpandREAD_REGISTER called for non-i64 type result.");
5998
6000 DAG.getVTList(MVT::i32, MVT::i32, MVT::Other),
6001 N->getOperand(0),
6002 N->getOperand(1));
6003
6004 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0),
6005 Read.getValue(1)));
6006 Results.push_back(Read.getValue(2)); // Chain
6007}
6008
6009/// \p BC is a bitcast that is about to be turned into a VMOVDRR.
6010/// When \p DstVT, the destination type of \p BC, is on the vector
6011/// register bank and the source of bitcast, \p Op, operates on the same bank,
6012/// it might be possible to combine them, such that everything stays on the
6013/// vector register bank.
6014/// \p return The node that would replace \p BT, if the combine
6015/// is possible.
6017 SelectionDAG &DAG) {
6018 SDValue Op = BC->getOperand(0);
6019 EVT DstVT = BC->getValueType(0);
6020
6021 // The only vector instruction that can produce a scalar (remember,
6022 // since the bitcast was about to be turned into VMOVDRR, the source
6023 // type is i64) from a vector is EXTRACT_VECTOR_ELT.
6024 // Moreover, we can do this combine only if there is one use.
6025 // Finally, if the destination type is not a vector, there is not
6026 // much point on forcing everything on the vector bank.
6027 if (!DstVT.isVector() || Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
6028 !Op.hasOneUse())
6029 return SDValue();
6030
6031 // If the index is not constant, we will introduce an additional
6032 // multiply that will stick.
6033 // Give up in that case.
6034 ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Op.getOperand(1));
6035 if (!Index)
6036 return SDValue();
6037 unsigned DstNumElt = DstVT.getVectorNumElements();
6038
6039 // Compute the new index.
6040 const APInt &APIntIndex = Index->getAPIntValue();
6041 APInt NewIndex(APIntIndex.getBitWidth(), DstNumElt);
6042 NewIndex *= APIntIndex;
6043 // Check if the new constant index fits into i32.
6044 if (NewIndex.getBitWidth() > 32)
6045 return SDValue();
6046
6047 // vMTy bitcast(i64 extractelt vNi64 src, i32 index) ->
6048 // vMTy extractsubvector vNxMTy (bitcast vNi64 src), i32 index*M)
6049 SDLoc dl(Op);
6050 SDValue ExtractSrc = Op.getOperand(0);
6051 EVT VecVT = EVT::getVectorVT(
6052 *DAG.getContext(), DstVT.getScalarType(),
6053 ExtractSrc.getValueType().getVectorNumElements() * DstNumElt);
6054 SDValue BitCast = DAG.getNode(ISD::BITCAST, dl, VecVT, ExtractSrc);
6055 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, BitCast,
6056 DAG.getConstant(NewIndex.getZExtValue(), dl, MVT::i32));
6057}
6058
6059/// ExpandBITCAST - If the target supports VFP, this function is called to
6060/// expand a bit convert where either the source or destination type is i64 to
6061/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
6062/// operand type is illegal (e.g., v2f32 for a target that doesn't support
6063/// vectors), since the legalizer won't know what to do with that.
6064SDValue ARMTargetLowering::ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
6065 const ARMSubtarget *Subtarget) const {
6066 SDLoc dl(N);
6067 SDValue Op = N->getOperand(0);
6068
6069 // This function is only supposed to be called for i16 and i64 types, either
6070 // as the source or destination of the bit convert.
6071 EVT SrcVT = Op.getValueType();
6072 EVT DstVT = N->getValueType(0);
6073
6074 if ((SrcVT == MVT::i16 || SrcVT == MVT::i32) &&
6075 (DstVT == MVT::f16 || DstVT == MVT::bf16))
6076 return MoveToHPR(SDLoc(N), DAG, MVT::i32, DstVT.getSimpleVT(),
6077 DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i32, Op));
6078
6079 if ((DstVT == MVT::i16 || DstVT == MVT::i32) &&
6080 (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
6081 if (Subtarget->hasFullFP16() && !Subtarget->hasBF16())
6082 Op = DAG.getBitcast(MVT::f16, Op);
6083 return DAG.getNode(
6084 ISD::TRUNCATE, SDLoc(N), DstVT,
6085 MoveFromHPR(SDLoc(N), DAG, MVT::i32, SrcVT.getSimpleVT(), Op));
6086 }
6087
6088 if (!(SrcVT == MVT::i64 || DstVT == MVT::i64))
6089 return SDValue();
6090
6091 // Turn i64->f64 into VMOVDRR.
6092 if (SrcVT == MVT::i64 && isTypeLegal(DstVT)) {
6093 // Do not force values to GPRs (this is what VMOVDRR does for the inputs)
6094 // if we can combine the bitcast with its source.
6096 return Val;
6097 SDValue Lo, Hi;
6098 std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32);
6099 return DAG.getNode(ISD::BITCAST, dl, DstVT,
6100 DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi));
6101 }
6102
6103 // Turn f64->i64 into VMOVRRD.
6104 if (DstVT == MVT::i64 && isTypeLegal(SrcVT)) {
6105 SDValue Cvt;
6106 if (DAG.getDataLayout().isBigEndian() && SrcVT.isVector() &&
6107 SrcVT.getVectorNumElements() > 1)
6108 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6109 DAG.getVTList(MVT::i32, MVT::i32),
6110 DAG.getNode(ARMISD::VREV64, dl, SrcVT, Op));
6111 else
6112 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6113 DAG.getVTList(MVT::i32, MVT::i32), Op);
6114 // Merge the pieces into a single i64 value.
6115 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1));
6116 }
6117
6118 return SDValue();
6119}
6120
6121/// getZeroVector - Returns a vector of specified type with all zero elements.
6122/// Zero vectors are used to represent vector negation and in those cases
6123/// will be implemented with the NEON VNEG instruction. However, VNEG does
6124/// not support i64 elements, so sometimes the zero vectors will need to be
6125/// explicitly constructed. Regardless, use a canonical VMOV to create the
6126/// zero vector.
6127static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
6128 assert(VT.isVector() && "Expected a vector type");
6129 // The canonical modified immediate encoding of a zero vector is....0!
6130 SDValue EncodedVal = DAG.getTargetConstant(0, dl, MVT::i32);
6131 EVT VmovVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
6132 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, EncodedVal);
6133 return DAG.getNode(ISD::BITCAST, dl, VT, Vmov);
6134}
6135
6136/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
6137/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6138SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
6139 SelectionDAG &DAG) const {
6140 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6141 EVT VT = Op.getValueType();
6142 unsigned VTBits = VT.getSizeInBits();
6143 SDLoc dl(Op);
6144 SDValue ShOpLo = Op.getOperand(0);
6145 SDValue ShOpHi = Op.getOperand(1);
6146 SDValue ShAmt = Op.getOperand(2);
6147 SDValue ARMcc;
6148 unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
6149
6150 assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
6151
6152 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6153 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6154 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt);
6155 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6156 DAG.getConstant(VTBits, dl, MVT::i32));
6157 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt);
6158 SDValue LoSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6159 SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
6160 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6161 ISD::SETGE, ARMcc, DAG, dl);
6162 SDValue Lo =
6163 DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
6164
6165 SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
6166 SDValue HiBigShift = Opc == ISD::SRA
6167 ? DAG.getNode(Opc, dl, VT, ShOpHi,
6168 DAG.getConstant(VTBits - 1, dl, VT))
6169 : DAG.getConstant(0, dl, VT);
6170 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6171 ISD::SETGE, ARMcc, DAG, dl);
6172 SDValue Hi =
6173 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6174
6175 SDValue Ops[2] = { Lo, Hi };
6176 return DAG.getMergeValues(Ops, dl);
6177}
6178
6179/// LowerShiftLeftParts - Lower SHL_PARTS, which returns two
6180/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6181SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op,
6182 SelectionDAG &DAG) const {
6183 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6184 EVT VT = Op.getValueType();
6185 unsigned VTBits = VT.getSizeInBits();
6186 SDLoc dl(Op);
6187 SDValue ShOpLo = Op.getOperand(0);
6188 SDValue ShOpHi = Op.getOperand(1);
6189 SDValue ShAmt = Op.getOperand(2);
6190 SDValue ARMcc;
6191
6192 assert(Op.getOpcode() == ISD::SHL_PARTS);
6193 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6194 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6195 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
6196 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
6197 SDValue HiSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6198
6199 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6200 DAG.getConstant(VTBits, dl, MVT::i32));
6201 SDValue HiBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
6202 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6203 ISD::SETGE, ARMcc, DAG, dl);
6204 SDValue Hi =
6205 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6206
6207 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6208 ISD::SETGE, ARMcc, DAG, dl);
6209 SDValue LoSmallShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
6210 SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift,
6211 DAG.getConstant(0, dl, VT), ARMcc, CmpLo);
6212
6213 SDValue Ops[2] = { Lo, Hi };
6214 return DAG.getMergeValues(Ops, dl);
6215}
6216
6217SDValue ARMTargetLowering::LowerGET_ROUNDING(SDValue Op,
6218 SelectionDAG &DAG) const {
6219 // The rounding mode is in bits 23:22 of the FPSCR.
6220 // The ARM rounding mode value to FLT_ROUNDS mapping is 0->1, 1->2, 2->3, 3->0
6221 // The formula we use to implement this is (((FPSCR + 1 << 22) >> 22) & 3)
6222 // so that the shift + and get folded into a bitfield extract.
6223 SDLoc dl(Op);
6224 SDValue Chain = Op.getOperand(0);
6225 SDValue Ops[] = {Chain,
6226 DAG.getConstant(Intrinsic::arm_get_fpscr, dl, MVT::i32)};
6227
6228 SDValue FPSCR =
6229 DAG.getNode(ISD::INTRINSIC_W_CHAIN, dl, {MVT::i32, MVT::Other}, Ops);
6230 Chain = FPSCR.getValue(1);
6231 SDValue FltRounds = DAG.getNode(ISD::ADD, dl, MVT::i32, FPSCR,
6232 DAG.getConstant(1U << 22, dl, MVT::i32));
6233 SDValue RMODE = DAG.getNode(ISD::SRL, dl, MVT::i32, FltRounds,
6234 DAG.getConstant(22, dl, MVT::i32));
6235 SDValue And = DAG.getNode(ISD::AND, dl, MVT::i32, RMODE,
6236 DAG.getConstant(3, dl, MVT::i32));
6237 return DAG.getMergeValues({And, Chain}, dl);
6238}
6239
6240SDValue ARMTargetLowering::LowerSET_ROUNDING(SDValue Op,
6241 SelectionDAG &DAG) const {
6242 SDLoc DL(Op);
6243 SDValue Chain = Op->getOperand(0);
6244 SDValue RMValue = Op->getOperand(1);
6245
6246 // The rounding mode is in bits 23:22 of the FPSCR.
6247 // The llvm.set.rounding argument value to ARM rounding mode value mapping
6248 // is 0->3, 1->0, 2->1, 3->2. The formula we use to implement this is
6249 // ((arg - 1) & 3) << 22).
6250 //
6251 // It is expected that the argument of llvm.set.rounding is within the
6252 // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
6253 // responsibility of the code generated llvm.set.rounding to ensure this
6254 // condition.
6255
6256 // Calculate new value of FPSCR[23:22].
6257 RMValue = DAG.getNode(ISD::SUB, DL, MVT::i32, RMValue,
6258 DAG.getConstant(1, DL, MVT::i32));
6259 RMValue = DAG.getNode(ISD::AND, DL, MVT::i32, RMValue,
6260 DAG.getConstant(0x3, DL, MVT::i32));
6261 RMValue = DAG.getNode(ISD::SHL, DL, MVT::i32, RMValue,
6262 DAG.getConstant(ARM::RoundingBitsPos, DL, MVT::i32));
6263
6264 // Get current value of FPSCR.
6265 SDValue Ops[] = {Chain,
6266 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6267 SDValue FPSCR =
6268 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6269 Chain = FPSCR.getValue(1);
6270 FPSCR = FPSCR.getValue(0);
6271
6272 // Put new rounding mode into FPSCR[23:22].
6273 const unsigned RMMask = ~(ARM::Rounding::rmMask << ARM::RoundingBitsPos);
6274 FPSCR = DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6275 DAG.getConstant(RMMask, DL, MVT::i32));
6276 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCR, RMValue);
6277 SDValue Ops2[] = {
6278 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6279 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6280}
6281
6282SDValue ARMTargetLowering::LowerSET_FPMODE(SDValue Op,
6283 SelectionDAG &DAG) const {
6284 SDLoc DL(Op);
6285 SDValue Chain = Op->getOperand(0);
6286 SDValue Mode = Op->getOperand(1);
6287
6288 // Generate nodes to build:
6289 // FPSCR = (FPSCR & FPStatusBits) | (Mode & ~FPStatusBits)
6290 SDValue Ops[] = {Chain,
6291 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6292 SDValue FPSCR =
6293 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6294 Chain = FPSCR.getValue(1);
6295 FPSCR = FPSCR.getValue(0);
6296
6297 SDValue FPSCRMasked =
6298 DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6299 DAG.getConstant(ARM::FPStatusBits, DL, MVT::i32));
6300 SDValue InputMasked =
6301 DAG.getNode(ISD::AND, DL, MVT::i32, Mode,
6302 DAG.getConstant(~ARM::FPStatusBits, DL, MVT::i32));
6303 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCRMasked, InputMasked);
6304
6305 SDValue Ops2[] = {
6306 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6307 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6308}
6309
6310SDValue ARMTargetLowering::LowerRESET_FPMODE(SDValue Op,
6311 SelectionDAG &DAG) const {
6312 SDLoc DL(Op);
6313 SDValue Chain = Op->getOperand(0);
6314
6315 // To get the default FP mode all control bits are cleared:
6316 // FPSCR = FPSCR & (FPStatusBits | FPReservedBits)
6317 SDValue Ops[] = {Chain,
6318 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6319 SDValue FPSCR =
6320 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6321 Chain = FPSCR.getValue(1);
6322 FPSCR = FPSCR.getValue(0);
6323
6324 SDValue FPSCRMasked = DAG.getNode(
6325 ISD::AND, DL, MVT::i32, FPSCR,
6327 SDValue Ops2[] = {Chain,
6328 DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32),
6329 FPSCRMasked};
6330 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6331}
6332
6334 const ARMSubtarget *ST) {
6335 SDLoc dl(N);
6336 EVT VT = N->getValueType(0);
6337 if (VT.isVector() && ST->hasNEON()) {
6338
6339 // Compute the least significant set bit: LSB = X & -X
6340 SDValue X = N->getOperand(0);
6341 SDValue NX = DAG.getNode(ISD::SUB, dl, VT, getZeroVector(VT, DAG, dl), X);
6342 SDValue LSB = DAG.getNode(ISD::AND, dl, VT, X, NX);
6343
6344 EVT ElemTy = VT.getVectorElementType();
6345
6346 if (ElemTy == MVT::i8) {
6347 // Compute with: cttz(x) = ctpop(lsb - 1)
6348 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6349 DAG.getTargetConstant(1, dl, ElemTy));
6350 SDValue Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6351 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6352 }
6353
6354 if ((ElemTy == MVT::i16 || ElemTy == MVT::i32) &&
6355 (N->getOpcode() == ISD::CTTZ_ZERO_POISON)) {
6356 // Compute with: cttz(x) = (width - 1) - ctlz(lsb), if x != 0
6357 unsigned NumBits = ElemTy.getSizeInBits();
6358 SDValue WidthMinus1 =
6359 DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6360 DAG.getTargetConstant(NumBits - 1, dl, ElemTy));
6361 SDValue CTLZ = DAG.getNode(ISD::CTLZ, dl, VT, LSB);
6362 return DAG.getNode(ISD::SUB, dl, VT, WidthMinus1, CTLZ);
6363 }
6364
6365 // Compute with: cttz(x) = ctpop(lsb - 1)
6366
6367 // Compute LSB - 1.
6368 SDValue Bits;
6369 if (ElemTy == MVT::i64) {
6370 // Load constant 0xffff'ffff'ffff'ffff to register.
6371 SDValue FF = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6372 DAG.getTargetConstant(0x1eff, dl, MVT::i32));
6373 Bits = DAG.getNode(ISD::ADD, dl, VT, LSB, FF);
6374 } else {
6375 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6376 DAG.getTargetConstant(1, dl, ElemTy));
6377 Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6378 }
6379 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6380 }
6381
6382 if (!ST->hasV6T2Ops())
6383 return SDValue();
6384
6385 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, VT, N->getOperand(0));
6386 return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
6387}
6388
6390 const ARMSubtarget *ST) {
6391 EVT VT = N->getValueType(0);
6392 SDLoc DL(N);
6393
6394 assert(ST->hasNEON() && "Custom ctpop lowering requires NEON.");
6395 assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
6396 VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
6397 "Unexpected type for custom ctpop lowering");
6398
6399 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6400 EVT VT8Bit = VT.is64BitVector() ? MVT::v8i8 : MVT::v16i8;
6401 SDValue Res = DAG.getBitcast(VT8Bit, N->getOperand(0));
6402 Res = DAG.getNode(ISD::CTPOP, DL, VT8Bit, Res);
6403
6404 // Widen v8i8/v16i8 CTPOP result to VT by repeatedly widening pairwise adds.
6405 unsigned EltSize = 8;
6406 unsigned NumElts = VT.is64BitVector() ? 8 : 16;
6407 while (EltSize != VT.getScalarSizeInBits()) {
6409 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddlu, DL,
6410 TLI.getPointerTy(DAG.getDataLayout())));
6411 Ops.push_back(Res);
6412
6413 EltSize *= 2;
6414 NumElts /= 2;
6415 MVT WidenVT = MVT::getVectorVT(MVT::getIntegerVT(EltSize), NumElts);
6416 Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, WidenVT, Ops);
6417 }
6418
6419 return Res;
6420}
6421
6422/// Getvshiftimm - Check if this is a valid build_vector for the immediate
6423/// operand of a vector shift operation, where all the elements of the
6424/// build_vector must have the same constant integer value.
6425static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) {
6426 // Ignore bit_converts.
6427 while (Op.getOpcode() == ISD::BITCAST)
6428 Op = Op.getOperand(0);
6430 APInt SplatBits, SplatUndef;
6431 unsigned SplatBitSize;
6432 bool HasAnyUndefs;
6433 if (!BVN ||
6434 !BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6435 ElementBits) ||
6436 SplatBitSize > ElementBits)
6437 return false;
6438 Cnt = SplatBits.getSExtValue();
6439 return true;
6440}
6441
6442/// isVShiftLImm - Check if this is a valid build_vector for the immediate
6443/// operand of a vector shift left operation. That value must be in the range:
6444/// 0 <= Value < ElementBits for a left shift; or
6445/// 0 <= Value <= ElementBits for a long left shift.
6446static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) {
6447 assert(VT.isVector() && "vector shift count is not a vector type");
6448 int64_t ElementBits = VT.getScalarSizeInBits();
6449 if (!getVShiftImm(Op, ElementBits, Cnt))
6450 return false;
6451 return (Cnt >= 0 && (isLong ? Cnt - 1 : Cnt) < ElementBits);
6452}
6453
6454/// isVShiftRImm - Check if this is a valid build_vector for the immediate
6455/// operand of a vector shift right operation. For a shift opcode, the value
6456/// is positive, but for an intrinsic the value count must be negative. The
6457/// absolute value must be in the range:
6458/// 1 <= |Value| <= ElementBits for a right shift; or
6459/// 1 <= |Value| <= ElementBits/2 for a narrow right shift.
6460static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic,
6461 int64_t &Cnt) {
6462 assert(VT.isVector() && "vector shift count is not a vector type");
6463 int64_t ElementBits = VT.getScalarSizeInBits();
6464 if (!getVShiftImm(Op, ElementBits, Cnt))
6465 return false;
6466 if (!isIntrinsic)
6467 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits / 2 : ElementBits));
6468 if (Cnt >= -(isNarrow ? ElementBits / 2 : ElementBits) && Cnt <= -1) {
6469 Cnt = -Cnt;
6470 return true;
6471 }
6472 return false;
6473}
6474
6476 const ARMSubtarget *ST) {
6477 EVT VT = N->getValueType(0);
6478 SDLoc dl(N);
6479 int64_t Cnt;
6480
6481 if (!VT.isVector())
6482 return SDValue();
6483
6484 // We essentially have two forms here. Shift by an immediate and shift by a
6485 // vector register (there are also shift by a gpr, but that is just handled
6486 // with a tablegen pattern). We cannot easily match shift by an immediate in
6487 // tablegen so we do that here and generate a VSHLIMM/VSHRsIMM/VSHRuIMM.
6488 // For shifting by a vector, we don't have VSHR, only VSHL (which can be
6489 // signed or unsigned, and a negative shift indicates a shift right).
6490 if (N->getOpcode() == ISD::SHL) {
6491 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt))
6492 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
6493 DAG.getConstant(Cnt, dl, MVT::i32));
6494 return DAG.getNode(ARMISD::VSHLu, dl, VT, N->getOperand(0),
6495 N->getOperand(1));
6496 }
6497
6498 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
6499 "unexpected vector shift opcode");
6500
6501 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
6502 unsigned VShiftOpc =
6503 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
6504 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
6505 DAG.getConstant(Cnt, dl, MVT::i32));
6506 }
6507
6508 // Other right shifts we don't have operations for (we use a shift left by a
6509 // negative number).
6510 EVT ShiftVT = N->getOperand(1).getValueType();
6511 SDValue NegatedCount = DAG.getNode(
6512 ISD::SUB, dl, ShiftVT, getZeroVector(ShiftVT, DAG, dl), N->getOperand(1));
6513 unsigned VShiftOpc =
6514 (N->getOpcode() == ISD::SRA ? ARMISD::VSHLs : ARMISD::VSHLu);
6515 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0), NegatedCount);
6516}
6517
6519 const ARMSubtarget *ST) {
6520 EVT VT = N->getValueType(0);
6521 SDLoc dl(N);
6522
6523 // We can get here for a node like i32 = ISD::SHL i32, i64
6524 if (VT != MVT::i64)
6525 return SDValue();
6526
6527 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA ||
6528 N->getOpcode() == ISD::SHL) &&
6529 "Unknown shift to lower!");
6530
6531 unsigned ShOpc = N->getOpcode();
6532 if (ST->hasMVEIntegerOps()) {
6533 SDValue ShAmt = N->getOperand(1);
6534 unsigned ShPartsOpc = ARMISD::LSLL;
6536
6537 // If the shift amount is greater than 32 or has a greater bitwidth than 64
6538 // then do the default optimisation
6539 if ((!Con && ShAmt->getValueType(0).getSizeInBits() > 64) ||
6540 (Con && (Con->getAPIntValue() == 0 || Con->getAPIntValue().uge(32))))
6541 return SDValue();
6542
6543 // Extract the lower 32 bits of the shift amount if it's not an i32
6544 if (ShAmt->getValueType(0) != MVT::i32)
6545 ShAmt = DAG.getZExtOrTrunc(ShAmt, dl, MVT::i32);
6546
6547 if (ShOpc == ISD::SRL) {
6548 if (!Con)
6549 // There is no t2LSRLr instruction so negate and perform an lsll if the
6550 // shift amount is in a register, emulating a right shift.
6551 ShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6552 DAG.getConstant(0, dl, MVT::i32), ShAmt);
6553 else
6554 // Else generate an lsrl on the immediate shift amount
6555 ShPartsOpc = ARMISD::LSRL;
6556 } else if (ShOpc == ISD::SRA)
6557 ShPartsOpc = ARMISD::ASRL;
6558
6559 // Split Lower/Upper 32 bits of the destination/source
6560 SDValue Lo, Hi;
6561 std::tie(Lo, Hi) =
6562 DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6563 // Generate the shift operation as computed above
6564 Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi,
6565 ShAmt);
6566 // The upper 32 bits come from the second return value of lsll
6567 Hi = SDValue(Lo.getNode(), 1);
6568 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6569 }
6570
6571 // We only lower SRA, SRL of 1 here, all others use generic lowering.
6572 if (!isOneConstant(N->getOperand(1)) || N->getOpcode() == ISD::SHL)
6573 return SDValue();
6574
6575 // If we are in thumb mode, we don't have RRX.
6576 if (ST->isThumb1Only())
6577 return SDValue();
6578
6579 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr.
6580 SDValue Lo, Hi;
6581 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6582
6583 // First, build a LSRS1/ASRS1 op, which shifts the top part by one and
6584 // captures the shifted out bit into a carry flag.
6585 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::LSRS1 : ARMISD::ASRS1;
6586 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, FlagsVT), Hi);
6587
6588 // The low part is an ARMISD::RRX operand, which shifts the carry in.
6589 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1));
6590
6591 // Merge the pieces into a single i64 value.
6592 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6593}
6594
6596 const ARMSubtarget *ST) {
6597 bool Invert = false;
6598 bool Swap = false;
6599 unsigned Opc = ARMCC::AL;
6600
6601 SDValue Op0 = Op.getOperand(0);
6602 SDValue Op1 = Op.getOperand(1);
6603 SDValue CC = Op.getOperand(2);
6604 EVT VT = Op.getValueType();
6605 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
6606 SDLoc dl(Op);
6607
6608 EVT CmpVT;
6609 if (ST->hasNEON())
6611 else {
6612 assert(ST->hasMVEIntegerOps() &&
6613 "No hardware support for integer vector comparison!");
6614
6615 if (Op.getValueType().getVectorElementType() != MVT::i1)
6616 return SDValue();
6617
6618 // Make sure we expand floating point setcc to scalar if we do not have
6619 // mve.fp, so that we can handle them from there.
6620 if (Op0.getValueType().isFloatingPoint() && !ST->hasMVEFloatOps())
6621 return SDValue();
6622
6623 CmpVT = VT;
6624 }
6625
6626 if (Op0.getValueType().getVectorElementType() == MVT::i64 &&
6627 (SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE)) {
6628 // Special-case integer 64-bit equality comparisons. They aren't legal,
6629 // but they can be lowered with a few vector instructions.
6630 unsigned CmpElements = CmpVT.getVectorNumElements() * 2;
6631 EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, CmpElements);
6632 SDValue CastOp0 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op0);
6633 SDValue CastOp1 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op1);
6634 SDValue Cmp = DAG.getNode(ISD::SETCC, dl, SplitVT, CastOp0, CastOp1,
6635 DAG.getCondCode(ISD::SETEQ));
6636 SDValue Reversed = DAG.getNode(ARMISD::VREV64, dl, SplitVT, Cmp);
6637 SDValue Merged = DAG.getNode(ISD::AND, dl, SplitVT, Cmp, Reversed);
6638 Merged = DAG.getNode(ISD::BITCAST, dl, CmpVT, Merged);
6639 if (SetCCOpcode == ISD::SETNE)
6640 Merged = DAG.getNOT(dl, Merged, CmpVT);
6641 Merged = DAG.getSExtOrTrunc(Merged, dl, VT);
6642 return Merged;
6643 }
6644
6645 if (CmpVT.getVectorElementType() == MVT::i64)
6646 // 64-bit comparisons are not legal in general.
6647 return SDValue();
6648
6649 if (Op1.getValueType().isFloatingPoint()) {
6650 switch (SetCCOpcode) {
6651 default: llvm_unreachable("Illegal FP comparison");
6652 case ISD::SETUNE:
6653 case ISD::SETNE:
6654 if (ST->hasMVEFloatOps()) {
6655 Opc = ARMCC::NE; break;
6656 } else {
6657 Invert = true; [[fallthrough]];
6658 }
6659 case ISD::SETOEQ:
6660 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6661 case ISD::SETOLT:
6662 case ISD::SETLT: Swap = true; [[fallthrough]];
6663 case ISD::SETOGT:
6664 case ISD::SETGT: Opc = ARMCC::GT; break;
6665 case ISD::SETOLE:
6666 case ISD::SETLE: Swap = true; [[fallthrough]];
6667 case ISD::SETOGE:
6668 case ISD::SETGE: Opc = ARMCC::GE; break;
6669 case ISD::SETUGE: Swap = true; [[fallthrough]];
6670 case ISD::SETULE: Invert = true; Opc = ARMCC::GT; break;
6671 case ISD::SETUGT: Swap = true; [[fallthrough]];
6672 case ISD::SETULT: Invert = true; Opc = ARMCC::GE; break;
6673 case ISD::SETUEQ: Invert = true; [[fallthrough]];
6674 case ISD::SETONE: {
6675 // Expand this to (OLT | OGT).
6676 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6677 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6678 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6679 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6680 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6681 if (Invert)
6682 Result = DAG.getNOT(dl, Result, VT);
6683 return Result;
6684 }
6685 case ISD::SETUO: Invert = true; [[fallthrough]];
6686 case ISD::SETO: {
6687 // Expand this to (OLT | OGE).
6688 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6689 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6690 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6691 DAG.getConstant(ARMCC::GE, dl, MVT::i32));
6692 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6693 if (Invert)
6694 Result = DAG.getNOT(dl, Result, VT);
6695 return Result;
6696 }
6697 }
6698 } else {
6699 // Integer comparisons.
6700 switch (SetCCOpcode) {
6701 default: llvm_unreachable("Illegal integer comparison");
6702 case ISD::SETNE:
6703 if (ST->hasMVEIntegerOps()) {
6704 Opc = ARMCC::NE; break;
6705 } else {
6706 Invert = true; [[fallthrough]];
6707 }
6708 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6709 case ISD::SETLT: Swap = true; [[fallthrough]];
6710 case ISD::SETGT: Opc = ARMCC::GT; break;
6711 case ISD::SETLE: Swap = true; [[fallthrough]];
6712 case ISD::SETGE: Opc = ARMCC::GE; break;
6713 case ISD::SETULT: Swap = true; [[fallthrough]];
6714 case ISD::SETUGT: Opc = ARMCC::HI; break;
6715 case ISD::SETULE: Swap = true; [[fallthrough]];
6716 case ISD::SETUGE: Opc = ARMCC::HS; break;
6717 }
6718
6719 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero).
6720 if (ST->hasNEON() && Opc == ARMCC::EQ) {
6721 SDValue AndOp;
6723 AndOp = Op0;
6724 else if (ISD::isBuildVectorAllZeros(Op0.getNode()))
6725 AndOp = Op1;
6726
6727 // Ignore bitconvert.
6728 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BITCAST)
6729 AndOp = AndOp.getOperand(0);
6730
6731 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
6732 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
6733 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
6734 SDValue Result = DAG.getNode(ARMISD::VTST, dl, CmpVT, Op0, Op1);
6735 if (!Invert)
6736 Result = DAG.getNOT(dl, Result, VT);
6737 return Result;
6738 }
6739 }
6740 }
6741
6742 if (Swap)
6743 std::swap(Op0, Op1);
6744
6745 // If one of the operands is a constant vector zero, attempt to fold the
6746 // comparison to a specialized compare-against-zero form.
6748 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::EQ ||
6749 Opc == ARMCC::NE)) {
6750 if (Opc == ARMCC::GE)
6751 Opc = ARMCC::LE;
6752 else if (Opc == ARMCC::GT)
6753 Opc = ARMCC::LT;
6754 std::swap(Op0, Op1);
6755 }
6756
6757 SDValue Result;
6759 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::LE ||
6760 Opc == ARMCC::LT || Opc == ARMCC::NE || Opc == ARMCC::EQ))
6761 Result = DAG.getNode(ARMISD::VCMPZ, dl, CmpVT, Op0,
6762 DAG.getConstant(Opc, dl, MVT::i32));
6763 else
6764 Result = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6765 DAG.getConstant(Opc, dl, MVT::i32));
6766
6767 Result = DAG.getSExtOrTrunc(Result, dl, VT);
6768
6769 if (Invert)
6770 Result = DAG.getNOT(dl, Result, VT);
6771
6772 return Result;
6773}
6774
6776 SDValue LHS = Op.getOperand(0);
6777 SDValue RHS = Op.getOperand(1);
6778
6779 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
6780
6781 SDValue Carry = Op.getOperand(2);
6782 SDValue Cond = Op.getOperand(3);
6783 SDLoc DL(Op);
6784
6785 // ARMISD::SUBE expects a carry not a borrow like ISD::USUBO_CARRY so we
6786 // have to invert the carry first.
6787 SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
6788
6789 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
6790 SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, InvCarry);
6791
6792 SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
6793 SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
6794 SDValue ARMcc = DAG.getConstant(
6795 IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
6796 return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
6797 Cmp.getValue(1));
6798}
6799
6800/// isVMOVModifiedImm - Check if the specified splat value corresponds to a
6801/// valid vector constant for a NEON or MVE instruction with a "modified
6802/// immediate" operand (e.g., VMOV). If so, return the encoded value.
6803static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
6804 unsigned SplatBitSize, SelectionDAG &DAG,
6805 const SDLoc &dl, EVT &VT, EVT VectorVT,
6806 VMOVModImmType type) {
6807 unsigned OpCmode, Imm;
6808 bool is128Bits = VectorVT.is128BitVector();
6809
6810 // SplatBitSize is set to the smallest size that splats the vector, so a
6811 // zero vector will always have SplatBitSize == 8. However, NEON modified
6812 // immediate instructions others than VMOV do not support the 8-bit encoding
6813 // of a zero vector, and the default encoding of zero is supposed to be the
6814 // 32-bit version.
6815 if (SplatBits == 0)
6816 SplatBitSize = 32;
6817
6818 switch (SplatBitSize) {
6819 case 8:
6820 if (type != VMOVModImm)
6821 return SDValue();
6822 // Any 1-byte value is OK. Op=0, Cmode=1110.
6823 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
6824 OpCmode = 0xe;
6825 Imm = SplatBits;
6826 VT = is128Bits ? MVT::v16i8 : MVT::v8i8;
6827 break;
6828
6829 case 16:
6830 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero.
6831 VT = is128Bits ? MVT::v8i16 : MVT::v4i16;
6832 if ((SplatBits & ~0xff) == 0) {
6833 // Value = 0x00nn: Op=x, Cmode=100x.
6834 OpCmode = 0x8;
6835 Imm = SplatBits;
6836 break;
6837 }
6838 if ((SplatBits & ~0xff00) == 0) {
6839 // Value = 0xnn00: Op=x, Cmode=101x.
6840 OpCmode = 0xa;
6841 Imm = SplatBits >> 8;
6842 break;
6843 }
6844 return SDValue();
6845
6846 case 32:
6847 // NEON's 32-bit VMOV supports splat values where:
6848 // * only one byte is nonzero, or
6849 // * the least significant byte is 0xff and the second byte is nonzero, or
6850 // * the least significant 2 bytes are 0xff and the third is nonzero.
6851 VT = is128Bits ? MVT::v4i32 : MVT::v2i32;
6852 if ((SplatBits & ~0xff) == 0) {
6853 // Value = 0x000000nn: Op=x, Cmode=000x.
6854 OpCmode = 0;
6855 Imm = SplatBits;
6856 break;
6857 }
6858 if ((SplatBits & ~0xff00) == 0) {
6859 // Value = 0x0000nn00: Op=x, Cmode=001x.
6860 OpCmode = 0x2;
6861 Imm = SplatBits >> 8;
6862 break;
6863 }
6864 if ((SplatBits & ~0xff0000) == 0) {
6865 // Value = 0x00nn0000: Op=x, Cmode=010x.
6866 OpCmode = 0x4;
6867 Imm = SplatBits >> 16;
6868 break;
6869 }
6870 if ((SplatBits & ~0xff000000) == 0) {
6871 // Value = 0xnn000000: Op=x, Cmode=011x.
6872 OpCmode = 0x6;
6873 Imm = SplatBits >> 24;
6874 break;
6875 }
6876
6877 // cmode == 0b1100 and cmode == 0b1101 are not supported for VORR or VBIC
6878 if (type == OtherModImm) return SDValue();
6879
6880 if ((SplatBits & ~0xffff) == 0 &&
6881 ((SplatBits | SplatUndef) & 0xff) == 0xff) {
6882 // Value = 0x0000nnff: Op=x, Cmode=1100.
6883 OpCmode = 0xc;
6884 Imm = SplatBits >> 8;
6885 break;
6886 }
6887
6888 // cmode == 0b1101 is not supported for MVE VMVN
6889 if (type == MVEVMVNModImm)
6890 return SDValue();
6891
6892 if ((SplatBits & ~0xffffff) == 0 &&
6893 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
6894 // Value = 0x00nnffff: Op=x, Cmode=1101.
6895 OpCmode = 0xd;
6896 Imm = SplatBits >> 16;
6897 break;
6898 }
6899
6900 // Note: there are a few 32-bit splat values (specifically: 00ffff00,
6901 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not
6902 // VMOV.I32. A (very) minor optimization would be to replicate the value
6903 // and fall through here to test for a valid 64-bit splat. But, then the
6904 // caller would also need to check and handle the change in size.
6905 return SDValue();
6906
6907 case 64: {
6908 if (type != VMOVModImm)
6909 return SDValue();
6910 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
6911 uint64_t BitMask = 0xff;
6912 unsigned ImmMask = 1;
6913 Imm = 0;
6914 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) {
6915 if (((SplatBits | SplatUndef) & BitMask) == BitMask) {
6916 Imm |= ImmMask;
6917 } else if ((SplatBits & BitMask) != 0) {
6918 return SDValue();
6919 }
6920 BitMask <<= 8;
6921 ImmMask <<= 1;
6922 }
6923
6924 // Op=1, Cmode=1110.
6925 OpCmode = 0x1e;
6926 VT = is128Bits ? MVT::v2i64 : MVT::v1i64;
6927 break;
6928 }
6929
6930 default:
6931 llvm_unreachable("unexpected size for isVMOVModifiedImm");
6932 }
6933
6934 unsigned EncodedVal = ARM_AM::createVMOVModImm(OpCmode, Imm);
6935 return DAG.getTargetConstant(EncodedVal, dl, MVT::i32);
6936}
6937
6938SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
6939 const ARMSubtarget *ST) const {
6940 EVT VT = Op.getValueType();
6941 bool IsDouble = (VT == MVT::f64);
6942 ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
6943 const APFloat &FPVal = CFP->getValueAPF();
6944
6945 // Prevent floating-point constants from using literal loads
6946 // when execute-only is enabled.
6947 if (ST->genExecuteOnly()) {
6948 // We shouldn't trigger this for v6m execute-only
6949 assert((!ST->isThumb1Only() || ST->hasV8MBaselineOps()) &&
6950 "Unexpected architecture");
6951
6952 // If we can represent the constant as an immediate, don't lower it
6953 if (isFPImmLegal(FPVal, VT))
6954 return Op;
6955 // Otherwise, construct as integer, and move to float register
6956 APInt INTVal = FPVal.bitcastToAPInt();
6957 SDLoc DL(CFP);
6958 switch (VT.getSimpleVT().SimpleTy) {
6959 default:
6960 llvm_unreachable("Unknown floating point type!");
6961 break;
6962 case MVT::f64: {
6963 SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);
6964 SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);
6965 return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);
6966 }
6967 case MVT::f32:
6968 return DAG.getNode(ARMISD::VMOVSR, DL, VT,
6969 DAG.getConstant(INTVal, DL, MVT::i32));
6970 }
6971 }
6972
6973 if (!ST->hasVFP3Base())
6974 return SDValue();
6975
6976 // Use the default (constant pool) lowering for double constants when we have
6977 // an SP-only FPU
6978 if (IsDouble && !Subtarget->hasFP64())
6979 return SDValue();
6980
6981 // Try splatting with a VMOV.f32...
6982 int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);
6983
6984 if (ImmVal != -1) {
6985 if (IsDouble || !ST->useNEONForSinglePrecisionFP()) {
6986 // We have code in place to select a valid ConstantFP already, no need to
6987 // do any mangling.
6988 return Op;
6989 }
6990
6991 // It's a float and we are trying to use NEON operations where
6992 // possible. Lower it to a splat followed by an extract.
6993 SDLoc DL(Op);
6994 SDValue NewVal = DAG.getTargetConstant(ImmVal, DL, MVT::i32);
6995 SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
6996 NewVal);
6997 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
6998 DAG.getConstant(0, DL, MVT::i32));
6999 }
7000
7001 // The rest of our options are NEON only, make sure that's allowed before
7002 // proceeding..
7003 if (!ST->hasNEON() || (!IsDouble && !ST->useNEONForSinglePrecisionFP()))
7004 return SDValue();
7005
7006 EVT VMovVT;
7007 uint64_t iVal = FPVal.bitcastToAPInt().getZExtValue();
7008
7009 // It wouldn't really be worth bothering for doubles except for one very
7010 // important value, which does happen to match: 0.0. So make sure we don't do
7011 // anything stupid.
7012 if (IsDouble && (iVal & 0xffffffff) != (iVal >> 32))
7013 return SDValue();
7014
7015 // Try a VMOV.i32 (FIXME: i8, i16, or i64 could work too).
7016 SDValue NewVal = isVMOVModifiedImm(iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op),
7017 VMovVT, VT, VMOVModImm);
7018 if (NewVal != SDValue()) {
7019 SDLoc DL(Op);
7020 SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
7021 NewVal);
7022 if (IsDouble)
7023 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7024
7025 // It's a float: cast and extract a vector element.
7026 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7027 VecConstant);
7028 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7029 DAG.getConstant(0, DL, MVT::i32));
7030 }
7031
7032 // Finally, try a VMVN.i32
7033 NewVal = isVMOVModifiedImm(~iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op), VMovVT,
7034 VT, VMVNModImm);
7035 if (NewVal != SDValue()) {
7036 SDLoc DL(Op);
7037 SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
7038
7039 if (IsDouble)
7040 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7041
7042 // It's a float: cast and extract a vector element.
7043 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7044 VecConstant);
7045 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7046 DAG.getConstant(0, DL, MVT::i32));
7047 }
7048
7049 return SDValue();
7050}
7051
7052// check if an VEXT instruction can handle the shuffle mask when the
7053// vector sources of the shuffle are the same.
7054static bool isSingletonVEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
7055 unsigned NumElts = VT.getVectorNumElements();
7056
7057 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7058 if (M[0] < 0)
7059 return false;
7060
7061 Imm = M[0];
7062
7063 // If this is a VEXT shuffle, the immediate value is the index of the first
7064 // element. The other shuffle indices must be the successive elements after
7065 // the first one.
7066 unsigned ExpectedElt = Imm;
7067 for (unsigned i = 1; i < NumElts; ++i) {
7068 // Increment the expected index. If it wraps around, just follow it
7069 // back to index zero and keep going.
7070 ++ExpectedElt;
7071 if (ExpectedElt == NumElts)
7072 ExpectedElt = 0;
7073
7074 if (M[i] < 0) continue; // ignore UNDEF indices
7075 if (ExpectedElt != static_cast<unsigned>(M[i]))
7076 return false;
7077 }
7078
7079 return true;
7080}
7081
7082static bool isVEXTMask(ArrayRef<int> M, EVT VT,
7083 bool &ReverseVEXT, unsigned &Imm) {
7084 unsigned NumElts = VT.getVectorNumElements();
7085 ReverseVEXT = false;
7086
7087 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7088 if (M[0] < 0)
7089 return false;
7090
7091 Imm = M[0];
7092
7093 // If this is a VEXT shuffle, the immediate value is the index of the first
7094 // element. The other shuffle indices must be the successive elements after
7095 // the first one.
7096 unsigned ExpectedElt = Imm;
7097 for (unsigned i = 1; i < NumElts; ++i) {
7098 // Increment the expected index. If it wraps around, it may still be
7099 // a VEXT but the source vectors must be swapped.
7100 ExpectedElt += 1;
7101 if (ExpectedElt == NumElts * 2) {
7102 ExpectedElt = 0;
7103 ReverseVEXT = true;
7104 }
7105
7106 if (M[i] < 0) continue; // ignore UNDEF indices
7107 if (ExpectedElt != static_cast<unsigned>(M[i]))
7108 return false;
7109 }
7110
7111 // Adjust the index value if the source operands will be swapped.
7112 if (ReverseVEXT)
7113 Imm -= NumElts;
7114
7115 return true;
7116}
7117
7118static bool isVTBLMask(ArrayRef<int> M, EVT VT) {
7119 // We can handle <8 x i8> vector shuffles. If the index in the mask is out of
7120 // range, then 0 is placed into the resulting vector. So pretty much any mask
7121 // of 8 elements can work here.
7122 return VT == MVT::v8i8 && M.size() == 8;
7123}
7124
7125static unsigned SelectPairHalf(unsigned Elements, ArrayRef<int> Mask,
7126 unsigned Index) {
7127 if (Mask.size() == Elements * 2)
7128 return Index / Elements;
7129 return Mask[Index] == 0 ? 0 : 1;
7130}
7131
7132// Checks whether the shuffle mask represents a vector transpose (VTRN) by
7133// checking that pairs of elements in the shuffle mask represent the same index
7134// in each vector, incrementing the expected index by 2 at each step.
7135// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 2, 6]
7136// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,c,g}
7137// v2={e,f,g,h}
7138// WhichResult gives the offset for each element in the mask based on which
7139// of the two results it belongs to.
7140//
7141// The transpose can be represented either as:
7142// result1 = shufflevector v1, v2, result1_shuffle_mask
7143// result2 = shufflevector v1, v2, result2_shuffle_mask
7144// where v1/v2 and the shuffle masks have the same number of elements
7145// (here WhichResult (see below) indicates which result is being checked)
7146//
7147// or as:
7148// results = shufflevector v1, v2, shuffle_mask
7149// where both results are returned in one vector and the shuffle mask has twice
7150// as many elements as v1/v2 (here WhichResult will always be 0 if true) here we
7151// want to check the low half and high half of the shuffle mask as if it were
7152// the other case
7153static bool isVTRNMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7154 unsigned EltSz = VT.getScalarSizeInBits();
7155 if (EltSz == 64)
7156 return false;
7157
7158 unsigned NumElts = VT.getVectorNumElements();
7159 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7160 return false;
7161
7162 // If the mask is twice as long as the input vector then we need to check the
7163 // upper and lower parts of the mask with a matching value for WhichResult
7164 // FIXME: A mask with only even values will be rejected in case the first
7165 // element is undefined, e.g. [-1, 4, 2, 6] will be rejected, because only
7166 // M[0] is used to determine WhichResult
7167 for (unsigned i = 0; i < M.size(); i += NumElts) {
7168 WhichResult = SelectPairHalf(NumElts, M, i);
7169 for (unsigned j = 0; j < NumElts; j += 2) {
7170 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7171 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + NumElts + WhichResult))
7172 return false;
7173 }
7174 }
7175
7176 if (M.size() == NumElts*2)
7177 WhichResult = 0;
7178
7179 return true;
7180}
7181
7182/// isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of
7183/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7184/// Mask is e.g., <0, 0, 2, 2> instead of <0, 4, 2, 6>.
7185static bool isVTRN_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7186 unsigned EltSz = VT.getScalarSizeInBits();
7187 if (EltSz == 64)
7188 return false;
7189
7190 unsigned NumElts = VT.getVectorNumElements();
7191 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7192 return false;
7193
7194 for (unsigned i = 0; i < M.size(); i += NumElts) {
7195 WhichResult = SelectPairHalf(NumElts, M, i);
7196 for (unsigned j = 0; j < NumElts; j += 2) {
7197 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7198 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + WhichResult))
7199 return false;
7200 }
7201 }
7202
7203 if (M.size() == NumElts*2)
7204 WhichResult = 0;
7205
7206 return true;
7207}
7208
7209// Checks whether the shuffle mask represents a vector unzip (VUZP) by checking
7210// that the mask elements are either all even and in steps of size 2 or all odd
7211// and in steps of size 2.
7212// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 2, 4, 6]
7213// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,c,e,g}
7214// v2={e,f,g,h}
7215// Requires similar checks to that of isVTRNMask with
7216// respect the how results are returned.
7217static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7218 unsigned EltSz = VT.getScalarSizeInBits();
7219 if (EltSz == 64)
7220 return false;
7221
7222 unsigned NumElts = VT.getVectorNumElements();
7223 if (M.size() != NumElts && M.size() != NumElts*2)
7224 return false;
7225
7226 for (unsigned i = 0; i < M.size(); i += NumElts) {
7227 WhichResult = SelectPairHalf(NumElts, M, i);
7228 for (unsigned j = 0; j < NumElts; ++j) {
7229 if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
7230 return false;
7231 }
7232 }
7233
7234 if (M.size() == NumElts*2)
7235 WhichResult = 0;
7236
7237 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7238 if (VT.is64BitVector() && EltSz == 32)
7239 return false;
7240
7241 return true;
7242}
7243
7244/// isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of
7245/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7246/// Mask is e.g., <0, 2, 0, 2> instead of <0, 2, 4, 6>,
7247static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7248 unsigned EltSz = VT.getScalarSizeInBits();
7249 if (EltSz == 64)
7250 return false;
7251
7252 unsigned NumElts = VT.getVectorNumElements();
7253 if (M.size() != NumElts && M.size() != NumElts*2)
7254 return false;
7255
7256 unsigned Half = NumElts / 2;
7257 for (unsigned i = 0; i < M.size(); i += NumElts) {
7258 WhichResult = SelectPairHalf(NumElts, M, i);
7259 for (unsigned j = 0; j < NumElts; j += Half) {
7260 unsigned Idx = WhichResult;
7261 for (unsigned k = 0; k < Half; ++k) {
7262 int MIdx = M[i + j + k];
7263 if (MIdx >= 0 && (unsigned) MIdx != Idx)
7264 return false;
7265 Idx += 2;
7266 }
7267 }
7268 }
7269
7270 if (M.size() == NumElts*2)
7271 WhichResult = 0;
7272
7273 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7274 if (VT.is64BitVector() && EltSz == 32)
7275 return false;
7276
7277 return true;
7278}
7279
7280// Checks whether the shuffle mask represents a vector zip (VZIP) by checking
7281// that pairs of elements of the shufflemask represent the same index in each
7282// vector incrementing sequentially through the vectors.
7283// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 1, 5]
7284// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,b,f}
7285// v2={e,f,g,h}
7286// Requires similar checks to that of isVTRNMask with respect the how results
7287// are returned.
7288static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7289 unsigned EltSz = VT.getScalarSizeInBits();
7290 if (EltSz == 64)
7291 return false;
7292
7293 unsigned NumElts = VT.getVectorNumElements();
7294 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7295 return false;
7296
7297 for (unsigned i = 0; i < M.size(); i += NumElts) {
7298 WhichResult = SelectPairHalf(NumElts, M, i);
7299 unsigned Idx = WhichResult * NumElts / 2;
7300 for (unsigned j = 0; j < NumElts; j += 2) {
7301 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7302 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx + NumElts))
7303 return false;
7304 Idx += 1;
7305 }
7306 }
7307
7308 if (M.size() == NumElts*2)
7309 WhichResult = 0;
7310
7311 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7312 if (VT.is64BitVector() && EltSz == 32)
7313 return false;
7314
7315 return true;
7316}
7317
7318/// isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of
7319/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7320/// Mask is e.g., <0, 0, 1, 1> instead of <0, 4, 1, 5>.
7321static bool isVZIP_v_undef_Mask(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))
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/// Check if \p ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN),
7352/// and return the corresponding ARMISD opcode if it is, or 0 if it isn't.
7353static unsigned isNEONTwoResultShuffleMask(ArrayRef<int> ShuffleMask, EVT VT,
7354 unsigned &WhichResult,
7355 bool &isV_UNDEF) {
7356 isV_UNDEF = false;
7357 if (isVTRNMask(ShuffleMask, VT, WhichResult))
7358 return ARMISD::VTRN;
7359 if (isVUZPMask(ShuffleMask, VT, WhichResult))
7360 return ARMISD::VUZP;
7361 if (isVZIPMask(ShuffleMask, VT, WhichResult))
7362 return ARMISD::VZIP;
7363
7364 isV_UNDEF = true;
7365 if (isVTRN_v_undef_Mask(ShuffleMask, VT, WhichResult))
7366 return ARMISD::VTRN;
7367 if (isVUZP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7368 return ARMISD::VUZP;
7369 if (isVZIP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7370 return ARMISD::VZIP;
7371
7372 return 0;
7373}
7374
7375/// \return true if this is a reverse operation on an vector.
7376static bool isReverseMask(ArrayRef<int> M, EVT VT) {
7377 unsigned NumElts = VT.getVectorNumElements();
7378 // Make sure the mask has the right size.
7379 if (NumElts != M.size())
7380 return false;
7381
7382 // Look for <15, ..., 3, -1, 1, 0>.
7383 for (unsigned i = 0; i != NumElts; ++i)
7384 if (M[i] >= 0 && M[i] != (int) (NumElts - 1 - i))
7385 return false;
7386
7387 return true;
7388}
7389
7390static bool isTruncMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7391 unsigned NumElts = VT.getVectorNumElements();
7392 // Make sure the mask has the right size.
7393 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7394 return false;
7395
7396 // Half-width truncation patterns (e.g. v4i32 -> v8i16):
7397 // !Top && SingleSource: <0, 2, 4, 6, 0, 2, 4, 6>
7398 // !Top && !SingleSource: <0, 2, 4, 6, 8, 10, 12, 14>
7399 // Top && SingleSource: <1, 3, 5, 7, 1, 3, 5, 7>
7400 // Top && !SingleSource: <1, 3, 5, 7, 9, 11, 13, 15>
7401 int Ofs = Top ? 1 : 0;
7402 int Upper = SingleSource ? 0 : NumElts;
7403 for (int i = 0, e = NumElts / 2; i != e; ++i) {
7404 if (M[i] >= 0 && M[i] != (i * 2) + Ofs)
7405 return false;
7406 if (M[i + e] >= 0 && M[i + e] != (i * 2) + Ofs + Upper)
7407 return false;
7408 }
7409 return true;
7410}
7411
7412static bool isVMOVNMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7413 unsigned NumElts = VT.getVectorNumElements();
7414 // Make sure the mask has the right size.
7415 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7416 return false;
7417
7418 // If Top
7419 // Look for <0, N, 2, N+2, 4, N+4, ..>.
7420 // This inserts Input2 into Input1
7421 // else if not Top
7422 // Look for <0, N+1, 2, N+3, 4, N+5, ..>
7423 // This inserts Input1 into Input2
7424 unsigned Offset = Top ? 0 : 1;
7425 unsigned N = SingleSource ? 0 : NumElts;
7426 for (unsigned i = 0; i < NumElts; i += 2) {
7427 if (M[i] >= 0 && M[i] != (int)i)
7428 return false;
7429 if (M[i + 1] >= 0 && M[i + 1] != (int)(N + i + Offset))
7430 return false;
7431 }
7432
7433 return true;
7434}
7435
7436static bool isVMOVNTruncMask(ArrayRef<int> M, EVT ToVT, bool rev) {
7437 unsigned NumElts = ToVT.getVectorNumElements();
7438 if (NumElts != M.size())
7439 return false;
7440
7441 // Test if the Trunc can be convertible to a VMOVN with this shuffle. We are
7442 // looking for patterns of:
7443 // !rev: 0 N/2 1 N/2+1 2 N/2+2 ...
7444 // rev: N/2 0 N/2+1 1 N/2+2 2 ...
7445
7446 unsigned Off0 = rev ? NumElts / 2 : 0;
7447 unsigned Off1 = rev ? 0 : NumElts / 2;
7448 for (unsigned i = 0; i < NumElts; i += 2) {
7449 if (M[i] >= 0 && M[i] != (int)(Off0 + i / 2))
7450 return false;
7451 if (M[i + 1] >= 0 && M[i + 1] != (int)(Off1 + i / 2))
7452 return false;
7453 }
7454
7455 return true;
7456}
7457
7458// Reconstruct an MVE VCVT from a BuildVector of scalar fptrunc, all extracted
7459// from a pair of inputs. For example:
7460// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7461// FP_ROUND(EXTRACT_ELT(Y, 0),
7462// FP_ROUND(EXTRACT_ELT(X, 1),
7463// FP_ROUND(EXTRACT_ELT(Y, 1), ...)
7465 const ARMSubtarget *ST) {
7466 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7467 if (!ST->hasMVEFloatOps())
7468 return SDValue();
7469
7470 SDLoc dl(BV);
7471 EVT VT = BV.getValueType();
7472 if (VT != MVT::v8f16)
7473 return SDValue();
7474
7475 // We are looking for a buildvector of fptrunc elements, where all the
7476 // elements are interleavingly extracted from two sources. Check the first two
7477 // items are valid enough and extract some info from them (they are checked
7478 // properly in the loop below).
7479 if (BV.getOperand(0).getOpcode() != ISD::FP_ROUND ||
7482 return SDValue();
7483 if (BV.getOperand(1).getOpcode() != ISD::FP_ROUND ||
7486 return SDValue();
7487 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7488 SDValue Op1 = BV.getOperand(1).getOperand(0).getOperand(0);
7489 if (Op0.getValueType() != MVT::v4f32 || Op1.getValueType() != MVT::v4f32)
7490 return SDValue();
7491
7492 // Check all the values in the BuildVector line up with our expectations.
7493 for (unsigned i = 1; i < 4; i++) {
7494 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7495 return Trunc.getOpcode() == ISD::FP_ROUND &&
7497 Trunc.getOperand(0).getOperand(0) == Op &&
7498 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7499 };
7500 if (!Check(BV.getOperand(i * 2 + 0), Op0, i))
7501 return SDValue();
7502 if (!Check(BV.getOperand(i * 2 + 1), Op1, i))
7503 return SDValue();
7504 }
7505
7506 SDValue N1 = DAG.getNode(ARMISD::VCVTN, dl, VT, DAG.getUNDEF(VT), Op0,
7507 DAG.getConstant(0, dl, MVT::i32));
7508 return DAG.getNode(ARMISD::VCVTN, dl, VT, N1, Op1,
7509 DAG.getConstant(1, dl, MVT::i32));
7510}
7511
7512// Reconstruct an MVE VCVT from a BuildVector of scalar fpext, all extracted
7513// from a single input on alternating lanes. For example:
7514// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7515// FP_ROUND(EXTRACT_ELT(X, 2),
7516// FP_ROUND(EXTRACT_ELT(X, 4), ...)
7518 const ARMSubtarget *ST) {
7519 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7520 if (!ST->hasMVEFloatOps())
7521 return SDValue();
7522
7523 SDLoc dl(BV);
7524 EVT VT = BV.getValueType();
7525 if (VT != MVT::v4f32)
7526 return SDValue();
7527
7528 // We are looking for a buildvector of fptext elements, where all the
7529 // elements are alternating lanes from a single source. For example <0,2,4,6>
7530 // or <1,3,5,7>. Check the first two items are valid enough and extract some
7531 // info from them (they are checked properly in the loop below).
7532 if (BV.getOperand(0).getOpcode() != ISD::FP_EXTEND ||
7534 return SDValue();
7535 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7537 if (Op0.getValueType() != MVT::v8f16 || (Offset != 0 && Offset != 1))
7538 return SDValue();
7539
7540 // Check all the values in the BuildVector line up with our expectations.
7541 for (unsigned i = 1; i < 4; i++) {
7542 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7543 return Trunc.getOpcode() == ISD::FP_EXTEND &&
7545 Trunc.getOperand(0).getOperand(0) == Op &&
7546 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7547 };
7548 if (!Check(BV.getOperand(i), Op0, 2 * i + Offset))
7549 return SDValue();
7550 }
7551
7552 return DAG.getNode(ARMISD::VCVTL, dl, VT, Op0,
7553 DAG.getConstant(Offset, dl, MVT::i32));
7554}
7555
7556// If N is an integer constant that can be moved into a register in one
7557// instruction, return an SDValue of such a constant (will become a MOV
7558// instruction). Otherwise return null.
7560 const ARMSubtarget *ST, const SDLoc &dl) {
7561 uint64_t Val;
7562 if (!isa<ConstantSDNode>(N))
7563 return SDValue();
7564 Val = N->getAsZExtVal();
7565
7566 if (ST->isThumb1Only()) {
7567 if (Val <= 255 || ~Val <= 255)
7568 return DAG.getConstant(Val, dl, MVT::i32);
7569 } else {
7570 if (ARM_AM::getSOImmVal(Val) != -1 || ARM_AM::getSOImmVal(~Val) != -1)
7571 return DAG.getConstant(Val, dl, MVT::i32);
7572 }
7573 return SDValue();
7574}
7575
7577 const ARMSubtarget *ST) {
7578 SDLoc dl(Op);
7579 EVT VT = Op.getValueType();
7580
7581 assert(ST->hasMVEIntegerOps() && "LowerBUILD_VECTOR_i1 called without MVE!");
7582
7583 unsigned NumElts = VT.getVectorNumElements();
7584 unsigned BoolMask;
7585 unsigned BitsPerBool;
7586 if (NumElts == 2) {
7587 BitsPerBool = 8;
7588 BoolMask = 0xff;
7589 } else if (NumElts == 4) {
7590 BitsPerBool = 4;
7591 BoolMask = 0xf;
7592 } else if (NumElts == 8) {
7593 BitsPerBool = 2;
7594 BoolMask = 0x3;
7595 } else if (NumElts == 16) {
7596 BitsPerBool = 1;
7597 BoolMask = 0x1;
7598 } else
7599 return SDValue();
7600
7601 // If this is a single value copied into all lanes (a splat), we can just sign
7602 // extend that single value
7603 SDValue FirstOp = Op.getOperand(0);
7604 if (!isa<ConstantSDNode>(FirstOp) &&
7605 llvm::all_of(llvm::drop_begin(Op->ops()), [&FirstOp](const SDUse &U) {
7606 return U.get().isUndef() || U.get() == FirstOp;
7607 })) {
7608 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
7609 DAG.getValueType(MVT::i1));
7610 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
7611 }
7612
7613 // First create base with bits set where known
7614 unsigned Bits32 = 0;
7615 for (unsigned i = 0; i < NumElts; ++i) {
7616 SDValue V = Op.getOperand(i);
7617 if (!isa<ConstantSDNode>(V) && !V.isUndef())
7618 continue;
7619 bool BitSet = V.isUndef() ? false : V->getAsZExtVal();
7620 if (BitSet)
7621 Bits32 |= BoolMask << (i * BitsPerBool);
7622 }
7623
7624 // Add in unknown nodes
7625 SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
7626 DAG.getConstant(Bits32, dl, MVT::i32));
7627 for (unsigned i = 0; i < NumElts; ++i) {
7628 SDValue V = Op.getOperand(i);
7629 if (isa<ConstantSDNode>(V) || V.isUndef())
7630 continue;
7631 Base = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Base, V,
7632 DAG.getConstant(i, dl, MVT::i32));
7633 }
7634
7635 return Base;
7636}
7637
7639 const ARMSubtarget *ST) {
7640 if (!ST->hasMVEIntegerOps())
7641 return SDValue();
7642
7643 // We are looking for a buildvector where each element is Op[0] + i*N
7644 EVT VT = Op.getValueType();
7645 SDValue Op0 = Op.getOperand(0);
7646 unsigned NumElts = VT.getVectorNumElements();
7647
7648 // Get the increment value from operand 1
7649 SDValue Op1 = Op.getOperand(1);
7650 if (Op1.getOpcode() != ISD::ADD || Op1.getOperand(0) != Op0 ||
7652 return SDValue();
7653 unsigned N = Op1.getConstantOperandVal(1);
7654 if (N != 1 && N != 2 && N != 4 && N != 8)
7655 return SDValue();
7656
7657 // Check that each other operand matches
7658 for (unsigned I = 2; I < NumElts; I++) {
7659 SDValue OpI = Op.getOperand(I);
7660 if (OpI.getOpcode() != ISD::ADD || OpI.getOperand(0) != Op0 ||
7662 OpI.getConstantOperandVal(1) != I * N)
7663 return SDValue();
7664 }
7665
7666 SDLoc DL(Op);
7667 return DAG.getNode(ARMISD::VIDUP, DL, DAG.getVTList(VT, MVT::i32), Op0,
7668 DAG.getConstant(N, DL, MVT::i32));
7669}
7670
7671// Returns true if the operation N can be treated as qr instruction variant at
7672// operand Op.
7673static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op) {
7674 switch (N->getOpcode()) {
7675 case ISD::ADD:
7676 case ISD::MUL:
7677 case ISD::SADDSAT:
7678 case ISD::UADDSAT:
7679 case ISD::AVGFLOORS:
7680 case ISD::AVGFLOORU:
7681 return true;
7682 case ISD::SUB:
7683 case ISD::SSUBSAT:
7684 case ISD::USUBSAT:
7685 return N->getOperand(1).getNode() == Op;
7687 switch (N->getConstantOperandVal(0)) {
7688 case Intrinsic::arm_mve_add_predicated:
7689 case Intrinsic::arm_mve_mul_predicated:
7690 case Intrinsic::arm_mve_qadd_predicated:
7691 case Intrinsic::arm_mve_vhadd:
7692 case Intrinsic::arm_mve_hadd_predicated:
7693 case Intrinsic::arm_mve_vqdmulh:
7694 case Intrinsic::arm_mve_qdmulh_predicated:
7695 case Intrinsic::arm_mve_vqrdmulh:
7696 case Intrinsic::arm_mve_qrdmulh_predicated:
7697 case Intrinsic::arm_mve_vqdmull:
7698 case Intrinsic::arm_mve_vqdmull_predicated:
7699 return true;
7700 case Intrinsic::arm_mve_sub_predicated:
7701 case Intrinsic::arm_mve_qsub_predicated:
7702 case Intrinsic::arm_mve_vhsub:
7703 case Intrinsic::arm_mve_hsub_predicated:
7704 return N->getOperand(2).getNode() == Op;
7705 default:
7706 return false;
7707 }
7708 default:
7709 return false;
7710 }
7711}
7712
7713// If this is a case we can't handle, return null and let the default
7714// expansion code take care of it.
7715SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
7716 const ARMSubtarget *ST) const {
7717 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode());
7718 SDLoc dl(Op);
7719 EVT VT = Op.getValueType();
7720
7721 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
7722 return LowerBUILD_VECTOR_i1(Op, DAG, ST);
7723
7724 if (SDValue R = LowerBUILD_VECTORToVIDUP(Op, DAG, ST))
7725 return R;
7726
7727 APInt SplatBits, SplatUndef;
7728 unsigned SplatBitSize;
7729 bool HasAnyUndefs;
7730 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
7731 if (SplatUndef.isAllOnes())
7732 return DAG.getUNDEF(VT);
7733
7734 // If all the users of this constant splat are qr instruction variants,
7735 // generate a vdup of the constant.
7736 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == SplatBitSize &&
7737 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32) &&
7738 all_of(BVN->users(),
7739 [BVN](const SDNode *U) { return IsQRMVEInstruction(U, BVN); })) {
7740 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7741 : SplatBitSize == 16 ? MVT::v8i16
7742 : MVT::v16i8;
7743 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7744 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7745 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7746 }
7747
7748 if ((ST->hasNEON() && SplatBitSize <= 64) ||
7749 (ST->hasMVEIntegerOps() && SplatBitSize <= 64)) {
7750 // Check if an immediate VMOV works.
7751 EVT VmovVT;
7752 SDValue Val =
7753 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
7754 SplatBitSize, DAG, dl, VmovVT, VT, VMOVModImm);
7755
7756 if (Val.getNode()) {
7757 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, Val);
7758 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7759 }
7760
7761 // Try an immediate VMVN.
7762 uint64_t NegatedImm = (~SplatBits).getZExtValue();
7763 Val = isVMOVModifiedImm(
7764 NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, dl, VmovVT,
7765 VT, ST->hasMVEIntegerOps() ? MVEVMVNModImm : VMVNModImm);
7766 if (Val.getNode()) {
7767 SDValue Vmov = DAG.getNode(ARMISD::VMVNIMM, dl, VmovVT, Val);
7768 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7769 }
7770
7771 // Use vmov.f32 to materialize other v2f32 and v4f32 splats.
7772 if ((VT == MVT::v2f32 || VT == MVT::v4f32) && SplatBitSize == 32) {
7773 int ImmVal = ARM_AM::getFP32Imm(SplatBits);
7774 if (ImmVal != -1) {
7775 SDValue Val = DAG.getTargetConstant(ImmVal, dl, MVT::i32);
7776 return DAG.getNode(ARMISD::VMOVFPIMM, dl, VT, Val);
7777 }
7778 }
7779
7780 // If we are under MVE, generate a VDUP(constant), bitcast to the original
7781 // type.
7782 if (ST->hasMVEIntegerOps() &&
7783 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32)) {
7784 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7785 : SplatBitSize == 16 ? MVT::v8i16
7786 : MVT::v16i8;
7787 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7788 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7789 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7790 }
7791 }
7792 }
7793
7794 // Scan through the operands to see if only one value is used.
7795 //
7796 // As an optimisation, even if more than one value is used it may be more
7797 // profitable to splat with one value then change some lanes.
7798 //
7799 // Heuristically we decide to do this if the vector has a "dominant" value,
7800 // defined as splatted to more than half of the lanes.
7801 unsigned NumElts = VT.getVectorNumElements();
7802 bool isOnlyLowElement = true;
7803 bool usesOnlyOneValue = true;
7804 bool hasDominantValue = false;
7805 bool isConstant = true;
7806
7807 // Map of the number of times a particular SDValue appears in the
7808 // element list.
7809 DenseMap<SDValue, unsigned> ValueCounts;
7810 SDValue Value;
7811 for (unsigned i = 0; i < NumElts; ++i) {
7812 SDValue V = Op.getOperand(i);
7813 if (V.isUndef())
7814 continue;
7815 if (i > 0)
7816 isOnlyLowElement = false;
7818 isConstant = false;
7819
7820 unsigned &Count = ValueCounts[V];
7821
7822 // Is this value dominant? (takes up more than half of the lanes)
7823 if (++Count > (NumElts / 2)) {
7824 hasDominantValue = true;
7825 Value = V;
7826 }
7827 }
7828 if (ValueCounts.size() != 1)
7829 usesOnlyOneValue = false;
7830 if (!Value.getNode() && !ValueCounts.empty())
7831 Value = ValueCounts.begin()->first;
7832
7833 if (ValueCounts.empty())
7834 return DAG.getUNDEF(VT);
7835
7836 // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
7837 // Keep going if we are hitting this case.
7838 if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()) &&
7839 (VT != MVT::v8f16 || ST->hasFullFP16()))
7840 return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
7841
7842 unsigned EltSize = VT.getScalarSizeInBits();
7843
7844 // Use VDUP for non-constant splats. For f32 constant splats, reduce to
7845 // i32 and try again.
7846 if (hasDominantValue && EltSize <= 32) {
7847 if (!isConstant) {
7848 SDValue N;
7849
7850 // If we are VDUPing a value that comes directly from a vector, that will
7851 // cause an unnecessary move to and from a GPR, where instead we could
7852 // just use VDUPLANE. We can only do this if the lane being extracted
7853 // is at a constant index, as the VDUP from lane instructions only have
7854 // constant-index forms.
7855 ConstantSDNode *constIndex;
7856 if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7857 (constIndex = dyn_cast<ConstantSDNode>(Value->getOperand(1)))) {
7858 // We need to create a new undef vector to use for the VDUPLANE if the
7859 // size of the vector from which we get the value is different than the
7860 // size of the vector that we need to create. We will insert the element
7861 // such that the register coalescer will remove unnecessary copies.
7862 if (VT != Value->getOperand(0).getValueType()) {
7863 unsigned index = constIndex->getAPIntValue().getLimitedValue() %
7865 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7866 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DAG.getUNDEF(VT),
7867 Value, DAG.getConstant(index, dl, MVT::i32)),
7868 DAG.getConstant(index, dl, MVT::i32));
7869 } else
7870 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7871 Value->getOperand(0), Value->getOperand(1));
7872 } else
7873 N = DAG.getNode(ARMISD::VDUP, dl, VT, Value);
7874
7875 if (!usesOnlyOneValue) {
7876 // The dominant value was splatted as 'N', but we now have to insert
7877 // all differing elements.
7878 for (unsigned I = 0; I < NumElts; ++I) {
7879 if (Op.getOperand(I) == Value)
7880 continue;
7882 Ops.push_back(N);
7883 Ops.push_back(Op.getOperand(I));
7884 Ops.push_back(DAG.getConstant(I, dl, MVT::i32));
7885 N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ops);
7886 }
7887 }
7888 return N;
7889 }
7892 MVT FVT = VT.getVectorElementType().getSimpleVT();
7893 assert(FVT == MVT::f32 || FVT == MVT::f16);
7894 MVT IVT = (FVT == MVT::f32) ? MVT::i32 : MVT::i16;
7895 for (unsigned i = 0; i < NumElts; ++i)
7896 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, IVT,
7897 Op.getOperand(i)));
7898 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), IVT, NumElts);
7899 SDValue Val = DAG.getBuildVector(VecVT, dl, Ops);
7900 Val = LowerBUILD_VECTOR(Val, DAG, ST);
7901 if (Val.getNode())
7902 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7903 }
7904 if (usesOnlyOneValue) {
7905 SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl);
7906 if (isConstant && Val.getNode())
7907 return DAG.getNode(ARMISD::VDUP, dl, VT, Val);
7908 }
7909 }
7910
7911 // If all elements are constants and the case above didn't get hit, fall back
7912 // to the default expansion, which will generate a load from the constant
7913 // pool.
7914 if (isConstant)
7915 return SDValue();
7916
7917 // Reconstruct the BUILDVECTOR to one of the legal shuffles (such as vext and
7918 // vmovn). Empirical tests suggest this is rarely worth it for vectors of
7919 // length <= 2.
7920 if (NumElts >= 4)
7921 if (SDValue shuffle = ReconstructShuffle(Op, DAG))
7922 return shuffle;
7923
7924 // Attempt to turn a buildvector of scalar fptrunc's or fpext's back into
7925 // VCVT's
7926 if (SDValue VCVT = LowerBuildVectorOfFPTrunc(Op, DAG, Subtarget))
7927 return VCVT;
7928 if (SDValue VCVT = LowerBuildVectorOfFPExt(Op, DAG, Subtarget))
7929 return VCVT;
7930
7931 if (ST->hasNEON() && VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
7932 // If we haven't found an efficient lowering, try splitting a 128-bit vector
7933 // into two 64-bit vectors; we might discover a better way to lower it.
7934 SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
7935 EVT ExtVT = VT.getVectorElementType();
7936 EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
7937 SDValue Lower = DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[0], NumElts / 2));
7938 if (Lower.getOpcode() == ISD::BUILD_VECTOR)
7939 Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
7940 SDValue Upper =
7941 DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[NumElts / 2], NumElts / 2));
7942 if (Upper.getOpcode() == ISD::BUILD_VECTOR)
7943 Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
7944 if (Lower && Upper)
7945 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
7946 }
7947
7948 // Vectors with 32- or 64-bit elements can be built by directly assigning
7949 // the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
7950 // will be legalized.
7951 if (EltSize >= 32) {
7952 // Do the expansion with floating-point types, since that is what the VFP
7953 // registers are defined to use, and since i64 is not legal.
7954 EVT EltVT = EVT::getFloatingPointVT(EltSize);
7955 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
7957 for (unsigned i = 0; i < NumElts; ++i)
7958 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, EltVT, Op.getOperand(i)));
7959 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
7960 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7961 }
7962
7963 // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
7964 // know the default expansion would otherwise fall back on something even
7965 // worse. For a vector with one or two non-undef values, that's
7966 // scalar_to_vector for the elements followed by a shuffle (provided the
7967 // shuffle is valid for the target) and materialization element by element
7968 // on the stack followed by a load for everything else.
7969 if ((!isConstant && !usesOnlyOneValue) ||
7970 (VT == MVT::v8f16 && !ST->hasFullFP16())) {
7971 SDValue Vec = DAG.getUNDEF(VT);
7972 for (unsigned i = 0 ; i < NumElts; ++i) {
7973 SDValue V = Op.getOperand(i);
7974 if (V.isUndef())
7975 continue;
7976 SDValue LaneIdx = DAG.getConstant(i, dl, MVT::i32);
7977 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
7978 }
7979 return Vec;
7980 }
7981
7982 return SDValue();
7983}
7984
7985// Gather data to see if the operation can be modelled as a
7986// shuffle in combination with VEXTs.
7987SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
7988 SelectionDAG &DAG) const {
7989 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7990 SDLoc dl(Op);
7991 EVT VT = Op.getValueType();
7992 unsigned NumElts = VT.getVectorNumElements();
7993
7994 struct ShuffleSourceInfo {
7995 SDValue Vec;
7996 unsigned MinElt = std::numeric_limits<unsigned>::max();
7997 unsigned MaxElt = 0;
7998
7999 // We may insert some combination of BITCASTs and VEXT nodes to force Vec to
8000 // be compatible with the shuffle we intend to construct. As a result
8001 // ShuffleVec will be some sliding window into the original Vec.
8002 SDValue ShuffleVec;
8003
8004 // Code should guarantee that element i in Vec starts at element "WindowBase
8005 // + i * WindowScale in ShuffleVec".
8006 int WindowBase = 0;
8007 int WindowScale = 1;
8008
8009 ShuffleSourceInfo(SDValue Vec) : Vec(Vec), ShuffleVec(Vec) {}
8010
8011 bool operator ==(SDValue OtherVec) { return Vec == OtherVec; }
8012 };
8013
8014 // First gather all vectors used as an immediate source for this BUILD_VECTOR
8015 // node.
8017 for (unsigned i = 0; i < NumElts; ++i) {
8018 SDValue V = Op.getOperand(i);
8019 if (V.isUndef())
8020 continue;
8021 else if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
8022 // A shuffle can only come from building a vector from various
8023 // elements of other vectors.
8024 return SDValue();
8025 } else if (!isa<ConstantSDNode>(V.getOperand(1))) {
8026 // Furthermore, shuffles require a constant mask, whereas extractelts
8027 // accept variable indices.
8028 return SDValue();
8029 }
8030
8031 // Add this element source to the list if it's not already there.
8032 SDValue SourceVec = V.getOperand(0);
8033 auto Source = llvm::find(Sources, SourceVec);
8034 if (Source == Sources.end())
8035 Source = Sources.insert(Sources.end(), ShuffleSourceInfo(SourceVec));
8036
8037 // Update the minimum and maximum lane number seen.
8038 unsigned EltNo = V.getConstantOperandVal(1);
8039 Source->MinElt = std::min(Source->MinElt, EltNo);
8040 Source->MaxElt = std::max(Source->MaxElt, EltNo);
8041 }
8042
8043 // Currently only do something sane when at most two source vectors
8044 // are involved.
8045 if (Sources.size() > 2)
8046 return SDValue();
8047
8048 // Find out the smallest element size among result and two sources, and use
8049 // it as element size to build the shuffle_vector.
8050 EVT SmallestEltTy = VT.getVectorElementType();
8051 for (auto &Source : Sources) {
8052 EVT SrcEltTy = Source.Vec.getValueType().getVectorElementType();
8053 if (SrcEltTy.bitsLT(SmallestEltTy))
8054 SmallestEltTy = SrcEltTy;
8055 }
8056 unsigned ResMultiplier =
8057 VT.getScalarSizeInBits() / SmallestEltTy.getSizeInBits();
8058 NumElts = VT.getSizeInBits() / SmallestEltTy.getSizeInBits();
8059 EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
8060
8061 // If the source vector is too wide or too narrow, we may nevertheless be able
8062 // to construct a compatible shuffle either by concatenating it with UNDEF or
8063 // extracting a suitable range of elements.
8064 for (auto &Src : Sources) {
8065 EVT SrcVT = Src.ShuffleVec.getValueType();
8066
8067 uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
8068 uint64_t VTSize = VT.getFixedSizeInBits();
8069 if (SrcVTSize == VTSize)
8070 continue;
8071
8072 // This stage of the search produces a source with the same element type as
8073 // the original, but with a total width matching the BUILD_VECTOR output.
8074 EVT EltVT = SrcVT.getVectorElementType();
8075 unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
8076 EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
8077
8078 if (SrcVTSize < VTSize) {
8079 if (2 * SrcVTSize != VTSize)
8080 return SDValue();
8081 // We can pad out the smaller vector for free, so if it's part of a
8082 // shuffle...
8083 Src.ShuffleVec =
8084 DAG.getNode(ISD::CONCAT_VECTORS, dl, DestVT, Src.ShuffleVec,
8085 DAG.getUNDEF(Src.ShuffleVec.getValueType()));
8086 continue;
8087 }
8088
8089 if (SrcVTSize != 2 * VTSize)
8090 return SDValue();
8091
8092 if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
8093 // Span too large for a VEXT to cope
8094 return SDValue();
8095 }
8096
8097 if (Src.MinElt >= NumSrcElts) {
8098 // The extraction can just take the second half
8099 Src.ShuffleVec =
8100 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8101 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8102 Src.WindowBase = -NumSrcElts;
8103 } else if (Src.MaxElt < NumSrcElts) {
8104 // The extraction can just take the first half
8105 Src.ShuffleVec =
8106 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8107 DAG.getConstant(0, dl, MVT::i32));
8108 } else {
8109 // An actual VEXT is needed
8110 SDValue VEXTSrc1 =
8111 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8112 DAG.getConstant(0, dl, MVT::i32));
8113 SDValue VEXTSrc2 =
8114 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8115 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8116
8117 Src.ShuffleVec = DAG.getNode(ARMISD::VEXT, dl, DestVT, VEXTSrc1,
8118 VEXTSrc2,
8119 DAG.getConstant(Src.MinElt, dl, MVT::i32));
8120 Src.WindowBase = -Src.MinElt;
8121 }
8122 }
8123
8124 // Another possible incompatibility occurs from the vector element types. We
8125 // can fix this by bitcasting the source vectors to the same type we intend
8126 // for the shuffle.
8127 for (auto &Src : Sources) {
8128 EVT SrcEltTy = Src.ShuffleVec.getValueType().getVectorElementType();
8129 if (SrcEltTy == SmallestEltTy)
8130 continue;
8131 assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
8132 Src.ShuffleVec = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, ShuffleVT, Src.ShuffleVec);
8133 Src.WindowScale = SrcEltTy.getSizeInBits() / SmallestEltTy.getSizeInBits();
8134 Src.WindowBase *= Src.WindowScale;
8135 }
8136
8137 // Final check before we try to actually produce a shuffle.
8138 LLVM_DEBUG({
8139 for (auto Src : Sources)
8140 assert(Src.ShuffleVec.getValueType() == ShuffleVT);
8141 });
8142
8143 // The stars all align, our next step is to produce the mask for the shuffle.
8144 SmallVector<int, 8> Mask(ShuffleVT.getVectorNumElements(), -1);
8145 int BitsPerShuffleLane = ShuffleVT.getScalarSizeInBits();
8146 for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
8147 SDValue Entry = Op.getOperand(i);
8148 if (Entry.isUndef())
8149 continue;
8150
8151 auto Src = llvm::find(Sources, Entry.getOperand(0));
8152 int EltNo = cast<ConstantSDNode>(Entry.getOperand(1))->getSExtValue();
8153
8154 // EXTRACT_VECTOR_ELT performs an implicit any_ext; BUILD_VECTOR an implicit
8155 // trunc. So only std::min(SrcBits, DestBits) actually get defined in this
8156 // segment.
8157 EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
8158 int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
8159 VT.getScalarSizeInBits());
8160 int LanesDefined = BitsDefined / BitsPerShuffleLane;
8161
8162 // This source is expected to fill ResMultiplier lanes of the final shuffle,
8163 // starting at the appropriate offset.
8164 int *LaneMask = &Mask[i * ResMultiplier];
8165
8166 int ExtractBase = EltNo * Src->WindowScale + Src->WindowBase;
8167 ExtractBase += NumElts * (Src - Sources.begin());
8168 for (int j = 0; j < LanesDefined; ++j)
8169 LaneMask[j] = ExtractBase + j;
8170 }
8171
8172
8173 // We can't handle more than two sources. This should have already
8174 // been checked before this point.
8175 assert(Sources.size() <= 2 && "Too many sources!");
8176
8177 SDValue ShuffleOps[] = { DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT) };
8178 for (unsigned i = 0; i < Sources.size(); ++i)
8179 ShuffleOps[i] = Sources[i].ShuffleVec;
8180
8181 SDValue Shuffle = buildLegalVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
8182 ShuffleOps[1], Mask, DAG);
8183 if (!Shuffle)
8184 return SDValue();
8185 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuffle);
8186}
8187
8189 OP_COPY = 0, // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
8198 OP_VUZPL, // VUZP, left result
8199 OP_VUZPR, // VUZP, right result
8200 OP_VZIPL, // VZIP, left result
8201 OP_VZIPR, // VZIP, right result
8202 OP_VTRNL, // VTRN, left result
8203 OP_VTRNR // VTRN, right result
8204};
8205
8206static bool isLegalMVEShuffleOp(unsigned PFEntry) {
8207 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8208 switch (OpNum) {
8209 case OP_COPY:
8210 case OP_VREV:
8211 case OP_VDUP0:
8212 case OP_VDUP1:
8213 case OP_VDUP2:
8214 case OP_VDUP3:
8215 return true;
8216 }
8217 return false;
8218}
8219
8220/// isShuffleMaskLegal - Targets can use this to indicate that they only
8221/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
8222/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
8223/// are assumed to be legal.
8225 if (VT.getVectorNumElements() == 4 &&
8226 (VT.is128BitVector() || VT.is64BitVector())) {
8227 unsigned PFIndexes[4];
8228 for (unsigned i = 0; i != 4; ++i) {
8229 if (M[i] < 0)
8230 PFIndexes[i] = 8;
8231 else
8232 PFIndexes[i] = M[i];
8233 }
8234
8235 // Compute the index in the perfect shuffle table.
8236 unsigned PFTableIndex =
8237 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8238 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8239 unsigned Cost = (PFEntry >> 30);
8240
8241 if (Cost <= 4 && (Subtarget->hasNEON() || isLegalMVEShuffleOp(PFEntry)))
8242 return true;
8243 }
8244
8245 bool ReverseVEXT, isV_UNDEF;
8246 unsigned Imm, WhichResult;
8247
8248 unsigned EltSize = VT.getScalarSizeInBits();
8249 if (EltSize >= 32 ||
8251 ShuffleVectorInst::isIdentityMask(M, M.size()) ||
8252 isVREVMask(M, VT, 64) ||
8253 isVREVMask(M, VT, 32) ||
8254 isVREVMask(M, VT, 16))
8255 return true;
8256 else if (Subtarget->hasNEON() &&
8257 (isVEXTMask(M, VT, ReverseVEXT, Imm) ||
8258 isVTBLMask(M, VT) ||
8259 isNEONTwoResultShuffleMask(M, VT, WhichResult, isV_UNDEF)))
8260 return true;
8261 else if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8262 isReverseMask(M, VT))
8263 return true;
8264 else if (Subtarget->hasMVEIntegerOps() &&
8265 (isVMOVNMask(M, VT, true, false) ||
8266 isVMOVNMask(M, VT, false, false) || isVMOVNMask(M, VT, true, true)))
8267 return true;
8268 else if (Subtarget->hasMVEIntegerOps() &&
8269 (isTruncMask(M, VT, false, false) ||
8270 isTruncMask(M, VT, false, true) ||
8271 isTruncMask(M, VT, true, false) || isTruncMask(M, VT, true, true)))
8272 return true;
8273 else
8274 return false;
8275}
8276
8277/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
8278/// the specified operations to build the shuffle.
8280 SDValue RHS, SelectionDAG &DAG,
8281 const SDLoc &dl) {
8282 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8283 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8284 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8285
8286 if (OpNum == OP_COPY) {
8287 if (LHSID == (1*9+2)*9+3) return LHS;
8288 assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
8289 return RHS;
8290 }
8291
8292 SDValue OpLHS, OpRHS;
8293 OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
8294 OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);
8295 EVT VT = OpLHS.getValueType();
8296
8297 switch (OpNum) {
8298 default: llvm_unreachable("Unknown shuffle opcode!");
8299 case OP_VREV:
8300 // VREV divides the vector in half and swaps within the half.
8301 if (VT.getScalarSizeInBits() == 32)
8302 return DAG.getNode(ARMISD::VREV64, dl, VT, OpLHS);
8303 // vrev <4 x i16> -> VREV32
8304 if (VT.getScalarSizeInBits() == 16)
8305 return DAG.getNode(ARMISD::VREV32, dl, VT, OpLHS);
8306 // vrev <4 x i8> -> VREV16
8307 assert(VT.getScalarSizeInBits() == 8);
8308 return DAG.getNode(ARMISD::VREV16, dl, VT, OpLHS);
8309 case OP_VDUP0:
8310 case OP_VDUP1:
8311 case OP_VDUP2:
8312 case OP_VDUP3:
8313 return DAG.getNode(ARMISD::VDUPLANE, dl, VT,
8314 OpLHS, DAG.getConstant(OpNum-OP_VDUP0, dl, MVT::i32));
8315 case OP_VEXT1:
8316 case OP_VEXT2:
8317 case OP_VEXT3:
8318 return DAG.getNode(ARMISD::VEXT, dl, VT,
8319 OpLHS, OpRHS,
8320 DAG.getConstant(OpNum - OP_VEXT1 + 1, dl, MVT::i32));
8321 case OP_VUZPL:
8322 case OP_VUZPR:
8323 return DAG.getNode(ARMISD::VUZP, dl, DAG.getVTList(VT, VT),
8324 OpLHS, OpRHS).getValue(OpNum-OP_VUZPL);
8325 case OP_VZIPL:
8326 case OP_VZIPR:
8327 return DAG.getNode(ARMISD::VZIP, dl, DAG.getVTList(VT, VT),
8328 OpLHS, OpRHS).getValue(OpNum-OP_VZIPL);
8329 case OP_VTRNL:
8330 case OP_VTRNR:
8331 return DAG.getNode(ARMISD::VTRN, dl, DAG.getVTList(VT, VT),
8332 OpLHS, OpRHS).getValue(OpNum-OP_VTRNL);
8333 }
8334}
8335
8337 ArrayRef<int> ShuffleMask,
8338 SelectionDAG &DAG) {
8339 // Check to see if we can use the VTBL instruction.
8340 SDValue V1 = Op.getOperand(0);
8341 SDValue V2 = Op.getOperand(1);
8342 SDLoc DL(Op);
8343
8344 SmallVector<SDValue, 8> VTBLMask;
8345 for (int I : ShuffleMask)
8346 VTBLMask.push_back(DAG.getSignedConstant(I, DL, MVT::i32));
8347
8348 if (V2.getNode()->isUndef())
8349 return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1,
8350 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8351
8352 return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2,
8353 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8354}
8355
8357 SDLoc DL(Op);
8358 EVT VT = Op.getValueType();
8359
8360 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8361 "Expect an v8i16/v16i8 type");
8362 SDValue OpLHS = DAG.getNode(ARMISD::VREV64, DL, VT, Op.getOperand(0));
8363 // For a v16i8 type: After the VREV, we have got <7, ..., 0, 15, ..., 8>. Now,
8364 // extract the first 8 bytes into the top double word and the last 8 bytes
8365 // into the bottom double word, through a new vector shuffle that will be
8366 // turned into a VEXT on Neon, or a couple of VMOVDs on MVE.
8367 std::vector<int> NewMask;
8368 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8369 NewMask.push_back(VT.getVectorNumElements() / 2 + i);
8370 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8371 NewMask.push_back(i);
8372 return DAG.getVectorShuffle(VT, DL, OpLHS, OpLHS, NewMask);
8373}
8374
8376 switch (VT.getSimpleVT().SimpleTy) {
8377 case MVT::v2i1:
8378 return MVT::v2f64;
8379 case MVT::v4i1:
8380 return MVT::v4i32;
8381 case MVT::v8i1:
8382 return MVT::v8i16;
8383 case MVT::v16i1:
8384 return MVT::v16i8;
8385 default:
8386 llvm_unreachable("Unexpected vector predicate type");
8387 }
8388}
8389
8391 SelectionDAG &DAG) {
8392 // Converting from boolean predicates to integers involves creating a vector
8393 // of all ones or all zeroes and selecting the lanes based upon the real
8394 // predicate.
8396 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff), dl, MVT::i32);
8397 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllOnes);
8398
8399 SDValue AllZeroes =
8400 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0x0), dl, MVT::i32);
8401 AllZeroes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllZeroes);
8402
8403 // Get full vector type from predicate type
8405
8406 SDValue RecastV1;
8407 // If the real predicate is an v8i1 or v4i1 (not v16i1) then we need to recast
8408 // this to a v16i1. This cannot be done with an ordinary bitcast because the
8409 // sizes are not the same. We have to use a MVE specific PREDICATE_CAST node,
8410 // since we know in hardware the sizes are really the same.
8411 if (VT != MVT::v16i1)
8412 RecastV1 = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Pred);
8413 else
8414 RecastV1 = Pred;
8415
8416 // Select either all ones or zeroes depending upon the real predicate bits.
8417 SDValue PredAsVector =
8418 DAG.getNode(ISD::VSELECT, dl, MVT::v16i8, RecastV1, AllOnes, AllZeroes);
8419
8420 // Recast our new predicate-as-integer v16i8 vector into something
8421 // appropriate for the shuffle, i.e. v4i32 for a real v4i1 predicate.
8422 return DAG.getNode(ISD::BITCAST, dl, NewVT, PredAsVector);
8423}
8424
8426 const ARMSubtarget *ST) {
8427 EVT VT = Op.getValueType();
8429 ArrayRef<int> ShuffleMask = SVN->getMask();
8430
8431 assert(ST->hasMVEIntegerOps() &&
8432 "No support for vector shuffle of boolean predicates");
8433
8434 SDValue V1 = Op.getOperand(0);
8435 SDValue V2 = Op.getOperand(1);
8436 SDLoc dl(Op);
8437 if (isReverseMask(ShuffleMask, VT)) {
8438 SDValue cast = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, V1);
8439 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, cast);
8440 SDValue srl = DAG.getNode(ISD::SRL, dl, MVT::i32, rbit,
8441 DAG.getConstant(16, dl, MVT::i32));
8442 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, srl);
8443 }
8444
8445 // Until we can come up with optimised cases for every single vector
8446 // shuffle in existence we have chosen the least painful strategy. This is
8447 // to essentially promote the boolean predicate to a 8-bit integer, where
8448 // each predicate represents a byte. Then we fall back on a normal integer
8449 // vector shuffle and convert the result back into a predicate vector. In
8450 // many cases the generated code might be even better than scalar code
8451 // operating on bits. Just imagine trying to shuffle 8 arbitrary 2-bit
8452 // fields in a register into 8 other arbitrary 2-bit fields!
8453 SDValue PredAsVector1 = PromoteMVEPredVector(dl, V1, VT, DAG);
8454 EVT NewVT = PredAsVector1.getValueType();
8455 SDValue PredAsVector2 = V2.isUndef() ? DAG.getUNDEF(NewVT)
8456 : PromoteMVEPredVector(dl, V2, VT, DAG);
8457 assert(PredAsVector2.getValueType() == NewVT &&
8458 "Expected identical vector type in expanded i1 shuffle!");
8459
8460 // Do the shuffle!
8461 SDValue Shuffled = DAG.getVectorShuffle(NewVT, dl, PredAsVector1,
8462 PredAsVector2, ShuffleMask);
8463
8464 // Now return the result of comparing the shuffled vector with zero,
8465 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1. For a v2i1
8466 // we convert to a v4i1 compare to fill in the two halves of the i64 as i32s.
8467 if (VT == MVT::v2i1) {
8468 SDValue BC = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Shuffled);
8469 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, BC,
8470 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8471 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8472 }
8473 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Shuffled,
8474 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8475}
8476
8478 ArrayRef<int> ShuffleMask,
8479 SelectionDAG &DAG) {
8480 // Attempt to lower the vector shuffle using as many whole register movs as
8481 // possible. This is useful for types smaller than 32bits, which would
8482 // often otherwise become a series for grp movs.
8483 SDLoc dl(Op);
8484 EVT VT = Op.getValueType();
8485 if (VT.getScalarSizeInBits() >= 32)
8486 return SDValue();
8487
8488 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8489 "Unexpected vector type");
8490 int NumElts = VT.getVectorNumElements();
8491 int QuarterSize = NumElts / 4;
8492 // The four final parts of the vector, as i32's
8493 SDValue Parts[4];
8494
8495 // Look for full lane vmovs like <0,1,2,3> or <u,5,6,7> etc, (but not
8496 // <u,u,u,u>), returning the vmov lane index
8497 auto getMovIdx = [](ArrayRef<int> ShuffleMask, int Start, int Length) {
8498 // Detect which mov lane this would be from the first non-undef element.
8499 int MovIdx = -1;
8500 for (int i = 0; i < Length; i++) {
8501 if (ShuffleMask[Start + i] >= 0) {
8502 if (ShuffleMask[Start + i] % Length != i)
8503 return -1;
8504 MovIdx = ShuffleMask[Start + i] / Length;
8505 break;
8506 }
8507 }
8508 // If all items are undef, leave this for other combines
8509 if (MovIdx == -1)
8510 return -1;
8511 // Check the remaining values are the correct part of the same mov
8512 for (int i = 1; i < Length; i++) {
8513 if (ShuffleMask[Start + i] >= 0 &&
8514 (ShuffleMask[Start + i] / Length != MovIdx ||
8515 ShuffleMask[Start + i] % Length != i))
8516 return -1;
8517 }
8518 return MovIdx;
8519 };
8520
8521 for (int Part = 0; Part < 4; ++Part) {
8522 // Does this part look like a mov
8523 int Elt = getMovIdx(ShuffleMask, Part * QuarterSize, QuarterSize);
8524 if (Elt != -1) {
8525 SDValue Input = Op->getOperand(0);
8526 if (Elt >= 4) {
8527 Input = Op->getOperand(1);
8528 Elt -= 4;
8529 }
8530 SDValue BitCast = DAG.getBitcast(MVT::v4f32, Input);
8531 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, BitCast,
8532 DAG.getConstant(Elt, dl, MVT::i32));
8533 }
8534 }
8535
8536 // Nothing interesting found, just return
8537 if (!Parts[0] && !Parts[1] && !Parts[2] && !Parts[3])
8538 return SDValue();
8539
8540 // The other parts need to be built with the old shuffle vector, cast to a
8541 // v4i32 and extract_vector_elts
8542 if (!Parts[0] || !Parts[1] || !Parts[2] || !Parts[3]) {
8543 SmallVector<int, 16> NewShuffleMask;
8544 for (int Part = 0; Part < 4; ++Part)
8545 for (int i = 0; i < QuarterSize; i++)
8546 NewShuffleMask.push_back(
8547 Parts[Part] ? -1 : ShuffleMask[Part * QuarterSize + i]);
8548 SDValue NewShuffle = DAG.getVectorShuffle(
8549 VT, dl, Op->getOperand(0), Op->getOperand(1), NewShuffleMask);
8550 SDValue BitCast = DAG.getBitcast(MVT::v4f32, NewShuffle);
8551
8552 for (int Part = 0; Part < 4; ++Part)
8553 if (!Parts[Part])
8554 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32,
8555 BitCast, DAG.getConstant(Part, dl, MVT::i32));
8556 }
8557 // Build a vector out of the various parts and bitcast it back to the original
8558 // type.
8559 SDValue NewVec = DAG.getNode(ARMISD::BUILD_VECTOR, dl, MVT::v4f32, Parts);
8560 return DAG.getBitcast(VT, NewVec);
8561}
8562
8564 ArrayRef<int> ShuffleMask,
8565 SelectionDAG &DAG) {
8566 SDValue V1 = Op.getOperand(0);
8567 SDValue V2 = Op.getOperand(1);
8568 EVT VT = Op.getValueType();
8569 unsigned NumElts = VT.getVectorNumElements();
8570
8571 // An One-Off Identity mask is one that is mostly an identity mask from as
8572 // single source but contains a single element out-of-place, either from a
8573 // different vector or from another position in the same vector. As opposed to
8574 // lowering this via a ARMISD::BUILD_VECTOR we can generate an extract/insert
8575 // pair directly.
8576 auto isOneOffIdentityMask = [](ArrayRef<int> Mask, EVT VT, int BaseOffset,
8577 int &OffElement) {
8578 OffElement = -1;
8579 int NonUndef = 0;
8580 for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
8581 if (Mask[i] == -1)
8582 continue;
8583 NonUndef++;
8584 if (Mask[i] != i + BaseOffset) {
8585 if (OffElement == -1)
8586 OffElement = i;
8587 else
8588 return false;
8589 }
8590 }
8591 return NonUndef > 2 && OffElement != -1;
8592 };
8593 int OffElement;
8594 SDValue VInput;
8595 if (isOneOffIdentityMask(ShuffleMask, VT, 0, OffElement))
8596 VInput = V1;
8597 else if (isOneOffIdentityMask(ShuffleMask, VT, NumElts, OffElement))
8598 VInput = V2;
8599 else
8600 return SDValue();
8601
8602 SDLoc dl(Op);
8603 EVT SVT = VT.getScalarType() == MVT::i8 || VT.getScalarType() == MVT::i16
8604 ? MVT::i32
8605 : VT.getScalarType();
8606 SDValue Elt = DAG.getNode(
8607 ISD::EXTRACT_VECTOR_ELT, dl, SVT,
8608 ShuffleMask[OffElement] < (int)NumElts ? V1 : V2,
8609 DAG.getVectorIdxConstant(ShuffleMask[OffElement] % NumElts, dl));
8610 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, VInput, Elt,
8611 DAG.getVectorIdxConstant(OffElement % NumElts, dl));
8612}
8613
8615 const ARMSubtarget *ST) {
8616 SDValue V1 = Op.getOperand(0);
8617 SDValue V2 = Op.getOperand(1);
8618 SDLoc dl(Op);
8619 EVT VT = Op.getValueType();
8621 unsigned EltSize = VT.getScalarSizeInBits();
8622
8623 if (ST->hasMVEIntegerOps() && EltSize == 1)
8624 return LowerVECTOR_SHUFFLE_i1(Op, DAG, ST);
8625
8626 // Convert shuffles that are directly supported on NEON to target-specific
8627 // DAG nodes, instead of keeping them as shuffles and matching them again
8628 // during code selection. This is more efficient and avoids the possibility
8629 // of inconsistencies between legalization and selection.
8630 // FIXME: floating-point vectors should be canonicalized to integer vectors
8631 // of the same time so that they get CSEd properly.
8632 ArrayRef<int> ShuffleMask = SVN->getMask();
8633
8634 if (EltSize <= 32) {
8635 if (SVN->isSplat()) {
8636 int Lane = SVN->getSplatIndex();
8637 // If this is undef splat, generate it via "just" vdup, if possible.
8638 if (Lane == -1) Lane = 0;
8639
8640 // Test if V1 is a SCALAR_TO_VECTOR.
8641 if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR) {
8642 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8643 }
8644 // Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
8645 // (and probably will turn into a SCALAR_TO_VECTOR once legalization
8646 // reaches it).
8647 if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
8648 !isa<ConstantSDNode>(V1.getOperand(0))) {
8649 bool IsScalarToVector = true;
8650 for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
8651 if (!V1.getOperand(i).isUndef()) {
8652 IsScalarToVector = false;
8653 break;
8654 }
8655 if (IsScalarToVector)
8656 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8657 }
8658 return DAG.getNode(ARMISD::VDUPLANE, dl, VT, V1,
8659 DAG.getConstant(Lane, dl, MVT::i32));
8660 }
8661
8662 bool ReverseVEXT = false;
8663 unsigned Imm = 0;
8664 if (ST->hasNEON() && isVEXTMask(ShuffleMask, VT, ReverseVEXT, Imm)) {
8665 if (ReverseVEXT)
8666 std::swap(V1, V2);
8667 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V2,
8668 DAG.getConstant(Imm, dl, MVT::i32));
8669 }
8670
8671 if (isVREVMask(ShuffleMask, VT, 64))
8672 return DAG.getNode(ARMISD::VREV64, dl, VT, V1);
8673 if (isVREVMask(ShuffleMask, VT, 32))
8674 return DAG.getNode(ARMISD::VREV32, dl, VT, V1);
8675 if (isVREVMask(ShuffleMask, VT, 16))
8676 return DAG.getNode(ARMISD::VREV16, dl, VT, V1);
8677
8678 if (ST->hasNEON() && V2->isUndef() && isSingletonVEXTMask(ShuffleMask, VT, Imm)) {
8679 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V1,
8680 DAG.getConstant(Imm, dl, MVT::i32));
8681 }
8682
8683 // Check for Neon shuffles that modify both input vectors in place.
8684 // If both results are used, i.e., if there are two shuffles with the same
8685 // source operands and with masks corresponding to both results of one of
8686 // these operations, DAG memoization will ensure that a single node is
8687 // used for both shuffles.
8688 unsigned WhichResult = 0;
8689 bool isV_UNDEF = false;
8690 if (ST->hasNEON()) {
8691 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8692 ShuffleMask, VT, WhichResult, isV_UNDEF)) {
8693 if (isV_UNDEF)
8694 V2 = V1;
8695 return DAG.getNode(ShuffleOpc, dl, DAG.getVTList(VT, VT), V1, V2)
8696 .getValue(WhichResult);
8697 }
8698 }
8699 if (ST->hasMVEIntegerOps()) {
8700 if (isVMOVNMask(ShuffleMask, VT, false, false))
8701 return DAG.getNode(ARMISD::VMOVN, dl, VT, V2, V1,
8702 DAG.getConstant(0, dl, MVT::i32));
8703 if (isVMOVNMask(ShuffleMask, VT, true, false))
8704 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V2,
8705 DAG.getConstant(1, dl, MVT::i32));
8706 if (isVMOVNMask(ShuffleMask, VT, true, true))
8707 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V1,
8708 DAG.getConstant(1, dl, MVT::i32));
8709 }
8710
8711 // Also check for these shuffles through CONCAT_VECTORS: we canonicalize
8712 // shuffles that produce a result larger than their operands with:
8713 // shuffle(concat(v1, undef), concat(v2, undef))
8714 // ->
8715 // shuffle(concat(v1, v2), undef)
8716 // because we can access quad vectors (see PerformVECTOR_SHUFFLECombine).
8717 //
8718 // This is useful in the general case, but there are special cases where
8719 // native shuffles produce larger results: the two-result ops.
8720 //
8721 // Look through the concat when lowering them:
8722 // shuffle(concat(v1, v2), undef)
8723 // ->
8724 // concat(VZIP(v1, v2):0, :1)
8725 //
8726 if (ST->hasNEON() && V1->getOpcode() == ISD::CONCAT_VECTORS && V2->isUndef()) {
8727 SDValue SubV1 = V1->getOperand(0);
8728 SDValue SubV2 = V1->getOperand(1);
8729 EVT SubVT = SubV1.getValueType();
8730
8731 // We expect these to have been canonicalized to -1.
8732 assert(llvm::all_of(ShuffleMask, [&](int i) {
8733 return i < (int)VT.getVectorNumElements();
8734 }) && "Unexpected shuffle index into UNDEF operand!");
8735
8736 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8737 ShuffleMask, SubVT, WhichResult, isV_UNDEF)) {
8738 if (isV_UNDEF)
8739 SubV2 = SubV1;
8740 assert((WhichResult == 0) &&
8741 "In-place shuffle of concat can only have one result!");
8742 SDValue Res = DAG.getNode(ShuffleOpc, dl, DAG.getVTList(SubVT, SubVT),
8743 SubV1, SubV2);
8744 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Res.getValue(0),
8745 Res.getValue(1));
8746 }
8747 }
8748 }
8749
8750 if (ST->hasMVEIntegerOps() && EltSize <= 32 &&
8751 (ST->hasFullFP16() || VT != MVT::v8f16)) {
8752 if (SDValue V = LowerVECTOR_SHUFFLEUsingOneOff(Op, ShuffleMask, DAG))
8753 return V;
8754
8755 for (bool Top : {false, true}) {
8756 for (bool SingleSource : {false, true}) {
8757 if (isTruncMask(ShuffleMask, VT, Top, SingleSource)) {
8758 MVT FromSVT = MVT::getIntegerVT(EltSize * 2);
8759 MVT FromVT = MVT::getVectorVT(FromSVT, ShuffleMask.size() / 2);
8760 SDValue Lo = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT, V1);
8761 SDValue Hi = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT,
8762 SingleSource ? V1 : V2);
8763 if (Top) {
8764 SDValue Amt = DAG.getConstant(EltSize, dl, FromVT);
8765 Lo = DAG.getNode(ISD::SRL, dl, FromVT, Lo, Amt);
8766 Hi = DAG.getNode(ISD::SRL, dl, FromVT, Hi, Amt);
8767 }
8768 return DAG.getNode(ARMISD::MVETRUNC, dl, VT, Lo, Hi);
8769 }
8770 }
8771 }
8772 }
8773
8774 // If the shuffle is not directly supported and it has 4 elements, use
8775 // the PerfectShuffle-generated table to synthesize it from other shuffles.
8776 unsigned NumElts = VT.getVectorNumElements();
8777 if (NumElts == 4) {
8778 unsigned PFIndexes[4];
8779 for (unsigned i = 0; i != 4; ++i) {
8780 if (ShuffleMask[i] < 0)
8781 PFIndexes[i] = 8;
8782 else
8783 PFIndexes[i] = ShuffleMask[i];
8784 }
8785
8786 // Compute the index in the perfect shuffle table.
8787 unsigned PFTableIndex =
8788 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8789 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8790 unsigned Cost = (PFEntry >> 30);
8791
8792 if (Cost <= 4) {
8793 if (ST->hasNEON())
8794 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8795 else if (isLegalMVEShuffleOp(PFEntry)) {
8796 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8797 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8798 unsigned PFEntryLHS = PerfectShuffleTable[LHSID];
8799 unsigned PFEntryRHS = PerfectShuffleTable[RHSID];
8800 if (isLegalMVEShuffleOp(PFEntryLHS) && isLegalMVEShuffleOp(PFEntryRHS))
8801 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8802 }
8803 }
8804 }
8805
8806 // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
8807 if (EltSize >= 32) {
8808 // Do the expansion with floating-point types, since that is what the VFP
8809 // registers are defined to use, and since i64 is not legal.
8810 EVT EltVT = EVT::getFloatingPointVT(EltSize);
8811 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
8812 V1 = DAG.getNode(ISD::BITCAST, dl, VecVT, V1);
8813 V2 = DAG.getNode(ISD::BITCAST, dl, VecVT, V2);
8815 for (unsigned i = 0; i < NumElts; ++i) {
8816 if (ShuffleMask[i] < 0)
8817 Ops.push_back(DAG.getUNDEF(EltVT));
8818 else
8819 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
8820 ShuffleMask[i] < (int)NumElts ? V1 : V2,
8821 DAG.getConstant(ShuffleMask[i] & (NumElts-1),
8822 dl, MVT::i32)));
8823 }
8824 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
8825 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
8826 }
8827
8828 if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8829 isReverseMask(ShuffleMask, VT))
8830 return LowerReverse_VECTOR_SHUFFLE(Op, DAG);
8831
8832 if (ST->hasNEON() && VT == MVT::v8i8)
8833 if (SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG))
8834 return NewOp;
8835
8836 if (ST->hasMVEIntegerOps())
8837 if (SDValue NewOp = LowerVECTOR_SHUFFLEUsingMovs(Op, ShuffleMask, DAG))
8838 return NewOp;
8839
8840 // Lower v8f16 via v8i16 to avoid invalid f16 nodes.
8841 if (VT == MVT::v8f16 && !ST->hasFullFP16()) {
8842 SDValue BC0 =
8843 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(0));
8844 SDValue BC1 =
8845 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(1));
8846 SDValue Shuf = DAG.getVectorShuffle(MVT::v8i16, dl, BC0, BC1, ShuffleMask);
8847 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuf);
8848 }
8849
8850 return SDValue();
8851}
8852
8854 const ARMSubtarget *ST) {
8855 EVT VecVT = Op.getOperand(0).getValueType();
8856 SDLoc dl(Op);
8857
8858 assert(ST->hasMVEIntegerOps() &&
8859 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8860
8861 SDValue Conv =
8862 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8863 unsigned Lane = Op.getConstantOperandVal(2);
8864 unsigned LaneWidth =
8866 unsigned Mask = ((1 << LaneWidth) - 1) << Lane * LaneWidth;
8867 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32,
8868 Op.getOperand(1), DAG.getValueType(MVT::i1));
8869 SDValue BFI = DAG.getNode(ARMISD::BFI, dl, MVT::i32, Conv, Ext,
8870 DAG.getConstant(~Mask, dl, MVT::i32));
8871 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), BFI);
8872}
8873
8874SDValue ARMTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
8875 SelectionDAG &DAG) const {
8876 // INSERT_VECTOR_ELT is legal only for immediate indexes.
8877 SDValue Lane = Op.getOperand(2);
8878 if (!isa<ConstantSDNode>(Lane))
8879 return SDValue();
8880
8881 SDValue Elt = Op.getOperand(1);
8882 EVT EltVT = Elt.getValueType();
8883
8884 if (Subtarget->hasMVEIntegerOps() &&
8885 Op.getValueType().getScalarSizeInBits() == 1)
8886 return LowerINSERT_VECTOR_ELT_i1(Op, DAG, Subtarget);
8887
8888 if (getTypeAction(*DAG.getContext(), EltVT) ==
8890 // INSERT_VECTOR_ELT doesn't want f16 operands promoting to f32,
8891 // but the type system will try to do that if we don't intervene.
8892 // Reinterpret any such vector-element insertion as one with the
8893 // corresponding integer types.
8894
8895 SDLoc dl(Op);
8896
8897 EVT IEltVT = MVT::getIntegerVT(EltVT.getScalarSizeInBits());
8898 assert(getTypeAction(*DAG.getContext(), IEltVT) !=
8900
8901 SDValue VecIn = Op.getOperand(0);
8902 EVT VecVT = VecIn.getValueType();
8903 EVT IVecVT = EVT::getVectorVT(*DAG.getContext(), IEltVT,
8904 VecVT.getVectorNumElements());
8905
8906 SDValue IElt = DAG.getNode(ISD::BITCAST, dl, IEltVT, Elt);
8907 SDValue IVecIn = DAG.getNode(ISD::BITCAST, dl, IVecVT, VecIn);
8908 SDValue IVecOut = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, IVecVT,
8909 IVecIn, IElt, Lane);
8910 return DAG.getNode(ISD::BITCAST, dl, VecVT, IVecOut);
8911 }
8912
8913 return Op;
8914}
8915
8917 const ARMSubtarget *ST) {
8918 EVT VecVT = Op.getOperand(0).getValueType();
8919 SDLoc dl(Op);
8920
8921 assert(ST->hasMVEIntegerOps() &&
8922 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8923
8924 SDValue Conv =
8925 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8926 unsigned Lane = Op.getConstantOperandVal(1);
8927 unsigned LaneWidth =
8929 SDValue Shift = DAG.getNode(ISD::SRL, dl, MVT::i32, Conv,
8930 DAG.getConstant(Lane * LaneWidth, dl, MVT::i32));
8931 return Shift;
8932}
8933
8935 const ARMSubtarget *ST) {
8936 // EXTRACT_VECTOR_ELT is legal only for immediate indexes.
8937 SDValue Lane = Op.getOperand(1);
8938 if (!isa<ConstantSDNode>(Lane))
8939 return SDValue();
8940
8941 SDValue Vec = Op.getOperand(0);
8942 EVT VT = Vec.getValueType();
8943
8944 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8945 return LowerEXTRACT_VECTOR_ELT_i1(Op, DAG, ST);
8946
8947 if (Op.getValueType() == MVT::i32 && Vec.getScalarValueSizeInBits() < 32) {
8948 SDLoc dl(Op);
8949 return DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane);
8950 }
8951
8952 return Op;
8953}
8954
8956 const ARMSubtarget *ST) {
8957 SDLoc dl(Op);
8958 assert(Op.getValueType().getScalarSizeInBits() == 1 &&
8959 "Unexpected custom CONCAT_VECTORS lowering");
8960 assert(isPowerOf2_32(Op.getNumOperands()) &&
8961 "Unexpected custom CONCAT_VECTORS lowering");
8962 assert(ST->hasMVEIntegerOps() &&
8963 "CONCAT_VECTORS lowering only supported for MVE");
8964
8965 auto ConcatPair = [&](SDValue V1, SDValue V2) {
8966 EVT Op1VT = V1.getValueType();
8967 EVT Op2VT = V2.getValueType();
8968 assert(Op1VT == Op2VT && "Operand types don't match!");
8969 assert((Op1VT == MVT::v2i1 || Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) &&
8970 "Unexpected i1 concat operations!");
8971 EVT VT = Op1VT.getDoubleNumVectorElementsVT(*DAG.getContext());
8972
8973 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
8974 SDValue NewV2 = PromoteMVEPredVector(dl, V2, Op2VT, DAG);
8975
8976 // We now have Op1 + Op2 promoted to vectors of integers, where v8i1 gets
8977 // promoted to v8i16, etc.
8978 MVT ElType =
8980 unsigned NumElts = 2 * Op1VT.getVectorNumElements();
8981
8982 EVT ConcatVT = MVT::getVectorVT(ElType, NumElts);
8983 if (Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) {
8984 // Use MVETRUNC to truncate the combined NewV1::NewV2 into the smaller
8985 // ConcatVT.
8986 SDValue ConVec =
8987 DAG.getNode(ARMISD::MVETRUNC, dl, ConcatVT, NewV1, NewV2);
8988 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
8989 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8990 }
8991
8992 // Extract the vector elements from Op1 and Op2 one by one and truncate them
8993 // to be the right size for the destination. For example, if Op1 is v4i1
8994 // then the promoted vector is v4i32. The result of concatenation gives a
8995 // v8i1, which when promoted is v8i16. That means each i32 element from Op1
8996 // needs truncating to i16 and inserting in the result.
8997 auto ExtractInto = [&DAG, &dl](SDValue NewV, SDValue ConVec, unsigned &j) {
8998 EVT NewVT = NewV.getValueType();
8999 EVT ConcatVT = ConVec.getValueType();
9000 unsigned ExtScale = 1;
9001 if (NewVT == MVT::v2f64) {
9002 NewV = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, NewV);
9003 ExtScale = 2;
9004 }
9005 for (unsigned i = 0, e = NewVT.getVectorNumElements(); i < e; i++, j++) {
9006 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV,
9007 DAG.getIntPtrConstant(i * ExtScale, dl));
9008 ConVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ConcatVT, ConVec, Elt,
9009 DAG.getConstant(j, dl, MVT::i32));
9010 }
9011 return ConVec;
9012 };
9013 unsigned j = 0;
9014 SDValue ConVec = DAG.getNode(ISD::UNDEF, dl, ConcatVT);
9015 ConVec = ExtractInto(NewV1, ConVec, j);
9016 ConVec = ExtractInto(NewV2, ConVec, j);
9017
9018 // Now return the result of comparing the subvector with zero, which will
9019 // generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9020 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9021 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9022 };
9023
9024 // Concat each pair of subvectors and pack into the lower half of the array.
9025 SmallVector<SDValue> ConcatOps(Op->ops());
9026 while (ConcatOps.size() > 1) {
9027 for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) {
9028 SDValue V1 = ConcatOps[I];
9029 SDValue V2 = ConcatOps[I + 1];
9030 ConcatOps[I / 2] = ConcatPair(V1, V2);
9031 }
9032 ConcatOps.resize(ConcatOps.size() / 2);
9033 }
9034 return ConcatOps[0];
9035}
9036
9038 const ARMSubtarget *ST) {
9039 EVT VT = Op->getValueType(0);
9040 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
9041 return LowerCONCAT_VECTORS_i1(Op, DAG, ST);
9042
9043 // The only time a CONCAT_VECTORS operation can have legal types is when
9044 // two 64-bit vectors are concatenated to a 128-bit vector.
9045 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
9046 "unexpected CONCAT_VECTORS");
9047 SDLoc dl(Op);
9048 SDValue Val = DAG.getUNDEF(MVT::v2f64);
9049 SDValue Op0 = Op.getOperand(0);
9050 SDValue Op1 = Op.getOperand(1);
9051 if (!Op0.isUndef())
9052 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9053 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op0),
9054 DAG.getIntPtrConstant(0, dl));
9055 if (!Op1.isUndef())
9056 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9057 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op1),
9058 DAG.getIntPtrConstant(1, dl));
9059 return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Val);
9060}
9061
9063 const ARMSubtarget *ST) {
9064 SDValue V1 = Op.getOperand(0);
9065 SDValue V2 = Op.getOperand(1);
9066 SDLoc dl(Op);
9067 EVT VT = Op.getValueType();
9068 EVT Op1VT = V1.getValueType();
9069 unsigned NumElts = VT.getVectorNumElements();
9070 unsigned Index = V2->getAsZExtVal();
9071
9072 assert(VT.getScalarSizeInBits() == 1 &&
9073 "Unexpected custom EXTRACT_SUBVECTOR lowering");
9074 assert(ST->hasMVEIntegerOps() &&
9075 "EXTRACT_SUBVECTOR lowering only supported for MVE");
9076
9077 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9078
9079 // We now have Op1 promoted to a vector of integers, where v8i1 gets
9080 // promoted to v8i16, etc.
9081
9083
9084 if (NumElts == 2) {
9085 EVT SubVT = MVT::v4i32;
9086 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9087 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j += 2) {
9088 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9089 DAG.getIntPtrConstant(i, dl));
9090 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9091 DAG.getConstant(j, dl, MVT::i32));
9092 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9093 DAG.getConstant(j + 1, dl, MVT::i32));
9094 }
9095 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, SubVec,
9096 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9097 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
9098 }
9099
9100 EVT SubVT = MVT::getVectorVT(ElType, NumElts);
9101 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9102 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j++) {
9103 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9104 DAG.getIntPtrConstant(i, dl));
9105 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9106 DAG.getConstant(j, dl, MVT::i32));
9107 }
9108
9109 // Now return the result of comparing the subvector with zero,
9110 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9111 return DAG.getNode(ARMISD::VCMPZ, dl, VT, SubVec,
9112 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9113}
9114
9115// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
9117 const ARMSubtarget *ST) {
9118 assert(ST->hasMVEIntegerOps() && "Expected MVE!");
9119 EVT VT = N->getValueType(0);
9120 assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
9121 "Expected a vector i1 type!");
9122 SDValue Op = N->getOperand(0);
9123 EVT FromVT = Op.getValueType();
9124 SDLoc DL(N);
9125
9126 SDValue And =
9127 DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
9128 return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
9129 DAG.getCondCode(ISD::SETNE));
9130}
9131
9133 const ARMSubtarget *Subtarget) {
9134 if (!Subtarget->hasMVEIntegerOps())
9135 return SDValue();
9136
9137 EVT ToVT = N->getValueType(0);
9138 if (ToVT.getScalarType() == MVT::i1)
9139 return LowerTruncatei1(N, DAG, Subtarget);
9140
9141 // MVE does not have a single instruction to perform the truncation of a v4i32
9142 // into the lower half of a v8i16, in the same way that a NEON vmovn would.
9143 // Most of the instructions in MVE follow the 'Beats' system, where moving
9144 // values from different lanes is usually something that the instructions
9145 // avoid.
9146 //
9147 // Instead it has top/bottom instructions such as VMOVLT/B and VMOVNT/B,
9148 // which take a the top/bottom half of a larger lane and extend it (or do the
9149 // opposite, truncating into the top/bottom lane from a larger lane). Note
9150 // that because of the way we widen lanes, a v4i16 is really a v4i32 using the
9151 // bottom 16bits from each vector lane. This works really well with T/B
9152 // instructions, but that doesn't extend to v8i32->v8i16 where the lanes need
9153 // to move order.
9154 //
9155 // But truncates and sext/zext are always going to be fairly common from llvm.
9156 // We have several options for how to deal with them:
9157 // - Wherever possible combine them into an instruction that makes them
9158 // "free". This includes loads/stores, which can perform the trunc as part
9159 // of the memory operation. Or certain shuffles that can be turned into
9160 // VMOVN/VMOVL.
9161 // - Lane Interleaving to transform blocks surrounded by ext/trunc. So
9162 // trunc(mul(sext(a), sext(b))) may become
9163 // VMOVNT(VMUL(VMOVLB(a), VMOVLB(b)), VMUL(VMOVLT(a), VMOVLT(b))). (Which in
9164 // this case can use VMULL). This is performed in the
9165 // MVELaneInterleavingPass.
9166 // - Otherwise we have an option. By default we would expand the
9167 // zext/sext/trunc into a series of lane extract/inserts going via GPR
9168 // registers. One for each vector lane in the vector. This can obviously be
9169 // very expensive.
9170 // - The other option is to use the fact that loads/store can extend/truncate
9171 // to turn a trunc into two truncating stack stores and a stack reload. This
9172 // becomes 3 back-to-back memory operations, but at least that is less than
9173 // all the insert/extracts.
9174 //
9175 // In order to do the last, we convert certain trunc's into MVETRUNC, which
9176 // are either optimized where they can be, or eventually lowered into stack
9177 // stores/loads. This prevents us from splitting a v8i16 trunc into two stores
9178 // two early, where other instructions would be better, and stops us from
9179 // having to reconstruct multiple buildvector shuffles into loads/stores.
9180 if (ToVT != MVT::v8i16 && ToVT != MVT::v16i8)
9181 return SDValue();
9182 EVT FromVT = N->getOperand(0).getValueType();
9183 if (FromVT != MVT::v8i32 && FromVT != MVT::v16i16)
9184 return SDValue();
9185
9186 SDValue Lo, Hi;
9187 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
9188 SDLoc DL(N);
9189 return DAG.getNode(ARMISD::MVETRUNC, DL, ToVT, Lo, Hi);
9190}
9191
9193 const ARMSubtarget *Subtarget) {
9194 if (!Subtarget->hasMVEIntegerOps())
9195 return SDValue();
9196
9197 // See LowerTruncate above for an explanation of MVEEXT/MVETRUNC.
9198
9199 EVT ToVT = N->getValueType(0);
9200 if (ToVT != MVT::v16i32 && ToVT != MVT::v8i32 && ToVT != MVT::v16i16)
9201 return SDValue();
9202 SDValue Op = N->getOperand(0);
9203 EVT FromVT = Op.getValueType();
9204 if (FromVT != MVT::v8i16 && FromVT != MVT::v16i8)
9205 return SDValue();
9206
9207 SDLoc DL(N);
9208 EVT ExtVT = ToVT.getHalfNumVectorElementsVT(*DAG.getContext());
9209 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8)
9210 ExtVT = MVT::v8i16;
9211
9212 unsigned Opcode =
9214 SDValue Ext = DAG.getNode(Opcode, DL, DAG.getVTList(ExtVT, ExtVT), Op);
9215 SDValue Ext1 = Ext.getValue(1);
9216
9217 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8) {
9218 Ext = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext);
9219 Ext1 = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext1);
9220 }
9221
9222 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Ext, Ext1);
9223}
9224
9225/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
9226/// element has been zero/sign-extended, depending on the isSigned parameter,
9227/// from an integer type half its size.
9229 bool isSigned) {
9230 // A v2i64 BUILD_VECTOR will have been legalized to a BITCAST from v4i32.
9231 EVT VT = N->getValueType(0);
9232 if (VT == MVT::v2i64 && N->getOpcode() == ISD::BITCAST) {
9233 SDNode *BVN = N->getOperand(0).getNode();
9234 if (BVN->getValueType(0) != MVT::v4i32 ||
9235 BVN->getOpcode() != ISD::BUILD_VECTOR)
9236 return false;
9237 unsigned LoElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9238 unsigned HiElt = 1 - LoElt;
9243 if (!Lo0 || !Hi0 || !Lo1 || !Hi1)
9244 return false;
9245 if (isSigned) {
9246 if (Hi0->getSExtValue() == Lo0->getSExtValue() >> 32 &&
9247 Hi1->getSExtValue() == Lo1->getSExtValue() >> 32)
9248 return true;
9249 } else {
9250 if (Hi0->isZero() && Hi1->isZero())
9251 return true;
9252 }
9253 return false;
9254 }
9255
9256 if (N->getOpcode() != ISD::BUILD_VECTOR)
9257 return false;
9258
9259 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
9260 SDNode *Elt = N->getOperand(i).getNode();
9262 unsigned EltSize = VT.getScalarSizeInBits();
9263 unsigned HalfSize = EltSize / 2;
9264 if (isSigned) {
9265 if (!isIntN(HalfSize, C->getSExtValue()))
9266 return false;
9267 } else {
9268 if (!isUIntN(HalfSize, C->getZExtValue()))
9269 return false;
9270 }
9271 continue;
9272 }
9273 return false;
9274 }
9275
9276 return true;
9277}
9278
9279/// isSignExtended - Check if a node is a vector value that is sign-extended
9280/// or a constant BUILD_VECTOR with sign-extended elements.
9282 if (N->getOpcode() == ISD::SIGN_EXTEND || ISD::isSEXTLoad(N))
9283 return true;
9284 if (isExtendedBUILD_VECTOR(N, DAG, true))
9285 return true;
9286 return false;
9287}
9288
9289/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
9290/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
9292 if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
9294 return true;
9295 if (isExtendedBUILD_VECTOR(N, DAG, false))
9296 return true;
9297 return false;
9298}
9299
9300static EVT getExtensionTo64Bits(const EVT &OrigVT) {
9301 if (OrigVT.getSizeInBits() >= 64)
9302 return OrigVT;
9303
9304 assert(OrigVT.isSimple() && "Expecting a simple value type");
9305
9306 MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
9307 switch (OrigSimpleTy) {
9308 default: llvm_unreachable("Unexpected Vector Type");
9309 case MVT::v2i8:
9310 case MVT::v2i16:
9311 return MVT::v2i32;
9312 case MVT::v4i8:
9313 return MVT::v4i16;
9314 }
9315}
9316
9317/// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
9318/// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
9319/// We insert the required extension here to get the vector to fill a D register.
9321 const EVT &OrigTy,
9322 const EVT &ExtTy,
9323 unsigned ExtOpcode) {
9324 // The vector originally had a size of OrigTy. It was then extended to ExtTy.
9325 // We expect the ExtTy to be 128-bits total. If the OrigTy is less than
9326 // 64-bits we need to insert a new extension so that it will be 64-bits.
9327 assert(ExtTy.is128BitVector() && "Unexpected extension size");
9328 if (OrigTy.getSizeInBits() >= 64)
9329 return N;
9330
9331 // Must extend size to at least 64 bits to be used as an operand for VMULL.
9332 EVT NewVT = getExtensionTo64Bits(OrigTy);
9333
9334 return DAG.getNode(ExtOpcode, SDLoc(N), NewVT, N);
9335}
9336
9337/// SkipLoadExtensionForVMULL - return a load of the original vector size that
9338/// does not do any sign/zero extension. If the original vector is less
9339/// than 64 bits, an appropriate extension will be added after the load to
9340/// reach a total size of 64 bits. We have to add the extension separately
9341/// because ARM does not have a sign/zero extending load for vectors.
9343 EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
9344
9345 // The load already has the right type.
9346 if (ExtendedTy == LD->getMemoryVT())
9347 return DAG.getLoad(LD->getMemoryVT(), SDLoc(LD), LD->getChain(),
9348 LD->getBasePtr(), LD->getPointerInfo(), LD->getAlign(),
9349 LD->getMemOperand()->getFlags());
9350
9351 // We need to create a zextload/sextload. We cannot just create a load
9352 // followed by a zext/zext node because LowerMUL is also run during normal
9353 // operation legalization where we can't create illegal types.
9354 return DAG.getExtLoad(LD->getExtensionType(), SDLoc(LD), ExtendedTy,
9355 LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
9356 LD->getMemoryVT(), LD->getAlign(),
9357 LD->getMemOperand()->getFlags());
9358}
9359
9360/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
9361/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
9362/// the unextended value. The unextended vector should be 64 bits so that it can
9363/// be used as an operand to a VMULL instruction. If the original vector size
9364/// before extension is less than 64 bits we add a an extension to resize
9365/// the vector to 64 bits.
9367 if (N->getOpcode() == ISD::SIGN_EXTEND ||
9368 N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
9369 return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
9370 N->getOperand(0)->getValueType(0),
9371 N->getValueType(0),
9372 N->getOpcode());
9373
9374 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
9375 assert((ISD::isSEXTLoad(LD) || ISD::isZEXTLoad(LD)) &&
9376 "Expected extending load");
9377
9378 SDValue newLoad = SkipLoadExtensionForVMULL(LD, DAG);
9379 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), newLoad.getValue(1));
9380 unsigned Opcode = ISD::isSEXTLoad(LD) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
9381 SDValue extLoad =
9382 DAG.getNode(Opcode, SDLoc(newLoad), LD->getValueType(0), newLoad);
9383 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 0), extLoad);
9384
9385 return newLoad;
9386 }
9387
9388 // Otherwise, the value must be a BUILD_VECTOR. For v2i64, it will
9389 // have been legalized as a BITCAST from v4i32.
9390 if (N->getOpcode() == ISD::BITCAST) {
9391 SDNode *BVN = N->getOperand(0).getNode();
9393 BVN->getValueType(0) == MVT::v4i32 && "expected v4i32 BUILD_VECTOR");
9394 unsigned LowElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9395 return DAG.getBuildVector(
9396 MVT::v2i32, SDLoc(N),
9397 {BVN->getOperand(LowElt), BVN->getOperand(LowElt + 2)});
9398 }
9399 // Construct a new BUILD_VECTOR with elements truncated to half the size.
9400 assert(N->getOpcode() == ISD::BUILD_VECTOR && "expected BUILD_VECTOR");
9401 EVT VT = N->getValueType(0);
9402 unsigned EltSize = VT.getScalarSizeInBits() / 2;
9403 unsigned NumElts = VT.getVectorNumElements();
9404 MVT TruncVT = MVT::getIntegerVT(EltSize);
9406 SDLoc dl(N);
9407 for (unsigned i = 0; i != NumElts; ++i) {
9408 const APInt &CInt = N->getConstantOperandAPInt(i);
9409 // Element types smaller than 32 bits are not legal, so use i32 elements.
9410 // The values are implicitly truncated so sext vs. zext doesn't matter.
9411 Ops.push_back(DAG.getConstant(CInt.zextOrTrunc(32), dl, MVT::i32));
9412 }
9413 return DAG.getBuildVector(MVT::getVectorVT(TruncVT, NumElts), dl, Ops);
9414}
9415
9416static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
9417 unsigned Opcode = N->getOpcode();
9418 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9419 SDNode *N0 = N->getOperand(0).getNode();
9420 SDNode *N1 = N->getOperand(1).getNode();
9421 return N0->hasOneUse() && N1->hasOneUse() &&
9422 isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
9423 }
9424 return false;
9425}
9426
9427static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
9428 unsigned Opcode = N->getOpcode();
9429 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9430 SDNode *N0 = N->getOperand(0).getNode();
9431 SDNode *N1 = N->getOperand(1).getNode();
9432 return N0->hasOneUse() && N1->hasOneUse() &&
9433 isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
9434 }
9435 return false;
9436}
9437
9439 // Multiplications are only custom-lowered for 128-bit vectors so that
9440 // VMULL can be detected. Otherwise v2i64 multiplications are not legal.
9441 EVT VT = Op.getValueType();
9442 assert(VT.is128BitVector() && VT.isInteger() &&
9443 "unexpected type for custom-lowering ISD::MUL");
9444 SDNode *N0 = Op.getOperand(0).getNode();
9445 SDNode *N1 = Op.getOperand(1).getNode();
9446 unsigned NewOpc = 0;
9447 bool isMLA = false;
9448 bool isN0SExt = isSignExtended(N0, DAG);
9449 bool isN1SExt = isSignExtended(N1, DAG);
9450 if (isN0SExt && isN1SExt)
9451 NewOpc = ARMISD::VMULLs;
9452 else {
9453 bool isN0ZExt = isZeroExtended(N0, DAG);
9454 bool isN1ZExt = isZeroExtended(N1, DAG);
9455 if (isN0ZExt && isN1ZExt)
9456 NewOpc = ARMISD::VMULLu;
9457 else if (isN1SExt || isN1ZExt) {
9458 // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
9459 // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
9460 if (isN1SExt && isAddSubSExt(N0, DAG)) {
9461 NewOpc = ARMISD::VMULLs;
9462 isMLA = true;
9463 } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
9464 NewOpc = ARMISD::VMULLu;
9465 isMLA = true;
9466 } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
9467 std::swap(N0, N1);
9468 NewOpc = ARMISD::VMULLu;
9469 isMLA = true;
9470 }
9471 }
9472
9473 if (!NewOpc) {
9474 if (VT == MVT::v2i64)
9475 // Fall through to expand this. It is not legal.
9476 return SDValue();
9477 else
9478 // Other vector multiplications are legal.
9479 return Op;
9480 }
9481 }
9482
9483 // Legalize to a VMULL instruction.
9484 SDLoc DL(Op);
9485 SDValue Op0;
9486 SDValue Op1 = SkipExtensionForVMULL(N1, DAG);
9487 if (!isMLA) {
9488 Op0 = SkipExtensionForVMULL(N0, DAG);
9490 Op1.getValueType().is64BitVector() &&
9491 "unexpected types for extended operands to VMULL");
9492 return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
9493 }
9494
9495 // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
9496 // isel lowering to take advantage of no-stall back to back vmul + vmla.
9497 // vmull q0, d4, d6
9498 // vmlal q0, d5, d6
9499 // is faster than
9500 // vaddl q0, d4, d5
9501 // vmovl q1, d6
9502 // vmul q0, q0, q1
9503 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG);
9504 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG);
9505 EVT Op1VT = Op1.getValueType();
9506 return DAG.getNode(N0->getOpcode(), DL, VT,
9507 DAG.getNode(NewOpc, DL, VT,
9508 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
9509 DAG.getNode(NewOpc, DL, VT,
9510 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
9511}
9512
9514 SelectionDAG &DAG) {
9515 // TODO: Should this propagate fast-math-flags?
9516
9517 // Convert to float
9518 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo));
9519 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo));
9520 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X);
9521 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y);
9522 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X);
9523 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y);
9524 // Get reciprocal estimate.
9525 // float4 recip = vrecpeq_f32(yf);
9526 Y = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9527 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9528 Y);
9529 // Because char has a smaller range than uchar, we can actually get away
9530 // without any newton steps. This requires that we use a weird bias
9531 // of 0xb000, however (again, this has been exhaustively tested).
9532 // float4 result = as_float4(as_int4(xf*recip) + 0xb000);
9533 X = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, X, Y);
9534 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, X);
9535 Y = DAG.getConstant(0xb000, dl, MVT::v4i32);
9536 X = DAG.getNode(ISD::ADD, dl, MVT::v4i32, X, Y);
9537 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, X);
9538 // Convert back to short.
9539 X = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, X);
9540 X = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, X);
9541 return X;
9542}
9543
9545 SelectionDAG &DAG) {
9546 // TODO: Should this propagate fast-math-flags?
9547
9548 SDValue N2;
9549 // Convert to float.
9550 // float4 yf = vcvt_f32_s32(vmovl_s16(y));
9551 // float4 xf = vcvt_f32_s32(vmovl_s16(x));
9552 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N0);
9553 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N1);
9554 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9555 N1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9556
9557 // Use reciprocal estimate and one refinement step.
9558 // float4 recip = vrecpeq_f32(yf);
9559 // recip *= vrecpsq_f32(yf, recip);
9560 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9561 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9562 N1);
9563 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9564 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9565 N1, N2);
9566 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9567 // Because short has a smaller range than ushort, we can actually get away
9568 // with only a single newton step. This requires that we use a weird bias
9569 // of 89, however (again, this has been exhaustively tested).
9570 // float4 result = as_float4(as_int4(xf*recip) + 0x89);
9571 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9572 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9573 N1 = DAG.getConstant(0x89, dl, MVT::v4i32);
9574 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9575 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9576 // Convert back to integer and return.
9577 // return vmovn_s32(vcvt_s32_f32(result));
9578 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9579 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9580 return N0;
9581}
9582
9584 const ARMSubtarget *ST) {
9585 EVT VT = Op.getValueType();
9586 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9587 "unexpected type for custom-lowering ISD::SDIV");
9588
9589 SDLoc dl(Op);
9590 SDValue N0 = Op.getOperand(0);
9591 SDValue N1 = Op.getOperand(1);
9592 SDValue N2, N3;
9593
9594 if (VT == MVT::v8i8) {
9595 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N0);
9596 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N1);
9597
9598 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9599 DAG.getIntPtrConstant(4, dl));
9600 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9601 DAG.getIntPtrConstant(4, dl));
9602 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9603 DAG.getIntPtrConstant(0, dl));
9604 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9605 DAG.getIntPtrConstant(0, dl));
9606
9607 N0 = LowerSDIV_v4i8(N0, N1, dl, DAG); // v4i16
9608 N2 = LowerSDIV_v4i8(N2, N3, dl, DAG); // v4i16
9609
9610 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9611 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9612
9613 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v8i8, N0);
9614 return N0;
9615 }
9616 return LowerSDIV_v4i16(N0, N1, dl, DAG);
9617}
9618
9620 const ARMSubtarget *ST) {
9621 // TODO: Should this propagate fast-math-flags?
9622 EVT VT = Op.getValueType();
9623 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9624 "unexpected type for custom-lowering ISD::UDIV");
9625
9626 SDLoc dl(Op);
9627 SDValue N0 = Op.getOperand(0);
9628 SDValue N1 = Op.getOperand(1);
9629 SDValue N2, N3;
9630
9631 if (VT == MVT::v8i8) {
9632 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N0);
9633 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N1);
9634
9635 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9636 DAG.getIntPtrConstant(4, dl));
9637 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9638 DAG.getIntPtrConstant(4, dl));
9639 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9640 DAG.getIntPtrConstant(0, dl));
9641 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9642 DAG.getIntPtrConstant(0, dl));
9643
9644 N0 = LowerSDIV_v4i16(N0, N1, dl, DAG); // v4i16
9645 N2 = LowerSDIV_v4i16(N2, N3, dl, DAG); // v4i16
9646
9647 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9648 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9649
9650 N0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v8i8,
9651 DAG.getConstant(Intrinsic::arm_neon_vqmovnsu, dl,
9652 MVT::i32),
9653 N0);
9654 return N0;
9655 }
9656
9657 // v4i16 sdiv ... Convert to float.
9658 // float4 yf = vcvt_f32_s32(vmovl_u16(y));
9659 // float4 xf = vcvt_f32_s32(vmovl_u16(x));
9660 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N0);
9661 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N1);
9662 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9663 SDValue BN1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9664
9665 // Use reciprocal estimate and two refinement steps.
9666 // float4 recip = vrecpeq_f32(yf);
9667 // recip *= vrecpsq_f32(yf, recip);
9668 // recip *= vrecpsq_f32(yf, recip);
9669 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9670 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9671 BN1);
9672 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9673 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9674 BN1, N2);
9675 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9676 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9677 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9678 BN1, N2);
9679 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9680 // Simply multiplying by the reciprocal estimate can leave us a few ulps
9681 // too low, so we add 2 ulps (exhaustive testing shows that this is enough,
9682 // and that it will never cause us to return an answer too large).
9683 // float4 result = as_float4(as_int4(xf*recip) + 2);
9684 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9685 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9686 N1 = DAG.getConstant(2, dl, MVT::v4i32);
9687 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9688 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9689 // Convert back to integer and return.
9690 // return vmovn_u32(vcvt_s32_f32(result));
9691 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9692 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9693 return N0;
9694}
9695
9697 unsigned Opcode, bool IsSigned) {
9698 EVT VT0 = Op.getValue(0).getValueType();
9699 EVT VT1 = Op.getValue(1).getValueType();
9700
9701 bool InvertCarry = Opcode == ARMISD::SUBE;
9702 SDValue OpLHS = Op.getOperand(0);
9703 SDValue OpRHS = Op.getOperand(1);
9704 SDValue OpCarryIn = valueToCarryFlag(Op.getOperand(2), DAG, InvertCarry);
9705
9706 SDLoc DL(Op);
9707
9708 SDValue Result = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::i32), OpLHS,
9709 OpRHS, OpCarryIn);
9710
9711 SDValue OutFlag =
9712 IsSigned ? overflowFlagToValue(Result.getValue(1), VT1, DAG)
9713 : carryFlagToValue(Result.getValue(1), VT1, DAG, InvertCarry);
9714
9715 return DAG.getMergeValues({Result, OutFlag}, DL);
9716}
9717
9718SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
9719 bool Signed,
9720 SDValue &Chain) const {
9721 EVT VT = Op.getValueType();
9722 assert((VT == MVT::i32 || VT == MVT::i64) &&
9723 "unexpected type for custom lowering DIV");
9724 SDLoc dl(Op);
9725
9726 const auto &DL = DAG.getDataLayout();
9727 RTLIB::Libcall LC;
9728 if (Signed)
9729 LC = VT == MVT::i32 ? RTLIB::SDIVREM_I32 : RTLIB::SDIVREM_I64;
9730 else
9731 LC = VT == MVT::i32 ? RTLIB::UDIVREM_I32 : RTLIB::UDIVREM_I64;
9732
9733 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
9734 SDValue ES = DAG.getExternalSymbol(LCImpl, getPointerTy(DL));
9735
9737
9738 for (auto AI : {1, 0}) {
9739 SDValue Operand = Op.getOperand(AI);
9740 Args.emplace_back(Operand,
9741 Operand.getValueType().getTypeForEVT(*DAG.getContext()));
9742 }
9743
9744 CallLoweringInfo CLI(DAG);
9745 CLI.setDebugLoc(dl).setChain(Chain).setCallee(
9747 VT.getTypeForEVT(*DAG.getContext()), ES, std::move(Args));
9748
9749 return LowerCallTo(CLI).first;
9750}
9751
9752// This is a code size optimisation: return the original SDIV node to
9753// DAGCombiner when we don't want to expand SDIV into a sequence of
9754// instructions, and an empty node otherwise which will cause the
9755// SDIV to be expanded in DAGCombine.
9756SDValue
9757ARMTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
9758 SelectionDAG &DAG,
9759 SmallVectorImpl<SDNode *> &Created) const {
9760 // TODO: Support SREM
9761 if (N->getOpcode() != ISD::SDIV)
9762 return SDValue();
9763
9764 const auto &ST = DAG.getSubtarget<ARMSubtarget>();
9765 const bool MinSize = ST.hasMinSize();
9766 const bool HasDivide = ST.isThumb() ? ST.hasDivideInThumbMode()
9767 : ST.hasDivideInARMMode();
9768
9769 // Don't touch vector types; rewriting this may lead to scalarizing
9770 // the int divs.
9771 if (N->getOperand(0).getValueType().isVector())
9772 return SDValue();
9773
9774 // Bail if MinSize is not set, and also for both ARM and Thumb mode we need
9775 // hwdiv support for this to be really profitable.
9776 if (!(MinSize && HasDivide))
9777 return SDValue();
9778
9779 // ARM mode is a bit simpler than Thumb: we can handle large power
9780 // of 2 immediates with 1 mov instruction; no further checks required,
9781 // just return the sdiv node.
9782 if (!ST.isThumb())
9783 return SDValue(N, 0);
9784
9785 // In Thumb mode, immediates larger than 128 need a wide 4-byte MOV,
9786 // and thus lose the code size benefits of a MOVS that requires only 2.
9787 // TargetTransformInfo and 'getIntImmCodeSizeCost' could be helpful here,
9788 // but as it's doing exactly this, it's not worth the trouble to get TTI.
9789 if (Divisor.sgt(128))
9790 return SDValue();
9791
9792 return SDValue(N, 0);
9793}
9794
9795SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
9796 bool Signed) const {
9797 assert(Op.getValueType() == MVT::i32 &&
9798 "unexpected type for custom lowering DIV");
9799 SDLoc dl(Op);
9800
9801 SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
9802 DAG.getEntryNode(), Op.getOperand(1));
9803
9804 return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9805}
9806
9808 SDLoc DL(N);
9809 SDValue Op = N->getOperand(1);
9810 if (N->getValueType(0) == MVT::i32)
9811 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
9812 SDValue Lo, Hi;
9813 std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32);
9814 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
9815 DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
9816}
9817
9818void ARMTargetLowering::ExpandDIV_Windows(
9819 SDValue Op, SelectionDAG &DAG, bool Signed,
9821 const auto &DL = DAG.getDataLayout();
9822
9823 assert(Op.getValueType() == MVT::i64 &&
9824 "unexpected type for custom lowering DIV");
9825 SDLoc dl(Op);
9826
9827 SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
9828
9829 SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9830
9831 SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
9832 SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
9833 DAG.getConstant(32, dl, getPointerTy(DL)));
9834 Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper);
9835
9836 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lower, Upper));
9837}
9838
9839std::pair<SDValue, SDValue>
9840ARMTargetLowering::LowerAEABIUnalignedLoad(SDValue Op,
9841 SelectionDAG &DAG) const {
9842 // If we have an unaligned load from a i32 or i64 that would normally be
9843 // split into separate ldrb's, we can use the __aeabi_uread4/__aeabi_uread8
9844 // functions instead.
9845 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9846 EVT MemVT = LD->getMemoryVT();
9847 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9848 return std::make_pair(SDValue(), SDValue());
9849
9850 const auto &MF = DAG.getMachineFunction();
9851 unsigned AS = LD->getAddressSpace();
9852 Align Alignment = LD->getAlign();
9853 const DataLayout &DL = DAG.getDataLayout();
9854 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9855 RTLIB::Libcall LC =
9856 (MemVT == MVT::i32) ? RTLIB::AEABI_UREAD4 : RTLIB::AEABI_UREAD8;
9857
9858 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9859 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9860 MakeLibCallOptions Opts;
9861 SDLoc dl(Op);
9862
9863 auto Pair = makeLibCall(DAG, LC, MemVT.getSimpleVT(), LD->getBasePtr(),
9864 Opts, dl, LD->getChain());
9865
9866 // If necessary, extend the node to 64bit
9867 if (LD->getExtensionType() != ISD::NON_EXTLOAD) {
9868 unsigned ExtType = LD->getExtensionType() == ISD::SEXTLOAD
9871 SDValue EN = DAG.getNode(ExtType, dl, LD->getValueType(0), Pair.first);
9872 Pair.first = EN;
9873 }
9874 return Pair;
9875 }
9876
9877 // Default expand to individual loads
9878 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9879 return expandUnalignedLoad(LD, DAG);
9880 return std::make_pair(SDValue(), SDValue());
9881}
9882
9883SDValue ARMTargetLowering::LowerAEABIUnalignedStore(SDValue Op,
9884 SelectionDAG &DAG) const {
9885 // If we have an unaligned store to a i32 or i64 that would normally be
9886 // split into separate ldrb's, we can use the __aeabi_uwrite4/__aeabi_uwrite8
9887 // functions instead.
9888 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9889 EVT MemVT = ST->getMemoryVT();
9890 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9891 return SDValue();
9892
9893 const auto &MF = DAG.getMachineFunction();
9894 unsigned AS = ST->getAddressSpace();
9895 Align Alignment = ST->getAlign();
9896 const DataLayout &DL = DAG.getDataLayout();
9897 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9898 RTLIB::Libcall LC =
9899 (MemVT == MVT::i32) ? RTLIB::AEABI_UWRITE4 : RTLIB::AEABI_UWRITE8;
9900
9901 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9902 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9903
9904 SDLoc dl(Op);
9905
9906 // If necessary, trunc the value to 32bit
9907 SDValue StoreVal = ST->getOperand(1);
9908 if (ST->isTruncatingStore())
9909 StoreVal = DAG.getNode(ISD::TRUNCATE, dl, MemVT, ST->getOperand(1));
9910
9911 MakeLibCallOptions Opts;
9912 auto CallResult =
9913 makeLibCall(DAG, LC, MVT::isVoid, {StoreVal, ST->getBasePtr()}, Opts,
9914 dl, ST->getChain());
9915
9916 return CallResult.second;
9917 }
9918
9919 // Default expand to individual stores
9920 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9921 return expandUnalignedStore(ST, DAG);
9922 return SDValue();
9923}
9924
9926 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9927 EVT MemVT = LD->getMemoryVT();
9928 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9929 MemVT == MVT::v16i1) &&
9930 "Expected a predicate type!");
9931 assert(MemVT == Op.getValueType());
9932 assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
9933 "Expected a non-extending load");
9934 assert(LD->isUnindexed() && "Expected a unindexed load");
9935
9936 // The basic MVE VLDR on a v2i1/v4i1/v8i1 actually loads the entire 16bit
9937 // predicate, with the "v4i1" bits spread out over the 16 bits loaded. We
9938 // need to make sure that 8/4/2 bits are actually loaded into the correct
9939 // place, which means loading the value and then shuffling the values into
9940 // the bottom bits of the predicate.
9941 // Equally, VLDR for an v16i1 will actually load 32bits (so will be incorrect
9942 // for BE).
9943 // Speaking of BE, apparently the rest of llvm will assume a reverse order to
9944 // a natural VMSR(load), so needs to be reversed.
9945
9946 SDLoc dl(Op);
9947 SDValue Load = DAG.getExtLoad(
9948 ISD::EXTLOAD, dl, MVT::i32, LD->getChain(), LD->getBasePtr(),
9950 LD->getMemOperand());
9951 SDValue Val = Load;
9952 if (DAG.getDataLayout().isBigEndian())
9953 Val = DAG.getNode(ISD::SRL, dl, MVT::i32,
9954 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Load),
9955 DAG.getConstant(32 - MemVT.getSizeInBits(), dl, MVT::i32));
9956 SDValue Pred = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Val);
9957 if (MemVT != MVT::v16i1)
9958 Pred = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MemVT, Pred,
9959 DAG.getConstant(0, dl, MVT::i32));
9960 return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
9961}
9962
9963void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9964 SelectionDAG &DAG) const {
9965 LoadSDNode *LD = cast<LoadSDNode>(N);
9966 EVT MemVT = LD->getMemoryVT();
9967
9968 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
9969 !Subtarget->isThumb1Only() && LD->isVolatile() &&
9970 LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
9971 assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
9972 SDLoc dl(N);
9974 ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
9975 {LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
9976 SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
9977 SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
9978 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
9979 Results.append({Pair, Result.getValue(2)});
9980 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
9981 auto Pair = LowerAEABIUnalignedLoad(SDValue(N, 0), DAG);
9982 if (Pair.first) {
9983 Results.push_back(Pair.first);
9984 Results.push_back(Pair.second);
9985 }
9986 }
9987}
9988
9990 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9991 EVT MemVT = ST->getMemoryVT();
9992 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9993 MemVT == MVT::v16i1) &&
9994 "Expected a predicate type!");
9995 assert(MemVT == ST->getValue().getValueType());
9996 assert(!ST->isTruncatingStore() && "Expected a non-extending store");
9997 assert(ST->isUnindexed() && "Expected a unindexed store");
9998
9999 // Only store the v2i1 or v4i1 or v8i1 worth of bits, via a buildvector with
10000 // top bits unset and a scalar store.
10001 SDLoc dl(Op);
10002 SDValue Build = ST->getValue();
10003 if (MemVT != MVT::v16i1) {
10005 for (unsigned I = 0; I < MemVT.getVectorNumElements(); I++) {
10006 unsigned Elt = DAG.getDataLayout().isBigEndian()
10007 ? MemVT.getVectorNumElements() - I - 1
10008 : I;
10009 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Build,
10010 DAG.getConstant(Elt, dl, MVT::i32)));
10011 }
10012 for (unsigned I = MemVT.getVectorNumElements(); I < 16; I++)
10013 Ops.push_back(DAG.getUNDEF(MVT::i32));
10014 Build = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i1, Ops);
10015 }
10016 SDValue GRP = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Build);
10017 if (MemVT == MVT::v16i1 && DAG.getDataLayout().isBigEndian())
10018 GRP = DAG.getNode(ISD::SRL, dl, MVT::i32,
10019 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, GRP),
10020 DAG.getConstant(16, dl, MVT::i32));
10021 return DAG.getTruncStore(
10022 ST->getChain(), dl, GRP, ST->getBasePtr(),
10024 ST->getMemOperand());
10025}
10026
10027SDValue ARMTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG,
10028 const ARMSubtarget *Subtarget) const {
10029 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10030 EVT MemVT = ST->getMemoryVT();
10031
10032 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10033 !Subtarget->isThumb1Only() && ST->isVolatile() &&
10034 ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10035 assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
10036 SDNode *N = Op.getNode();
10037 SDLoc dl(N);
10038
10039 SDValue Lo = DAG.getNode(
10040 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10041 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
10042 MVT::i32));
10043 SDValue Hi = DAG.getNode(
10044 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10045 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
10046 MVT::i32));
10047
10048 return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
10049 {ST->getChain(), Lo, Hi, ST->getBasePtr()},
10050 MemVT, ST->getMemOperand());
10051 } else if (Subtarget->hasMVEIntegerOps() &&
10052 ((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10053 MemVT == MVT::v16i1))) {
10054 return LowerPredicateStore(Op, DAG);
10055 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10056 return LowerAEABIUnalignedStore(Op, DAG);
10057 }
10058 return SDValue();
10059}
10060
10061static bool isZeroVector(SDValue N) {
10062 return (ISD::isBuildVectorAllZeros(N.getNode()) ||
10063 (N->getOpcode() == ARMISD::VMOVIMM &&
10064 isNullConstant(N->getOperand(0))));
10065}
10066
10069 MVT VT = Op.getSimpleValueType();
10070 SDValue Mask = N->getMask();
10071 SDValue PassThru = N->getPassThru();
10072 SDLoc dl(Op);
10073
10074 if (isZeroVector(PassThru))
10075 return Op;
10076
10077 // MVE Masked loads use zero as the passthru value. Here we convert undef to
10078 // zero too, and other values are lowered to a select.
10079 SDValue ZeroVec = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
10080 DAG.getTargetConstant(0, dl, MVT::i32));
10081 SDValue NewLoad = DAG.getMaskedLoad(
10082 VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask, ZeroVec,
10083 N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
10084 N->getExtensionType(), N->isExpandingLoad());
10085 SDValue Combo = NewLoad;
10086 bool PassThruIsCastZero = (PassThru.getOpcode() == ISD::BITCAST ||
10087 PassThru.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
10088 isZeroVector(PassThru->getOperand(0));
10089 if (!PassThru.isUndef() && !PassThruIsCastZero)
10090 Combo = DAG.getNode(ISD::VSELECT, dl, VT, Mask, NewLoad, PassThru);
10091 return DAG.getMergeValues({Combo, NewLoad.getValue(1)}, dl);
10092}
10093
10095 const ARMSubtarget *ST) {
10096 if (!ST->hasMVEIntegerOps())
10097 return SDValue();
10098
10099 SDLoc dl(Op);
10100 unsigned BaseOpcode = 0;
10101 switch (Op->getOpcode()) {
10102 default: llvm_unreachable("Expected VECREDUCE opcode");
10103 case ISD::VECREDUCE_FADD: BaseOpcode = ISD::FADD; break;
10104 case ISD::VECREDUCE_FMUL: BaseOpcode = ISD::FMUL; break;
10105 case ISD::VECREDUCE_MUL: BaseOpcode = ISD::MUL; break;
10106 case ISD::VECREDUCE_AND: BaseOpcode = ISD::AND; break;
10107 case ISD::VECREDUCE_OR: BaseOpcode = ISD::OR; break;
10108 case ISD::VECREDUCE_XOR: BaseOpcode = ISD::XOR; break;
10109 case ISD::VECREDUCE_FMAX: BaseOpcode = ISD::FMAXNUM; break;
10110 case ISD::VECREDUCE_FMIN: BaseOpcode = ISD::FMINNUM; break;
10111 }
10112
10113 SDValue Op0 = Op->getOperand(0);
10114 EVT VT = Op0.getValueType();
10115 EVT EltVT = VT.getVectorElementType();
10116 unsigned NumElts = VT.getVectorNumElements();
10117 unsigned NumActiveLanes = NumElts;
10118
10119 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10120 NumActiveLanes == 2) &&
10121 "Only expected a power 2 vector size");
10122
10123 // Use Mul(X, Rev(X)) until 4 items remain. Going down to 4 vector elements
10124 // allows us to easily extract vector elements from the lanes.
10125 while (NumActiveLanes > 4) {
10126 unsigned RevOpcode = NumActiveLanes == 16 ? ARMISD::VREV16 : ARMISD::VREV32;
10127 SDValue Rev = DAG.getNode(RevOpcode, dl, VT, Op0);
10128 Op0 = DAG.getNode(BaseOpcode, dl, VT, Op0, Rev);
10129 NumActiveLanes /= 2;
10130 }
10131
10132 SDValue Res;
10133 if (NumActiveLanes == 4) {
10134 // The remaining 4 elements are summed sequentially
10135 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10136 DAG.getConstant(0 * NumElts / 4, dl, MVT::i32));
10137 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10138 DAG.getConstant(1 * NumElts / 4, dl, MVT::i32));
10139 SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10140 DAG.getConstant(2 * NumElts / 4, dl, MVT::i32));
10141 SDValue Ext3 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10142 DAG.getConstant(3 * NumElts / 4, dl, MVT::i32));
10143 SDValue Res0 = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10144 SDValue Res1 = DAG.getNode(BaseOpcode, dl, EltVT, Ext2, Ext3, Op->getFlags());
10145 Res = DAG.getNode(BaseOpcode, dl, EltVT, Res0, Res1, Op->getFlags());
10146 } else {
10147 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10148 DAG.getConstant(0, dl, MVT::i32));
10149 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10150 DAG.getConstant(1, dl, MVT::i32));
10151 Res = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10152 }
10153
10154 // Result type may be wider than element type.
10155 if (EltVT != Op->getValueType(0))
10156 Res = DAG.getNode(ISD::ANY_EXTEND, dl, Op->getValueType(0), Res);
10157 return Res;
10158}
10159
10161 const ARMSubtarget *ST) {
10162 if (!ST->hasMVEFloatOps())
10163 return SDValue();
10164 return LowerVecReduce(Op, DAG, ST);
10165}
10166
10168 const ARMSubtarget *ST) {
10169 if (!ST->hasNEON())
10170 return SDValue();
10171
10172 SDLoc dl(Op);
10173 SDValue Op0 = Op->getOperand(0);
10174 EVT VT = Op0.getValueType();
10175 EVT EltVT = VT.getVectorElementType();
10176
10177 unsigned PairwiseIntrinsic = 0;
10178 switch (Op->getOpcode()) {
10179 default:
10180 llvm_unreachable("Expected VECREDUCE opcode");
10182 PairwiseIntrinsic = Intrinsic::arm_neon_vpminu;
10183 break;
10185 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxu;
10186 break;
10188 PairwiseIntrinsic = Intrinsic::arm_neon_vpmins;
10189 break;
10191 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxs;
10192 break;
10193 }
10194 SDValue PairwiseOp = DAG.getConstant(PairwiseIntrinsic, dl, MVT::i32);
10195
10196 unsigned NumElts = VT.getVectorNumElements();
10197 unsigned NumActiveLanes = NumElts;
10198
10199 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10200 NumActiveLanes == 2) &&
10201 "Only expected a power 2 vector size");
10202
10203 // Split 128-bit vectors, since vpmin/max takes 2 64-bit vectors.
10204 if (VT.is128BitVector()) {
10205 SDValue Lo, Hi;
10206 std::tie(Lo, Hi) = DAG.SplitVector(Op0, dl);
10207 VT = Lo.getValueType();
10208 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Lo, Hi});
10209 NumActiveLanes /= 2;
10210 }
10211
10212 // Use pairwise reductions until one lane remains
10213 while (NumActiveLanes > 1) {
10214 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Op0, Op0});
10215 NumActiveLanes /= 2;
10216 }
10217
10218 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10219 DAG.getConstant(0, dl, MVT::i32));
10220
10221 // Result type may be wider than element type.
10222 if (EltVT != Op.getValueType()) {
10223 unsigned Extend = 0;
10224 switch (Op->getOpcode()) {
10225 default:
10226 llvm_unreachable("Expected VECREDUCE opcode");
10229 Extend = ISD::ZERO_EXTEND;
10230 break;
10233 Extend = ISD::SIGN_EXTEND;
10234 break;
10235 }
10236 Res = DAG.getNode(Extend, dl, Op.getValueType(), Res);
10237 }
10238 return Res;
10239}
10240
10242 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering()))
10243 // Acquire/Release load/store is not legal for targets without a dmb or
10244 // equivalent available.
10245 return SDValue();
10246
10247 // Monotonic load/store is legal for all targets.
10248 return Op;
10249}
10250
10253 SelectionDAG &DAG,
10254 const ARMSubtarget *Subtarget) {
10255 SDLoc DL(N);
10256 // Under Power Management extensions, the cycle-count is:
10257 // mrc p15, #0, <Rt>, c9, c13, #0
10258 SDValue Ops[] = { N->getOperand(0), // Chain
10259 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
10260 DAG.getTargetConstant(15, DL, MVT::i32),
10261 DAG.getTargetConstant(0, DL, MVT::i32),
10262 DAG.getTargetConstant(9, DL, MVT::i32),
10263 DAG.getTargetConstant(13, DL, MVT::i32),
10264 DAG.getTargetConstant(0, DL, MVT::i32)
10265 };
10266
10267 SDValue Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
10268 DAG.getVTList(MVT::i32, MVT::Other), Ops);
10269 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Cycles32,
10270 DAG.getConstant(0, DL, MVT::i32)));
10271 Results.push_back(Cycles32.getValue(1));
10272}
10273
10275 SDValue V1) {
10276 SDLoc dl(V0.getNode());
10277 SDValue RegClass =
10278 DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
10279 SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
10280 SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
10281 const SDValue Ops[] = {RegClass, V0, SubReg0, V1, SubReg1};
10282 return SDValue(
10283 DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
10284}
10285
10287 SDLoc dl(V.getNode());
10288 auto [VLo, VHi] = DAG.SplitScalar(V, dl, MVT::i32, MVT::i32);
10289 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10290 if (isBigEndian)
10291 std::swap(VLo, VHi);
10292 return createGPRPairNode2xi32(DAG, VLo, VHi);
10293}
10294
10297 SelectionDAG &DAG) {
10298 assert(N->getValueType(0) == MVT::i64 &&
10299 "AtomicCmpSwap on types less than 64 should be legal");
10300 SDValue Ops[] = {
10301 createGPRPairNode2xi32(DAG, N->getOperand(1),
10302 DAG.getUNDEF(MVT::i32)), // pointer, temp
10303 createGPRPairNodei64(DAG, N->getOperand(2)), // expected
10304 createGPRPairNodei64(DAG, N->getOperand(3)), // new
10305 N->getOperand(0), // chain in
10306 };
10307 SDNode *CmpSwap = DAG.getMachineNode(
10308 ARM::CMP_SWAP_64, SDLoc(N),
10309 DAG.getVTList(MVT::Untyped, MVT::Untyped, MVT::Other), Ops);
10310
10311 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
10312 DAG.setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
10313
10314 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10315
10316 SDValue Lo =
10317 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0,
10318 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10319 SDValue Hi =
10320 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1,
10321 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10322 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i64, Lo, Hi));
10323 Results.push_back(SDValue(CmpSwap, 2));
10324}
10325
10326SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
10327 SDLoc dl(Op);
10328 EVT VT = Op.getValueType();
10329 SDValue Chain = Op.getOperand(0);
10330 SDValue LHS = Op.getOperand(1);
10331 SDValue RHS = Op.getOperand(2);
10332 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
10333 bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
10334
10335 // If we don't have instructions of this float type then soften to a libcall
10336 // and use SETCC instead.
10337 if (isUnsupportedFloatingType(LHS.getValueType())) {
10338 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS,
10339 Chain, IsSignaling);
10340 if (!RHS.getNode()) {
10341 RHS = DAG.getConstant(0, dl, LHS.getValueType());
10342 CC = ISD::SETNE;
10343 }
10344 SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
10345 DAG.getCondCode(CC));
10346 return DAG.getMergeValues({Result, Chain}, dl);
10347 }
10348
10349 ARMCC::CondCodes CondCode, CondCode2;
10350 FPCCToARMCC(CC, CondCode, CondCode2);
10351
10352 SDValue True = DAG.getConstant(1, dl, VT);
10353 SDValue False = DAG.getConstant(0, dl, VT);
10354 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
10355 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
10356 SDValue Result = getCMOV(dl, VT, False, True, ARMcc, Cmp, DAG);
10357 if (CondCode2 != ARMCC::AL) {
10358 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
10359 Result = getCMOV(dl, VT, Result, True, ARMcc, Cmp, DAG);
10360 }
10361 return DAG.getMergeValues({Result, Chain}, dl);
10362}
10363
10364SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
10365 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
10366
10367 EVT VT = getPointerTy(DAG.getDataLayout());
10368 int FI = MFI.CreateFixedObject(4, 0, false);
10369 return DAG.getFrameIndex(FI, VT);
10370}
10371
10372SDValue ARMTargetLowering::LowerFP_TO_BF16(SDValue Op,
10373 SelectionDAG &DAG) const {
10374 SDLoc DL(Op);
10375 MakeLibCallOptions CallOptions;
10376 MVT SVT = Op.getOperand(0).getSimpleValueType();
10377 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, MVT::bf16);
10378 SDValue Res =
10379 makeLibCall(DAG, LC, MVT::f32, Op.getOperand(0), CallOptions, DL).first;
10380 return DAG.getBitcast(MVT::i32, Res);
10381}
10382
10383SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
10384 SDLoc dl(Op);
10385 SDValue LHS = Op.getOperand(0);
10386 SDValue RHS = Op.getOperand(1);
10387
10388 // Determine if this is signed or unsigned comparison
10389 bool IsSigned = (Op.getOpcode() == ISD::SCMP);
10390
10391 // Special case for Thumb1 UCMP only
10392 if (!IsSigned && Subtarget->isThumb1Only()) {
10393 // For Thumb unsigned comparison, use this sequence:
10394 // subs r2, r0, r1 ; r2 = LHS - RHS, sets flags
10395 // sbc r2, r2 ; r2 = r2 - r2 - !carry
10396 // cmp r1, r0 ; compare RHS with LHS
10397 // sbc r1, r1 ; r1 = r1 - r1 - !carry
10398 // subs r0, r2, r1 ; r0 = r2 - r1 (final result)
10399
10400 // First subtraction: LHS - RHS
10401 SDValue Sub1WithFlags = DAG.getNode(
10402 ARMISD::SUBC, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10403 SDValue Sub1Result = Sub1WithFlags.getValue(0);
10404 SDValue Flags1 = Sub1WithFlags.getValue(1);
10405
10406 // SUBE: Sub1Result - Sub1Result - !carry
10407 // This gives 0 if LHS >= RHS (unsigned), -1 if LHS < RHS (unsigned)
10408 SDValue Sbc1 =
10409 DAG.getNode(ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT),
10410 Sub1Result, Sub1Result, Flags1);
10411 SDValue Sbc1Result = Sbc1.getValue(0);
10412
10413 // Second comparison: RHS vs LHS (reverse comparison)
10414 SDValue CmpFlags = DAG.getNode(ARMISD::CMP, dl, FlagsVT, RHS, LHS);
10415
10416 // SUBE: RHS - RHS - !carry
10417 // This gives 0 if RHS <= LHS (unsigned), -1 if RHS > LHS (unsigned)
10418 SDValue Sbc2 = DAG.getNode(
10419 ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT), RHS, RHS, CmpFlags);
10420 SDValue Sbc2Result = Sbc2.getValue(0);
10421
10422 // Final subtraction: Sbc1Result - Sbc2Result (no flags needed)
10423 SDValue Result =
10424 DAG.getNode(ISD::SUB, dl, MVT::i32, Sbc1Result, Sbc2Result);
10425 if (Op.getValueType() != MVT::i32)
10426 Result = DAG.getSExtOrTrunc(Result, dl, Op.getValueType());
10427
10428 return Result;
10429 }
10430
10431 // For the ARM assembly pattern:
10432 // subs r0, r0, r1 ; subtract RHS from LHS and set flags
10433 // movgt r0, #1 ; if LHS > RHS, set result to 1 (GT for signed, HI for
10434 // unsigned) mvnlt r0, #0 ; if LHS < RHS, set result to -1 (LT for
10435 // signed, LO for unsigned)
10436 // ; if LHS == RHS, result remains 0 from the subs
10437
10438 // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
10439 unsigned Opcode = ARMISD::SUBC;
10440
10441 // Check if RHS is a subtraction against 0: (0 - X)
10442 if (RHS.getOpcode() == ISD::SUB) {
10443 SDValue SubLHS = RHS.getOperand(0);
10444 SDValue SubRHS = RHS.getOperand(1);
10445
10446 // Check if it's 0 - X
10447 if (isNullConstant(SubLHS)) {
10448 bool CanUseAdd = false;
10449 if (IsSigned) {
10450 // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
10451 if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
10453 .isMinSignedValue()) {
10454 CanUseAdd = true;
10455 }
10456 } else {
10457 // For UCMP: only if X is known to never be zero
10458 if (DAG.isKnownNeverZero(SubRHS)) {
10459 CanUseAdd = true;
10460 }
10461 }
10462
10463 if (CanUseAdd) {
10464 Opcode = ARMISD::ADDC;
10465 RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
10466 // LHS - (0 - X)
10467 }
10468 }
10469 }
10470
10471 // Generate the operation with flags
10472 SDValue OpWithFlags =
10473 DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10474
10475 SDValue OpResult = OpWithFlags.getValue(0);
10476 SDValue Flags = OpWithFlags.getValue(1);
10477
10478 // Constants for conditional moves
10479 SDValue One = DAG.getConstant(1, dl, MVT::i32);
10480 SDValue MinusOne = DAG.getAllOnesConstant(dl, MVT::i32);
10481
10482 // Select condition codes based on signed vs unsigned
10483 ARMCC::CondCodes GTCond = IsSigned ? ARMCC::GT : ARMCC::HI;
10484 ARMCC::CondCodes LTCond = IsSigned ? ARMCC::LT : ARMCC::LO;
10485
10486 // First conditional move: if greater than, set to 1
10487 SDValue GTCondValue = DAG.getConstant(GTCond, dl, MVT::i32);
10488 SDValue Result1 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, OpResult, One,
10489 GTCondValue, Flags);
10490
10491 // Second conditional move: if less than, set to -1
10492 SDValue LTCondValue = DAG.getConstant(LTCond, dl, MVT::i32);
10493 SDValue Result2 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, Result1, MinusOne,
10494 LTCondValue, Flags);
10495
10496 if (Op.getValueType() != MVT::i32)
10497 Result2 = DAG.getSExtOrTrunc(Result2, dl, Op.getValueType());
10498
10499 return Result2;
10500}
10501
10503 LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
10504 switch (Op.getOpcode()) {
10505 default: llvm_unreachable("Don't know how to custom lower this!");
10506 case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
10507 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
10508 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
10509 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
10510 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
10511 case ISD::SELECT: return LowerSELECT(Op, DAG);
10512 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10513 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
10514 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
10515 case ISD::BR_JT: return LowerBR_JT(Op, DAG);
10516 case ISD::VASTART: return LowerVASTART(Op, DAG);
10517 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget);
10518 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget);
10519 case ISD::SINT_TO_FP:
10520 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
10523 case ISD::FP_TO_SINT:
10524 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
10526 case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG, Subtarget);
10527 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
10528 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
10529 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
10530 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
10531 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
10532 case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
10533 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
10534 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
10535 Subtarget);
10536 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);
10537 case ISD::SHL:
10538 case ISD::SRL:
10539 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget);
10540 case ISD::SREM: return LowerREM(Op.getNode(), DAG);
10541 case ISD::UREM: return LowerREM(Op.getNode(), DAG);
10542 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
10543 case ISD::SRL_PARTS:
10544 case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
10545 case ISD::CTTZ:
10546 case ISD::CTTZ_ZERO_POISON: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
10547 case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
10548 case ISD::SETCC: return LowerVSETCC(Op, DAG, Subtarget);
10549 case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
10550 case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
10551 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
10552 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
10553 case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG, Subtarget);
10554 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
10555 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
10556 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
10557 case ISD::TRUNCATE: return LowerTruncate(Op.getNode(), DAG, Subtarget);
10558 case ISD::SIGN_EXTEND:
10559 case ISD::ZERO_EXTEND: return LowerVectorExtend(Op.getNode(), DAG, Subtarget);
10560 case ISD::GET_ROUNDING: return LowerGET_ROUNDING(Op, DAG);
10561 case ISD::SET_ROUNDING: return LowerSET_ROUNDING(Op, DAG);
10562 case ISD::SET_FPMODE:
10563 return LowerSET_FPMODE(Op, DAG);
10564 case ISD::RESET_FPMODE:
10565 return LowerRESET_FPMODE(Op, DAG);
10566 case ISD::MUL: return LowerMUL(Op, DAG);
10567 case ISD::SDIV:
10568 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10569 !Op.getValueType().isVector())
10570 return LowerDIV_Windows(Op, DAG, /* Signed */ true);
10571 return LowerSDIV(Op, DAG, Subtarget);
10572 case ISD::UDIV:
10573 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10574 !Op.getValueType().isVector())
10575 return LowerDIV_Windows(Op, DAG, /* Signed */ false);
10576 return LowerUDIV(Op, DAG, Subtarget);
10577 case ISD::UADDO_CARRY:
10578 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, false /*unsigned*/);
10579 case ISD::USUBO_CARRY:
10580 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, false /*unsigned*/);
10581 case ISD::SADDO_CARRY:
10582 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, true /*signed*/);
10583 case ISD::SSUBO_CARRY:
10584 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, true /*signed*/);
10585 case ISD::UADDO:
10586 case ISD::USUBO:
10587 case ISD::UMULO:
10588 case ISD::SADDO:
10589 case ISD::SSUBO:
10590 case ISD::SMULO:
10591 return LowerALUO(Op, DAG);
10592 case ISD::SADDSAT:
10593 case ISD::SSUBSAT:
10594 case ISD::UADDSAT:
10595 case ISD::USUBSAT:
10596 return LowerADDSUBSAT(Op, DAG, Subtarget);
10597 case ISD::LOAD: {
10598 auto *LD = cast<LoadSDNode>(Op);
10599 EVT MemVT = LD->getMemoryVT();
10600 if (Subtarget->hasMVEIntegerOps() &&
10601 (MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10602 MemVT == MVT::v16i1))
10603 return LowerPredicateLoad(Op, DAG);
10604
10605 auto Pair = LowerAEABIUnalignedLoad(Op, DAG);
10606 if (Pair.first)
10607 return DAG.getMergeValues({Pair.first, Pair.second}, SDLoc(Pair.first));
10608 return SDValue();
10609 }
10610 case ISD::STORE:
10611 return LowerSTORE(Op, DAG, Subtarget);
10612 case ISD::MLOAD:
10613 return LowerMLOAD(Op, DAG);
10614 case ISD::VECREDUCE_MUL:
10615 case ISD::VECREDUCE_AND:
10616 case ISD::VECREDUCE_OR:
10617 case ISD::VECREDUCE_XOR:
10618 return LowerVecReduce(Op, DAG, Subtarget);
10623 return LowerVecReduceF(Op, DAG, Subtarget);
10628 return LowerVecReduceMinMax(Op, DAG, Subtarget);
10629 case ISD::ATOMIC_LOAD:
10630 case ISD::ATOMIC_STORE:
10631 return LowerAtomicLoadStore(Op, DAG);
10632 case ISD::SDIVREM:
10633 case ISD::UDIVREM: return LowerDivRem(Op, DAG);
10635 if (getTargetMachine().getTargetTriple().isOSWindows())
10636 return LowerDYNAMIC_STACKALLOC(Op, DAG);
10637 llvm_unreachable("Don't know how to custom lower this!");
10639 case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
10641 case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
10642 case ISD::STRICT_FSETCC:
10643 case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
10644 case ISD::SPONENTRY:
10645 return LowerSPONENTRY(Op, DAG);
10646 case ISD::FP_TO_BF16:
10647 return LowerFP_TO_BF16(Op, DAG);
10648 case ARMISD::WIN__DBZCHK: return SDValue();
10649 case ISD::UCMP:
10650 case ISD::SCMP:
10651 return LowerCMP(Op, DAG);
10652 case ISD::ABS:
10653 return LowerABS(Op, DAG);
10654 case ISD::STRICT_LROUND:
10656 case ISD::STRICT_LRINT:
10657 case ISD::STRICT_LLRINT: {
10658 assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10659 Op.getOperand(1).getValueType() == MVT::bf16) &&
10660 "Expected custom lowering of rounding operations only for f16");
10661 SDLoc DL(Op);
10662 SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10663 {Op.getOperand(0), Op.getOperand(1)});
10664 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10665 {Ext.getValue(1), Ext.getValue(0)});
10666 }
10667 }
10668}
10669
10671 SelectionDAG &DAG) {
10672 unsigned IntNo = N->getConstantOperandVal(0);
10673 unsigned Opc = 0;
10674 if (IntNo == Intrinsic::arm_smlald)
10675 Opc = ARMISD::SMLALD;
10676 else if (IntNo == Intrinsic::arm_smlaldx)
10677 Opc = ARMISD::SMLALDX;
10678 else if (IntNo == Intrinsic::arm_smlsld)
10679 Opc = ARMISD::SMLSLD;
10680 else if (IntNo == Intrinsic::arm_smlsldx)
10681 Opc = ARMISD::SMLSLDX;
10682 else
10683 return;
10684
10685 SDLoc dl(N);
10686 SDValue Lo, Hi;
10687 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32);
10688
10689 SDValue LongMul = DAG.getNode(Opc, dl,
10690 DAG.getVTList(MVT::i32, MVT::i32),
10691 N->getOperand(1), N->getOperand(2),
10692 Lo, Hi);
10693 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
10694 LongMul.getValue(0), LongMul.getValue(1)));
10695}
10696
10697/// ReplaceNodeResults - Replace the results of node with an illegal result
10698/// type with new values built out of custom code.
10701 SelectionDAG &DAG) const {
10702 SDValue Res;
10703 switch (N->getOpcode()) {
10704 default:
10705 llvm_unreachable("Don't know how to custom expand this!");
10706 case ISD::READ_REGISTER:
10708 break;
10709 case ISD::BITCAST:
10710 Res = ExpandBITCAST(N, DAG, Subtarget);
10711 break;
10712 case ISD::SRL:
10713 case ISD::SRA:
10714 case ISD::SHL:
10715 Res = Expand64BitShift(N, DAG, Subtarget);
10716 break;
10717 case ISD::SREM:
10718 case ISD::UREM:
10719 Res = LowerREM(N, DAG);
10720 break;
10721 case ISD::SDIVREM:
10722 case ISD::UDIVREM:
10723 Res = LowerDivRem(SDValue(N, 0), DAG);
10724 assert(Res.getNumOperands() == 2 && "DivRem needs two values");
10725 Results.push_back(Res.getValue(0));
10726 Results.push_back(Res.getValue(1));
10727 return;
10728 case ISD::SADDSAT:
10729 case ISD::SSUBSAT:
10730 case ISD::UADDSAT:
10731 case ISD::USUBSAT:
10732 Res = LowerADDSUBSAT(SDValue(N, 0), DAG, Subtarget);
10733 break;
10735 ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
10736 return;
10737 case ISD::UDIV:
10738 case ISD::SDIV:
10739 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
10740 "can only expand DIV on Windows");
10741 return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
10742 Results);
10745 return;
10747 return ReplaceLongIntrinsic(N, Results, DAG);
10748 case ISD::LOAD:
10749 LowerLOAD(N, Results, DAG);
10750 break;
10751 case ISD::STORE:
10752 Res = LowerAEABIUnalignedStore(SDValue(N, 0), DAG);
10753 break;
10754 case ISD::TRUNCATE:
10755 Res = LowerTruncate(N, DAG, Subtarget);
10756 break;
10757 case ISD::SIGN_EXTEND:
10758 case ISD::ZERO_EXTEND:
10759 Res = LowerVectorExtend(N, DAG, Subtarget);
10760 break;
10763 Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
10764 break;
10765 }
10766 if (Res.getNode())
10767 Results.push_back(Res);
10768}
10769
10770//===----------------------------------------------------------------------===//
10771// ARM Scheduler Hooks
10772//===----------------------------------------------------------------------===//
10773
10774/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and
10775/// registers the function context.
10776void ARMTargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
10778 MachineBasicBlock *DispatchBB,
10779 int FI) const {
10780 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
10781 "ROPI/RWPI not currently supported with SjLj");
10782 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10783 DebugLoc dl = MI.getDebugLoc();
10784 MachineFunction *MF = MBB->getParent();
10785 MachineRegisterInfo *MRI = &MF->getRegInfo();
10788 const Function &F = MF->getFunction();
10789
10790 bool isThumb = Subtarget->isThumb();
10791 bool isThumb2 = Subtarget->isThumb2();
10792
10793 unsigned PCLabelId = AFI->createPICLabelUId();
10794 unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8;
10796 ARMConstantPoolMBB::Create(F.getContext(), DispatchBB, PCLabelId, PCAdj);
10797 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
10798
10799 const TargetRegisterClass *TRC = isThumb ? &ARM::tGPRRegClass
10800 : &ARM::GPRRegClass;
10801
10802 // Grab constant pool and fixed stack memory operands.
10803 MachineMemOperand *CPMMO =
10806
10807 MachineMemOperand *FIMMOSt =
10810
10811 // Load the address of the dispatch MBB into the jump buffer.
10812 if (isThumb2) {
10813 // Incoming value: jbuf
10814 // ldr.n r5, LCPI1_1
10815 // orr r5, r5, #1
10816 // add r5, pc
10817 // str r5, [$jbuf, #+4] ; &jbuf[1]
10818 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10819 BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1)
10821 .addMemOperand(CPMMO)
10823 // Set the low bit because of thumb mode.
10824 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10825 BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2)
10826 .addReg(NewVReg1, RegState::Kill)
10827 .addImm(0x01)
10829 .add(condCodeOp());
10830 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10831 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3)
10832 .addReg(NewVReg2, RegState::Kill)
10833 .addImm(PCLabelId);
10834 BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12))
10835 .addReg(NewVReg3, RegState::Kill)
10836 .addFrameIndex(FI)
10837 .addImm(36) // &jbuf[1] :: pc
10838 .addMemOperand(FIMMOSt)
10840 } else if (isThumb) {
10841 // Incoming value: jbuf
10842 // ldr.n r1, LCPI1_4
10843 // add r1, pc
10844 // mov r2, #1
10845 // orrs r1, r2
10846 // add r2, $jbuf, #+4 ; &jbuf[1]
10847 // str r1, [r2]
10848 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10849 BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1)
10851 .addMemOperand(CPMMO)
10853 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10854 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2)
10855 .addReg(NewVReg1, RegState::Kill)
10856 .addImm(PCLabelId);
10857 // Set the low bit because of thumb mode.
10858 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10859 BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3)
10860 .addReg(ARM::CPSR, RegState::Define)
10861 .addImm(1)
10863 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10864 BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4)
10865 .addReg(ARM::CPSR, RegState::Define)
10866 .addReg(NewVReg2, RegState::Kill)
10867 .addReg(NewVReg3, RegState::Kill)
10869 Register NewVReg5 = MRI->createVirtualRegister(TRC);
10870 BuildMI(*MBB, MI, dl, TII->get(ARM::tADDframe), NewVReg5)
10871 .addFrameIndex(FI)
10872 .addImm(36); // &jbuf[1] :: pc
10873 BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi))
10874 .addReg(NewVReg4, RegState::Kill)
10875 .addReg(NewVReg5, RegState::Kill)
10876 .addImm(0)
10877 .addMemOperand(FIMMOSt)
10879 } else {
10880 // Incoming value: jbuf
10881 // ldr r1, LCPI1_1
10882 // add r1, pc, r1
10883 // str r1, [$jbuf, #+4] ; &jbuf[1]
10884 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10885 BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1)
10887 .addImm(0)
10888 .addMemOperand(CPMMO)
10890 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10891 BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
10892 .addReg(NewVReg1, RegState::Kill)
10893 .addImm(PCLabelId)
10895 BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
10896 .addReg(NewVReg2, RegState::Kill)
10897 .addFrameIndex(FI)
10898 .addImm(36) // &jbuf[1] :: pc
10899 .addMemOperand(FIMMOSt)
10901 }
10902}
10903
10904void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
10905 MachineBasicBlock *MBB) const {
10906 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10907 DebugLoc dl = MI.getDebugLoc();
10908 MachineFunction *MF = MBB->getParent();
10909 MachineRegisterInfo *MRI = &MF->getRegInfo();
10910 MachineFrameInfo &MFI = MF->getFrameInfo();
10911 int FI = MFI.getFunctionContextIndex();
10912
10913 const TargetRegisterClass *TRC = Subtarget->isThumb() ? &ARM::tGPRRegClass
10914 : &ARM::GPRnopcRegClass;
10915
10916 // Get a mapping of the call site numbers to all of the landing pads they're
10917 // associated with.
10918 DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2>> CallSiteNumToLPad;
10919 unsigned MaxCSNum = 0;
10920 for (MachineBasicBlock &BB : *MF) {
10921 if (!BB.isEHPad())
10922 continue;
10923
10924 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
10925 // pad.
10926 for (MachineInstr &II : BB) {
10927 if (!II.isEHLabel())
10928 continue;
10929
10930 MCSymbol *Sym = II.getOperand(0).getMCSymbol();
10931 if (!MF->hasCallSiteLandingPad(Sym)) continue;
10932
10933 SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
10934 for (unsigned Idx : CallSiteIdxs) {
10935 CallSiteNumToLPad[Idx].push_back(&BB);
10936 MaxCSNum = std::max(MaxCSNum, Idx);
10937 }
10938 break;
10939 }
10940 }
10941
10942 // Get an ordered list of the machine basic blocks for the jump table.
10943 std::vector<MachineBasicBlock*> LPadList;
10944 SmallPtrSet<MachineBasicBlock*, 32> InvokeBBs;
10945 LPadList.reserve(CallSiteNumToLPad.size());
10946 for (unsigned I = 1; I <= MaxCSNum; ++I) {
10947 SmallVectorImpl<MachineBasicBlock*> &MBBList = CallSiteNumToLPad[I];
10948 for (MachineBasicBlock *MBB : MBBList) {
10949 LPadList.push_back(MBB);
10950 InvokeBBs.insert_range(MBB->predecessors());
10951 }
10952 }
10953
10954 assert(!LPadList.empty() &&
10955 "No landing pad destinations for the dispatch jump table!");
10956
10957 // Create the jump table and associated information.
10958 MachineJumpTableInfo *JTI =
10959 MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline);
10960 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
10961
10962 // Create the MBBs for the dispatch code.
10963
10964 // Shove the dispatch's address into the return slot in the function context.
10965 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
10966 DispatchBB->setIsEHPad();
10967
10968 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
10969
10970 BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
10971 DispatchBB->addSuccessor(TrapBB);
10972
10973 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
10974 DispatchBB->addSuccessor(DispContBB);
10975
10976 // Insert and MBBs.
10977 MF->insert(MF->end(), DispatchBB);
10978 MF->insert(MF->end(), DispContBB);
10979 MF->insert(MF->end(), TrapBB);
10980
10981 // Insert code into the entry block that creates and registers the function
10982 // context.
10983 SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI);
10984
10985 MachineMemOperand *FIMMOLd = MF->getMachineMemOperand(
10988
10989 MachineInstrBuilder MIB;
10990 MIB = BuildMI(DispatchBB, dl, TII->get(ARM::Int_eh_sjlj_dispatchsetup));
10991
10992 const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
10993 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
10994
10995 // Add a register mask with no preserved registers. This results in all
10996 // registers being marked as clobbered. This can't work if the dispatch block
10997 // is in a Thumb1 function and is linked with ARM code which uses the FP
10998 // registers, as there is no way to preserve the FP registers in Thumb1 mode.
11000
11001 bool IsPositionIndependent = isPositionIndependent();
11002 unsigned NumLPads = LPadList.size();
11003 if (Subtarget->isThumb2()) {
11004 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11005 BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1)
11006 .addFrameIndex(FI)
11007 .addImm(4)
11008 .addMemOperand(FIMMOLd)
11010
11011 if (NumLPads < 256) {
11012 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri))
11013 .addReg(NewVReg1)
11014 .addImm(LPadList.size())
11016 } else {
11017 Register VReg1 = MRI->createVirtualRegister(TRC);
11018 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVi16), VReg1)
11019 .addImm(NumLPads & 0xFFFF)
11021
11022 unsigned VReg2 = VReg1;
11023 if ((NumLPads & 0xFFFF0000) != 0) {
11024 VReg2 = MRI->createVirtualRegister(TRC);
11025 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVTi16), VReg2)
11026 .addReg(VReg1)
11027 .addImm(NumLPads >> 16)
11029 }
11030
11031 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPrr))
11032 .addReg(NewVReg1)
11033 .addReg(VReg2)
11035 }
11036
11037 BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc))
11038 .addMBB(TrapBB)
11040 .addReg(ARM::CPSR);
11041
11042 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11043 BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT), NewVReg3)
11044 .addJumpTableIndex(MJTI)
11046
11047 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11048 BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg4)
11049 .addReg(NewVReg3, RegState::Kill)
11050 .addReg(NewVReg1)
11053 .add(condCodeOp());
11054
11055 BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT))
11056 .addReg(NewVReg4, RegState::Kill)
11057 .addReg(NewVReg1)
11058 .addJumpTableIndex(MJTI);
11059 } else if (Subtarget->isThumb()) {
11060 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11061 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1)
11062 .addFrameIndex(FI)
11063 .addImm(1)
11064 .addMemOperand(FIMMOLd)
11066
11067 if (NumLPads < 256) {
11068 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8))
11069 .addReg(NewVReg1)
11070 .addImm(NumLPads)
11072 } else {
11073 MachineConstantPool *ConstantPool = MF->getConstantPool();
11074 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11075 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11076
11077 // MachineConstantPool wants an explicit alignment.
11078 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11079 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11080
11081 Register VReg1 = MRI->createVirtualRegister(TRC);
11082 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRpci))
11083 .addReg(VReg1, RegState::Define)
11086 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPr))
11087 .addReg(NewVReg1)
11088 .addReg(VReg1)
11090 }
11091
11092 BuildMI(DispatchBB, dl, TII->get(ARM::tBcc))
11093 .addMBB(TrapBB)
11095 .addReg(ARM::CPSR);
11096
11097 Register NewVReg2 = MRI->createVirtualRegister(TRC);
11098 BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2)
11099 .addReg(ARM::CPSR, RegState::Define)
11100 .addReg(NewVReg1)
11101 .addImm(2)
11103
11104 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11105 BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3)
11106 .addJumpTableIndex(MJTI)
11108
11109 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11110 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4)
11111 .addReg(ARM::CPSR, RegState::Define)
11112 .addReg(NewVReg2, RegState::Kill)
11113 .addReg(NewVReg3)
11115
11116 MachineMemOperand *JTMMOLd =
11117 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11119
11120 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11121 BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5)
11122 .addReg(NewVReg4, RegState::Kill)
11123 .addImm(0)
11124 .addMemOperand(JTMMOLd)
11126
11127 unsigned NewVReg6 = NewVReg5;
11128 if (IsPositionIndependent) {
11129 NewVReg6 = MRI->createVirtualRegister(TRC);
11130 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6)
11131 .addReg(ARM::CPSR, RegState::Define)
11132 .addReg(NewVReg5, RegState::Kill)
11133 .addReg(NewVReg3)
11135 }
11136
11137 BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr))
11138 .addReg(NewVReg6, RegState::Kill)
11139 .addJumpTableIndex(MJTI);
11140 } else {
11141 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11142 BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1)
11143 .addFrameIndex(FI)
11144 .addImm(4)
11145 .addMemOperand(FIMMOLd)
11147
11148 if (NumLPads < 256) {
11149 BuildMI(DispatchBB, dl, TII->get(ARM::CMPri))
11150 .addReg(NewVReg1)
11151 .addImm(NumLPads)
11153 } else if (Subtarget->hasV6T2Ops() && isUInt<16>(NumLPads)) {
11154 Register VReg1 = MRI->createVirtualRegister(TRC);
11155 BuildMI(DispatchBB, dl, TII->get(ARM::MOVi16), VReg1)
11156 .addImm(NumLPads & 0xFFFF)
11158
11159 unsigned VReg2 = VReg1;
11160 if ((NumLPads & 0xFFFF0000) != 0) {
11161 VReg2 = MRI->createVirtualRegister(TRC);
11162 BuildMI(DispatchBB, dl, TII->get(ARM::MOVTi16), VReg2)
11163 .addReg(VReg1)
11164 .addImm(NumLPads >> 16)
11166 }
11167
11168 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11169 .addReg(NewVReg1)
11170 .addReg(VReg2)
11172 } else {
11173 MachineConstantPool *ConstantPool = MF->getConstantPool();
11174 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11175 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11176
11177 // MachineConstantPool wants an explicit alignment.
11178 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11179 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11180
11181 Register VReg1 = MRI->createVirtualRegister(TRC);
11182 BuildMI(DispatchBB, dl, TII->get(ARM::LDRcp))
11183 .addReg(VReg1, RegState::Define)
11185 .addImm(0)
11187 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11188 .addReg(NewVReg1)
11189 .addReg(VReg1, RegState::Kill)
11191 }
11192
11193 BuildMI(DispatchBB, dl, TII->get(ARM::Bcc))
11194 .addMBB(TrapBB)
11196 .addReg(ARM::CPSR);
11197
11198 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11199 BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg3)
11200 .addReg(NewVReg1)
11203 .add(condCodeOp());
11204 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11205 BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg4)
11206 .addJumpTableIndex(MJTI)
11208
11209 MachineMemOperand *JTMMOLd =
11210 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11212 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11213 BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg5)
11214 .addReg(NewVReg3, RegState::Kill)
11215 .addReg(NewVReg4)
11216 .addImm(0)
11217 .addMemOperand(JTMMOLd)
11219
11220 if (IsPositionIndependent) {
11221 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd))
11222 .addReg(NewVReg5, RegState::Kill)
11223 .addReg(NewVReg4)
11224 .addJumpTableIndex(MJTI);
11225 } else {
11226 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTr))
11227 .addReg(NewVReg5, RegState::Kill)
11228 .addJumpTableIndex(MJTI);
11229 }
11230 }
11231
11232 // Add the jump table entries as successors to the MBB.
11233 SmallPtrSet<MachineBasicBlock*, 8> SeenMBBs;
11234 for (MachineBasicBlock *CurMBB : LPadList) {
11235 if (SeenMBBs.insert(CurMBB).second)
11236 DispContBB->addSuccessor(CurMBB);
11237 }
11238
11239 // N.B. the order the invoke BBs are processed in doesn't matter here.
11240 const MCPhysReg *SavedRegs = RI.getCalleeSavedRegs(MF);
11242 for (MachineBasicBlock *BB : InvokeBBs) {
11243
11244 // Remove the landing pad successor from the invoke block and replace it
11245 // with the new dispatch block.
11246 SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
11247 while (!Successors.empty()) {
11248 MachineBasicBlock *SMBB = Successors.pop_back_val();
11249 if (SMBB->isEHPad()) {
11250 BB->removeSuccessor(SMBB);
11251 MBBLPads.push_back(SMBB);
11252 }
11253 }
11254
11255 BB->addSuccessor(DispatchBB, BranchProbability::getZero());
11256 BB->normalizeSuccProbs();
11257
11258 // Find the invoke call and mark all of the callee-saved registers as
11259 // 'implicit defined' so that they're spilled. This prevents code from
11260 // moving instructions to before the EH block, where they will never be
11261 // executed.
11263 II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
11264 if (!II->isCall()) continue;
11265
11266 DenseSet<unsigned> DefRegs;
11268 OI = II->operands_begin(), OE = II->operands_end();
11269 OI != OE; ++OI) {
11270 if (!OI->isReg()) continue;
11271 DefRegs.insert(OI->getReg());
11272 }
11273
11274 MachineInstrBuilder MIB(*MF, &*II);
11275
11276 for (unsigned i = 0; SavedRegs[i] != 0; ++i) {
11277 unsigned Reg = SavedRegs[i];
11278 if (Subtarget->isThumb2() &&
11279 !ARM::tGPRRegClass.contains(Reg) &&
11280 !ARM::hGPRRegClass.contains(Reg))
11281 continue;
11282 if (Subtarget->isThumb1Only() && !ARM::tGPRRegClass.contains(Reg))
11283 continue;
11284 if (!Subtarget->isThumb() && !ARM::GPRRegClass.contains(Reg))
11285 continue;
11286 if (!DefRegs.contains(Reg))
11288 }
11289
11290 break;
11291 }
11292 }
11293
11294 // Mark all former landing pads as non-landing pads. The dispatch is the only
11295 // landing pad now.
11296 for (MachineBasicBlock *MBBLPad : MBBLPads)
11297 MBBLPad->setIsEHPad(false);
11298
11299 // The instruction is gone now.
11300 MI.eraseFromParent();
11301}
11302
11303static
11305 for (MachineBasicBlock *S : MBB->successors())
11306 if (S != Succ)
11307 return S;
11308 llvm_unreachable("Expecting a BB with two successors!");
11309}
11310
11311/// Return the load opcode for a given load size. If load size >= 8,
11312/// neon opcode will be returned.
11313static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2) {
11314 if (LdSize >= 8)
11315 return LdSize == 16 ? ARM::VLD1q32wb_fixed
11316 : LdSize == 8 ? ARM::VLD1d32wb_fixed : 0;
11317 if (IsThumb1)
11318 return LdSize == 4 ? ARM::tLDRi
11319 : LdSize == 2 ? ARM::tLDRHi
11320 : LdSize == 1 ? ARM::tLDRBi : 0;
11321 if (IsThumb2)
11322 return LdSize == 4 ? ARM::t2LDR_POST
11323 : LdSize == 2 ? ARM::t2LDRH_POST
11324 : LdSize == 1 ? ARM::t2LDRB_POST : 0;
11325 return LdSize == 4 ? ARM::LDR_POST_IMM
11326 : LdSize == 2 ? ARM::LDRH_POST
11327 : LdSize == 1 ? ARM::LDRB_POST_IMM : 0;
11328}
11329
11330/// Return the store opcode for a given store size. If store size >= 8,
11331/// neon opcode will be returned.
11332static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2) {
11333 if (StSize >= 8)
11334 return StSize == 16 ? ARM::VST1q32wb_fixed
11335 : StSize == 8 ? ARM::VST1d32wb_fixed : 0;
11336 if (IsThumb1)
11337 return StSize == 4 ? ARM::tSTRi
11338 : StSize == 2 ? ARM::tSTRHi
11339 : StSize == 1 ? ARM::tSTRBi : 0;
11340 if (IsThumb2)
11341 return StSize == 4 ? ARM::t2STR_POST
11342 : StSize == 2 ? ARM::t2STRH_POST
11343 : StSize == 1 ? ARM::t2STRB_POST : 0;
11344 return StSize == 4 ? ARM::STR_POST_IMM
11345 : StSize == 2 ? ARM::STRH_POST
11346 : StSize == 1 ? ARM::STRB_POST_IMM : 0;
11347}
11348
11349/// Emit a post-increment load operation with given size. The instructions
11350/// will be added to BB at Pos.
11352 const TargetInstrInfo *TII, const DebugLoc &dl,
11353 unsigned LdSize, unsigned Data, unsigned AddrIn,
11354 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11355 unsigned LdOpc = getLdOpcode(LdSize, IsThumb1, IsThumb2);
11356 assert(LdOpc != 0 && "Should have a load opcode");
11357 if (LdSize >= 8) {
11358 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11359 .addReg(AddrOut, RegState::Define)
11360 .addReg(AddrIn)
11361 .addImm(0)
11363 } else if (IsThumb1) {
11364 // load + update AddrIn
11365 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11366 .addReg(AddrIn)
11367 .addImm(0)
11369 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11370 .add(t1CondCodeOp())
11371 .addReg(AddrIn)
11372 .addImm(LdSize)
11374 } else if (IsThumb2) {
11375 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11376 .addReg(AddrOut, RegState::Define)
11377 .addReg(AddrIn)
11378 .addImm(LdSize)
11380 } else { // arm
11381 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11382 .addReg(AddrOut, RegState::Define)
11383 .addReg(AddrIn)
11384 .addReg(0)
11385 .addImm(LdSize)
11387 }
11388}
11389
11390/// Emit a post-increment store operation with given size. The instructions
11391/// will be added to BB at Pos.
11393 const TargetInstrInfo *TII, const DebugLoc &dl,
11394 unsigned StSize, unsigned Data, unsigned AddrIn,
11395 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11396 unsigned StOpc = getStOpcode(StSize, IsThumb1, IsThumb2);
11397 assert(StOpc != 0 && "Should have a store opcode");
11398 if (StSize >= 8) {
11399 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11400 .addReg(AddrIn)
11401 .addImm(0)
11402 .addReg(Data)
11404 } else if (IsThumb1) {
11405 // store + update AddrIn
11406 BuildMI(*BB, Pos, dl, TII->get(StOpc))
11407 .addReg(Data)
11408 .addReg(AddrIn)
11409 .addImm(0)
11411 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11412 .add(t1CondCodeOp())
11413 .addReg(AddrIn)
11414 .addImm(StSize)
11416 } else if (IsThumb2) {
11417 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11418 .addReg(Data)
11419 .addReg(AddrIn)
11420 .addImm(StSize)
11422 } else { // arm
11423 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11424 .addReg(Data)
11425 .addReg(AddrIn)
11426 .addReg(0)
11427 .addImm(StSize)
11429 }
11430}
11431
11433ARMTargetLowering::EmitStructByval(MachineInstr &MI,
11434 MachineBasicBlock *BB) const {
11435 // This pseudo instruction has 3 operands: dst, src, size
11436 // We expand it to a loop if size > Subtarget->getMaxInlineSizeThreshold().
11437 // Otherwise, we will generate unrolled scalar copies.
11438 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11439 const BasicBlock *LLVM_BB = BB->getBasicBlock();
11441
11442 Register dest = MI.getOperand(0).getReg();
11443 Register src = MI.getOperand(1).getReg();
11444 unsigned SizeVal = MI.getOperand(2).getImm();
11445 unsigned Alignment = MI.getOperand(3).getImm();
11446 DebugLoc dl = MI.getDebugLoc();
11447
11448 MachineFunction *MF = BB->getParent();
11449 MachineRegisterInfo &MRI = MF->getRegInfo();
11450 unsigned UnitSize = 0;
11451 const TargetRegisterClass *TRC = nullptr;
11452 const TargetRegisterClass *VecTRC = nullptr;
11453
11454 bool IsThumb1 = Subtarget->isThumb1Only();
11455 bool IsThumb2 = Subtarget->isThumb2();
11456 bool IsThumb = Subtarget->isThumb();
11457
11458 if (Alignment & 1) {
11459 UnitSize = 1;
11460 } else if (Alignment & 2) {
11461 UnitSize = 2;
11462 } else {
11463 // Check whether we can use NEON instructions.
11464 if (!MF->getFunction().hasFnAttribute(Attribute::NoImplicitFloat) &&
11465 Subtarget->hasNEON()) {
11466 if ((Alignment % 16 == 0) && SizeVal >= 16)
11467 UnitSize = 16;
11468 else if ((Alignment % 8 == 0) && SizeVal >= 8)
11469 UnitSize = 8;
11470 }
11471 // Can't use NEON instructions.
11472 if (UnitSize == 0)
11473 UnitSize = 4;
11474 }
11475
11476 // Select the correct opcode and register class for unit size load/store
11477 bool IsNeon = UnitSize >= 8;
11478 TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
11479 if (IsNeon)
11480 VecTRC = UnitSize == 16 ? &ARM::DPairRegClass
11481 : UnitSize == 8 ? &ARM::DPRRegClass
11482 : nullptr;
11483
11484 unsigned BytesLeft = SizeVal % UnitSize;
11485 unsigned LoopSize = SizeVal - BytesLeft;
11486
11487 if (SizeVal <= Subtarget->getMaxInlineSizeThreshold()) {
11488 // Use LDR and STR to copy.
11489 // [scratch, srcOut] = LDR_POST(srcIn, UnitSize)
11490 // [destOut] = STR_POST(scratch, destIn, UnitSize)
11491 unsigned srcIn = src;
11492 unsigned destIn = dest;
11493 for (unsigned i = 0; i < LoopSize; i+=UnitSize) {
11494 Register srcOut = MRI.createVirtualRegister(TRC);
11495 Register destOut = MRI.createVirtualRegister(TRC);
11496 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11497 emitPostLd(BB, MI, TII, dl, UnitSize, scratch, srcIn, srcOut,
11498 IsThumb1, IsThumb2);
11499 emitPostSt(BB, MI, TII, dl, UnitSize, scratch, destIn, destOut,
11500 IsThumb1, IsThumb2);
11501 srcIn = srcOut;
11502 destIn = destOut;
11503 }
11504
11505 // Handle the leftover bytes with LDRB and STRB.
11506 // [scratch, srcOut] = LDRB_POST(srcIn, 1)
11507 // [destOut] = STRB_POST(scratch, destIn, 1)
11508 for (unsigned i = 0; i < BytesLeft; i++) {
11509 Register srcOut = MRI.createVirtualRegister(TRC);
11510 Register destOut = MRI.createVirtualRegister(TRC);
11511 Register scratch = MRI.createVirtualRegister(TRC);
11512 emitPostLd(BB, MI, TII, dl, 1, scratch, srcIn, srcOut,
11513 IsThumb1, IsThumb2);
11514 emitPostSt(BB, MI, TII, dl, 1, scratch, destIn, destOut,
11515 IsThumb1, IsThumb2);
11516 srcIn = srcOut;
11517 destIn = destOut;
11518 }
11519 MI.eraseFromParent(); // The instruction is gone now.
11520 return BB;
11521 }
11522
11523 // Expand the pseudo op to a loop.
11524 // thisMBB:
11525 // ...
11526 // movw varEnd, # --> with thumb2
11527 // movt varEnd, #
11528 // ldrcp varEnd, idx --> without thumb2
11529 // fallthrough --> loopMBB
11530 // loopMBB:
11531 // PHI varPhi, varEnd, varLoop
11532 // PHI srcPhi, src, srcLoop
11533 // PHI destPhi, dst, destLoop
11534 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11535 // [destLoop] = STR_POST(scratch, destPhi, UnitSize)
11536 // subs varLoop, varPhi, #UnitSize
11537 // bne loopMBB
11538 // fallthrough --> exitMBB
11539 // exitMBB:
11540 // epilogue to handle left-over bytes
11541 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11542 // [destOut] = STRB_POST(scratch, destLoop, 1)
11543 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11544 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11545 MF->insert(It, loopMBB);
11546 MF->insert(It, exitMBB);
11547
11548 // Set the call frame size on entry to the new basic blocks.
11549 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11550 loopMBB->setCallFrameSize(CallFrameSize);
11551 exitMBB->setCallFrameSize(CallFrameSize);
11552
11553 // Transfer the remainder of BB and its successor edges to exitMBB.
11554 exitMBB->splice(exitMBB->begin(), BB,
11555 std::next(MachineBasicBlock::iterator(MI)), BB->end());
11557
11558 // Load an immediate to varEnd.
11559 Register varEnd = MRI.createVirtualRegister(TRC);
11560 if (Subtarget->useMovt()) {
11561 BuildMI(BB, dl, TII->get(IsThumb ? ARM::t2MOVi32imm : ARM::MOVi32imm),
11562 varEnd)
11563 .addImm(LoopSize);
11564 } else if (Subtarget->genExecuteOnly()) {
11565 assert(IsThumb && "Non-thumb expected to have used movt");
11566 BuildMI(BB, dl, TII->get(ARM::tMOVi32imm), varEnd).addImm(LoopSize);
11567 } else {
11568 MachineConstantPool *ConstantPool = MF->getConstantPool();
11569 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11570 const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
11571
11572 // MachineConstantPool wants an explicit alignment.
11573 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11574 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11575 MachineMemOperand *CPMMO =
11578
11579 if (IsThumb)
11580 BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci))
11581 .addReg(varEnd, RegState::Define)
11584 .addMemOperand(CPMMO);
11585 else
11586 BuildMI(*BB, MI, dl, TII->get(ARM::LDRcp))
11587 .addReg(varEnd, RegState::Define)
11589 .addImm(0)
11591 .addMemOperand(CPMMO);
11592 }
11593 BB->addSuccessor(loopMBB);
11594
11595 // Generate the loop body:
11596 // varPhi = PHI(varLoop, varEnd)
11597 // srcPhi = PHI(srcLoop, src)
11598 // destPhi = PHI(destLoop, dst)
11599 MachineBasicBlock *entryBB = BB;
11600 BB = loopMBB;
11601 Register varLoop = MRI.createVirtualRegister(TRC);
11602 Register varPhi = MRI.createVirtualRegister(TRC);
11603 Register srcLoop = MRI.createVirtualRegister(TRC);
11604 Register srcPhi = MRI.createVirtualRegister(TRC);
11605 Register destLoop = MRI.createVirtualRegister(TRC);
11606 Register destPhi = MRI.createVirtualRegister(TRC);
11607
11608 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), varPhi)
11609 .addReg(varLoop).addMBB(loopMBB)
11610 .addReg(varEnd).addMBB(entryBB);
11611 BuildMI(BB, dl, TII->get(ARM::PHI), srcPhi)
11612 .addReg(srcLoop).addMBB(loopMBB)
11613 .addReg(src).addMBB(entryBB);
11614 BuildMI(BB, dl, TII->get(ARM::PHI), destPhi)
11615 .addReg(destLoop).addMBB(loopMBB)
11616 .addReg(dest).addMBB(entryBB);
11617
11618 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11619 // [destLoop] = STR_POST(scratch, destPhi, UnitSiz)
11620 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11621 emitPostLd(BB, BB->end(), TII, dl, UnitSize, scratch, srcPhi, srcLoop,
11622 IsThumb1, IsThumb2);
11623 emitPostSt(BB, BB->end(), TII, dl, UnitSize, scratch, destPhi, destLoop,
11624 IsThumb1, IsThumb2);
11625
11626 // Decrement loop variable by UnitSize.
11627 if (IsThumb1) {
11628 BuildMI(*BB, BB->end(), dl, TII->get(ARM::tSUBi8), varLoop)
11629 .add(t1CondCodeOp())
11630 .addReg(varPhi)
11631 .addImm(UnitSize)
11633 } else {
11634 MachineInstrBuilder MIB =
11635 BuildMI(*BB, BB->end(), dl,
11636 TII->get(IsThumb2 ? ARM::t2SUBri : ARM::SUBri), varLoop);
11637 MIB.addReg(varPhi)
11638 .addImm(UnitSize)
11640 .add(condCodeOp());
11641 MIB->getOperand(5).setReg(ARM::CPSR);
11642 MIB->getOperand(5).setIsDef(true);
11643 }
11644 BuildMI(*BB, BB->end(), dl,
11645 TII->get(IsThumb1 ? ARM::tBcc : IsThumb2 ? ARM::t2Bcc : ARM::Bcc))
11646 .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
11647
11648 // loopMBB can loop back to loopMBB or fall through to exitMBB.
11649 BB->addSuccessor(loopMBB);
11650 BB->addSuccessor(exitMBB);
11651
11652 // Add epilogue to handle BytesLeft.
11653 BB = exitMBB;
11654 auto StartOfExit = exitMBB->begin();
11655
11656 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11657 // [destOut] = STRB_POST(scratch, destLoop, 1)
11658 unsigned srcIn = srcLoop;
11659 unsigned destIn = destLoop;
11660 for (unsigned i = 0; i < BytesLeft; i++) {
11661 Register srcOut = MRI.createVirtualRegister(TRC);
11662 Register destOut = MRI.createVirtualRegister(TRC);
11663 Register scratch = MRI.createVirtualRegister(TRC);
11664 emitPostLd(BB, StartOfExit, TII, dl, 1, scratch, srcIn, srcOut,
11665 IsThumb1, IsThumb2);
11666 emitPostSt(BB, StartOfExit, TII, dl, 1, scratch, destIn, destOut,
11667 IsThumb1, IsThumb2);
11668 srcIn = srcOut;
11669 destIn = destOut;
11670 }
11671
11672 MI.eraseFromParent(); // The instruction is gone now.
11673 return BB;
11674}
11675
11677ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
11678 MachineBasicBlock *MBB) const {
11679 const TargetMachine &TM = getTargetMachine();
11680 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
11681 DebugLoc DL = MI.getDebugLoc();
11682
11683 assert(TM.getTargetTriple().isOSWindows() &&
11684 "__chkstk is only supported on Windows");
11685 assert(Subtarget->isThumb2() && "Windows on ARM requires Thumb-2 mode");
11686
11687 // __chkstk takes the number of words to allocate on the stack in R4, and
11688 // returns the stack adjustment in number of bytes in R4. This will not
11689 // clober any other registers (other than the obvious lr).
11690 //
11691 // Although, technically, IP should be considered a register which may be
11692 // clobbered, the call itself will not touch it. Windows on ARM is a pure
11693 // thumb-2 environment, so there is no interworking required. As a result, we
11694 // do not expect a veneer to be emitted by the linker, clobbering IP.
11695 //
11696 // Each module receives its own copy of __chkstk, so no import thunk is
11697 // required, again, ensuring that IP is not clobbered.
11698 //
11699 // Finally, although some linkers may theoretically provide a trampoline for
11700 // out of range calls (which is quite common due to a 32M range limitation of
11701 // branches for Thumb), we can generate the long-call version via
11702 // -mcmodel=large, alleviating the need for the trampoline which may clobber
11703 // IP.
11704
11705 RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE);
11706 if (ChkStkLibcall == RTLIB::Unsupported)
11707 reportFatalUsageError("no available implementation of __chkstk");
11708
11709 const char *ChkStk = getLibcallImplName(ChkStkLibcall).data();
11710 switch (TM.getCodeModel()) {
11711 case CodeModel::Tiny:
11712 llvm_unreachable("Tiny code model not available on ARM.");
11713 case CodeModel::Small:
11714 case CodeModel::Medium:
11715 case CodeModel::Kernel:
11716 BuildMI(*MBB, MI, DL, TII.get(ARM::tBL))
11718 .addExternalSymbol(ChkStk)
11721 .addReg(ARM::R12,
11723 .addReg(ARM::CPSR,
11725 break;
11726 case CodeModel::Large: {
11727 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
11728 Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11729
11730 BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
11731 .addExternalSymbol(ChkStk);
11737 .addReg(ARM::R12,
11739 .addReg(ARM::CPSR,
11741 break;
11742 }
11743 }
11744
11745 BuildMI(*MBB, MI, DL, TII.get(ARM::t2SUBrr), ARM::SP)
11746 .addReg(ARM::SP, RegState::Kill)
11747 .addReg(ARM::R4, RegState::Kill)
11750 .add(condCodeOp());
11751
11752 MI.eraseFromParent();
11753 return MBB;
11754}
11755
11757ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
11758 MachineBasicBlock *MBB) const {
11759 DebugLoc DL = MI.getDebugLoc();
11760 MachineFunction *MF = MBB->getParent();
11761 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11762
11763 MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
11764 MF->insert(++MBB->getIterator(), ContBB);
11765 ContBB->splice(ContBB->begin(), MBB,
11766 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
11768 MBB->addSuccessor(ContBB);
11769
11770 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11771 BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
11772 MF->push_back(TrapBB);
11773 MBB->addSuccessor(TrapBB);
11774
11775 BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
11776 .addReg(MI.getOperand(0).getReg())
11777 .addImm(0)
11779 BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
11780 .addMBB(TrapBB)
11782 .addReg(ARM::CPSR);
11783
11784 MI.eraseFromParent();
11785 return ContBB;
11786}
11787
11788// The CPSR operand of SelectItr might be missing a kill marker
11789// because there were multiple uses of CPSR, and ISel didn't know
11790// which to mark. Figure out whether SelectItr should have had a
11791// kill marker, and set it if it should. Returns the correct kill
11792// marker value.
11795 const TargetRegisterInfo* TRI) {
11796 // Scan forward through BB for a use/def of CPSR.
11797 MachineBasicBlock::iterator miI(std::next(SelectItr));
11798 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
11799 const MachineInstr& mi = *miI;
11800 if (mi.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
11801 return false;
11802 if (mi.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
11803 break; // Should have kill-flag - update below.
11804 }
11805
11806 // If we hit the end of the block, check whether CPSR is live into a
11807 // successor.
11808 if (miI == BB->end()) {
11809 for (MachineBasicBlock *Succ : BB->successors())
11810 if (Succ->isLiveIn(ARM::CPSR))
11811 return false;
11812 }
11813
11814 // We found a def, or hit the end of the basic block and CPSR wasn't live
11815 // out. SelectMI should have a kill flag on CPSR.
11816 SelectItr->addRegisterKilled(ARM::CPSR, TRI);
11817 return true;
11818}
11819
11820/// Adds logic in loop entry MBB to calculate loop iteration count and adds
11821/// t2WhileLoopSetup and t2WhileLoopStart to generate WLS loop
11823 MachineBasicBlock *TpLoopBody,
11824 MachineBasicBlock *TpExit, Register OpSizeReg,
11825 const TargetInstrInfo *TII, DebugLoc Dl,
11826 MachineRegisterInfo &MRI) {
11827 // Calculates loop iteration count = ceil(n/16) = (n + 15) >> 4.
11828 Register AddDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11829 BuildMI(TpEntry, Dl, TII->get(ARM::t2ADDri), AddDestReg)
11830 .addUse(OpSizeReg)
11831 .addImm(15)
11833 .addReg(0);
11834
11835 Register LsrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11836 BuildMI(TpEntry, Dl, TII->get(ARM::t2LSRri), LsrDestReg)
11837 .addUse(AddDestReg, RegState::Kill)
11838 .addImm(4)
11840 .addReg(0);
11841
11842 Register TotalIterationsReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11843 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopSetup), TotalIterationsReg)
11844 .addUse(LsrDestReg, RegState::Kill);
11845
11846 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopStart))
11847 .addUse(TotalIterationsReg)
11848 .addMBB(TpExit);
11849
11850 BuildMI(TpEntry, Dl, TII->get(ARM::t2B))
11851 .addMBB(TpLoopBody)
11853
11854 return TotalIterationsReg;
11855}
11856
11857/// Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and
11858/// t2DoLoopEnd. These are used by later passes to generate tail predicated
11859/// loops.
11860static void genTPLoopBody(MachineBasicBlock *TpLoopBody,
11861 MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit,
11862 const TargetInstrInfo *TII, DebugLoc Dl,
11863 MachineRegisterInfo &MRI, Register OpSrcReg,
11864 Register OpDestReg, Register ElementCountReg,
11865 Register TotalIterationsReg, bool IsMemcpy) {
11866 // First insert 4 PHI nodes for: Current pointer to Src (if memcpy), Dest
11867 // array, loop iteration counter, predication counter.
11868
11869 Register SrcPhiReg, CurrSrcReg;
11870 if (IsMemcpy) {
11871 // Current position in the src array
11872 SrcPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11873 CurrSrcReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11874 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), SrcPhiReg)
11875 .addUse(OpSrcReg)
11876 .addMBB(TpEntry)
11877 .addUse(CurrSrcReg)
11878 .addMBB(TpLoopBody);
11879 }
11880
11881 // Current position in the dest array
11882 Register DestPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11883 Register CurrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11884 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), DestPhiReg)
11885 .addUse(OpDestReg)
11886 .addMBB(TpEntry)
11887 .addUse(CurrDestReg)
11888 .addMBB(TpLoopBody);
11889
11890 // Current loop counter
11891 Register LoopCounterPhiReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11892 Register RemainingLoopIterationsReg =
11893 MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11894 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), LoopCounterPhiReg)
11895 .addUse(TotalIterationsReg)
11896 .addMBB(TpEntry)
11897 .addUse(RemainingLoopIterationsReg)
11898 .addMBB(TpLoopBody);
11899
11900 // Predication counter
11901 Register PredCounterPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11902 Register RemainingElementsReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11903 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), PredCounterPhiReg)
11904 .addUse(ElementCountReg)
11905 .addMBB(TpEntry)
11906 .addUse(RemainingElementsReg)
11907 .addMBB(TpLoopBody);
11908
11909 // Pass predication counter to VCTP
11910 Register VccrReg = MRI.createVirtualRegister(&ARM::VCCRRegClass);
11911 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VCTP8), VccrReg)
11912 .addUse(PredCounterPhiReg)
11914 .addReg(0)
11915 .addReg(0);
11916
11917 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2SUBri), RemainingElementsReg)
11918 .addUse(PredCounterPhiReg)
11919 .addImm(16)
11921 .addReg(0);
11922
11923 // VLDRB (only if memcpy) and VSTRB instructions, predicated using VPR
11924 Register SrcValueReg;
11925 if (IsMemcpy) {
11926 SrcValueReg = MRI.createVirtualRegister(&ARM::MQPRRegClass);
11927 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VLDRBU8_post))
11928 .addDef(CurrSrcReg)
11929 .addDef(SrcValueReg)
11930 .addReg(SrcPhiReg)
11931 .addImm(16)
11933 .addUse(VccrReg)
11934 .addReg(0);
11935 } else
11936 SrcValueReg = OpSrcReg;
11937
11938 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VSTRBU8_post))
11939 .addDef(CurrDestReg)
11940 .addUse(SrcValueReg)
11941 .addReg(DestPhiReg)
11942 .addImm(16)
11944 .addUse(VccrReg)
11945 .addReg(0);
11946
11947 // Add the pseudoInstrs for decrementing the loop counter and marking the
11948 // end:t2DoLoopDec and t2DoLoopEnd
11949 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopDec), RemainingLoopIterationsReg)
11950 .addUse(LoopCounterPhiReg)
11951 .addImm(1);
11952
11953 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopEnd))
11954 .addUse(RemainingLoopIterationsReg)
11955 .addMBB(TpLoopBody);
11956
11957 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2B))
11958 .addMBB(TpExit)
11960}
11961
11963 // KCFI is supported in all ARM/Thumb modes
11964 return true;
11965}
11966
11970 const TargetInstrInfo *TII) const {
11971 assert(MBBI->isCall() && MBBI->getCFIType() &&
11972 "Invalid call instruction for a KCFI check");
11973
11974 MachineOperand *TargetOp = nullptr;
11975 switch (MBBI->getOpcode()) {
11976 // ARM mode opcodes
11977 case ARM::BLX:
11978 case ARM::BLX_pred:
11979 case ARM::BLX_noip:
11980 case ARM::BLX_pred_noip:
11981 case ARM::BX_CALL:
11982 TargetOp = &MBBI->getOperand(0);
11983 break;
11984 case ARM::TCRETURNri:
11985 case ARM::TCRETURNrinotr12:
11986 case ARM::TAILJMPr:
11987 case ARM::TAILJMPr4:
11988 TargetOp = &MBBI->getOperand(0);
11989 break;
11990 // Thumb mode opcodes (Thumb1 and Thumb2)
11991 // Note: Most Thumb call instructions have predicate operands before the
11992 // target register Format: tBLXr pred, predreg, target_register, ...
11993 case ARM::tBLXr: // Thumb1/Thumb2: BLX register (requires V5T)
11994 case ARM::tBLXr_noip: // Thumb1/Thumb2: BLX register, no IP clobber
11995 case ARM::tBX_CALL: // Thumb1 only: BX call (push LR, BX)
11996 TargetOp = &MBBI->getOperand(2);
11997 break;
11998 // Tail call instructions don't have predicates, target is operand 0
11999 case ARM::tTAILJMPr: // Thumb1/Thumb2: Tail call via register
12000 TargetOp = &MBBI->getOperand(0);
12001 break;
12002 default:
12003 llvm_unreachable("Unexpected CFI call opcode");
12004 }
12005
12006 assert(TargetOp && TargetOp->isReg() && "Invalid target operand");
12007 TargetOp->setIsRenamable(false);
12008
12009 // Select the appropriate KCFI_CHECK variant based on the instruction set
12010 unsigned KCFICheckOpcode;
12011 if (Subtarget->isThumb()) {
12012 if (Subtarget->isThumb2()) {
12013 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb2;
12014 } else {
12015 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb1;
12016 }
12017 } else {
12018 KCFICheckOpcode = ARM::KCFI_CHECK_ARM;
12019 }
12020
12021 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(KCFICheckOpcode))
12022 .addReg(TargetOp->getReg())
12023 .addImm(MBBI->getCFIType())
12024 .getInstr();
12025}
12026
12029 MachineBasicBlock *BB) const {
12030 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
12031 DebugLoc dl = MI.getDebugLoc();
12032 bool isThumb2 = Subtarget->isThumb2();
12033 switch (MI.getOpcode()) {
12034 default: {
12035 MI.print(errs());
12036 llvm_unreachable("Unexpected instr type to insert");
12037 }
12038
12039 // Thumb1 post-indexed loads are really just single-register LDMs.
12040 case ARM::tLDR_postidx: {
12041 MachineOperand Def(MI.getOperand(1));
12042 BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD))
12043 .add(Def) // Rn_wb
12044 .add(MI.getOperand(2)) // Rn
12045 .add(MI.getOperand(3)) // PredImm
12046 .add(MI.getOperand(4)) // PredReg
12047 .add(MI.getOperand(0)) // Rt
12048 .cloneMemRefs(MI);
12049 MI.eraseFromParent();
12050 return BB;
12051 }
12052
12053 case ARM::MVE_MEMCPYLOOPINST:
12054 case ARM::MVE_MEMSETLOOPINST: {
12055
12056 // Transformation below expands MVE_MEMCPYLOOPINST/MVE_MEMSETLOOPINST Pseudo
12057 // into a Tail Predicated (TP) Loop. It adds the instructions to calculate
12058 // the iteration count =ceil(size_in_bytes/16)) in the TP entry block and
12059 // adds the relevant instructions in the TP loop Body for generation of a
12060 // WLSTP loop.
12061
12062 // Below is relevant portion of the CFG after the transformation.
12063 // The Machine Basic Blocks are shown along with branch conditions (in
12064 // brackets). Note that TP entry/exit MBBs depict the entry/exit of this
12065 // portion of the CFG and may not necessarily be the entry/exit of the
12066 // function.
12067
12068 // (Relevant) CFG after transformation:
12069 // TP entry MBB
12070 // |
12071 // |-----------------|
12072 // (n <= 0) (n > 0)
12073 // | |
12074 // | TP loop Body MBB<--|
12075 // | | |
12076 // \ |___________|
12077 // \ /
12078 // TP exit MBB
12079
12080 MachineFunction *MF = BB->getParent();
12081 MachineFunctionProperties &Properties = MF->getProperties();
12082 MachineRegisterInfo &MRI = MF->getRegInfo();
12083
12084 Register OpDestReg = MI.getOperand(0).getReg();
12085 Register OpSrcReg = MI.getOperand(1).getReg();
12086 Register OpSizeReg = MI.getOperand(2).getReg();
12087
12088 // Allocate the required MBBs and add to parent function.
12089 MachineBasicBlock *TpEntry = BB;
12090 MachineBasicBlock *TpLoopBody = MF->CreateMachineBasicBlock();
12091 MachineBasicBlock *TpExit;
12092
12093 MF->push_back(TpLoopBody);
12094
12095 // If any instructions are present in the current block after
12096 // MVE_MEMCPYLOOPINST or MVE_MEMSETLOOPINST, split the current block and
12097 // move the instructions into the newly created exit block. If there are no
12098 // instructions add an explicit branch to the FallThrough block and then
12099 // split.
12100 //
12101 // The split is required for two reasons:
12102 // 1) A terminator(t2WhileLoopStart) will be placed at that site.
12103 // 2) Since a TPLoopBody will be added later, any phis in successive blocks
12104 // need to be updated. splitAt() already handles this.
12105 TpExit = BB->splitAt(MI, false);
12106 if (TpExit == BB) {
12107 assert(BB->canFallThrough() && "Exit Block must be Fallthrough of the "
12108 "block containing memcpy/memset Pseudo");
12109 TpExit = BB->getFallThrough();
12110 BuildMI(BB, dl, TII->get(ARM::t2B))
12111 .addMBB(TpExit)
12113 TpExit = BB->splitAt(MI, false);
12114 }
12115
12116 // Add logic for iteration count
12117 Register TotalIterationsReg =
12118 genTPEntry(TpEntry, TpLoopBody, TpExit, OpSizeReg, TII, dl, MRI);
12119
12120 // Add the vectorized (and predicated) loads/store instructions
12121 bool IsMemcpy = MI.getOpcode() == ARM::MVE_MEMCPYLOOPINST;
12122 genTPLoopBody(TpLoopBody, TpEntry, TpExit, TII, dl, MRI, OpSrcReg,
12123 OpDestReg, OpSizeReg, TotalIterationsReg, IsMemcpy);
12124
12125 // Required to avoid conflict with the MachineVerifier during testing.
12126 Properties.resetNoPHIs();
12127
12128 // Connect the blocks
12129 TpEntry->addSuccessor(TpLoopBody);
12130 TpLoopBody->addSuccessor(TpLoopBody);
12131 TpLoopBody->addSuccessor(TpExit);
12132
12133 // Reorder for a more natural layout
12134 TpLoopBody->moveAfter(TpEntry);
12135 TpExit->moveAfter(TpLoopBody);
12136
12137 // Finally, remove the memcpy Pseudo Instruction
12138 MI.eraseFromParent();
12139
12140 // Return the exit block as it may contain other instructions requiring a
12141 // custom inserter
12142 return TpExit;
12143 }
12144
12145 // The Thumb2 pre-indexed stores have the same MI operands, they just
12146 // define them differently in the .td files from the isel patterns, so
12147 // they need pseudos.
12148 case ARM::t2STR_preidx:
12149 MI.setDesc(TII->get(ARM::t2STR_PRE));
12150 return BB;
12151 case ARM::t2STRB_preidx:
12152 MI.setDesc(TII->get(ARM::t2STRB_PRE));
12153 return BB;
12154 case ARM::t2STRH_preidx:
12155 MI.setDesc(TII->get(ARM::t2STRH_PRE));
12156 return BB;
12157
12158 case ARM::STRi_preidx:
12159 case ARM::STRBi_preidx: {
12160 unsigned NewOpc = MI.getOpcode() == ARM::STRi_preidx ? ARM::STR_PRE_IMM
12161 : ARM::STRB_PRE_IMM;
12162 // Decode the offset.
12163 unsigned Offset = MI.getOperand(4).getImm();
12164 bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub;
12166 if (isSub)
12167 Offset = -Offset;
12168
12169 MachineMemOperand *MMO = *MI.memoperands_begin();
12170 BuildMI(*BB, MI, dl, TII->get(NewOpc))
12171 .add(MI.getOperand(0)) // Rn_wb
12172 .add(MI.getOperand(1)) // Rt
12173 .add(MI.getOperand(2)) // Rn
12174 .addImm(Offset) // offset (skip GPR==zero_reg)
12175 .add(MI.getOperand(5)) // pred
12176 .add(MI.getOperand(6))
12177 .addMemOperand(MMO);
12178 MI.eraseFromParent();
12179 return BB;
12180 }
12181 case ARM::STRr_preidx:
12182 case ARM::STRBr_preidx:
12183 case ARM::STRH_preidx: {
12184 unsigned NewOpc;
12185 switch (MI.getOpcode()) {
12186 default: llvm_unreachable("unexpected opcode!");
12187 case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break;
12188 case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break;
12189 case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break;
12190 }
12191 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc));
12192 for (const MachineOperand &MO : MI.operands())
12193 MIB.add(MO);
12194 MI.eraseFromParent();
12195 return BB;
12196 }
12197
12198 case ARM::tMOVCCr_pseudo: {
12199 // To "insert" a SELECT_CC instruction, we actually have to insert the
12200 // diamond control-flow pattern. The incoming instruction knows the
12201 // destination vreg to set, the condition code register to branch on, the
12202 // true/false values to select between, and a branch opcode to use.
12203 const BasicBlock *LLVM_BB = BB->getBasicBlock();
12205
12206 // thisMBB:
12207 // ...
12208 // TrueVal = ...
12209 // cmpTY ccX, r1, r2
12210 // bCC copy1MBB
12211 // fallthrough --> copy0MBB
12212 MachineBasicBlock *thisMBB = BB;
12213 MachineFunction *F = BB->getParent();
12214 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12215 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
12216 F->insert(It, copy0MBB);
12217 F->insert(It, sinkMBB);
12218
12219 // Set the call frame size on entry to the new basic blocks.
12220 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12221 copy0MBB->setCallFrameSize(CallFrameSize);
12222 sinkMBB->setCallFrameSize(CallFrameSize);
12223
12224 // Check whether CPSR is live past the tMOVCCr_pseudo.
12225 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
12226 if (!MI.killsRegister(ARM::CPSR, /*TRI=*/nullptr) &&
12227 !checkAndUpdateCPSRKill(MI, thisMBB, TRI)) {
12228 copy0MBB->addLiveIn(ARM::CPSR);
12229 sinkMBB->addLiveIn(ARM::CPSR);
12230 }
12231
12232 // Transfer the remainder of BB and its successor edges to sinkMBB.
12233 sinkMBB->splice(sinkMBB->begin(), BB,
12234 std::next(MachineBasicBlock::iterator(MI)), BB->end());
12236
12237 BB->addSuccessor(copy0MBB);
12238 BB->addSuccessor(sinkMBB);
12239
12240 BuildMI(BB, dl, TII->get(ARM::tBcc))
12241 .addMBB(sinkMBB)
12242 .addImm(MI.getOperand(3).getImm())
12243 .addReg(MI.getOperand(4).getReg());
12244
12245 // copy0MBB:
12246 // %FalseValue = ...
12247 // # fallthrough to sinkMBB
12248 BB = copy0MBB;
12249
12250 // Update machine-CFG edges
12251 BB->addSuccessor(sinkMBB);
12252
12253 // sinkMBB:
12254 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12255 // ...
12256 BB = sinkMBB;
12257 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), MI.getOperand(0).getReg())
12258 .addReg(MI.getOperand(1).getReg())
12259 .addMBB(copy0MBB)
12260 .addReg(MI.getOperand(2).getReg())
12261 .addMBB(thisMBB);
12262
12263 MI.eraseFromParent(); // The pseudo instruction is gone now.
12264 return BB;
12265 }
12266
12267 case ARM::BCCi64:
12268 case ARM::BCCZi64: {
12269 // If there is an unconditional branch to the other successor, remove it.
12270 BB->erase(std::next(MachineBasicBlock::iterator(MI)), BB->end());
12271
12272 // Compare both parts that make up the double comparison separately for
12273 // equality.
12274 bool RHSisZero = MI.getOpcode() == ARM::BCCZi64;
12275
12276 Register LHS1 = MI.getOperand(1).getReg();
12277 Register LHS2 = MI.getOperand(2).getReg();
12278 if (RHSisZero) {
12279 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12280 .addReg(LHS1)
12281 .addImm(0)
12283 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12284 .addReg(LHS2).addImm(0)
12285 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12286 } else {
12287 Register RHS1 = MI.getOperand(3).getReg();
12288 Register RHS2 = MI.getOperand(4).getReg();
12289 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12290 .addReg(LHS1)
12291 .addReg(RHS1)
12293 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12294 .addReg(LHS2).addReg(RHS2)
12295 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12296 }
12297
12298 MachineBasicBlock *destMBB = MI.getOperand(RHSisZero ? 3 : 5).getMBB();
12299 MachineBasicBlock *exitMBB = OtherSucc(BB, destMBB);
12300 if (MI.getOperand(0).getImm() == ARMCC::NE)
12301 std::swap(destMBB, exitMBB);
12302
12303 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))
12304 .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
12305 if (isThumb2)
12306 BuildMI(BB, dl, TII->get(ARM::t2B))
12307 .addMBB(exitMBB)
12309 else
12310 BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);
12311
12312 MI.eraseFromParent(); // The pseudo instruction is gone now.
12313 return BB;
12314 }
12315
12316 case ARM::Int_eh_sjlj_setjmp:
12317 case ARM::Int_eh_sjlj_setjmp_nofp:
12318 case ARM::tInt_eh_sjlj_setjmp:
12319 case ARM::t2Int_eh_sjlj_setjmp:
12320 case ARM::t2Int_eh_sjlj_setjmp_nofp:
12321 return BB;
12322
12323 case ARM::Int_eh_sjlj_setup_dispatch:
12324 EmitSjLjDispatchBlock(MI, BB);
12325 return BB;
12326 case ARM::COPY_STRUCT_BYVAL_I32:
12327 ++NumLoopByVals;
12328 return EmitStructByval(MI, BB);
12329 case ARM::WIN__CHKSTK:
12330 return EmitLowered__chkstk(MI, BB);
12331 case ARM::WIN__DBZCHK:
12332 return EmitLowered__dbzchk(MI, BB);
12333 }
12334}
12335
12336/// Attaches vregs to MEMCPY that it will use as scratch registers
12337/// when it is expanded into LDM/STM. This is done as a post-isel lowering
12338/// instead of as a custom inserter because we need the use list from the SDNode.
12339static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget,
12340 MachineInstr &MI, const SDNode *Node) {
12341 bool isThumb1 = Subtarget->isThumb1Only();
12342
12343 MachineFunction *MF = MI.getParent()->getParent();
12344 MachineRegisterInfo &MRI = MF->getRegInfo();
12345 MachineInstrBuilder MIB(*MF, MI);
12346
12347 // If the new dst/src is unused mark it as dead.
12348 if (!Node->hasAnyUseOfValue(0)) {
12349 MI.getOperand(0).setIsDead(true);
12350 }
12351 if (!Node->hasAnyUseOfValue(1)) {
12352 MI.getOperand(1).setIsDead(true);
12353 }
12354
12355 // The MEMCPY both defines and kills the scratch registers.
12356 for (unsigned I = 0; I != MI.getOperand(4).getImm(); ++I) {
12357 Register TmpReg = MRI.createVirtualRegister(isThumb1 ? &ARM::tGPRRegClass
12358 : &ARM::GPRRegClass);
12360 }
12361}
12362
12364 SDNode *Node) const {
12365 if (MI.getOpcode() == ARM::MEMCPY) {
12366 attachMEMCPYScratchRegs(Subtarget, MI, Node);
12367 return;
12368 }
12369
12370 const MCInstrDesc *MCID = &MI.getDesc();
12371 // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB,
12372 // RSC. Coming out of isel, they have an implicit CPSR def, but the optional
12373 // operand is still set to noreg. If needed, set the optional operand's
12374 // register to CPSR, and remove the redundant implicit def.
12375 //
12376 // e.g. ADCS (..., implicit-def CPSR) -> ADC (... opt:def CPSR).
12377
12378 // Rename pseudo opcodes.
12379 unsigned NewOpc = convertAddSubFlagsOpcode(MI.getOpcode());
12380 unsigned ccOutIdx;
12381 if (NewOpc) {
12382 const ARMBaseInstrInfo *TII = Subtarget->getInstrInfo();
12383 MCID = &TII->get(NewOpc);
12384
12385 assert(MCID->getNumOperands() ==
12386 MI.getDesc().getNumOperands() + 5 - MI.getDesc().getSize()
12387 && "converted opcode should be the same except for cc_out"
12388 " (and, on Thumb1, pred)");
12389
12390 MI.setDesc(*MCID);
12391
12392 // Add the optional cc_out operand
12393 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
12394
12395 // On Thumb1, move all input operands to the end, then add the predicate
12396 if (Subtarget->isThumb1Only()) {
12397 for (unsigned c = MCID->getNumOperands() - 4; c--;) {
12398 MI.addOperand(MI.getOperand(1));
12399 MI.removeOperand(1);
12400 }
12401
12402 // Restore the ties
12403 for (unsigned i = MI.getNumOperands(); i--;) {
12404 const MachineOperand& op = MI.getOperand(i);
12405 if (op.isReg() && op.isUse()) {
12406 int DefIdx = MCID->getOperandConstraint(i, MCOI::TIED_TO);
12407 if (DefIdx != -1)
12408 MI.tieOperands(DefIdx, i);
12409 }
12410 }
12411
12413 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/false));
12414 ccOutIdx = 1;
12415 } else
12416 ccOutIdx = MCID->getNumOperands() - 1;
12417 } else
12418 ccOutIdx = MCID->getNumOperands() - 1;
12419
12420 // Any ARM instruction that sets the 's' bit should specify an optional
12421 // "cc_out" operand in the last operand position.
12422 if (!MI.hasOptionalDef() || !MCID->operands()[ccOutIdx].isOptionalDef()) {
12423 assert(!NewOpc && "Optional cc_out operand required");
12424 return;
12425 }
12426 // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it
12427 // since we already have an optional CPSR def.
12428 bool definesCPSR = false;
12429 bool deadCPSR = false;
12430 for (unsigned i = MCID->getNumOperands(), e = MI.getNumOperands(); i != e;
12431 ++i) {
12432 const MachineOperand &MO = MI.getOperand(i);
12433 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
12434 definesCPSR = true;
12435 if (MO.isDead())
12436 deadCPSR = true;
12437 MI.removeOperand(i);
12438 break;
12439 }
12440 }
12441 if (!definesCPSR) {
12442 assert(!NewOpc && "Optional cc_out operand required");
12443 return;
12444 }
12445 assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag");
12446 if (deadCPSR) {
12447 assert(!MI.getOperand(ccOutIdx).getReg() &&
12448 "expect uninitialized optional cc_out operand");
12449 // Thumb1 instructions must have the S bit even if the CPSR is dead.
12450 if (!Subtarget->isThumb1Only())
12451 return;
12452 }
12453
12454 // If this instruction was defined with an optional CPSR def and its dag node
12455 // had a live implicit CPSR def, then activate the optional CPSR def.
12456 MachineOperand &MO = MI.getOperand(ccOutIdx);
12457 MO.setReg(ARM::CPSR);
12458 MO.setIsDef(true);
12459}
12460
12461//===----------------------------------------------------------------------===//
12462// ARM Optimization Hooks
12463//===----------------------------------------------------------------------===//
12464
12465// Helper function that checks if N is a null or all ones constant.
12466static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
12468}
12469
12470// Return true if N is conditionally 0 or all ones.
12471// Detects these expressions where cc is an i1 value:
12472//
12473// (select cc 0, y) [AllOnes=0]
12474// (select cc y, 0) [AllOnes=0]
12475// (zext cc) [AllOnes=0]
12476// (sext cc) [AllOnes=0/1]
12477// (select cc -1, y) [AllOnes=1]
12478// (select cc y, -1) [AllOnes=1]
12479//
12480// Invert is set when N is the null/all ones constant when CC is false.
12481// OtherOp is set to the alternative value of N.
12483 SDValue &CC, bool &Invert,
12484 SDValue &OtherOp,
12485 SelectionDAG &DAG) {
12486 switch (N->getOpcode()) {
12487 default: return false;
12488 case ISD::SELECT: {
12489 CC = N->getOperand(0);
12490 SDValue N1 = N->getOperand(1);
12491 SDValue N2 = N->getOperand(2);
12492 if (isZeroOrAllOnes(N1, AllOnes)) {
12493 Invert = false;
12494 OtherOp = N2;
12495 return true;
12496 }
12497 if (isZeroOrAllOnes(N2, AllOnes)) {
12498 Invert = true;
12499 OtherOp = N1;
12500 return true;
12501 }
12502 return false;
12503 }
12504 case ISD::ZERO_EXTEND:
12505 // (zext cc) can never be the all ones value.
12506 if (AllOnes)
12507 return false;
12508 [[fallthrough]];
12509 case ISD::SIGN_EXTEND: {
12510 SDLoc dl(N);
12511 EVT VT = N->getValueType(0);
12512 CC = N->getOperand(0);
12513 if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC)
12514 return false;
12515 Invert = !AllOnes;
12516 if (AllOnes)
12517 // When looking for an AllOnes constant, N is an sext, and the 'other'
12518 // value is 0.
12519 OtherOp = DAG.getConstant(0, dl, VT);
12520 else if (N->getOpcode() == ISD::ZERO_EXTEND)
12521 // When looking for a 0 constant, N can be zext or sext.
12522 OtherOp = DAG.getConstant(1, dl, VT);
12523 else
12524 OtherOp = DAG.getAllOnesConstant(dl, VT);
12525 return true;
12526 }
12527 }
12528}
12529
12530// Combine a constant select operand into its use:
12531//
12532// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
12533// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
12534// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
12535// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
12536// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
12537//
12538// The transform is rejected if the select doesn't have a constant operand that
12539// is null, or all ones when AllOnes is set.
12540//
12541// Also recognize sext/zext from i1:
12542//
12543// (add (zext cc), x) -> (select cc (add x, 1), x)
12544// (add (sext cc), x) -> (select cc (add x, -1), x)
12545//
12546// These transformations eventually create predicated instructions.
12547//
12548// @param N The node to transform.
12549// @param Slct The N operand that is a select.
12550// @param OtherOp The other N operand (x above).
12551// @param DCI Context.
12552// @param AllOnes Require the select constant to be all ones instead of null.
12553// @returns The new node, or SDValue() on failure.
12554static
12557 bool AllOnes = false) {
12558 SelectionDAG &DAG = DCI.DAG;
12559 EVT VT = N->getValueType(0);
12560 SDValue NonConstantVal;
12561 SDValue CCOp;
12562 bool SwapSelectOps;
12563 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
12564 NonConstantVal, DAG))
12565 return SDValue();
12566
12567 // Slct is now know to be the desired identity constant when CC is true.
12568 SDValue TrueVal = OtherOp;
12569 SDValue FalseVal = DAG.getNode(N->getOpcode(), SDLoc(N), VT,
12570 OtherOp, NonConstantVal);
12571 // Unless SwapSelectOps says CC should be false.
12572 if (SwapSelectOps)
12573 std::swap(TrueVal, FalseVal);
12574
12575 return DAG.getNode(ISD::SELECT, SDLoc(N), VT,
12576 CCOp, TrueVal, FalseVal);
12577}
12578
12579// Attempt combineSelectAndUse on each operand of a commutative operator N.
12580static
12583 SDValue N0 = N->getOperand(0);
12584 SDValue N1 = N->getOperand(1);
12585 if (N0.getNode()->hasOneUse())
12586 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
12587 return Result;
12588 if (N1.getNode()->hasOneUse())
12589 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
12590 return Result;
12591 return SDValue();
12592}
12593
12595 // VUZP shuffle node.
12596 if (N->getOpcode() == ARMISD::VUZP)
12597 return true;
12598
12599 // "VUZP" on i32 is an alias for VTRN.
12600 if (N->getOpcode() == ARMISD::VTRN && N->getValueType(0) == MVT::v2i32)
12601 return true;
12602
12603 return false;
12604}
12605
12608 const ARMSubtarget *Subtarget) {
12609 // Look for ADD(VUZP.0, VUZP.1).
12610 if (!IsVUZPShuffleNode(N0.getNode()) || N0.getNode() != N1.getNode() ||
12611 N0 == N1)
12612 return SDValue();
12613
12614 // Make sure the ADD is a 64-bit add; there is no 128-bit VPADD.
12615 if (!N->getValueType(0).is64BitVector())
12616 return SDValue();
12617
12618 // Generate vpadd.
12619 SelectionDAG &DAG = DCI.DAG;
12620 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12621 SDLoc dl(N);
12622 SDNode *Unzip = N0.getNode();
12623 EVT VT = N->getValueType(0);
12624
12626 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpadd, dl,
12627 TLI.getPointerTy(DAG.getDataLayout())));
12628 Ops.push_back(Unzip->getOperand(0));
12629 Ops.push_back(Unzip->getOperand(1));
12630
12631 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12632}
12633
12636 const ARMSubtarget *Subtarget) {
12637 // Check for two extended operands.
12638 if (!(N0.getOpcode() == ISD::SIGN_EXTEND &&
12639 N1.getOpcode() == ISD::SIGN_EXTEND) &&
12640 !(N0.getOpcode() == ISD::ZERO_EXTEND &&
12641 N1.getOpcode() == ISD::ZERO_EXTEND))
12642 return SDValue();
12643
12644 SDValue N00 = N0.getOperand(0);
12645 SDValue N10 = N1.getOperand(0);
12646
12647 // Look for ADD(SEXT(VUZP.0), SEXT(VUZP.1))
12648 if (!IsVUZPShuffleNode(N00.getNode()) || N00.getNode() != N10.getNode() ||
12649 N00 == N10)
12650 return SDValue();
12651
12652 // We only recognize Q register paddl here; this can't be reached until
12653 // after type legalization.
12654 if (!N00.getValueType().is64BitVector() ||
12656 return SDValue();
12657
12658 // Generate vpaddl.
12659 SelectionDAG &DAG = DCI.DAG;
12660 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12661 SDLoc dl(N);
12662 EVT VT = N->getValueType(0);
12663
12665 // Form vpaddl.sN or vpaddl.uN depending on the kind of extension.
12666 unsigned Opcode;
12667 if (N0.getOpcode() == ISD::SIGN_EXTEND)
12668 Opcode = Intrinsic::arm_neon_vpaddls;
12669 else
12670 Opcode = Intrinsic::arm_neon_vpaddlu;
12671 Ops.push_back(DAG.getConstant(Opcode, dl,
12672 TLI.getPointerTy(DAG.getDataLayout())));
12673 EVT ElemTy = N00.getValueType().getVectorElementType();
12674 unsigned NumElts = VT.getVectorNumElements();
12675 EVT ConcatVT = EVT::getVectorVT(*DAG.getContext(), ElemTy, NumElts * 2);
12676 SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), ConcatVT,
12677 N00.getOperand(0), N00.getOperand(1));
12678 Ops.push_back(Concat);
12679
12680 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12681}
12682
12683// FIXME: This function shouldn't be necessary; if we lower BUILD_VECTOR in
12684// an appropriate manner, we end up with ADD(VUZP(ZEXT(N))), which is
12685// much easier to match.
12686static SDValue
12689 const ARMSubtarget *Subtarget) {
12690 // Only perform optimization if after legalize, and if NEON is available. We
12691 // also expected both operands to be BUILD_VECTORs.
12692 if (DCI.isBeforeLegalize() || !Subtarget->hasNEON()
12693 || N0.getOpcode() != ISD::BUILD_VECTOR
12694 || N1.getOpcode() != ISD::BUILD_VECTOR)
12695 return SDValue();
12696
12697 // Check output type since VPADDL operand elements can only be 8, 16, or 32.
12698 EVT VT = N->getValueType(0);
12699 if (!VT.isInteger() || VT.getVectorElementType() == MVT::i64)
12700 return SDValue();
12701
12702 // Check that the vector operands are of the right form.
12703 // N0 and N1 are BUILD_VECTOR nodes with N number of EXTRACT_VECTOR
12704 // operands, where N is the size of the formed vector.
12705 // Each EXTRACT_VECTOR should have the same input vector and odd or even
12706 // index such that we have a pair wise add pattern.
12707
12708 // Grab the vector that all EXTRACT_VECTOR nodes should be referencing.
12710 return SDValue();
12711 SDValue Vec = N0->getOperand(0)->getOperand(0);
12712 SDNode *V = Vec.getNode();
12713 unsigned nextIndex = 0;
12714
12715 // For each operands to the ADD which are BUILD_VECTORs,
12716 // check to see if each of their operands are an EXTRACT_VECTOR with
12717 // the same vector and appropriate index.
12718 for (unsigned i = 0, e = N0->getNumOperands(); i != e; ++i) {
12721
12722 SDValue ExtVec0 = N0->getOperand(i);
12723 SDValue ExtVec1 = N1->getOperand(i);
12724
12725 // First operand is the vector, verify its the same.
12726 if (V != ExtVec0->getOperand(0).getNode() ||
12727 V != ExtVec1->getOperand(0).getNode())
12728 return SDValue();
12729
12730 // Second is the constant, verify its correct.
12733
12734 // For the constant, we want to see all the even or all the odd.
12735 if (!C0 || !C1 || C0->getZExtValue() != nextIndex
12736 || C1->getZExtValue() != nextIndex+1)
12737 return SDValue();
12738
12739 // Increment index.
12740 nextIndex+=2;
12741 } else
12742 return SDValue();
12743 }
12744
12745 // Don't generate vpaddl+vmovn; we'll match it to vpadd later. Also make sure
12746 // we're using the entire input vector, otherwise there's a size/legality
12747 // mismatch somewhere.
12748 if (nextIndex != Vec.getValueType().getVectorNumElements() ||
12750 return SDValue();
12751
12752 // Create VPADDL node.
12753 SelectionDAG &DAG = DCI.DAG;
12754 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12755
12756 SDLoc dl(N);
12757
12758 // Build operand list.
12760 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddls, dl,
12761 TLI.getPointerTy(DAG.getDataLayout())));
12762
12763 // Input is the vector.
12764 Ops.push_back(Vec);
12765
12766 // Get widened type and narrowed type.
12767 MVT widenType;
12768 unsigned numElem = VT.getVectorNumElements();
12769
12770 EVT inputLaneType = Vec.getValueType().getVectorElementType();
12771 switch (inputLaneType.getSimpleVT().SimpleTy) {
12772 case MVT::i8: widenType = MVT::getVectorVT(MVT::i16, numElem); break;
12773 case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break;
12774 case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break;
12775 default:
12776 llvm_unreachable("Invalid vector element type for padd optimization.");
12777 }
12778
12779 SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, widenType, Ops);
12780 unsigned ExtOp = VT.bitsGT(tmp.getValueType()) ? ISD::ANY_EXTEND : ISD::TRUNCATE;
12781 return DAG.getNode(ExtOp, dl, VT, tmp);
12782}
12783
12785 if (V->getOpcode() == ISD::UMUL_LOHI ||
12786 V->getOpcode() == ISD::SMUL_LOHI)
12787 return V;
12788 return SDValue();
12789}
12790
12791static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode,
12793 const ARMSubtarget *Subtarget) {
12794 if (!Subtarget->hasBaseDSP())
12795 return SDValue();
12796
12797 // SMLALBB, SMLALBT, SMLALTB, SMLALTT multiply two 16-bit values and
12798 // accumulates the product into a 64-bit value. The 16-bit values will
12799 // be sign extended somehow or SRA'd into 32-bit values
12800 // (addc (adde (mul 16bit, 16bit), lo), hi)
12801 SDValue Mul = AddcNode->getOperand(0);
12802 SDValue Lo = AddcNode->getOperand(1);
12803 if (Mul.getOpcode() != ISD::MUL) {
12804 Lo = AddcNode->getOperand(0);
12805 Mul = AddcNode->getOperand(1);
12806 if (Mul.getOpcode() != ISD::MUL)
12807 return SDValue();
12808 }
12809
12810 SDValue SRA = AddeNode->getOperand(0);
12811 SDValue Hi = AddeNode->getOperand(1);
12812 if (SRA.getOpcode() != ISD::SRA) {
12813 SRA = AddeNode->getOperand(1);
12814 Hi = AddeNode->getOperand(0);
12815 if (SRA.getOpcode() != ISD::SRA)
12816 return SDValue();
12817 }
12818 if (auto Const = dyn_cast<ConstantSDNode>(SRA.getOperand(1))) {
12819 if (Const->getZExtValue() != 31)
12820 return SDValue();
12821 } else
12822 return SDValue();
12823
12824 if (SRA.getOperand(0) != Mul)
12825 return SDValue();
12826
12827 SelectionDAG &DAG = DCI.DAG;
12828 SDLoc dl(AddcNode);
12829 unsigned Opcode = 0;
12830 SDValue Op0;
12831 SDValue Op1;
12832
12833 if (isS16(Mul.getOperand(0), DAG) && isS16(Mul.getOperand(1), DAG)) {
12834 Opcode = ARMISD::SMLALBB;
12835 Op0 = Mul.getOperand(0);
12836 Op1 = Mul.getOperand(1);
12837 } else if (isS16(Mul.getOperand(0), DAG) && isSRA16(Mul.getOperand(1))) {
12838 Opcode = ARMISD::SMLALBT;
12839 Op0 = Mul.getOperand(0);
12840 Op1 = Mul.getOperand(1).getOperand(0);
12841 } else if (isSRA16(Mul.getOperand(0)) && isS16(Mul.getOperand(1), DAG)) {
12842 Opcode = ARMISD::SMLALTB;
12843 Op0 = Mul.getOperand(0).getOperand(0);
12844 Op1 = Mul.getOperand(1);
12845 } else if (isSRA16(Mul.getOperand(0)) && isSRA16(Mul.getOperand(1))) {
12846 Opcode = ARMISD::SMLALTT;
12847 Op0 = Mul->getOperand(0).getOperand(0);
12848 Op1 = Mul->getOperand(1).getOperand(0);
12849 }
12850
12851 if (!Op0 || !Op1)
12852 return SDValue();
12853
12854 SDValue SMLAL = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
12855 Op0, Op1, Lo, Hi);
12856 // Replace the ADDs' nodes uses by the MLA node's values.
12857 SDValue HiMLALResult(SMLAL.getNode(), 1);
12858 SDValue LoMLALResult(SMLAL.getNode(), 0);
12859
12860 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult);
12861 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult);
12862
12863 // Return original node to notify the driver to stop replacing.
12864 SDValue resNode(AddcNode, 0);
12865 return resNode;
12866}
12867
12870 const ARMSubtarget *Subtarget) {
12871 // Look for multiply add opportunities.
12872 // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where
12873 // each add nodes consumes a value from ISD::UMUL_LOHI and there is
12874 // a glue link from the first add to the second add.
12875 // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by
12876 // a S/UMLAL instruction.
12877 // UMUL_LOHI
12878 // / :lo \ :hi
12879 // V \ [no multiline comment]
12880 // loAdd -> ADDC |
12881 // \ :carry /
12882 // V V
12883 // ADDE <- hiAdd
12884 //
12885 // In the special case where only the higher part of a signed result is used
12886 // and the add to the low part of the result of ISD::UMUL_LOHI adds or subtracts
12887 // a constant with the exact value of 0x80000000, we recognize we are dealing
12888 // with a "rounded multiply and add" (or subtract) and transform it into
12889 // either a ARMISD::SMMLAR or ARMISD::SMMLSR respectively.
12890
12891 assert((AddeSubeNode->getOpcode() == ARMISD::ADDE ||
12892 AddeSubeNode->getOpcode() == ARMISD::SUBE) &&
12893 "Expect an ADDE or SUBE");
12894
12895 assert(AddeSubeNode->getNumOperands() == 3 &&
12896 AddeSubeNode->getOperand(2).getValueType() == MVT::i32 &&
12897 "ADDE node has the wrong inputs");
12898
12899 // Check that we are chained to the right ADDC or SUBC node.
12900 SDNode *AddcSubcNode = AddeSubeNode->getOperand(2).getNode();
12901 if ((AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12902 AddcSubcNode->getOpcode() != ARMISD::ADDC) ||
12903 (AddeSubeNode->getOpcode() == ARMISD::SUBE &&
12904 AddcSubcNode->getOpcode() != ARMISD::SUBC))
12905 return SDValue();
12906
12907 SDValue AddcSubcOp0 = AddcSubcNode->getOperand(0);
12908 SDValue AddcSubcOp1 = AddcSubcNode->getOperand(1);
12909
12910 // Check if the two operands are from the same mul_lohi node.
12911 if (AddcSubcOp0.getNode() == AddcSubcOp1.getNode())
12912 return SDValue();
12913
12914 assert(AddcSubcNode->getNumValues() == 2 &&
12915 AddcSubcNode->getValueType(0) == MVT::i32 &&
12916 "Expect ADDC with two result values. First: i32");
12917
12918 // Check that the ADDC adds the low result of the S/UMUL_LOHI. If not, it
12919 // maybe a SMLAL which multiplies two 16-bit values.
12920 if (AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12921 AddcSubcOp0->getOpcode() != ISD::UMUL_LOHI &&
12922 AddcSubcOp0->getOpcode() != ISD::SMUL_LOHI &&
12923 AddcSubcOp1->getOpcode() != ISD::UMUL_LOHI &&
12924 AddcSubcOp1->getOpcode() != ISD::SMUL_LOHI)
12925 return AddCombineTo64BitSMLAL16(AddcSubcNode, AddeSubeNode, DCI, Subtarget);
12926
12927 // Check for the triangle shape.
12928 SDValue AddeSubeOp0 = AddeSubeNode->getOperand(0);
12929 SDValue AddeSubeOp1 = AddeSubeNode->getOperand(1);
12930
12931 // Make sure that the ADDE/SUBE operands are not coming from the same node.
12932 if (AddeSubeOp0.getNode() == AddeSubeOp1.getNode())
12933 return SDValue();
12934
12935 // Find the MUL_LOHI node walking up ADDE/SUBE's operands.
12936 bool IsLeftOperandMUL = false;
12937 SDValue MULOp = findMUL_LOHI(AddeSubeOp0);
12938 if (MULOp == SDValue())
12939 MULOp = findMUL_LOHI(AddeSubeOp1);
12940 else
12941 IsLeftOperandMUL = true;
12942 if (MULOp == SDValue())
12943 return SDValue();
12944
12945 // Figure out the right opcode.
12946 unsigned Opc = MULOp->getOpcode();
12947 unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
12948
12949 // Figure out the high and low input values to the MLAL node.
12950 SDValue *HiAddSub = nullptr;
12951 SDValue *LoMul = nullptr;
12952 SDValue *LowAddSub = nullptr;
12953
12954 // Ensure that ADDE/SUBE is from high result of ISD::xMUL_LOHI.
12955 if ((AddeSubeOp0 != MULOp.getValue(1)) && (AddeSubeOp1 != MULOp.getValue(1)))
12956 return SDValue();
12957
12958 if (IsLeftOperandMUL)
12959 HiAddSub = &AddeSubeOp1;
12960 else
12961 HiAddSub = &AddeSubeOp0;
12962
12963 // Ensure that LoMul and LowAddSub are taken from correct ISD::SMUL_LOHI node
12964 // whose low result is fed to the ADDC/SUBC we are checking.
12965
12966 if (AddcSubcOp0 == MULOp.getValue(0)) {
12967 LoMul = &AddcSubcOp0;
12968 LowAddSub = &AddcSubcOp1;
12969 }
12970 if (AddcSubcOp1 == MULOp.getValue(0)) {
12971 LoMul = &AddcSubcOp1;
12972 LowAddSub = &AddcSubcOp0;
12973 }
12974
12975 if (!LoMul)
12976 return SDValue();
12977
12978 // If HiAddSub is the same node as ADDC/SUBC or is a predecessor of ADDC/SUBC
12979 // the replacement below will create a cycle.
12980 if (AddcSubcNode == HiAddSub->getNode() ||
12981 AddcSubcNode->isPredecessorOf(HiAddSub->getNode()))
12982 return SDValue();
12983
12984 // Create the merged node.
12985 SelectionDAG &DAG = DCI.DAG;
12986
12987 // Start building operand list.
12989 Ops.push_back(LoMul->getOperand(0));
12990 Ops.push_back(LoMul->getOperand(1));
12991
12992 // Check whether we can use SMMLAR, SMMLSR or SMMULR instead. For this to be
12993 // the case, we must be doing signed multiplication and only use the higher
12994 // part of the result of the MLAL, furthermore the LowAddSub must be a constant
12995 // addition or subtraction with the value of 0x800000.
12996 if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && Subtarget->useMulOps() &&
12997 FinalOpc == ARMISD::SMLAL && !AddeSubeNode->hasAnyUseOfValue(1) &&
12998 LowAddSub->getNode()->getOpcode() == ISD::Constant &&
12999 static_cast<ConstantSDNode *>(LowAddSub->getNode())->getZExtValue() ==
13000 0x80000000) {
13001 Ops.push_back(*HiAddSub);
13002 if (AddcSubcNode->getOpcode() == ARMISD::SUBC) {
13003 FinalOpc = ARMISD::SMMLSR;
13004 } else {
13005 FinalOpc = ARMISD::SMMLAR;
13006 }
13007 SDValue NewNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode), MVT::i32, Ops);
13008 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), NewNode);
13009
13010 return SDValue(AddeSubeNode, 0);
13011 } else if (AddcSubcNode->getOpcode() == ARMISD::SUBC)
13012 // SMMLS is generated during instruction selection and the rest of this
13013 // function can not handle the case where AddcSubcNode is a SUBC.
13014 return SDValue();
13015
13016 // Finish building the operand list for {U/S}MLAL
13017 Ops.push_back(*LowAddSub);
13018 Ops.push_back(*HiAddSub);
13019
13020 SDValue MLALNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode),
13021 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13022
13023 // Replace the ADDs' nodes uses by the MLA node's values.
13024 SDValue HiMLALResult(MLALNode.getNode(), 1);
13025 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), HiMLALResult);
13026
13027 SDValue LoMLALResult(MLALNode.getNode(), 0);
13028 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcSubcNode, 0), LoMLALResult);
13029
13030 // Return original node to notify the driver to stop replacing.
13031 return SDValue(AddeSubeNode, 0);
13032}
13033
13036 const ARMSubtarget *Subtarget) {
13037 // UMAAL is similar to UMLAL except that it adds two unsigned values.
13038 // While trying to combine for the other MLAL nodes, first search for the
13039 // chance to use UMAAL. Check if Addc uses a node which has already
13040 // been combined into a UMLAL. The other pattern is UMLAL using Addc/Adde
13041 // as the addend, and it's handled in PerformUMLALCombine.
13042
13043 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13044 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13045
13046 // Check that we have a glued ADDC node.
13047 SDNode* AddcNode = AddeNode->getOperand(2).getNode();
13048 if (AddcNode->getOpcode() != ARMISD::ADDC)
13049 return SDValue();
13050
13051 // Find the converted UMAAL or quit if it doesn't exist.
13052 SDNode *UmlalNode = nullptr;
13053 SDValue AddHi;
13054 if (AddcNode->getOperand(0).getOpcode() == ARMISD::UMLAL) {
13055 UmlalNode = AddcNode->getOperand(0).getNode();
13056 AddHi = AddcNode->getOperand(1);
13057 } else if (AddcNode->getOperand(1).getOpcode() == ARMISD::UMLAL) {
13058 UmlalNode = AddcNode->getOperand(1).getNode();
13059 AddHi = AddcNode->getOperand(0);
13060 } else {
13061 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13062 }
13063
13064 // The ADDC should be glued to an ADDE node, which uses the same UMLAL as
13065 // the ADDC as well as Zero.
13066 if (!isNullConstant(UmlalNode->getOperand(3)))
13067 return SDValue();
13068
13069 if ((isNullConstant(AddeNode->getOperand(0)) &&
13070 AddeNode->getOperand(1).getNode() == UmlalNode) ||
13071 (AddeNode->getOperand(0).getNode() == UmlalNode &&
13072 isNullConstant(AddeNode->getOperand(1)))) {
13073 SelectionDAG &DAG = DCI.DAG;
13074 SDValue Ops[] = { UmlalNode->getOperand(0), UmlalNode->getOperand(1),
13075 UmlalNode->getOperand(2), AddHi };
13076 SDValue UMAAL = DAG.getNode(ARMISD::UMAAL, SDLoc(AddcNode),
13077 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13078
13079 // Replace the ADDs' nodes uses by the UMAAL node's values.
13080 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), SDValue(UMAAL.getNode(), 1));
13081 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), SDValue(UMAAL.getNode(), 0));
13082
13083 // Return original node to notify the driver to stop replacing.
13084 return SDValue(AddeNode, 0);
13085 }
13086 return SDValue();
13087}
13088
13090 const ARMSubtarget *Subtarget) {
13091 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13092 return SDValue();
13093
13094 // Check that we have a pair of ADDC and ADDE as operands.
13095 // Both addends of the ADDE must be zero.
13096 SDNode* AddcNode = N->getOperand(2).getNode();
13097 SDNode* AddeNode = N->getOperand(3).getNode();
13098 if ((AddcNode->getOpcode() == ARMISD::ADDC) &&
13099 (AddeNode->getOpcode() == ARMISD::ADDE) &&
13100 isNullConstant(AddeNode->getOperand(0)) &&
13101 isNullConstant(AddeNode->getOperand(1)) &&
13102 (AddeNode->getOperand(2).getNode() == AddcNode))
13103 return DAG.getNode(ARMISD::UMAAL, SDLoc(N),
13104 DAG.getVTList(MVT::i32, MVT::i32),
13105 {N->getOperand(0), N->getOperand(1),
13106 AddcNode->getOperand(0), AddcNode->getOperand(1)});
13107 else
13108 return SDValue();
13109}
13110
13113 const ARMSubtarget *Subtarget) {
13114 SelectionDAG &DAG(DCI.DAG);
13115
13116 if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
13117 // (SUBC (ADDE 0, 0, C), 1) -> C
13118 SDValue LHS = N->getOperand(0);
13119 SDValue RHS = N->getOperand(1);
13120 if (LHS->getOpcode() == ARMISD::ADDE &&
13121 isNullConstant(LHS->getOperand(0)) &&
13122 isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
13123 return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
13124 }
13125 }
13126
13127 if (Subtarget->isThumb1Only()) {
13128 SDValue RHS = N->getOperand(1);
13130 int32_t imm = C->getSExtValue();
13131 if (imm < 0 && imm > std::numeric_limits<int>::min()) {
13132 SDLoc DL(N);
13133 RHS = DAG.getConstant(-imm, DL, MVT::i32);
13134 unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
13135 : ARMISD::ADDC;
13136 return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
13137 }
13138 }
13139 }
13140
13141 return SDValue();
13142}
13143
13146 const ARMSubtarget *Subtarget) {
13147 if (Subtarget->isThumb1Only()) {
13148 SelectionDAG &DAG = DCI.DAG;
13149 SDValue RHS = N->getOperand(1);
13151 int64_t imm = C->getSExtValue();
13152 if (imm < 0) {
13153 SDLoc DL(N);
13154
13155 // The with-carry-in form matches bitwise not instead of the negation.
13156 // Effectively, the inverse interpretation of the carry flag already
13157 // accounts for part of the negation.
13158 RHS = DAG.getConstant(~imm, DL, MVT::i32);
13159
13160 unsigned Opcode = (N->getOpcode() == ARMISD::ADDE) ? ARMISD::SUBE
13161 : ARMISD::ADDE;
13162 return DAG.getNode(Opcode, DL, N->getVTList(),
13163 N->getOperand(0), RHS, N->getOperand(2));
13164 }
13165 }
13166 } else if (N->getOperand(1)->getOpcode() == ISD::SMUL_LOHI) {
13167 return AddCombineTo64bitMLAL(N, DCI, Subtarget);
13168 }
13169 return SDValue();
13170}
13171
13174 const ARMSubtarget *Subtarget) {
13175 if (!Subtarget->hasMVEIntegerOps())
13176 return SDValue();
13177
13178 SDLoc dl(N);
13179 SDValue SetCC;
13180 SDValue LHS;
13181 SDValue RHS;
13182 ISD::CondCode CC;
13183 SDValue TrueVal;
13184 SDValue FalseVal;
13185
13186 if (N->getOpcode() == ISD::SELECT &&
13187 N->getOperand(0)->getOpcode() == ISD::SETCC) {
13188 SetCC = N->getOperand(0);
13189 LHS = SetCC->getOperand(0);
13190 RHS = SetCC->getOperand(1);
13191 CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
13192 TrueVal = N->getOperand(1);
13193 FalseVal = N->getOperand(2);
13194 } else if (N->getOpcode() == ISD::SELECT_CC) {
13195 LHS = N->getOperand(0);
13196 RHS = N->getOperand(1);
13197 CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
13198 TrueVal = N->getOperand(2);
13199 FalseVal = N->getOperand(3);
13200 } else {
13201 return SDValue();
13202 }
13203
13204 unsigned int Opcode = 0;
13205 if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
13206 FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
13207 (CC == ISD::SETULT || CC == ISD::SETUGT)) {
13208 Opcode = ARMISD::VMINVu;
13209 if (CC == ISD::SETUGT)
13210 std::swap(TrueVal, FalseVal);
13211 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
13212 FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
13213 (CC == ISD::SETLT || CC == ISD::SETGT)) {
13214 Opcode = ARMISD::VMINVs;
13215 if (CC == ISD::SETGT)
13216 std::swap(TrueVal, FalseVal);
13217 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
13218 FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
13219 (CC == ISD::SETUGT || CC == ISD::SETULT)) {
13220 Opcode = ARMISD::VMAXVu;
13221 if (CC == ISD::SETULT)
13222 std::swap(TrueVal, FalseVal);
13223 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
13224 FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
13225 (CC == ISD::SETGT || CC == ISD::SETLT)) {
13226 Opcode = ARMISD::VMAXVs;
13227 if (CC == ISD::SETLT)
13228 std::swap(TrueVal, FalseVal);
13229 } else
13230 return SDValue();
13231
13232 // Normalise to the right hand side being the vector reduction
13233 switch (TrueVal->getOpcode()) {
13238 std::swap(LHS, RHS);
13239 std::swap(TrueVal, FalseVal);
13240 break;
13241 }
13242
13243 EVT VectorType = FalseVal->getOperand(0).getValueType();
13244
13245 if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
13246 VectorType != MVT::v4i32)
13247 return SDValue();
13248
13249 EVT VectorScalarType = VectorType.getVectorElementType();
13250
13251 // The values being selected must also be the ones being compared
13252 if (TrueVal != LHS || FalseVal != RHS)
13253 return SDValue();
13254
13255 EVT LeftType = LHS->getValueType(0);
13256 EVT RightType = RHS->getValueType(0);
13257
13258 // The types must match the reduced type too
13259 if (LeftType != VectorScalarType || RightType != VectorScalarType)
13260 return SDValue();
13261
13262 // Legalise the scalar to an i32
13263 if (VectorScalarType != MVT::i32)
13264 LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
13265
13266 // Generate the reduction as an i32 for legalisation purposes
13267 auto Reduction =
13268 DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
13269
13270 // The result isn't actually an i32 so truncate it back to its original type
13271 if (VectorScalarType != MVT::i32)
13272 Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
13273
13274 return Reduction;
13275}
13276
13277// A special combine for the vqdmulh family of instructions. This is one of the
13278// potential set of patterns that could patch this instruction. The base pattern
13279// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
13280// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
13281// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
13282// the max is unnecessary.
13284 EVT VT = N->getValueType(0);
13285 SDValue Shft;
13286 ConstantSDNode *Clamp;
13287
13288 if (!VT.isVector() || VT.getScalarSizeInBits() > 64)
13289 return SDValue();
13290
13291 if (N->getOpcode() == ISD::SMIN) {
13292 Shft = N->getOperand(0);
13293 Clamp = isConstOrConstSplat(N->getOperand(1));
13294 } else if (N->getOpcode() == ISD::VSELECT) {
13295 // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
13296 SDValue Cmp = N->getOperand(0);
13297 if (Cmp.getOpcode() != ISD::SETCC ||
13298 cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
13299 Cmp.getOperand(0) != N->getOperand(1) ||
13300 Cmp.getOperand(1) != N->getOperand(2))
13301 return SDValue();
13302 Shft = N->getOperand(1);
13303 Clamp = isConstOrConstSplat(N->getOperand(2));
13304 } else
13305 return SDValue();
13306
13307 if (!Clamp)
13308 return SDValue();
13309
13310 MVT ScalarType;
13311 int ShftAmt = 0;
13312 switch (Clamp->getSExtValue()) {
13313 case (1 << 7) - 1:
13314 ScalarType = MVT::i8;
13315 ShftAmt = 7;
13316 break;
13317 case (1 << 15) - 1:
13318 ScalarType = MVT::i16;
13319 ShftAmt = 15;
13320 break;
13321 case (1ULL << 31) - 1:
13322 ScalarType = MVT::i32;
13323 ShftAmt = 31;
13324 break;
13325 default:
13326 return SDValue();
13327 }
13328
13329 if (Shft.getOpcode() != ISD::SRA)
13330 return SDValue();
13332 if (!N1 || N1->getSExtValue() != ShftAmt)
13333 return SDValue();
13334
13335 SDValue Mul = Shft.getOperand(0);
13336 if (Mul.getOpcode() != ISD::MUL)
13337 return SDValue();
13338
13339 SDValue Ext0 = Mul.getOperand(0);
13340 SDValue Ext1 = Mul.getOperand(1);
13341 if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
13342 Ext1.getOpcode() != ISD::SIGN_EXTEND)
13343 return SDValue();
13344 EVT VecVT = Ext0.getOperand(0).getValueType();
13345 if (!VecVT.isPow2VectorType() || VecVT.getVectorNumElements() == 1)
13346 return SDValue();
13347 if (Ext1.getOperand(0).getValueType() != VecVT ||
13348 VecVT.getScalarType() != ScalarType ||
13349 VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
13350 return SDValue();
13351
13352 SDLoc DL(Mul);
13353 unsigned LegalLanes = 128 / (ShftAmt + 1);
13354 EVT LegalVecVT = MVT::getVectorVT(ScalarType, LegalLanes);
13355 // For types smaller than legal vectors extend to be legal and only use needed
13356 // lanes.
13357 if (VecVT.getSizeInBits() < 128) {
13358 EVT ExtVecVT =
13360 VecVT.getVectorNumElements());
13361 SDValue Inp0 =
13362 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext0.getOperand(0));
13363 SDValue Inp1 =
13364 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext1.getOperand(0));
13365 Inp0 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp0);
13366 Inp1 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp1);
13367 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13368 SDValue Trunc = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, ExtVecVT, VQDMULH);
13369 Trunc = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Trunc);
13370 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Trunc);
13371 }
13372
13373 // For larger types, split into legal sized chunks.
13374 assert(VecVT.getSizeInBits() % 128 == 0 && "Expected a power2 type");
13375 unsigned NumParts = VecVT.getSizeInBits() / 128;
13377 for (unsigned I = 0; I < NumParts; ++I) {
13378 SDValue Inp0 =
13379 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext0.getOperand(0),
13380 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13381 SDValue Inp1 =
13382 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext1.getOperand(0),
13383 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13384 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13385 Parts.push_back(VQDMULH);
13386 }
13387 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT,
13388 DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
13389}
13390
13393 const ARMSubtarget *Subtarget) {
13394 if (!Subtarget->hasMVEIntegerOps())
13395 return SDValue();
13396
13397 // Constant fold vselect 0, A, B -> B
13398 // and vselect 0xffff, A, B -> A
13399 if (N->getOperand(0).getOpcode() == ARMISD::PREDICATE_CAST &&
13400 isa<ConstantSDNode>(N->getOperand(0).getOperand(0))) {
13401 unsigned C = N->getOperand(0).getConstantOperandVal(0);
13402 if (C == 0)
13403 return N->getOperand(2);
13404 if (C == 0xffff)
13405 return N->getOperand(1);
13406 }
13407
13408 if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
13409 return V;
13410
13411 // Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
13412 //
13413 // We need to re-implement this optimization here as the implementation in the
13414 // Target-Independent DAGCombiner does not handle the kind of constant we make
13415 // (it calls isConstOrConstSplat with AllowTruncation set to false - and for
13416 // good reason, allowing truncation there would break other targets).
13417 //
13418 // Currently, this is only done for MVE, as it's the only target that benefits
13419 // from this transformation (e.g. VPNOT+VPSEL becomes a single VPSEL).
13420 if (N->getOperand(0).getOpcode() != ISD::XOR)
13421 return SDValue();
13422 SDValue XOR = N->getOperand(0);
13423
13424 // Check if the XOR's RHS is either a 1, or a BUILD_VECTOR of 1s.
13425 // It is important to check with truncation allowed as the BUILD_VECTORs we
13426 // generate in those situations will truncate their operands.
13427 ConstantSDNode *Const =
13428 isConstOrConstSplat(XOR->getOperand(1), /*AllowUndefs*/ false,
13429 /*AllowTruncation*/ true);
13430 if (!Const || !Const->isOne())
13431 return SDValue();
13432
13433 // Rewrite into vselect(cond, rhs, lhs).
13434 SDValue Cond = XOR->getOperand(0);
13435 SDValue LHS = N->getOperand(1);
13436 SDValue RHS = N->getOperand(2);
13437 EVT Type = N->getValueType(0);
13438 return DCI.DAG.getNode(ISD::VSELECT, SDLoc(N), Type, Cond, RHS, LHS);
13439}
13440
13441// Convert vsetcc([0,1,2,..], splat(n), ult) -> vctp n
13444 const ARMSubtarget *Subtarget) {
13445 SDValue Op0 = N->getOperand(0);
13446 SDValue Op1 = N->getOperand(1);
13447 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
13448 EVT VT = N->getValueType(0);
13449
13450 if (!Subtarget->hasMVEIntegerOps() ||
13452 return SDValue();
13453
13454 if (CC == ISD::SETUGE) {
13455 std::swap(Op0, Op1);
13456 CC = ISD::SETULT;
13457 }
13458
13459 if (CC != ISD::SETULT || VT.getScalarSizeInBits() != 1 ||
13461 return SDValue();
13462
13463 // Check first operand is BuildVector of 0,1,2,...
13464 for (unsigned I = 0; I < VT.getVectorNumElements(); I++) {
13465 if (!Op0.getOperand(I).isUndef() &&
13467 Op0.getConstantOperandVal(I) == I))
13468 return SDValue();
13469 }
13470
13471 // The second is a Splat of Op1S
13472 SDValue Op1S = DCI.DAG.getSplatValue(Op1);
13473 if (!Op1S)
13474 return SDValue();
13475
13476 unsigned Opc;
13477 switch (VT.getVectorNumElements()) {
13478 case 2:
13479 Opc = Intrinsic::arm_mve_vctp64;
13480 break;
13481 case 4:
13482 Opc = Intrinsic::arm_mve_vctp32;
13483 break;
13484 case 8:
13485 Opc = Intrinsic::arm_mve_vctp16;
13486 break;
13487 case 16:
13488 Opc = Intrinsic::arm_mve_vctp8;
13489 break;
13490 default:
13491 return SDValue();
13492 }
13493
13494 SDLoc DL(N);
13495 return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT,
13496 DCI.DAG.getConstant(Opc, DL, MVT::i32),
13497 DCI.DAG.getZExtOrTrunc(Op1S, DL, MVT::i32));
13498}
13499
13500/// PerformADDECombine - Target-specific dag combine transform from
13501/// ARMISD::ADDC, ARMISD::ADDE, and ISD::MUL_LOHI to MLAL or
13502/// ARMISD::ADDC, ARMISD::ADDE and ARMISD::UMLAL to ARMISD::UMAAL
13505 const ARMSubtarget *Subtarget) {
13506 // Only ARM and Thumb2 support UMLAL/SMLAL.
13507 if (Subtarget->isThumb1Only())
13508 return PerformAddeSubeCombine(N, DCI, Subtarget);
13509
13510 // Only perform the checks after legalize when the pattern is available.
13511 if (DCI.isBeforeLegalize()) return SDValue();
13512
13513 return AddCombineTo64bitUMAAL(N, DCI, Subtarget);
13514}
13515
13516/// PerformADDCombineWithOperands - Try DAG combinations for an ADD with
13517/// operands N0 and N1. This is a helper for PerformADDCombine that is
13518/// called with the default operands, and if that fails, with commuted
13519/// operands.
13522 const ARMSubtarget *Subtarget){
13523 // Attempt to create vpadd for this add.
13524 if (SDValue Result = AddCombineToVPADD(N, N0, N1, DCI, Subtarget))
13525 return Result;
13526
13527 // Attempt to create vpaddl for this add.
13528 if (SDValue Result = AddCombineVUZPToVPADDL(N, N0, N1, DCI, Subtarget))
13529 return Result;
13530 if (SDValue Result = AddCombineBUILD_VECTORToVPADDL(N, N0, N1, DCI,
13531 Subtarget))
13532 return Result;
13533
13534 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
13535 if (N0.getNode()->hasOneUse())
13536 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI))
13537 return Result;
13538 return SDValue();
13539}
13540
13542 EVT VT = N->getValueType(0);
13543 SDValue N0 = N->getOperand(0);
13544 SDValue N1 = N->getOperand(1);
13545 SDLoc dl(N);
13546
13547 auto IsVecReduce = [](SDValue Op) {
13548 switch (Op.getOpcode()) {
13549 case ISD::VECREDUCE_ADD:
13550 case ARMISD::VADDVs:
13551 case ARMISD::VADDVu:
13552 case ARMISD::VMLAVs:
13553 case ARMISD::VMLAVu:
13554 return true;
13555 }
13556 return false;
13557 };
13558
13559 auto DistrubuteAddAddVecReduce = [&](SDValue N0, SDValue N1) {
13560 // Distribute add(X, add(vecreduce(Y), vecreduce(Z))) ->
13561 // add(add(X, vecreduce(Y)), vecreduce(Z))
13562 // to make better use of vaddva style instructions.
13563 if (VT == MVT::i32 && N1.getOpcode() == ISD::ADD && !IsVecReduce(N0) &&
13564 IsVecReduce(N1.getOperand(0)) && IsVecReduce(N1.getOperand(1)) &&
13565 !isa<ConstantSDNode>(N0) && N1->hasOneUse()) {
13566 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0, N1.getOperand(0));
13567 return DAG.getNode(ISD::ADD, dl, VT, Add0, N1.getOperand(1));
13568 }
13569 // And turn add(add(A, reduce(B)), add(C, reduce(D))) ->
13570 // add(add(add(A, C), reduce(B)), reduce(D))
13571 if (VT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
13572 N1.getOpcode() == ISD::ADD && N0->hasOneUse() && N1->hasOneUse()) {
13573 unsigned N0RedOp = 0;
13574 if (!IsVecReduce(N0.getOperand(N0RedOp))) {
13575 N0RedOp = 1;
13576 if (!IsVecReduce(N0.getOperand(N0RedOp)))
13577 return SDValue();
13578 }
13579
13580 unsigned N1RedOp = 0;
13581 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13582 N1RedOp = 1;
13583 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13584 return SDValue();
13585
13586 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0.getOperand(1 - N0RedOp),
13587 N1.getOperand(1 - N1RedOp));
13588 SDValue Add1 =
13589 DAG.getNode(ISD::ADD, dl, VT, Add0, N0.getOperand(N0RedOp));
13590 return DAG.getNode(ISD::ADD, dl, VT, Add1, N1.getOperand(N1RedOp));
13591 }
13592 return SDValue();
13593 };
13594 if (SDValue R = DistrubuteAddAddVecReduce(N0, N1))
13595 return R;
13596 if (SDValue R = DistrubuteAddAddVecReduce(N1, N0))
13597 return R;
13598
13599 // Distribute add(vecreduce(load(Y)), vecreduce(load(Z)))
13600 // Or add(add(X, vecreduce(load(Y))), vecreduce(load(Z)))
13601 // by ascending load offsets. This can help cores prefetch if the order of
13602 // loads is more predictable.
13603 auto DistrubuteVecReduceLoad = [&](SDValue N0, SDValue N1, bool IsForward) {
13604 // Check if two reductions are known to load data where one is before/after
13605 // another. Return negative if N0 loads data before N1, positive if N1 is
13606 // before N0 and 0 otherwise if nothing is known.
13607 auto IsKnownOrderedLoad = [&](SDValue N0, SDValue N1) {
13608 // Look through to the first operand of a MUL, for the VMLA case.
13609 // Currently only looks at the first operand, in the hope they are equal.
13610 if (N0.getOpcode() == ISD::MUL)
13611 N0 = N0.getOperand(0);
13612 if (N1.getOpcode() == ISD::MUL)
13613 N1 = N1.getOperand(0);
13614
13615 // Return true if the two operands are loads to the same object and the
13616 // offset of the first is known to be less than the offset of the second.
13617 LoadSDNode *Load0 = dyn_cast<LoadSDNode>(N0);
13618 LoadSDNode *Load1 = dyn_cast<LoadSDNode>(N1);
13619 if (!Load0 || !Load1 || Load0->getChain() != Load1->getChain() ||
13620 !Load0->isSimple() || !Load1->isSimple() || Load0->isIndexed() ||
13621 Load1->isIndexed())
13622 return 0;
13623
13624 auto BaseLocDecomp0 = BaseIndexOffset::match(Load0, DAG);
13625 auto BaseLocDecomp1 = BaseIndexOffset::match(Load1, DAG);
13626
13627 if (!BaseLocDecomp0.getBase() ||
13628 BaseLocDecomp0.getBase() != BaseLocDecomp1.getBase() ||
13629 !BaseLocDecomp0.hasValidOffset() || !BaseLocDecomp1.hasValidOffset())
13630 return 0;
13631 if (BaseLocDecomp0.getOffset() < BaseLocDecomp1.getOffset())
13632 return -1;
13633 if (BaseLocDecomp0.getOffset() > BaseLocDecomp1.getOffset())
13634 return 1;
13635 return 0;
13636 };
13637
13638 SDValue X;
13639 if (N0.getOpcode() == ISD::ADD && N0->hasOneUse()) {
13640 if (IsVecReduce(N0.getOperand(0)) && IsVecReduce(N0.getOperand(1))) {
13641 int IsBefore = IsKnownOrderedLoad(N0.getOperand(0).getOperand(0),
13642 N0.getOperand(1).getOperand(0));
13643 if (IsBefore < 0) {
13644 X = N0.getOperand(0);
13645 N0 = N0.getOperand(1);
13646 } else if (IsBefore > 0) {
13647 X = N0.getOperand(1);
13648 N0 = N0.getOperand(0);
13649 } else
13650 return SDValue();
13651 } else if (IsVecReduce(N0.getOperand(0))) {
13652 X = N0.getOperand(1);
13653 N0 = N0.getOperand(0);
13654 } else if (IsVecReduce(N0.getOperand(1))) {
13655 X = N0.getOperand(0);
13656 N0 = N0.getOperand(1);
13657 } else
13658 return SDValue();
13659 } else if (IsForward && IsVecReduce(N0) && IsVecReduce(N1) &&
13660 IsKnownOrderedLoad(N0.getOperand(0), N1.getOperand(0)) < 0) {
13661 // Note this is backward to how you would expect. We create
13662 // add(reduce(load + 16), reduce(load + 0)) so that the
13663 // add(reduce(load+16), X) is combined into VADDVA(X, load+16)), leaving
13664 // the X as VADDV(load + 0)
13665 return DAG.getNode(ISD::ADD, dl, VT, N1, N0);
13666 } else
13667 return SDValue();
13668
13669 if (!IsVecReduce(N0) || !IsVecReduce(N1))
13670 return SDValue();
13671
13672 if (IsKnownOrderedLoad(N1.getOperand(0), N0.getOperand(0)) >= 0)
13673 return SDValue();
13674
13675 // Switch from add(add(X, N0), N1) to add(add(X, N1), N0)
13676 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, X, N1);
13677 return DAG.getNode(ISD::ADD, dl, VT, Add0, N0);
13678 };
13679 if (SDValue R = DistrubuteVecReduceLoad(N0, N1, true))
13680 return R;
13681 if (SDValue R = DistrubuteVecReduceLoad(N1, N0, false))
13682 return R;
13683 return SDValue();
13684}
13685
13687 const ARMSubtarget *Subtarget) {
13688 if (!Subtarget->hasMVEIntegerOps())
13689 return SDValue();
13690
13692 return R;
13693
13694 EVT VT = N->getValueType(0);
13695 SDValue N0 = N->getOperand(0);
13696 SDValue N1 = N->getOperand(1);
13697 SDLoc dl(N);
13698
13699 if (VT != MVT::i64)
13700 return SDValue();
13701
13702 // We are looking for a i64 add of a VADDLVx. Due to these being i64's, this
13703 // will look like:
13704 // t1: i32,i32 = ARMISD::VADDLVs x
13705 // t2: i64 = build_pair t1, t1:1
13706 // t3: i64 = add t2, y
13707 // Otherwise we try to push the add up above VADDLVAx, to potentially allow
13708 // the add to be simplified separately.
13709 // We also need to check for sext / zext and commutitive adds.
13710 auto MakeVecReduce = [&](unsigned Opcode, unsigned OpcodeA, SDValue NA,
13711 SDValue NB) {
13712 if (NB->getOpcode() != ISD::BUILD_PAIR)
13713 return SDValue();
13714 SDValue VecRed = NB->getOperand(0);
13715 if ((VecRed->getOpcode() != Opcode && VecRed->getOpcode() != OpcodeA) ||
13716 VecRed.getResNo() != 0 ||
13717 NB->getOperand(1) != SDValue(VecRed.getNode(), 1))
13718 return SDValue();
13719
13720 if (VecRed->getOpcode() == OpcodeA) {
13721 // add(NA, VADDLVA(Inp), Y) -> VADDLVA(add(NA, Inp), Y)
13722 SDValue Inp = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
13723 VecRed.getOperand(0), VecRed.getOperand(1));
13724 NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA);
13725 }
13726
13728 std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32);
13729
13730 unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0;
13731 for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++)
13732 Ops.push_back(VecRed->getOperand(I));
13733 SDValue Red =
13734 DAG.getNode(OpcodeA, dl, DAG.getVTList({MVT::i32, MVT::i32}), Ops);
13735 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Red,
13736 SDValue(Red.getNode(), 1));
13737 };
13738
13739 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N0, N1))
13740 return M;
13741 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N0, N1))
13742 return M;
13743 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N1, N0))
13744 return M;
13745 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N1, N0))
13746 return M;
13747 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N0, N1))
13748 return M;
13749 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N0, N1))
13750 return M;
13751 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N1, N0))
13752 return M;
13753 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N1, N0))
13754 return M;
13755 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N0, N1))
13756 return M;
13757 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N0, N1))
13758 return M;
13759 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N1, N0))
13760 return M;
13761 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
13762 return M;
13763 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
13764 return M;
13765 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
13766 return M;
13767 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
13768 return M;
13769 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
13770 return M;
13771 return SDValue();
13772}
13773
13774bool
13776 CombineLevel Level) const {
13777 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
13778 N->getOpcode() == ISD::SRL) &&
13779 "Expected shift op");
13780
13781 SDValue ShiftLHS = N->getOperand(0);
13782 if (!ShiftLHS->hasOneUse())
13783 return false;
13784
13785 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
13786 !ShiftLHS.getOperand(0)->hasOneUse())
13787 return false;
13788
13789 if (Level == BeforeLegalizeTypes)
13790 return true;
13791
13792 if (N->getOpcode() != ISD::SHL)
13793 return true;
13794
13795 if (Subtarget->isThumb1Only()) {
13796 // Avoid making expensive immediates by commuting shifts. (This logic
13797 // only applies to Thumb1 because ARM and Thumb2 immediates can be shifted
13798 // for free.)
13799 if (N->getOpcode() != ISD::SHL)
13800 return true;
13801 SDValue N1 = N->getOperand(0);
13802 if (N1->getOpcode() != ISD::ADD && N1->getOpcode() != ISD::AND &&
13803 N1->getOpcode() != ISD::OR && N1->getOpcode() != ISD::XOR)
13804 return true;
13805 if (auto *Const = dyn_cast<ConstantSDNode>(N1->getOperand(1))) {
13806 if (Const->getAPIntValue().ult(256))
13807 return false;
13808 if (N1->getOpcode() == ISD::ADD && Const->getAPIntValue().slt(0) &&
13809 Const->getAPIntValue().sgt(-256))
13810 return false;
13811 }
13812 return true;
13813 }
13814
13815 // Turn off commute-with-shift transform after legalization, so it doesn't
13816 // conflict with PerformSHLSimplify. (We could try to detect when
13817 // PerformSHLSimplify would trigger more precisely, but it isn't
13818 // really necessary.)
13819 return false;
13820}
13821
13823 const SDNode *N) const {
13824 assert(N->getOpcode() == ISD::XOR &&
13825 (N->getOperand(0).getOpcode() == ISD::SHL ||
13826 N->getOperand(0).getOpcode() == ISD::SRL) &&
13827 "Expected XOR(SHIFT) pattern");
13828
13829 // Only commute if the entire NOT mask is a hidden shifted mask.
13830 auto *XorC = dyn_cast<ConstantSDNode>(N->getOperand(1));
13831 auto *ShiftC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1));
13832 if (XorC && ShiftC) {
13833 unsigned MaskIdx, MaskLen;
13834 if (XorC->getAPIntValue().isShiftedMask(MaskIdx, MaskLen)) {
13835 unsigned ShiftAmt = ShiftC->getZExtValue();
13836 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
13837 if (N->getOperand(0).getOpcode() == ISD::SHL)
13838 return MaskIdx == ShiftAmt && MaskLen == (BitWidth - ShiftAmt);
13839 return MaskIdx == 0 && MaskLen == (BitWidth - ShiftAmt);
13840 }
13841 }
13842
13843 return false;
13844}
13845
13847 const SDNode *N) const {
13848 assert(((N->getOpcode() == ISD::SHL &&
13849 N->getOperand(0).getOpcode() == ISD::SRL) ||
13850 (N->getOpcode() == ISD::SRL &&
13851 N->getOperand(0).getOpcode() == ISD::SHL)) &&
13852 "Expected shift-shift mask");
13853
13854 if (!Subtarget->isThumb1Only())
13855 return true;
13856
13857 EVT VT = N->getValueType(0);
13858 if (VT.getScalarSizeInBits() > 32)
13859 return true;
13860
13861 return false;
13862}
13863
13865 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
13866 SDValue Y) const {
13867 return Subtarget->hasMVEIntegerOps() && isTypeLegal(VT) &&
13868 SelectOpcode == ISD::VSELECT;
13869}
13870
13872 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps()) {
13873 if (Subtarget->isThumb1Only())
13874 return VT.getScalarSizeInBits() <= 32;
13875 return true;
13876 }
13877 return VT.isScalarInteger();
13878}
13879
13881 EVT VT) const {
13882 if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
13883 return false;
13884
13885 switch (FPVT.getSimpleVT().SimpleTy) {
13886 case MVT::f16:
13887 return Subtarget->hasVFP2Base();
13888 case MVT::f32:
13889 return Subtarget->hasVFP2Base();
13890 case MVT::f64:
13891 return Subtarget->hasFP64();
13892 case MVT::v4f32:
13893 case MVT::v8f16:
13894 return Subtarget->hasMVEFloatOps();
13895 default:
13896 return false;
13897 }
13898}
13899
13902 const ARMSubtarget *ST) {
13903 // Allow the generic combiner to identify potential bswaps.
13904 if (DCI.isBeforeLegalize())
13905 return SDValue();
13906
13907 // DAG combiner will fold:
13908 // (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
13909 // (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2
13910 // Other code patterns that can be also be modified have the following form:
13911 // b + ((a << 1) | 510)
13912 // b + ((a << 1) & 510)
13913 // b + ((a << 1) ^ 510)
13914 // b + ((a << 1) + 510)
13915
13916 // Many instructions can perform the shift for free, but it requires both
13917 // the operands to be registers. If c1 << c2 is too large, a mov immediate
13918 // instruction will needed. So, unfold back to the original pattern if:
13919 // - if c1 and c2 are small enough that they don't require mov imms.
13920 // - the user(s) of the node can perform an shl
13921
13922 // No shifted operands for 16-bit instructions.
13923 if (ST->isThumb1Only())
13924 return SDValue();
13925
13926 // Check that all the users could perform the shl themselves.
13927 for (auto *U : N->users()) {
13928 switch(U->getOpcode()) {
13929 default:
13930 return SDValue();
13931 case ISD::SUB:
13932 case ISD::ADD:
13933 case ISD::AND:
13934 case ISD::OR:
13935 case ISD::XOR:
13936 case ISD::SETCC:
13937 case ARMISD::CMP:
13938 // Check that the user isn't already using a constant because there
13939 // aren't any instructions that support an immediate operand and a
13940 // shifted operand.
13941 if (isa<ConstantSDNode>(U->getOperand(0)) ||
13942 isa<ConstantSDNode>(U->getOperand(1)))
13943 return SDValue();
13944
13945 // Check that it's not already using a shift.
13946 if (U->getOperand(0).getOpcode() == ISD::SHL ||
13947 U->getOperand(1).getOpcode() == ISD::SHL)
13948 return SDValue();
13949 break;
13950 }
13951 }
13952
13953 if (N->getOpcode() != ISD::ADD && N->getOpcode() != ISD::OR &&
13954 N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND)
13955 return SDValue();
13956
13957 if (N->getOperand(0).getOpcode() != ISD::SHL)
13958 return SDValue();
13959
13960 SDValue SHL = N->getOperand(0);
13961
13962 auto *C1ShlC2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
13963 auto *C2 = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
13964 if (!C1ShlC2 || !C2)
13965 return SDValue();
13966
13967 APInt C2Int = C2->getAPIntValue();
13968 APInt C1Int = C1ShlC2->getAPIntValue();
13969 unsigned C2Width = C2Int.getBitWidth();
13970 if (C2Int.uge(C2Width))
13971 return SDValue();
13972 uint64_t C2Value = C2Int.getZExtValue();
13973
13974 // Check that performing a lshr will not lose any information.
13975 APInt Mask = APInt::getHighBitsSet(C2Width, C2Width - C2Value);
13976 if ((C1Int & Mask) != C1Int)
13977 return SDValue();
13978
13979 // Shift the first constant.
13980 C1Int.lshrInPlace(C2Int);
13981
13982 // The immediates are encoded as an 8-bit value that can be rotated.
13983 auto LargeImm = [](const APInt &Imm) {
13984 unsigned Zeros = Imm.countl_zero() + Imm.countr_zero();
13985 return Imm.getBitWidth() - Zeros > 8;
13986 };
13987
13988 if (LargeImm(C1Int) || LargeImm(C2Int))
13989 return SDValue();
13990
13991 SelectionDAG &DAG = DCI.DAG;
13992 SDLoc dl(N);
13993 SDValue X = SHL.getOperand(0);
13994 SDValue BinOp = DAG.getNode(N->getOpcode(), dl, MVT::i32, X,
13995 DAG.getConstant(C1Int, dl, MVT::i32));
13996 // Shift left to compensate for the lshr of C1Int.
13997 SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
13998
13999 LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
14000 SHL.dump(); N->dump());
14001 LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
14002 return Res;
14003}
14004
14005
14006/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
14007///
14010 const ARMSubtarget *Subtarget) {
14011 SDValue N0 = N->getOperand(0);
14012 SDValue N1 = N->getOperand(1);
14013
14014 // Only works one way, because it needs an immediate operand.
14015 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14016 return Result;
14017
14018 if (SDValue Result = PerformADDVecReduce(N, DCI.DAG, Subtarget))
14019 return Result;
14020
14021 // First try with the default operand order.
14022 if (SDValue Result = PerformADDCombineWithOperands(N, N0, N1, DCI, Subtarget))
14023 return Result;
14024
14025 // If that didn't work, try again with the operands commuted.
14026 return PerformADDCombineWithOperands(N, N1, N0, DCI, Subtarget);
14027}
14028
14029// Combine (sub 0, (csinc X, Y, CC)) -> (csinv -X, Y, CC)
14030// providing -X is as cheap as X (currently, just a constant).
14032 if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
14033 return SDValue();
14034 SDValue CSINC = N->getOperand(1);
14035 if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
14036 return SDValue();
14037
14039 if (!X)
14040 return SDValue();
14041
14042 return DAG.getNode(ARMISD::CSINV, SDLoc(N), MVT::i32,
14043 DAG.getNode(ISD::SUB, SDLoc(N), MVT::i32, N->getOperand(0),
14044 CSINC.getOperand(0)),
14045 CSINC.getOperand(1), CSINC.getOperand(2),
14046 CSINC.getOperand(3));
14047}
14048
14050 // Free to negate.
14052 return 0;
14053
14054 // Will save one instruction.
14055 if (Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)))
14056 return -1;
14057
14058 // Can freely negate by converting sra <-> srl.
14059 if (Op.getOpcode() == ISD::SRA || Op.getOpcode() == ISD::SRL) {
14060 ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1));
14061 if (Op.hasOneUse() && ShiftAmt &&
14062 ShiftAmt->getZExtValue() == Op.getValueType().getScalarSizeInBits() - 1)
14063 return 0;
14064 }
14065
14066 // Will have to create sub.
14067 return 1;
14068}
14069
14070// Try to fold
14071//
14072// (neg (cmov X, Y)) -> (cmov (neg X), (neg Y))
14073//
14074// The folding helps cmov to be matched with csneg without generating
14075// redundant neg instruction.
14077 assert(N->getOpcode() == ISD::SUB);
14078 if (!isNullConstant(N->getOperand(0)))
14079 return SDValue();
14080
14081 SDValue CMov = N->getOperand(1);
14082 if (CMov.getOpcode() != ARMISD::CMOV || !CMov->hasOneUse())
14083 return SDValue();
14084
14085 SDValue N0 = CMov.getOperand(0);
14086 SDValue N1 = CMov.getOperand(1);
14087
14088 // Only perform the fold if we actually save something.
14089 if (getNegationCost(N0) + getNegationCost(N1) > 0)
14090 return SDValue();
14091
14092 SDLoc DL(N);
14093 EVT VT = CMov.getValueType();
14094
14095 SDValue N0N = DAG.getNegative(N0, DL, VT);
14096 SDValue N1N = DAG.getNegative(N1, DL, VT);
14097 return DAG.getNode(ARMISD::CMOV, DL, VT, N0N, N1N, CMov.getOperand(2),
14098 CMov.getOperand(3));
14099}
14100
14101/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
14102///
14105 const ARMSubtarget *Subtarget) {
14106 SDValue N0 = N->getOperand(0);
14107 SDValue N1 = N->getOperand(1);
14108
14109 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
14110 if (N1.getNode()->hasOneUse())
14111 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI))
14112 return Result;
14113
14114 if (SDValue R = PerformSubCSINCCombine(N, DCI.DAG))
14115 return R;
14116
14117 if (SDValue Val = performNegCMovCombine(N, DCI.DAG))
14118 return Val;
14119
14120 if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector())
14121 return SDValue();
14122
14123 // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x))
14124 // so that we can readily pattern match more mve instructions which can use
14125 // a scalar operand.
14126 SDValue VDup = N->getOperand(1);
14127 if (VDup->getOpcode() != ARMISD::VDUP)
14128 return SDValue();
14129
14130 SDValue VMov = N->getOperand(0);
14131 if (VMov->getOpcode() == ISD::BITCAST)
14132 VMov = VMov->getOperand(0);
14133
14134 if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov))
14135 return SDValue();
14136
14137 SDLoc dl(N);
14138 SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32,
14139 DCI.DAG.getConstant(0, dl, MVT::i32),
14140 VDup->getOperand(0));
14141 return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate);
14142}
14143
14144/// PerformVMULCombine
14145/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the
14146/// special multiplier accumulator forwarding.
14147/// vmul d3, d0, d2
14148/// vmla d3, d1, d2
14149/// is faster than
14150/// vadd d3, d0, d1
14151/// vmul d3, d3, d2
14152// However, for (A + B) * (A + B),
14153// vadd d2, d0, d1
14154// vmul d3, d0, d2
14155// vmla d3, d1, d2
14156// is slower than
14157// vadd d2, d0, d1
14158// vmul d3, d2, d2
14161 const ARMSubtarget *Subtarget) {
14162 if (!Subtarget->hasVMLxForwarding())
14163 return SDValue();
14164
14165 SelectionDAG &DAG = DCI.DAG;
14166 SDValue N0 = N->getOperand(0);
14167 SDValue N1 = N->getOperand(1);
14168 unsigned Opcode = N0.getOpcode();
14169 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14170 Opcode != ISD::FADD && Opcode != ISD::FSUB) {
14171 Opcode = N1.getOpcode();
14172 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14173 Opcode != ISD::FADD && Opcode != ISD::FSUB)
14174 return SDValue();
14175 std::swap(N0, N1);
14176 }
14177
14178 if (N0 == N1)
14179 return SDValue();
14180
14181 EVT VT = N->getValueType(0);
14182 SDLoc DL(N);
14183 SDValue N00 = N0->getOperand(0);
14184 SDValue N01 = N0->getOperand(1);
14185 return DAG.getNode(Opcode, DL, VT,
14186 DAG.getNode(ISD::MUL, DL, VT, N00, N1),
14187 DAG.getNode(ISD::MUL, DL, VT, N01, N1));
14188}
14189
14191 const ARMSubtarget *Subtarget) {
14192 EVT VT = N->getValueType(0);
14193 if (VT != MVT::v2i64)
14194 return SDValue();
14195
14196 SDValue N0 = N->getOperand(0);
14197 SDValue N1 = N->getOperand(1);
14198
14199 auto IsSignExt = [&](SDValue Op) {
14200 if (Op->getOpcode() != ISD::SIGN_EXTEND_INREG)
14201 return SDValue();
14202 EVT VT = cast<VTSDNode>(Op->getOperand(1))->getVT();
14203 if (VT.getScalarSizeInBits() == 32)
14204 return Op->getOperand(0);
14205 return SDValue();
14206 };
14207 auto IsZeroExt = [&](SDValue Op) {
14208 // Zero extends are a little more awkward. At the point we are matching
14209 // this, we are looking for an AND with a (-1, 0, -1, 0) buildvector mask.
14210 // That might be before of after a bitcast depending on how the and is
14211 // placed. Because this has to look through bitcasts, it is currently only
14212 // supported on LE.
14213 if (!Subtarget->isLittle())
14214 return SDValue();
14215
14216 SDValue And = Op;
14217 if (And->getOpcode() == ISD::BITCAST)
14218 And = And->getOperand(0);
14219 if (And->getOpcode() != ISD::AND)
14220 return SDValue();
14221 SDValue Mask = And->getOperand(1);
14222 if (Mask->getOpcode() == ISD::BITCAST)
14223 Mask = Mask->getOperand(0);
14224
14225 if (Mask->getOpcode() != ISD::BUILD_VECTOR ||
14226 Mask.getValueType() != MVT::v4i32)
14227 return SDValue();
14228 if (isAllOnesConstant(Mask->getOperand(0)) &&
14229 isNullConstant(Mask->getOperand(1)) &&
14230 isAllOnesConstant(Mask->getOperand(2)) &&
14231 isNullConstant(Mask->getOperand(3)))
14232 return And->getOperand(0);
14233 return SDValue();
14234 };
14235
14236 SDLoc dl(N);
14237 if (SDValue Op0 = IsSignExt(N0)) {
14238 if (SDValue Op1 = IsSignExt(N1)) {
14239 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14240 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14241 return DAG.getNode(ARMISD::VMULLs, dl, VT, New0a, New1a);
14242 }
14243 }
14244 if (SDValue Op0 = IsZeroExt(N0)) {
14245 if (SDValue Op1 = IsZeroExt(N1)) {
14246 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14247 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14248 return DAG.getNode(ARMISD::VMULLu, dl, VT, New0a, New1a);
14249 }
14250 }
14251
14252 return SDValue();
14253}
14254
14257 const ARMSubtarget *Subtarget) {
14258 SelectionDAG &DAG = DCI.DAG;
14259
14260 EVT VT = N->getValueType(0);
14261 if (Subtarget->hasMVEIntegerOps() && VT == MVT::v2i64)
14262 return PerformMVEVMULLCombine(N, DAG, Subtarget);
14263
14264 if (Subtarget->isThumb1Only())
14265 return SDValue();
14266
14267 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14268 return SDValue();
14269
14270 if (VT.is64BitVector() || VT.is128BitVector())
14271 return PerformVMULCombine(N, DCI, Subtarget);
14272 if (VT != MVT::i32)
14273 return SDValue();
14274
14275 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14276 if (!C)
14277 return SDValue();
14278
14279 int64_t MulAmt = C->getSExtValue();
14280 unsigned ShiftAmt = llvm::countr_zero<uint64_t>(MulAmt);
14281
14282 ShiftAmt = ShiftAmt & (32 - 1);
14283 SDValue V = N->getOperand(0);
14284 SDLoc DL(N);
14285
14286 SDValue Res;
14287 MulAmt >>= ShiftAmt;
14288
14289 if (MulAmt >= 0) {
14290 if (llvm::has_single_bit<uint32_t>(MulAmt - 1)) {
14291 // (mul x, 2^N + 1) => (add (shl x, N), x)
14292 Res = DAG.getNode(ISD::ADD, DL, VT,
14293 V,
14294 DAG.getNode(ISD::SHL, DL, VT,
14295 V,
14296 DAG.getConstant(Log2_32(MulAmt - 1), DL,
14297 MVT::i32)));
14298 } else if (llvm::has_single_bit<uint32_t>(MulAmt + 1)) {
14299 // (mul x, 2^N - 1) => (sub (shl x, N), x)
14300 Res = DAG.getNode(ISD::SUB, DL, VT,
14301 DAG.getNode(ISD::SHL, DL, VT,
14302 V,
14303 DAG.getConstant(Log2_32(MulAmt + 1), DL,
14304 MVT::i32)),
14305 V);
14306 } else
14307 return SDValue();
14308 } else {
14309 uint64_t MulAmtAbs = -MulAmt;
14310 if (llvm::has_single_bit<uint32_t>(MulAmtAbs + 1)) {
14311 // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
14312 Res = DAG.getNode(ISD::SUB, DL, VT,
14313 V,
14314 DAG.getNode(ISD::SHL, DL, VT,
14315 V,
14316 DAG.getConstant(Log2_32(MulAmtAbs + 1), DL,
14317 MVT::i32)));
14318 } else if (llvm::has_single_bit<uint32_t>(MulAmtAbs - 1)) {
14319 // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
14320 Res = DAG.getNode(ISD::ADD, DL, VT,
14321 V,
14322 DAG.getNode(ISD::SHL, DL, VT,
14323 V,
14324 DAG.getConstant(Log2_32(MulAmtAbs - 1), DL,
14325 MVT::i32)));
14326 Res = DAG.getNode(ISD::SUB, DL, VT,
14327 DAG.getConstant(0, DL, MVT::i32), Res);
14328 } else
14329 return SDValue();
14330 }
14331
14332 if (ShiftAmt != 0)
14333 Res = DAG.getNode(ISD::SHL, DL, VT,
14334 Res, DAG.getConstant(ShiftAmt, DL, MVT::i32));
14335
14336 // Do not add new nodes to DAG combiner worklist.
14337 DCI.CombineTo(N, Res, false);
14338 return SDValue();
14339}
14340
14343 const ARMSubtarget *Subtarget) {
14344 // Allow DAGCombine to pattern-match before we touch the canonical form.
14345 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14346 return SDValue();
14347
14348 if (N->getValueType(0) != MVT::i32)
14349 return SDValue();
14350
14351 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14352 if (!N1C)
14353 return SDValue();
14354
14355 uint32_t C1 = (uint32_t)N1C->getZExtValue();
14356 // Don't transform uxtb/uxth.
14357 if (C1 == 255 || C1 == 65535)
14358 return SDValue();
14359
14360 SDNode *N0 = N->getOperand(0).getNode();
14361 if (!N0->hasOneUse())
14362 return SDValue();
14363
14364 if (N0->getOpcode() != ISD::SHL && N0->getOpcode() != ISD::SRL)
14365 return SDValue();
14366
14367 bool LeftShift = N0->getOpcode() == ISD::SHL;
14368
14370 if (!N01C)
14371 return SDValue();
14372
14373 uint32_t C2 = (uint32_t)N01C->getZExtValue();
14374 if (!C2 || C2 >= 32)
14375 return SDValue();
14376
14377 // Clear irrelevant bits in the mask.
14378 if (LeftShift)
14379 C1 &= (-1U << C2);
14380 else
14381 C1 &= (-1U >> C2);
14382
14383 SelectionDAG &DAG = DCI.DAG;
14384 SDLoc DL(N);
14385
14386 // We have a pattern of the form "(and (shl x, c2) c1)" or
14387 // "(and (srl x, c2) c1)", where c1 is a shifted mask. Try to
14388 // transform to a pair of shifts, to save materializing c1.
14389
14390 // First pattern: right shift, then mask off leading bits.
14391 // FIXME: Use demanded bits?
14392 if (!LeftShift && isMask_32(C1)) {
14393 uint32_t C3 = llvm::countl_zero(C1);
14394 if (C2 < C3) {
14395 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14396 DAG.getConstant(C3 - C2, DL, MVT::i32));
14397 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14398 DAG.getConstant(C3, DL, MVT::i32));
14399 }
14400 }
14401
14402 // First pattern, reversed: left shift, then mask off trailing bits.
14403 if (LeftShift && isMask_32(~C1)) {
14404 uint32_t C3 = llvm::countr_zero(C1);
14405 if (C2 < C3) {
14406 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14407 DAG.getConstant(C3 - C2, DL, MVT::i32));
14408 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14409 DAG.getConstant(C3, DL, MVT::i32));
14410 }
14411 }
14412
14413 // Second pattern: left shift, then mask off leading bits.
14414 // FIXME: Use demanded bits?
14415 if (LeftShift && isShiftedMask_32(C1)) {
14416 uint32_t Trailing = llvm::countr_zero(C1);
14417 uint32_t C3 = llvm::countl_zero(C1);
14418 if (Trailing == C2 && C2 + C3 < 32) {
14419 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14420 DAG.getConstant(C2 + C3, DL, MVT::i32));
14421 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14422 DAG.getConstant(C3, DL, MVT::i32));
14423 }
14424 }
14425
14426 // Second pattern, reversed: right shift, then mask off trailing bits.
14427 // FIXME: Handle other patterns of known/demanded bits.
14428 if (!LeftShift && isShiftedMask_32(C1)) {
14429 uint32_t Leading = llvm::countl_zero(C1);
14430 uint32_t C3 = llvm::countr_zero(C1);
14431 if (Leading == C2 && C2 + C3 < 32) {
14432 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14433 DAG.getConstant(C2 + C3, DL, MVT::i32));
14434 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14435 DAG.getConstant(C3, DL, MVT::i32));
14436 }
14437 }
14438
14439 // Transform "(and (shl x, c2) c1)" into "(shl (and x, c1>>c2), c2)"
14440 // if "c1 >> c2" is a cheaper immediate than "c1"
14441 if (LeftShift &&
14442 HasLowerConstantMaterializationCost(C1 >> C2, C1, Subtarget)) {
14443
14444 SDValue And = DAG.getNode(ISD::AND, DL, MVT::i32, N0->getOperand(0),
14445 DAG.getConstant(C1 >> C2, DL, MVT::i32));
14446 return DAG.getNode(ISD::SHL, DL, MVT::i32, And,
14447 DAG.getConstant(C2, DL, MVT::i32));
14448 }
14449
14450 return SDValue();
14451}
14452
14455 const ARMSubtarget *Subtarget) {
14456 // Attempt to use immediate-form VBIC
14457 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14458 SDLoc dl(N);
14459 EVT VT = N->getValueType(0);
14460 SelectionDAG &DAG = DCI.DAG;
14461
14462 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) || VT == MVT::v2i1 ||
14463 VT == MVT::v4i1 || VT == MVT::v8i1 || VT == MVT::v16i1)
14464 return SDValue();
14465
14466 APInt SplatBits, SplatUndef;
14467 unsigned SplatBitSize;
14468 bool HasAnyUndefs;
14469 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14470 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14471 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14472 SplatBitSize == 64) {
14473 EVT VbicVT;
14474 SDValue Val = isVMOVModifiedImm((~SplatBits).getZExtValue(),
14475 SplatUndef.getZExtValue(), SplatBitSize,
14476 DAG, dl, VbicVT, VT, OtherModImm);
14477 if (Val.getNode()) {
14478 SDValue Input =
14479 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VbicVT, N->getOperand(0));
14480 SDValue Vbic = DAG.getNode(ARMISD::VBICIMM, dl, VbicVT, Input, Val);
14481 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vbic);
14482 }
14483 }
14484 }
14485
14486 if (!Subtarget->isThumb1Only()) {
14487 // fold (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))
14488 if (SDValue Result = combineSelectAndUseCommutative(N, true, DCI))
14489 return Result;
14490
14491 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14492 return Result;
14493 }
14494
14495 if (Subtarget->isThumb1Only())
14496 if (SDValue Result = CombineANDShift(N, DCI, Subtarget))
14497 return Result;
14498
14499 return SDValue();
14500}
14501
14502// Try combining OR nodes to SMULWB, SMULWT.
14505 const ARMSubtarget *Subtarget) {
14506 if (!Subtarget->hasV6Ops() ||
14507 (Subtarget->isThumb() &&
14508 (!Subtarget->hasThumb2() || !Subtarget->hasDSP())))
14509 return SDValue();
14510
14511 SDValue SRL = OR->getOperand(0);
14512 SDValue SHL = OR->getOperand(1);
14513
14514 if (SRL.getOpcode() != ISD::SRL || SHL.getOpcode() != ISD::SHL) {
14515 SRL = OR->getOperand(1);
14516 SHL = OR->getOperand(0);
14517 }
14518 if (!isSRL16(SRL) || !isSHL16(SHL))
14519 return SDValue();
14520
14521 // The first operands to the shifts need to be the two results from the
14522 // same smul_lohi node.
14523 if ((SRL.getOperand(0).getNode() != SHL.getOperand(0).getNode()) ||
14524 SRL.getOperand(0).getOpcode() != ISD::SMUL_LOHI)
14525 return SDValue();
14526
14527 SDNode *SMULLOHI = SRL.getOperand(0).getNode();
14528 if (SRL.getOperand(0) != SDValue(SMULLOHI, 0) ||
14529 SHL.getOperand(0) != SDValue(SMULLOHI, 1))
14530 return SDValue();
14531
14532 // Now we have:
14533 // (or (srl (smul_lohi ?, ?), 16), (shl (smul_lohi ?, ?), 16)))
14534 // For SMUL[B|T] smul_lohi will take a 32-bit and a 16-bit arguments.
14535 // For SMUWB the 16-bit value will signed extended somehow.
14536 // For SMULWT only the SRA is required.
14537 // Check both sides of SMUL_LOHI
14538 SDValue OpS16 = SMULLOHI->getOperand(0);
14539 SDValue OpS32 = SMULLOHI->getOperand(1);
14540
14541 SelectionDAG &DAG = DCI.DAG;
14542 if (!isS16(OpS16, DAG) && !isSRA16(OpS16)) {
14543 OpS16 = OpS32;
14544 OpS32 = SMULLOHI->getOperand(0);
14545 }
14546
14547 SDLoc dl(OR);
14548 unsigned Opcode = 0;
14549 if (isS16(OpS16, DAG))
14550 Opcode = ARMISD::SMULWB;
14551 else if (isSRA16(OpS16)) {
14552 Opcode = ARMISD::SMULWT;
14553 OpS16 = OpS16->getOperand(0);
14554 }
14555 else
14556 return SDValue();
14557
14558 SDValue Res = DAG.getNode(Opcode, dl, MVT::i32, OpS32, OpS16);
14559 DAG.ReplaceAllUsesOfValueWith(SDValue(OR, 0), Res);
14560 return SDValue(OR, 0);
14561}
14562
14565 const ARMSubtarget *Subtarget) {
14566 // BFI is only available on V6T2+
14567 if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
14568 return SDValue();
14569
14570 EVT VT = N->getValueType(0);
14571 SDValue N0 = N->getOperand(0);
14572 SDValue N1 = N->getOperand(1);
14573 SelectionDAG &DAG = DCI.DAG;
14574 SDLoc DL(N);
14575 // 1) or (and A, mask), val => ARMbfi A, val, mask
14576 // iff (val & mask) == val
14577 //
14578 // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14579 // 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
14580 // && mask == ~mask2
14581 // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
14582 // && ~mask == mask2
14583 // (i.e., copy a bitfield value into another bitfield of the same width)
14584
14585 if (VT != MVT::i32)
14586 return SDValue();
14587
14588 SDValue N00 = N0.getOperand(0);
14589
14590 // The value and the mask need to be constants so we can verify this is
14591 // actually a bitfield set. If the mask is 0xffff, we can do better
14592 // via a movt instruction, so don't use BFI in that case.
14593 SDValue MaskOp = N0.getOperand(1);
14595 if (!MaskC)
14596 return SDValue();
14597 unsigned Mask = MaskC->getZExtValue();
14598 if (Mask == 0xffff)
14599 return SDValue();
14600 SDValue Res;
14601 // Case (1): or (and A, mask), val => ARMbfi A, val, mask
14603 if (N1C) {
14604 unsigned Val = N1C->getZExtValue();
14605 if ((Val & ~Mask) != Val)
14606 return SDValue();
14607
14608 if (ARM::isBitFieldInvertedMask(Mask)) {
14609 Val >>= llvm::countr_zero(~Mask);
14610
14611 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
14612 DAG.getConstant(Val, DL, MVT::i32),
14613 DAG.getConstant(Mask, DL, MVT::i32));
14614
14615 DCI.CombineTo(N, Res, false);
14616 // Return value from the original node to inform the combiner than N is
14617 // now dead.
14618 return SDValue(N, 0);
14619 }
14620 } else if (N1.getOpcode() == ISD::AND) {
14621 // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14623 if (!N11C)
14624 return SDValue();
14625 unsigned Mask2 = N11C->getZExtValue();
14626
14627 // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
14628 // as is to match.
14629 if (ARM::isBitFieldInvertedMask(Mask) &&
14630 (Mask == ~Mask2)) {
14631 // The pack halfword instruction works better for masks that fit it,
14632 // so use that when it's available.
14633 if (Subtarget->hasDSP() &&
14634 (Mask == 0xffff || Mask == 0xffff0000))
14635 return SDValue();
14636 // 2a
14637 unsigned amt = llvm::countr_zero(Mask2);
14638 Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
14639 DAG.getConstant(amt, DL, MVT::i32));
14640 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
14641 DAG.getConstant(Mask, DL, MVT::i32));
14642 DCI.CombineTo(N, Res, false);
14643 // Return value from the original node to inform the combiner than N is
14644 // now dead.
14645 return SDValue(N, 0);
14646 } else if (ARM::isBitFieldInvertedMask(~Mask) &&
14647 (~Mask == Mask2)) {
14648 // The pack halfword instruction works better for masks that fit it,
14649 // so use that when it's available.
14650 if (Subtarget->hasDSP() &&
14651 (Mask2 == 0xffff || Mask2 == 0xffff0000))
14652 return SDValue();
14653 // 2b
14654 unsigned lsb = llvm::countr_zero(Mask);
14655 Res = DAG.getNode(ISD::SRL, DL, VT, N00,
14656 DAG.getConstant(lsb, DL, MVT::i32));
14657 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
14658 DAG.getConstant(Mask2, DL, MVT::i32));
14659 DCI.CombineTo(N, Res, false);
14660 // Return value from the original node to inform the combiner than N is
14661 // now dead.
14662 return SDValue(N, 0);
14663 }
14664 }
14665
14666 if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
14667 N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
14669 // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
14670 // where lsb(mask) == #shamt and masked bits of B are known zero.
14671 SDValue ShAmt = N00.getOperand(1);
14672 unsigned ShAmtC = ShAmt->getAsZExtVal();
14673 unsigned LSB = llvm::countr_zero(Mask);
14674 if (ShAmtC != LSB)
14675 return SDValue();
14676
14677 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
14678 DAG.getConstant(~Mask, DL, MVT::i32));
14679
14680 DCI.CombineTo(N, Res, false);
14681 // Return value from the original node to inform the combiner than N is
14682 // now dead.
14683 return SDValue(N, 0);
14684 }
14685
14686 return SDValue();
14687}
14688
14689static bool isValidMVECond(unsigned CC, bool IsFloat) {
14690 switch (CC) {
14691 case ARMCC::EQ:
14692 case ARMCC::NE:
14693 case ARMCC::LE:
14694 case ARMCC::GT:
14695 case ARMCC::GE:
14696 case ARMCC::LT:
14697 return true;
14698 case ARMCC::HS:
14699 case ARMCC::HI:
14700 return !IsFloat;
14701 default:
14702 return false;
14703 };
14704}
14705
14707 if (N->getOpcode() == ARMISD::VCMP)
14708 return (ARMCC::CondCodes)N->getConstantOperandVal(2);
14709 else if (N->getOpcode() == ARMISD::VCMPZ)
14710 return (ARMCC::CondCodes)N->getConstantOperandVal(1);
14711 else
14712 llvm_unreachable("Not a VCMP/VCMPZ!");
14713}
14714
14717 return isValidMVECond(CC, N->getOperand(0).getValueType().isFloatingPoint());
14718}
14719
14721 const ARMSubtarget *Subtarget) {
14722 // Try to invert "or A, B" -> "and ~A, ~B", as the "and" is easier to chain
14723 // together with predicates
14724 EVT VT = N->getValueType(0);
14725 SDLoc DL(N);
14726 SDValue N0 = N->getOperand(0);
14727 SDValue N1 = N->getOperand(1);
14728
14729 auto IsFreelyInvertable = [&](SDValue V) {
14730 if (V->getOpcode() == ARMISD::VCMP || V->getOpcode() == ARMISD::VCMPZ)
14731 return CanInvertMVEVCMP(V);
14732 return false;
14733 };
14734
14735 // At least one operand must be freely invertable.
14736 if (!(IsFreelyInvertable(N0) || IsFreelyInvertable(N1)))
14737 return SDValue();
14738
14739 SDValue NewN0 = DAG.getLogicalNOT(DL, N0, VT);
14740 SDValue NewN1 = DAG.getLogicalNOT(DL, N1, VT);
14741 SDValue And = DAG.getNode(ISD::AND, DL, VT, NewN0, NewN1);
14742 return DAG.getLogicalNOT(DL, And, VT);
14743}
14744
14745// Try to form a NEON shift-{right, left}-and-insert (VSRI/VSLI) from:
14746// (or (and X, splat (i32 C1)), (srl Y, splat (i32 C2))) -> VSRI X, Y, #C2
14747// (or (and X, splat (i32 C1)), (shl Y, splat (i32 C2))) -> VSLI X, Y, #C2
14748// where C1 is a mask that preserves the bits not written by the shift/insert,
14749// i.e. `C1 == (1 << C2) - 1`.
14751 SDValue ShiftOp, EVT VT,
14752 SDLoc dl) {
14753 // Match (and X, Mask)
14754 if (AndOp.getOpcode() != ISD::AND)
14755 return SDValue();
14756
14757 SDValue X = AndOp.getOperand(0);
14758 SDValue Mask = AndOp.getOperand(1);
14759
14760 ConstantSDNode *MaskC = isConstOrConstSplat(Mask, false, true);
14761 if (!MaskC)
14762 return SDValue();
14763 APInt MaskBits =
14764 MaskC->getAPIntValue().trunc(Mask.getScalarValueSizeInBits());
14765
14766 // Match shift (srl/shl Y, CntVec)
14767 int64_t Cnt = 0;
14768 bool IsShiftRight = false;
14769 SDValue Y;
14770
14771 if (ShiftOp.getOpcode() == ARMISD::VSHRuIMM) {
14772 IsShiftRight = true;
14773 Y = ShiftOp.getOperand(0);
14774 Cnt = ShiftOp.getConstantOperandVal(1);
14775 } else if (ShiftOp.getOpcode() == ARMISD::VSHLIMM) {
14776 Y = ShiftOp.getOperand(0);
14777 Cnt = ShiftOp.getConstantOperandVal(1);
14778 } else {
14779 return SDValue();
14780 }
14781
14782 unsigned ElemBits = VT.getScalarSizeInBits();
14783 APInt RequiredMask = IsShiftRight
14784 ? APInt::getHighBitsSet(ElemBits, (unsigned)Cnt)
14785 : APInt::getLowBitsSet(ElemBits, (unsigned)Cnt);
14786 if (MaskBits != RequiredMask)
14787 return SDValue();
14788
14789 unsigned Opc = IsShiftRight ? ARMISD::VSRIIMM : ARMISD::VSLIIMM;
14790 return DAG.getNode(Opc, dl, VT, X, Y, DAG.getConstant(Cnt, dl, MVT::i32));
14791}
14792
14793/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
14795 const ARMSubtarget *Subtarget) {
14796 // Attempt to use immediate-form VORR
14797 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14798 SDLoc dl(N);
14799 EVT VT = N->getValueType(0);
14800 SelectionDAG &DAG = DCI.DAG;
14801
14802 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14803 return SDValue();
14804
14805 if (Subtarget->hasMVEIntegerOps() && (VT == MVT::v2i1 || VT == MVT::v4i1 ||
14806 VT == MVT::v8i1 || VT == MVT::v16i1))
14807 return PerformORCombine_i1(N, DAG, Subtarget);
14808
14809 APInt SplatBits, SplatUndef;
14810 unsigned SplatBitSize;
14811 bool HasAnyUndefs;
14812 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14813 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14814 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14815 SplatBitSize == 64) {
14816 EVT VorrVT;
14817 SDValue Val =
14818 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
14819 SplatBitSize, DAG, dl, VorrVT, VT, OtherModImm);
14820 if (Val.getNode()) {
14821 SDValue Input =
14822 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VorrVT, N->getOperand(0));
14823 SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
14824 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vorr);
14825 }
14826 }
14827 }
14828
14829 if (!Subtarget->isThumb1Only()) {
14830 // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
14831 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14832 return Result;
14833 if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
14834 return Result;
14835 }
14836
14837 SDValue N0 = N->getOperand(0);
14838 SDValue N1 = N->getOperand(1);
14839
14840 // (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
14841 // (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
14842 if (VT.isVector() &&
14843 ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
14844 (Subtarget->hasMVEIntegerOps() &&
14845 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
14846 if (SDValue ShiftInsert =
14847 PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
14848 return ShiftInsert;
14849
14850 if (SDValue ShiftInsert =
14851 PerformORCombineToShiftInsert(DAG, N1, N0, VT, dl))
14852 return ShiftInsert;
14853 }
14854
14855 // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
14856 if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
14858
14859 // The code below optimizes (or (and X, Y), Z).
14860 // The AND operand needs to have a single user to make these optimizations
14861 // profitable.
14862 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
14863 return SDValue();
14864
14865 APInt SplatUndef;
14866 unsigned SplatBitSize;
14867 bool HasAnyUndefs;
14868
14869 APInt SplatBits0, SplatBits1;
14872 // Ensure that the second operand of both ands are constants
14873 if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
14874 HasAnyUndefs) && !HasAnyUndefs) {
14875 if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
14876 HasAnyUndefs) && !HasAnyUndefs) {
14877 // Ensure that the bit width of the constants are the same and that
14878 // the splat arguments are logical inverses as per the pattern we
14879 // are trying to simplify.
14880 if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
14881 SplatBits0 == ~SplatBits1) {
14882 // Canonicalize the vector type to make instruction selection
14883 // simpler.
14884 EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
14885 SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
14886 N0->getOperand(1),
14887 N0->getOperand(0),
14888 N1->getOperand(0));
14889 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Result);
14890 }
14891 }
14892 }
14893 }
14894
14895 // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
14896 // reasonable.
14897 if (N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
14898 if (SDValue Res = PerformORCombineToBFI(N, DCI, Subtarget))
14899 return Res;
14900 }
14901
14902 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14903 return Result;
14904
14905 // (or x, (csinc 0, 0, cc)) -> (csinc x, 0, cc)
14906 // providing that the x is 0 or 1.
14907 SDValue CSINC = N1;
14908 SDValue Other = N0;
14909 if (CSINC.getOpcode() != ARMISD::CSINC)
14910 std::swap(CSINC, Other);
14911 if (CSINC.getOpcode() == ARMISD::CSINC &&
14912 isNullConstant(CSINC.getOperand(0)) &&
14913 isNullConstant(CSINC.getOperand(1)) &&
14915 return DAG.getNode(ARMISD::CSINC, dl, VT, Other, CSINC.getOperand(1),
14916 CSINC.getOperand(2), CSINC.getOperand(3));
14917
14918 return SDValue();
14919}
14920
14923 const ARMSubtarget *Subtarget) {
14924 EVT VT = N->getValueType(0);
14925 SelectionDAG &DAG = DCI.DAG;
14926
14927 if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14928 return SDValue();
14929
14930 if (!Subtarget->isThumb1Only()) {
14931 // fold (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
14932 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14933 return Result;
14934
14935 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14936 return Result;
14937 }
14938
14939 if (Subtarget->hasMVEIntegerOps()) {
14940 // fold (xor(vcmp/z, 1)) into a vcmp with the opposite condition.
14941 SDValue N0 = N->getOperand(0);
14942 SDValue N1 = N->getOperand(1);
14943 const TargetLowering *TLI = Subtarget->getTargetLowering();
14944 if (TLI->isConstTrueVal(N1) &&
14945 (N0->getOpcode() == ARMISD::VCMP || N0->getOpcode() == ARMISD::VCMPZ)) {
14946 if (CanInvertMVEVCMP(N0)) {
14947 SDLoc DL(N0);
14949
14951 Ops.push_back(N0->getOperand(0));
14952 if (N0->getOpcode() == ARMISD::VCMP)
14953 Ops.push_back(N0->getOperand(1));
14954 Ops.push_back(DAG.getConstant(CC, DL, MVT::i32));
14955 return DAG.getNode(N0->getOpcode(), DL, N0->getValueType(0), Ops);
14956 }
14957 }
14958 }
14959
14960 return SDValue();
14961}
14962
14963// ParseBFI - given a BFI instruction in N, extract the "from" value (Rn) and return it,
14964// and fill in FromMask and ToMask with (consecutive) bits in "from" to be extracted and
14965// their position in "to" (Rd).
14966static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask) {
14967 assert(N->getOpcode() == ARMISD::BFI);
14968
14969 SDValue From = N->getOperand(1);
14970 ToMask = ~N->getConstantOperandAPInt(2);
14971 FromMask = APInt::getLowBitsSet(ToMask.getBitWidth(), ToMask.popcount());
14972
14973 // If the Base came from a SHR #C, we can deduce that it is really testing bit
14974 // #C in the base of the SHR.
14975 if (From->getOpcode() == ISD::SRL &&
14976 isa<ConstantSDNode>(From->getOperand(1))) {
14977 APInt Shift = From->getConstantOperandAPInt(1);
14978 assert(Shift.getLimitedValue() < 32 && "Shift too large!");
14979 FromMask <<= Shift.getLimitedValue(31);
14980 From = From->getOperand(0);
14981 }
14982
14983 return From;
14984}
14985
14986// If A and B contain one contiguous set of bits, does A | B == A . B?
14987//
14988// Neither A nor B must be zero.
14989static bool BitsProperlyConcatenate(const APInt &A, const APInt &B) {
14990 unsigned LastActiveBitInA = A.countr_zero();
14991 unsigned FirstActiveBitInB = B.getBitWidth() - B.countl_zero() - 1;
14992 return LastActiveBitInA - 1 == FirstActiveBitInB;
14993}
14994
14996 // We have a BFI in N. Find a BFI it can combine with, if one exists.
14997 APInt ToMask, FromMask;
14998 SDValue From = ParseBFI(N, ToMask, FromMask);
14999 SDValue To = N->getOperand(0);
15000
15001 SDValue V = To;
15002 if (V.getOpcode() != ARMISD::BFI)
15003 return SDValue();
15004
15005 APInt NewToMask, NewFromMask;
15006 SDValue NewFrom = ParseBFI(V.getNode(), NewToMask, NewFromMask);
15007 if (NewFrom != From)
15008 return SDValue();
15009
15010 // Do the written bits conflict with any we've seen so far?
15011 if ((NewToMask & ToMask).getBoolValue())
15012 // Conflicting bits.
15013 return SDValue();
15014
15015 // Are the new bits contiguous when combined with the old bits?
15016 if (BitsProperlyConcatenate(ToMask, NewToMask) &&
15017 BitsProperlyConcatenate(FromMask, NewFromMask))
15018 return V;
15019 if (BitsProperlyConcatenate(NewToMask, ToMask) &&
15020 BitsProperlyConcatenate(NewFromMask, FromMask))
15021 return V;
15022
15023 return SDValue();
15024}
15025
15027 SDValue N0 = N->getOperand(0);
15028 SDValue N1 = N->getOperand(1);
15029
15030 if (N1.getOpcode() == ISD::AND) {
15031 // (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
15032 // the bits being cleared by the AND are not demanded by the BFI.
15034 if (!N11C)
15035 return SDValue();
15036 unsigned InvMask = N->getConstantOperandVal(2);
15037 unsigned LSB = llvm::countr_zero(~InvMask);
15038 unsigned Width = llvm::bit_width<unsigned>(~InvMask) - LSB;
15039 assert(Width <
15040 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
15041 "undefined behavior");
15042 unsigned Mask = (1u << Width) - 1;
15043 unsigned Mask2 = N11C->getZExtValue();
15044 if ((Mask & (~Mask2)) == 0)
15045 return DAG.getNode(ARMISD::BFI, SDLoc(N), N->getValueType(0),
15046 N->getOperand(0), N1.getOperand(0), N->getOperand(2));
15047 return SDValue();
15048 }
15049
15050 // Look for another BFI to combine with.
15051 if (SDValue CombineBFI = FindBFIToCombineWith(N)) {
15052 // We've found a BFI.
15053 APInt ToMask1, FromMask1;
15054 SDValue From1 = ParseBFI(N, ToMask1, FromMask1);
15055
15056 APInt ToMask2, FromMask2;
15057 SDValue From2 = ParseBFI(CombineBFI.getNode(), ToMask2, FromMask2);
15058 assert(From1 == From2);
15059 (void)From2;
15060
15061 // Create a new BFI, combining the two together.
15062 APInt NewFromMask = FromMask1 | FromMask2;
15063 APInt NewToMask = ToMask1 | ToMask2;
15064
15065 EVT VT = N->getValueType(0);
15066 SDLoc dl(N);
15067
15068 if (NewFromMask[0] == 0)
15069 From1 = DAG.getNode(ISD::SRL, dl, VT, From1,
15070 DAG.getConstant(NewFromMask.countr_zero(), dl, VT));
15071 return DAG.getNode(ARMISD::BFI, dl, VT, CombineBFI.getOperand(0), From1,
15072 DAG.getConstant(~NewToMask, dl, VT));
15073 }
15074
15075 // Reassociate BFI(BFI (A, B, M1), C, M2) to BFI(BFI (A, C, M2), B, M1) so
15076 // that lower bit insertions are performed first, providing that M1 and M2
15077 // do no overlap. This can allow multiple BFI instructions to be combined
15078 // together by the other folds above.
15079 if (N->getOperand(0).getOpcode() == ARMISD::BFI) {
15080 APInt ToMask1 = ~N->getConstantOperandAPInt(2);
15081 APInt ToMask2 = ~N0.getConstantOperandAPInt(2);
15082
15083 if (!N0.hasOneUse() || (ToMask1 & ToMask2) != 0 ||
15084 ToMask1.countl_zero() < ToMask2.countl_zero())
15085 return SDValue();
15086
15087 EVT VT = N->getValueType(0);
15088 SDLoc dl(N);
15089 SDValue BFI1 = DAG.getNode(ARMISD::BFI, dl, VT, N0.getOperand(0),
15090 N->getOperand(1), N->getOperand(2));
15091 return DAG.getNode(ARMISD::BFI, dl, VT, BFI1, N0.getOperand(1),
15092 N0.getOperand(2));
15093 }
15094
15095 return SDValue();
15096}
15097
15098// Check that N is CMPZ(CSINC(0, 0, CC, X)),
15099// or CMPZ(CMOV(1, 0, CC, X))
15100// return X if valid.
15102 if (Cmp->getOpcode() != ARMISD::CMPZ || !isNullConstant(Cmp->getOperand(1)))
15103 return SDValue();
15104 SDValue CSInc = Cmp->getOperand(0);
15105
15106 // Ignore any `And 1` nodes that may not yet have been removed. We are
15107 // looking for a value that produces 1/0, so these have no effect on the
15108 // code.
15109 while (CSInc.getOpcode() == ISD::AND &&
15110 isa<ConstantSDNode>(CSInc.getOperand(1)) &&
15111 CSInc.getConstantOperandVal(1) == 1 && CSInc->hasOneUse())
15112 CSInc = CSInc.getOperand(0);
15113
15114 if (CSInc.getOpcode() == ARMISD::CSINC &&
15115 isNullConstant(CSInc.getOperand(0)) &&
15116 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15118 return CSInc.getOperand(3);
15119 }
15120 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(0)) &&
15121 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15123 return CSInc.getOperand(3);
15124 }
15125 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(1)) &&
15126 isNullConstant(CSInc.getOperand(0)) && CSInc->hasOneUse()) {
15129 return CSInc.getOperand(3);
15130 }
15131 return SDValue();
15132}
15133
15135 // Given CMPZ(CSINC(C, 0, 0, EQ), 0), we can just use C directly. As in
15136 // t92: flags = ARMISD::CMPZ t74, 0
15137 // t93: i32 = ARMISD::CSINC 0, 0, 1, t92
15138 // t96: flags = ARMISD::CMPZ t93, 0
15139 // t114: i32 = ARMISD::CSINV 0, 0, 0, t96
15141 if (SDValue C = IsCMPZCSINC(N, Cond))
15142 if (Cond == ARMCC::EQ)
15143 return C;
15144 return SDValue();
15145}
15146
15148 // Fold away an unnecessary CMPZ/CSINC
15149 // CSXYZ A, B, C1 (CMPZ (CSINC 0, 0, C2, D), 0) ->
15150 // if C1==EQ -> CSXYZ A, B, C2, D
15151 // if C1==NE -> CSXYZ A, B, NOT(C2), D
15153 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
15154 if (N->getConstantOperandVal(2) == ARMCC::EQ)
15155 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15156 N->getOperand(1),
15157 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
15158 if (N->getConstantOperandVal(2) == ARMCC::NE)
15159 return DAG.getNode(
15160 N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15161 N->getOperand(1),
15163 }
15164 return SDValue();
15165}
15166
15167/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
15168/// ARMISD::VMOVRRD.
15171 const ARMSubtarget *Subtarget) {
15172 // vmovrrd(vmovdrr x, y) -> x,y
15173 SDValue InDouble = N->getOperand(0);
15174 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
15175 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
15176
15177 // vmovrrd(load f64) -> (load i32), (load i32)
15178 SDNode *InNode = InDouble.getNode();
15179 if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
15180 InNode->getValueType(0) == MVT::f64 &&
15181 InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
15182 !cast<LoadSDNode>(InNode)->isVolatile()) {
15183 // TODO: Should this be done for non-FrameIndex operands?
15184 LoadSDNode *LD = cast<LoadSDNode>(InNode);
15185
15186 SelectionDAG &DAG = DCI.DAG;
15187 SDLoc DL(LD);
15188 SDValue BasePtr = LD->getBasePtr();
15189 SDValue NewLD1 =
15190 DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, LD->getPointerInfo(),
15191 LD->getAlign(), LD->getMemOperand()->getFlags());
15192
15193 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
15194 DAG.getConstant(4, DL, MVT::i32));
15195
15196 SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, LD->getChain(), OffsetPtr,
15197 LD->getPointerInfo().getWithOffset(4),
15198 commonAlignment(LD->getAlign(), 4),
15199 LD->getMemOperand()->getFlags());
15200
15201 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
15202 if (DCI.DAG.getDataLayout().isBigEndian())
15203 std::swap (NewLD1, NewLD2);
15204 SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
15205 return Result;
15206 }
15207
15208 // VMOVRRD(extract(..(build_vector(a, b, c, d)))) -> a,b or c,d
15209 // VMOVRRD(extract(insert_vector(insert_vector(.., a, l1), b, l2))) -> a,b
15210 if (InDouble.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15211 isa<ConstantSDNode>(InDouble.getOperand(1))) {
15212 SDValue BV = InDouble.getOperand(0);
15213 // Look up through any nop bitcasts and vector_reg_casts. bitcasts may
15214 // change lane order under big endian.
15215 bool BVSwap = BV.getOpcode() == ISD::BITCAST;
15216 while (
15217 (BV.getOpcode() == ISD::BITCAST ||
15218 BV.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
15219 (BV.getValueType() == MVT::v2f64 || BV.getValueType() == MVT::v2i64)) {
15220 BVSwap = BV.getOpcode() == ISD::BITCAST;
15221 BV = BV.getOperand(0);
15222 }
15223 if (BV.getValueType() != MVT::v4i32)
15224 return SDValue();
15225
15226 // Handle buildvectors, pulling out the correct lane depending on
15227 // endianness.
15228 unsigned Offset = InDouble.getConstantOperandVal(1) == 1 ? 2 : 0;
15229 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
15230 SDValue Op0 = BV.getOperand(Offset);
15231 SDValue Op1 = BV.getOperand(Offset + 1);
15232 if (!Subtarget->isLittle() && BVSwap)
15233 std::swap(Op0, Op1);
15234
15235 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15236 }
15237
15238 // A chain of insert_vectors, grabbing the correct value of the chain of
15239 // inserts.
15240 SDValue Op0, Op1;
15241 while (BV.getOpcode() == ISD::INSERT_VECTOR_ELT) {
15242 if (isa<ConstantSDNode>(BV.getOperand(2))) {
15243 if (BV.getConstantOperandVal(2) == Offset && !Op0)
15244 Op0 = BV.getOperand(1);
15245 if (BV.getConstantOperandVal(2) == Offset + 1 && !Op1)
15246 Op1 = BV.getOperand(1);
15247 }
15248 BV = BV.getOperand(0);
15249 }
15250 if (!Subtarget->isLittle() && BVSwap)
15251 std::swap(Op0, Op1);
15252 if (Op0 && Op1)
15253 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15254 }
15255
15256 return SDValue();
15257}
15258
15259/// PerformVMOVDRRCombine - Target-specific dag combine xforms for
15260/// ARMISD::VMOVDRR. This is also used for BUILD_VECTORs with 2 operands.
15262 // N=vmovrrd(X); vmovdrr(N:0, N:1) -> bit_convert(X)
15263 SDValue Op0 = N->getOperand(0);
15264 SDValue Op1 = N->getOperand(1);
15265 if (Op0.getOpcode() == ISD::BITCAST)
15266 Op0 = Op0.getOperand(0);
15267 if (Op1.getOpcode() == ISD::BITCAST)
15268 Op1 = Op1.getOperand(0);
15269 if (Op0.getOpcode() == ARMISD::VMOVRRD &&
15270 Op0.getNode() == Op1.getNode() &&
15271 Op0.getResNo() == 0 && Op1.getResNo() == 1)
15272 return DAG.getNode(ISD::BITCAST, SDLoc(N),
15273 N->getValueType(0), Op0.getOperand(0));
15274 return SDValue();
15275}
15276
15279 SDValue Op0 = N->getOperand(0);
15280
15281 // VMOVhr (VMOVrh (X)) -> X
15282 if (Op0->getOpcode() == ARMISD::VMOVrh)
15283 return Op0->getOperand(0);
15284
15285 // FullFP16: half values are passed in S-registers, and we don't
15286 // need any of the bitcast and moves:
15287 //
15288 // t2: f32,ch1,gl1? = CopyFromReg ch, Register:f32 %0, gl?
15289 // t5: i32 = bitcast t2
15290 // t18: f16 = ARMISD::VMOVhr t5
15291 // =>
15292 // tN: f16,ch2,gl2? = CopyFromReg ch, Register::f32 %0, gl?
15293 if (Op0->getOpcode() == ISD::BITCAST) {
15294 SDValue Copy = Op0->getOperand(0);
15295 if (Copy.getValueType() == MVT::f32 &&
15296 Copy->getOpcode() == ISD::CopyFromReg) {
15297 bool HasGlue = Copy->getNumOperands() == 3;
15298 SDValue Ops[] = {Copy->getOperand(0), Copy->getOperand(1),
15299 HasGlue ? Copy->getOperand(2) : SDValue()};
15300 EVT OutTys[] = {N->getValueType(0), MVT::Other, MVT::Glue};
15301 SDValue NewCopy =
15303 DCI.DAG.getVTList(ArrayRef(OutTys, HasGlue ? 3 : 2)),
15304 ArrayRef(Ops, HasGlue ? 3 : 2));
15305
15306 // Update Users, Chains, and Potential Glue.
15307 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), NewCopy.getValue(0));
15308 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(1), NewCopy.getValue(1));
15309 if (HasGlue)
15310 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(2),
15311 NewCopy.getValue(2));
15312
15313 return NewCopy;
15314 }
15315 }
15316
15317 // fold (VMOVhr (load x)) -> (load (f16*)x)
15318 if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(Op0)) {
15319 if (LN0->hasOneUse() && LN0->isUnindexed() &&
15320 LN0->getMemoryVT() == MVT::i16) {
15321 SDValue Load =
15322 DCI.DAG.getLoad(N->getValueType(0), SDLoc(N), LN0->getChain(),
15323 LN0->getBasePtr(), LN0->getMemOperand());
15324 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15325 DCI.DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Load.getValue(1));
15326 return Load;
15327 }
15328 }
15329
15330 // Only the bottom 16 bits of the source register are used.
15331 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15332 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15333 if (TLI.SimplifyDemandedBits(Op0, DemandedMask, DCI))
15334 return SDValue(N, 0);
15335
15336 return SDValue();
15337}
15338
15340 SDValue N0 = N->getOperand(0);
15341 EVT VT = N->getValueType(0);
15342
15343 // fold (VMOVrh (fpconst x)) -> const x
15345 APFloat V = C->getValueAPF();
15346 return DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
15347 }
15348
15349 // fold (VMOVrh (load x)) -> (zextload (i16*)x)
15350 if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
15351 LoadSDNode *LN0 = cast<LoadSDNode>(N0);
15352
15353 SDValue Load =
15354 DAG.getExtLoad(ISD::ZEXTLOAD, SDLoc(N), VT, LN0->getChain(),
15355 LN0->getBasePtr(), MVT::i16, LN0->getMemOperand());
15356 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15357 DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
15358 return Load;
15359 }
15360
15361 // Fold VMOVrh(extract(x, n)) -> vgetlaneu(x, n)
15362 if (N0->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15364 return DAG.getNode(ARMISD::VGETLANEu, SDLoc(N), VT, N0->getOperand(0),
15365 N0->getOperand(1));
15366
15367 return SDValue();
15368}
15369
15370/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
15371/// are normal, non-volatile loads. If so, it is profitable to bitcast an
15372/// i64 vector to have f64 elements, since the value can then be loaded
15373/// directly into a VFP register.
15375 unsigned NumElts = N->getValueType(0).getVectorNumElements();
15376 for (unsigned i = 0; i < NumElts; ++i) {
15377 SDNode *Elt = N->getOperand(i).getNode();
15378 if (ISD::isNormalLoad(Elt) && !cast<LoadSDNode>(Elt)->isVolatile())
15379 return true;
15380 }
15381 return false;
15382}
15383
15384/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for
15385/// ISD::BUILD_VECTOR.
15388 const ARMSubtarget *Subtarget) {
15389 // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X):
15390 // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value
15391 // into a pair of GPRs, which is fine when the value is used as a scalar,
15392 // but if the i64 value is converted to a vector, we need to undo the VMOVRRD.
15393 SelectionDAG &DAG = DCI.DAG;
15394 if (N->getNumOperands() == 2)
15395 if (SDValue RV = PerformVMOVDRRCombine(N, DAG))
15396 return RV;
15397
15398 // Load i64 elements as f64 values so that type legalization does not split
15399 // them up into i32 values.
15400 EVT VT = N->getValueType(0);
15401 if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N))
15402 return SDValue();
15403 SDLoc dl(N);
15405 unsigned NumElts = VT.getVectorNumElements();
15406 for (unsigned i = 0; i < NumElts; ++i) {
15407 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i));
15408 Ops.push_back(V);
15409 // Make the DAGCombiner fold the bitcast.
15410 DCI.AddToWorklist(V.getNode());
15411 }
15412 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts);
15413 SDValue BV = DAG.getBuildVector(FloatVT, dl, Ops);
15414 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
15415}
15416
15417/// Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
15418static SDValue
15420 // ARMISD::BUILD_VECTOR is introduced when legalizing ISD::BUILD_VECTOR.
15421 // At that time, we may have inserted bitcasts from integer to float.
15422 // If these bitcasts have survived DAGCombine, change the lowering of this
15423 // BUILD_VECTOR in something more vector friendly, i.e., that does not
15424 // force to use floating point types.
15425
15426 // Make sure we can change the type of the vector.
15427 // This is possible iff:
15428 // 1. The vector is only used in a bitcast to a integer type. I.e.,
15429 // 1.1. Vector is used only once.
15430 // 1.2. Use is a bit convert to an integer type.
15431 // 2. The size of its operands are 32-bits (64-bits are not legal).
15432 EVT VT = N->getValueType(0);
15433 EVT EltVT = VT.getVectorElementType();
15434
15435 // Check 1.1. and 2.
15436 if (EltVT.getSizeInBits() != 32 || !N->hasOneUse())
15437 return SDValue();
15438
15439 // By construction, the input type must be float.
15440 assert(EltVT == MVT::f32 && "Unexpected type!");
15441
15442 // Check 1.2.
15443 SDNode *Use = *N->user_begin();
15444 if (Use->getOpcode() != ISD::BITCAST ||
15445 Use->getValueType(0).isFloatingPoint())
15446 return SDValue();
15447
15448 // Check profitability.
15449 // Model is, if more than half of the relevant operands are bitcast from
15450 // i32, turn the build_vector into a sequence of insert_vector_elt.
15451 // Relevant operands are everything that is not statically
15452 // (i.e., at compile time) bitcasted.
15453 unsigned NumOfBitCastedElts = 0;
15454 unsigned NumElts = VT.getVectorNumElements();
15455 unsigned NumOfRelevantElts = NumElts;
15456 for (unsigned Idx = 0; Idx < NumElts; ++Idx) {
15457 SDValue Elt = N->getOperand(Idx);
15458 if (Elt->getOpcode() == ISD::BITCAST) {
15459 // Assume only bit cast to i32 will go away.
15460 if (Elt->getOperand(0).getValueType() == MVT::i32)
15461 ++NumOfBitCastedElts;
15462 } else if (Elt.isUndef() || isa<ConstantSDNode>(Elt))
15463 // Constants are statically casted, thus do not count them as
15464 // relevant operands.
15465 --NumOfRelevantElts;
15466 }
15467
15468 // Check if more than half of the elements require a non-free bitcast.
15469 if (NumOfBitCastedElts <= NumOfRelevantElts / 2)
15470 return SDValue();
15471
15472 SelectionDAG &DAG = DCI.DAG;
15473 // Create the new vector type.
15474 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
15475 // Check if the type is legal.
15476 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15477 if (!TLI.isTypeLegal(VecVT))
15478 return SDValue();
15479
15480 // Combine:
15481 // ARMISD::BUILD_VECTOR E1, E2, ..., EN.
15482 // => BITCAST INSERT_VECTOR_ELT
15483 // (INSERT_VECTOR_ELT (...), (BITCAST EN-1), N-1),
15484 // (BITCAST EN), N.
15485 SDValue Vec = DAG.getUNDEF(VecVT);
15486 SDLoc dl(N);
15487 for (unsigned Idx = 0 ; Idx < NumElts; ++Idx) {
15488 SDValue V = N->getOperand(Idx);
15489 if (V.isUndef())
15490 continue;
15491 if (V.getOpcode() == ISD::BITCAST &&
15492 V->getOperand(0).getValueType() == MVT::i32)
15493 // Fold obvious case.
15494 V = V.getOperand(0);
15495 else {
15496 V = DAG.getNode(ISD::BITCAST, SDLoc(V), MVT::i32, V);
15497 // Make the DAGCombiner fold the bitcasts.
15498 DCI.AddToWorklist(V.getNode());
15499 }
15500 SDValue LaneIdx = DAG.getConstant(Idx, dl, MVT::i32);
15501 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Vec, V, LaneIdx);
15502 }
15503 Vec = DAG.getNode(ISD::BITCAST, dl, VT, Vec);
15504 // Make the DAGCombiner fold the bitcasts.
15505 DCI.AddToWorklist(Vec.getNode());
15506 return Vec;
15507}
15508
15509static SDValue
15511 EVT VT = N->getValueType(0);
15512 SDValue Op = N->getOperand(0);
15513 SDLoc dl(N);
15514
15515 // PREDICATE_CAST(PREDICATE_CAST(x)) == PREDICATE_CAST(x)
15516 if (Op->getOpcode() == ARMISD::PREDICATE_CAST) {
15517 // If the valuetypes are the same, we can remove the cast entirely.
15518 if (Op->getOperand(0).getValueType() == VT)
15519 return Op->getOperand(0);
15520 return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15521 }
15522
15523 // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
15524 // more VPNOT which might get folded as else predicates.
15525 if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
15526 SDValue X =
15527 DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15528 SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
15529 DCI.DAG.getConstant(65535, dl, MVT::i32));
15530 return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
15531 }
15532
15533 // Only the bottom 16 bits of the source register are used.
15534 if (Op.getValueType() == MVT::i32) {
15535 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15536 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15537 if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
15538 return SDValue(N, 0);
15539 }
15540 return SDValue();
15541}
15542
15544 const ARMSubtarget *ST) {
15545 EVT VT = N->getValueType(0);
15546 SDValue Op = N->getOperand(0);
15547 SDLoc dl(N);
15548
15549 // Under Little endian, a VECTOR_REG_CAST is equivalent to a BITCAST
15550 if (ST->isLittle())
15551 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
15552
15553 // VT VECTOR_REG_CAST (VT Op) -> Op
15554 if (Op.getValueType() == VT)
15555 return Op;
15556 // VECTOR_REG_CAST undef -> undef
15557 if (Op.isUndef())
15558 return DAG.getUNDEF(VT);
15559
15560 // VECTOR_REG_CAST(VECTOR_REG_CAST(x)) == VECTOR_REG_CAST(x)
15561 if (Op->getOpcode() == ARMISD::VECTOR_REG_CAST) {
15562 // If the valuetypes are the same, we can remove the cast entirely.
15563 if (Op->getOperand(0).getValueType() == VT)
15564 return Op->getOperand(0);
15565 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Op->getOperand(0));
15566 }
15567
15568 return SDValue();
15569}
15570
15572 const ARMSubtarget *Subtarget) {
15573 if (!Subtarget->hasMVEIntegerOps())
15574 return SDValue();
15575
15576 EVT VT = N->getValueType(0);
15577 SDValue Op0 = N->getOperand(0);
15578 SDValue Op1 = N->getOperand(1);
15579 ARMCC::CondCodes Cond = (ARMCC::CondCodes)N->getConstantOperandVal(2);
15580 SDLoc dl(N);
15581
15582 // vcmp X, 0, cc -> vcmpz X, cc
15583 if (isZeroVector(Op1))
15584 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op0, N->getOperand(2));
15585
15586 unsigned SwappedCond = getSwappedCondition(Cond);
15587 if (isValidMVECond(SwappedCond, VT.isFloatingPoint())) {
15588 // vcmp 0, X, cc -> vcmpz X, reversed(cc)
15589 if (isZeroVector(Op0))
15590 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op1,
15591 DAG.getConstant(SwappedCond, dl, MVT::i32));
15592 // vcmp vdup(Y), X, cc -> vcmp X, vdup(Y), reversed(cc)
15593 if (Op0->getOpcode() == ARMISD::VDUP && Op1->getOpcode() != ARMISD::VDUP)
15594 return DAG.getNode(ARMISD::VCMP, dl, VT, Op1, Op0,
15595 DAG.getConstant(SwappedCond, dl, MVT::i32));
15596 }
15597
15598 return SDValue();
15599}
15600
15601/// PerformInsertEltCombine - Target-specific dag combine xforms for
15602/// ISD::INSERT_VECTOR_ELT.
15605 // Bitcast an i64 load inserted into a vector to f64.
15606 // Otherwise, the i64 value will be legalized to a pair of i32 values.
15607 EVT VT = N->getValueType(0);
15608 SDNode *Elt = N->getOperand(1).getNode();
15609 if (VT.getVectorElementType() != MVT::i64 ||
15610 !ISD::isNormalLoad(Elt) || cast<LoadSDNode>(Elt)->isVolatile())
15611 return SDValue();
15612
15613 SelectionDAG &DAG = DCI.DAG;
15614 SDLoc dl(N);
15615 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
15617 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0));
15618 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1));
15619 // Make the DAGCombiner fold the bitcasts.
15620 DCI.AddToWorklist(Vec.getNode());
15621 DCI.AddToWorklist(V.getNode());
15622 SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT,
15623 Vec, V, N->getOperand(2));
15624 return DAG.getNode(ISD::BITCAST, dl, VT, InsElt);
15625}
15626
15627// Convert a pair of extracts from the same base vector to a VMOVRRD. Either
15628// directly or bitcast to an integer if the original is a float vector.
15629// extract(x, n); extract(x, n+1) -> VMOVRRD(extract v2f64 x, n/2)
15630// bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD(extract x, n/2)
15631static SDValue
15633 EVT VT = N->getValueType(0);
15634 SDLoc dl(N);
15635
15636 if (!DCI.isAfterLegalizeDAG() || VT != MVT::i32 ||
15637 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(MVT::f64))
15638 return SDValue();
15639
15640 SDValue Ext = SDValue(N, 0);
15641 if (Ext.getOpcode() == ISD::BITCAST &&
15642 Ext.getOperand(0).getValueType() == MVT::f32)
15643 Ext = Ext.getOperand(0);
15644 if (Ext.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
15646 Ext.getConstantOperandVal(1) % 2 != 0)
15647 return SDValue();
15648 if (Ext->hasOneUse() && (Ext->user_begin()->getOpcode() == ISD::SINT_TO_FP ||
15649 Ext->user_begin()->getOpcode() == ISD::UINT_TO_FP))
15650 return SDValue();
15651
15652 SDValue Op0 = Ext.getOperand(0);
15653 EVT VecVT = Op0.getValueType();
15654 unsigned ResNo = Op0.getResNo();
15655 unsigned Lane = Ext.getConstantOperandVal(1);
15656 if (VecVT.getVectorNumElements() != 4)
15657 return SDValue();
15658
15659 // Find another extract, of Lane + 1
15660 auto OtherIt = find_if(Op0->users(), [&](SDNode *V) {
15661 return V->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15662 isa<ConstantSDNode>(V->getOperand(1)) &&
15663 V->getConstantOperandVal(1) == Lane + 1 &&
15664 V->getOperand(0).getResNo() == ResNo;
15665 });
15666 if (OtherIt == Op0->users().end())
15667 return SDValue();
15668
15669 // For float extracts, we need to be converting to a i32 for both vector
15670 // lanes.
15671 SDValue OtherExt(*OtherIt, 0);
15672 if (OtherExt.getValueType() != MVT::i32) {
15673 if (!OtherExt->hasOneUse() ||
15674 OtherExt->user_begin()->getOpcode() != ISD::BITCAST ||
15675 OtherExt->user_begin()->getValueType(0) != MVT::i32)
15676 return SDValue();
15677 OtherExt = SDValue(*OtherExt->user_begin(), 0);
15678 }
15679
15680 // Convert the type to a f64 and extract with a VMOVRRD.
15681 SDValue F64 = DCI.DAG.getNode(
15682 ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
15683 DCI.DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v2f64, Op0),
15684 DCI.DAG.getConstant(Ext.getConstantOperandVal(1) / 2, dl, MVT::i32));
15685 SDValue VMOVRRD =
15686 DCI.DAG.getNode(ARMISD::VMOVRRD, dl, {MVT::i32, MVT::i32}, F64);
15687
15688 DCI.CombineTo(OtherExt.getNode(), SDValue(VMOVRRD.getNode(), 1));
15689 return VMOVRRD;
15690}
15691
15694 const ARMSubtarget *ST) {
15695 SDValue Op0 = N->getOperand(0);
15696 EVT VT = N->getValueType(0);
15697 SDLoc dl(N);
15698
15699 // extract (vdup x) -> x
15700 if (Op0->getOpcode() == ARMISD::VDUP) {
15701 SDValue X = Op0->getOperand(0);
15702 if (VT == MVT::f16 && X.getValueType() == MVT::i32)
15703 return DCI.DAG.getNode(ARMISD::VMOVhr, dl, VT, X);
15704 if (VT == MVT::i32 && X.getValueType() == MVT::f16)
15705 return DCI.DAG.getNode(ARMISD::VMOVrh, dl, VT, X);
15706 if (VT == MVT::f32 && X.getValueType() == MVT::i32)
15707 return DCI.DAG.getNode(ISD::BITCAST, dl, VT, X);
15708
15709 while (X.getValueType() != VT && X->getOpcode() == ISD::BITCAST)
15710 X = X->getOperand(0);
15711 if (X.getValueType() == VT)
15712 return X;
15713 }
15714
15715 // extract ARM_BUILD_VECTOR -> x
15716 if (Op0->getOpcode() == ARMISD::BUILD_VECTOR &&
15717 isa<ConstantSDNode>(N->getOperand(1)) &&
15718 N->getConstantOperandVal(1) < Op0.getNumOperands()) {
15719 return Op0.getOperand(N->getConstantOperandVal(1));
15720 }
15721
15722 // extract(bitcast(BUILD_VECTOR(VMOVDRR(a, b), ..))) -> a or b
15723 if (Op0.getValueType() == MVT::v4i32 &&
15724 isa<ConstantSDNode>(N->getOperand(1)) &&
15725 Op0.getOpcode() == ISD::BITCAST &&
15727 Op0.getOperand(0).getValueType() == MVT::v2f64) {
15728 SDValue BV = Op0.getOperand(0);
15729 unsigned Offset = N->getConstantOperandVal(1);
15730 SDValue MOV = BV.getOperand(Offset < 2 ? 0 : 1);
15731 if (MOV.getOpcode() == ARMISD::VMOVDRR)
15732 return MOV.getOperand(ST->isLittle() ? Offset % 2 : 1 - Offset % 2);
15733 }
15734
15735 // extract x, n; extract x, n+1 -> VMOVRRD x
15736 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
15737 return R;
15738
15739 // extract (MVETrunc(x)) -> extract x
15740 if (Op0->getOpcode() == ARMISD::MVETRUNC) {
15741 unsigned Idx = N->getConstantOperandVal(1);
15742 unsigned Vec =
15744 unsigned SubIdx =
15746 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Op0.getOperand(Vec),
15747 DCI.DAG.getConstant(SubIdx, dl, MVT::i32));
15748 }
15749
15750 // extract(bitcast(BUILD_VECTOR(extract(bitcast(a)), ..))) -> extract(a)
15751 if (ST->isLittle() && Op0.getOpcode() == ISD::BITCAST &&
15753 isa<ConstantSDNode>(N->getOperand(1)) &&
15756 unsigned Lane = N->getConstantOperandVal(1);
15757 EVT ExtVT = Op0.getValueType();
15758 EVT BVVT = Op0.getOperand(0).getValueType();
15759 unsigned BVLane =
15760 (Lane * BVVT.getVectorNumElements()) / ExtVT.getVectorNumElements();
15761 assert(BVLane < Op0.getOperand(0).getNumOperands());
15762 SDValue Ext = Op0.getOperand(0).getOperand(BVLane);
15763 if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15764 Ext.getOperand(0).getOpcode() == ISD::BITCAST &&
15766 Ext.getOperand(0).getOperand(0).getValueType() == ExtVT) {
15767 unsigned InnerLane = Ext.getConstantOperandVal(1);
15768 unsigned BVSubLane = Lane - (BVLane * ExtVT.getVectorNumElements()) /
15769 BVVT.getVectorNumElements();
15770 unsigned FinalLane = (InnerLane * ExtVT.getVectorNumElements()) /
15771 BVVT.getVectorNumElements() +
15772 BVSubLane;
15773 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT,
15774 Ext.getOperand(0).getOperand(0),
15775 DCI.DAG.getConstant(FinalLane, dl, MVT::i32));
15776 }
15777 }
15778
15779 return SDValue();
15780}
15781
15783 SDValue Op = N->getOperand(0);
15784 EVT VT = N->getValueType(0);
15785
15786 // sext_inreg(VGETLANEu) -> VGETLANEs
15787 if (Op.getOpcode() == ARMISD::VGETLANEu &&
15788 cast<VTSDNode>(N->getOperand(1))->getVT() ==
15789 Op.getOperand(0).getValueType().getScalarType())
15790 return DAG.getNode(ARMISD::VGETLANEs, SDLoc(N), VT, Op.getOperand(0),
15791 Op.getOperand(1));
15792
15793 return SDValue();
15794}
15795
15796static SDValue
15798 SDValue Vec = N->getOperand(0);
15799 SDValue SubVec = N->getOperand(1);
15800 uint64_t IdxVal = N->getConstantOperandVal(2);
15801 EVT VecVT = Vec.getValueType();
15802 EVT SubVT = SubVec.getValueType();
15803
15804 // Only do this for legal fixed vector types.
15805 if (!VecVT.isFixedLengthVector() ||
15806 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(VecVT) ||
15808 return SDValue();
15809
15810 // Ignore widening patterns.
15811 if (IdxVal == 0 && Vec.isUndef())
15812 return SDValue();
15813
15814 // Subvector must be half the width and an "aligned" insertion.
15815 unsigned NumSubElts = SubVT.getVectorNumElements();
15816 if ((SubVT.getSizeInBits() * 2) != VecVT.getSizeInBits() ||
15817 (IdxVal != 0 && IdxVal != NumSubElts))
15818 return SDValue();
15819
15820 // Fold insert_subvector -> concat_vectors
15821 // insert_subvector(Vec,Sub,lo) -> concat_vectors(Sub,extract(Vec,hi))
15822 // insert_subvector(Vec,Sub,hi) -> concat_vectors(extract(Vec,lo),Sub)
15823 SDLoc DL(N);
15824 SDValue Lo, Hi;
15825 if (IdxVal == 0) {
15826 Lo = SubVec;
15827 Hi = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15828 DCI.DAG.getVectorIdxConstant(NumSubElts, DL));
15829 } else {
15830 Lo = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15831 DCI.DAG.getVectorIdxConstant(0, DL));
15832 Hi = SubVec;
15833 }
15834 return DCI.DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Lo, Hi);
15835}
15836
15837// shuffle(MVETrunc(x, y)) -> VMOVN(x, y)
15839 SelectionDAG &DAG) {
15840 SDValue Trunc = N->getOperand(0);
15841 EVT VT = Trunc.getValueType();
15842 if (Trunc.getOpcode() != ARMISD::MVETRUNC || !N->getOperand(1).isUndef())
15843 return SDValue();
15844
15845 SDLoc DL(Trunc);
15846 if (isVMOVNTruncMask(N->getMask(), VT, false))
15847 return DAG.getNode(
15848 ARMISD::VMOVN, DL, VT,
15849 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15850 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15851 DAG.getConstant(1, DL, MVT::i32));
15852 else if (isVMOVNTruncMask(N->getMask(), VT, true))
15853 return DAG.getNode(
15854 ARMISD::VMOVN, DL, VT,
15855 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15856 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15857 DAG.getConstant(1, DL, MVT::i32));
15858 return SDValue();
15859}
15860
15861/// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for
15862/// ISD::VECTOR_SHUFFLE.
15865 return R;
15866
15867 // The LLVM shufflevector instruction does not require the shuffle mask
15868 // length to match the operand vector length, but ISD::VECTOR_SHUFFLE does
15869 // have that requirement. When translating to ISD::VECTOR_SHUFFLE, if the
15870 // operands do not match the mask length, they are extended by concatenating
15871 // them with undef vectors. That is probably the right thing for other
15872 // targets, but for NEON it is better to concatenate two double-register
15873 // size vector operands into a single quad-register size vector. Do that
15874 // transformation here:
15875 // shuffle(concat(v1, undef), concat(v2, undef)) ->
15876 // shuffle(concat(v1, v2), undef)
15877 SDValue Op0 = N->getOperand(0);
15878 SDValue Op1 = N->getOperand(1);
15879 if (Op0.getOpcode() != ISD::CONCAT_VECTORS ||
15880 Op1.getOpcode() != ISD::CONCAT_VECTORS ||
15881 Op0.getNumOperands() != 2 ||
15882 Op1.getNumOperands() != 2)
15883 return SDValue();
15884 SDValue Concat0Op1 = Op0.getOperand(1);
15885 SDValue Concat1Op1 = Op1.getOperand(1);
15886 if (!Concat0Op1.isUndef() || !Concat1Op1.isUndef())
15887 return SDValue();
15888 // Skip the transformation if any of the types are illegal.
15889 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15890 EVT VT = N->getValueType(0);
15891 if (!TLI.isTypeLegal(VT) ||
15892 !TLI.isTypeLegal(Concat0Op1.getValueType()) ||
15893 !TLI.isTypeLegal(Concat1Op1.getValueType()))
15894 return SDValue();
15895
15896 SDValue NewConcat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT,
15897 Op0.getOperand(0), Op1.getOperand(0));
15898 // Translate the shuffle mask.
15899 SmallVector<int, 16> NewMask;
15900 unsigned NumElts = VT.getVectorNumElements();
15901 unsigned HalfElts = NumElts/2;
15903 for (unsigned n = 0; n < NumElts; ++n) {
15904 int MaskElt = SVN->getMaskElt(n);
15905 int NewElt = -1;
15906 if (MaskElt < (int)HalfElts)
15907 NewElt = MaskElt;
15908 else if (MaskElt >= (int)NumElts && MaskElt < (int)(NumElts + HalfElts))
15909 NewElt = HalfElts + MaskElt - NumElts;
15910 NewMask.push_back(NewElt);
15911 }
15912 return DAG.getVectorShuffle(VT, SDLoc(N), NewConcat,
15913 DAG.getUNDEF(VT), NewMask);
15914}
15915
15916/// Load/store instruction that can be merged with a base address
15917/// update
15922 unsigned AddrOpIdx;
15923};
15924
15926 /// Instruction that updates a pointer
15928 /// Pointer increment operand
15930 /// Pointer increment value if it is a constant, or 0 otherwise
15931 unsigned ConstInc;
15932};
15933
15935 // Check that the add is independent of the load/store.
15936 // Otherwise, folding it would create a cycle. Search through Addr
15937 // as well, since the User may not be a direct user of Addr and
15938 // only share a base pointer.
15941 Worklist.push_back(N);
15942 Worklist.push_back(User);
15943 const unsigned MaxSteps = 1024;
15944 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
15945 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
15946 return false;
15947 return true;
15948}
15949
15951 struct BaseUpdateUser &User,
15952 bool SimpleConstIncOnly,
15954 SelectionDAG &DAG = DCI.DAG;
15955 SDNode *N = Target.N;
15956 MemSDNode *MemN = cast<MemSDNode>(N);
15957 SDLoc dl(N);
15958
15959 // Find the new opcode for the updating load/store.
15960 bool isLoadOp = true;
15961 bool isLaneOp = false;
15962 // Workaround for vst1x and vld1x intrinsics which do not have alignment
15963 // as an operand.
15964 bool hasAlignment = true;
15965 unsigned NewOpc = 0;
15966 unsigned NumVecs = 0;
15967 if (Target.isIntrinsic) {
15968 unsigned IntNo = N->getConstantOperandVal(1);
15969 switch (IntNo) {
15970 default:
15971 llvm_unreachable("unexpected intrinsic for Neon base update");
15972 case Intrinsic::arm_neon_vld1:
15973 NewOpc = ARMISD::VLD1_UPD;
15974 NumVecs = 1;
15975 break;
15976 case Intrinsic::arm_neon_vld2:
15977 NewOpc = ARMISD::VLD2_UPD;
15978 NumVecs = 2;
15979 break;
15980 case Intrinsic::arm_neon_vld3:
15981 NewOpc = ARMISD::VLD3_UPD;
15982 NumVecs = 3;
15983 break;
15984 case Intrinsic::arm_neon_vld4:
15985 NewOpc = ARMISD::VLD4_UPD;
15986 NumVecs = 4;
15987 break;
15988 case Intrinsic::arm_neon_vld1x2:
15989 NewOpc = ARMISD::VLD1x2_UPD;
15990 NumVecs = 2;
15991 hasAlignment = false;
15992 break;
15993 case Intrinsic::arm_neon_vld1x3:
15994 NewOpc = ARMISD::VLD1x3_UPD;
15995 NumVecs = 3;
15996 hasAlignment = false;
15997 break;
15998 case Intrinsic::arm_neon_vld1x4:
15999 NewOpc = ARMISD::VLD1x4_UPD;
16000 NumVecs = 4;
16001 hasAlignment = false;
16002 break;
16003 case Intrinsic::arm_neon_vld2dup:
16004 NewOpc = ARMISD::VLD2DUP_UPD;
16005 NumVecs = 2;
16006 break;
16007 case Intrinsic::arm_neon_vld3dup:
16008 NewOpc = ARMISD::VLD3DUP_UPD;
16009 NumVecs = 3;
16010 break;
16011 case Intrinsic::arm_neon_vld4dup:
16012 NewOpc = ARMISD::VLD4DUP_UPD;
16013 NumVecs = 4;
16014 break;
16015 case Intrinsic::arm_neon_vld2lane:
16016 NewOpc = ARMISD::VLD2LN_UPD;
16017 NumVecs = 2;
16018 isLaneOp = true;
16019 break;
16020 case Intrinsic::arm_neon_vld3lane:
16021 NewOpc = ARMISD::VLD3LN_UPD;
16022 NumVecs = 3;
16023 isLaneOp = true;
16024 break;
16025 case Intrinsic::arm_neon_vld4lane:
16026 NewOpc = ARMISD::VLD4LN_UPD;
16027 NumVecs = 4;
16028 isLaneOp = true;
16029 break;
16030 case Intrinsic::arm_neon_vst1:
16031 NewOpc = ARMISD::VST1_UPD;
16032 NumVecs = 1;
16033 isLoadOp = false;
16034 break;
16035 case Intrinsic::arm_neon_vst2:
16036 NewOpc = ARMISD::VST2_UPD;
16037 NumVecs = 2;
16038 isLoadOp = false;
16039 break;
16040 case Intrinsic::arm_neon_vst3:
16041 NewOpc = ARMISD::VST3_UPD;
16042 NumVecs = 3;
16043 isLoadOp = false;
16044 break;
16045 case Intrinsic::arm_neon_vst4:
16046 NewOpc = ARMISD::VST4_UPD;
16047 NumVecs = 4;
16048 isLoadOp = false;
16049 break;
16050 case Intrinsic::arm_neon_vst2lane:
16051 NewOpc = ARMISD::VST2LN_UPD;
16052 NumVecs = 2;
16053 isLoadOp = false;
16054 isLaneOp = true;
16055 break;
16056 case Intrinsic::arm_neon_vst3lane:
16057 NewOpc = ARMISD::VST3LN_UPD;
16058 NumVecs = 3;
16059 isLoadOp = false;
16060 isLaneOp = true;
16061 break;
16062 case Intrinsic::arm_neon_vst4lane:
16063 NewOpc = ARMISD::VST4LN_UPD;
16064 NumVecs = 4;
16065 isLoadOp = false;
16066 isLaneOp = true;
16067 break;
16068 case Intrinsic::arm_neon_vst1x2:
16069 NewOpc = ARMISD::VST1x2_UPD;
16070 NumVecs = 2;
16071 isLoadOp = false;
16072 hasAlignment = false;
16073 break;
16074 case Intrinsic::arm_neon_vst1x3:
16075 NewOpc = ARMISD::VST1x3_UPD;
16076 NumVecs = 3;
16077 isLoadOp = false;
16078 hasAlignment = false;
16079 break;
16080 case Intrinsic::arm_neon_vst1x4:
16081 NewOpc = ARMISD::VST1x4_UPD;
16082 NumVecs = 4;
16083 isLoadOp = false;
16084 hasAlignment = false;
16085 break;
16086 }
16087 } else {
16088 isLaneOp = true;
16089 switch (N->getOpcode()) {
16090 default:
16091 llvm_unreachable("unexpected opcode for Neon base update");
16092 case ARMISD::VLD1DUP:
16093 NewOpc = ARMISD::VLD1DUP_UPD;
16094 NumVecs = 1;
16095 break;
16096 case ARMISD::VLD2DUP:
16097 NewOpc = ARMISD::VLD2DUP_UPD;
16098 NumVecs = 2;
16099 break;
16100 case ARMISD::VLD3DUP:
16101 NewOpc = ARMISD::VLD3DUP_UPD;
16102 NumVecs = 3;
16103 break;
16104 case ARMISD::VLD4DUP:
16105 NewOpc = ARMISD::VLD4DUP_UPD;
16106 NumVecs = 4;
16107 break;
16108 case ISD::LOAD:
16109 NewOpc = ARMISD::VLD1_UPD;
16110 NumVecs = 1;
16111 isLaneOp = false;
16112 break;
16113 case ISD::STORE:
16114 NewOpc = ARMISD::VST1_UPD;
16115 NumVecs = 1;
16116 isLaneOp = false;
16117 isLoadOp = false;
16118 break;
16119 }
16120 }
16121
16122 // Find the size of memory referenced by the load/store.
16123 EVT VecTy;
16124 if (isLoadOp) {
16125 VecTy = N->getValueType(0);
16126 } else if (Target.isIntrinsic) {
16127 VecTy = N->getOperand(Target.AddrOpIdx + 1).getValueType();
16128 } else {
16129 assert(Target.isStore &&
16130 "Node has to be a load, a store, or an intrinsic!");
16131 VecTy = N->getOperand(1).getValueType();
16132 }
16133
16134 bool isVLDDUPOp =
16135 NewOpc == ARMISD::VLD1DUP_UPD || NewOpc == ARMISD::VLD2DUP_UPD ||
16136 NewOpc == ARMISD::VLD3DUP_UPD || NewOpc == ARMISD::VLD4DUP_UPD;
16137
16138 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16139 if (isLaneOp || isVLDDUPOp)
16140 NumBytes /= VecTy.getVectorNumElements();
16141
16142 if (NumBytes >= 3 * 16 && User.ConstInc != NumBytes) {
16143 // VLD3/4 and VST3/4 for 128-bit vectors are implemented with two
16144 // separate instructions that make it harder to use a non-constant update.
16145 return false;
16146 }
16147
16148 if (SimpleConstIncOnly && User.ConstInc != NumBytes)
16149 return false;
16150
16151 if (!isValidBaseUpdate(N, User.N))
16152 return false;
16153
16154 // OK, we found an ADD we can fold into the base update.
16155 // Now, create a _UPD node, taking care of not breaking alignment.
16156
16157 EVT AlignedVecTy = VecTy;
16158 Align Alignment = MemN->getAlign();
16159
16160 // If this is a less-than-standard-aligned load/store, change the type to
16161 // match the standard alignment.
16162 // The alignment is overlooked when selecting _UPD variants; and it's
16163 // easier to introduce bitcasts here than fix that.
16164 // There are 3 ways to get to this base-update combine:
16165 // - intrinsics: they are assumed to be properly aligned (to the standard
16166 // alignment of the memory type), so we don't need to do anything.
16167 // - ARMISD::VLDx nodes: they are only generated from the aforementioned
16168 // intrinsics, so, likewise, there's nothing to do.
16169 // - generic load/store instructions: the alignment is specified as an
16170 // explicit operand, rather than implicitly as the standard alignment
16171 // of the memory type (like the intrinsics). We need to change the
16172 // memory type to match the explicit alignment. That way, we don't
16173 // generate non-standard-aligned ARMISD::VLDx nodes.
16174 if (isa<LSBaseSDNode>(N)) {
16175 if (Alignment.value() < VecTy.getScalarSizeInBits() / 8) {
16176 MVT EltTy = MVT::getIntegerVT(Alignment.value() * 8);
16177 assert(NumVecs == 1 && "Unexpected multi-element generic load/store.");
16178 assert(!isLaneOp && "Unexpected generic load/store lane.");
16179 unsigned NumElts = NumBytes / (EltTy.getSizeInBits() / 8);
16180 AlignedVecTy = MVT::getVectorVT(EltTy, NumElts);
16181 }
16182 // Don't set an explicit alignment on regular load/stores that we want
16183 // to transform to VLD/VST 1_UPD nodes.
16184 // This matches the behavior of regular load/stores, which only get an
16185 // explicit alignment if the MMO alignment is larger than the standard
16186 // alignment of the memory type.
16187 // Intrinsics, however, always get an explicit alignment, set to the
16188 // alignment of the MMO.
16189 Alignment = Align(1);
16190 }
16191
16192 // Create the new updating load/store node.
16193 // First, create an SDVTList for the new updating node's results.
16194 EVT Tys[6];
16195 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16196 unsigned n;
16197 for (n = 0; n < NumResultVecs; ++n)
16198 Tys[n] = AlignedVecTy;
16199 Tys[n++] = MVT::i32;
16200 Tys[n] = MVT::Other;
16201 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16202
16203 // Then, gather the new node's operands.
16205 Ops.push_back(N->getOperand(0)); // incoming chain
16206 Ops.push_back(N->getOperand(Target.AddrOpIdx));
16207 Ops.push_back(User.Inc);
16208
16209 if (StoreSDNode *StN = dyn_cast<StoreSDNode>(N)) {
16210 // Try to match the intrinsic's signature
16211 Ops.push_back(StN->getValue());
16212 } else {
16213 // Loads (and of course intrinsics) match the intrinsics' signature,
16214 // so just add all but the alignment operand.
16215 unsigned LastOperand =
16216 hasAlignment ? N->getNumOperands() - 1 : N->getNumOperands();
16217 for (unsigned i = Target.AddrOpIdx + 1; i < LastOperand; ++i)
16218 Ops.push_back(N->getOperand(i));
16219 }
16220
16221 // For all node types, the alignment operand is always the last one.
16222 Ops.push_back(DAG.getConstant(Alignment.value(), dl, MVT::i32));
16223
16224 // If this is a non-standard-aligned STORE, the penultimate operand is the
16225 // stored value. Bitcast it to the aligned type.
16226 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::STORE) {
16227 SDValue &StVal = Ops[Ops.size() - 2];
16228 StVal = DAG.getNode(ISD::BITCAST, dl, AlignedVecTy, StVal);
16229 }
16230
16231 EVT LoadVT = isLaneOp ? VecTy.getVectorElementType() : AlignedVecTy;
16232 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, LoadVT,
16233 MemN->getMemOperand());
16234
16235 // Update the uses.
16236 SmallVector<SDValue, 5> NewResults;
16237 for (unsigned i = 0; i < NumResultVecs; ++i)
16238 NewResults.push_back(SDValue(UpdN.getNode(), i));
16239
16240 // If this is an non-standard-aligned LOAD, the first result is the loaded
16241 // value. Bitcast it to the expected result type.
16242 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::LOAD) {
16243 SDValue &LdVal = NewResults[0];
16244 LdVal = DAG.getNode(ISD::BITCAST, dl, VecTy, LdVal);
16245 }
16246
16247 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16248 DCI.CombineTo(N, NewResults);
16249 DCI.CombineTo(User.N, SDValue(UpdN.getNode(), NumResultVecs));
16250
16251 return true;
16252}
16253
16254// If (opcode ptr inc) is and ADD-like instruction, return the
16255// increment value. Otherwise return 0.
16256static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr,
16257 SDValue Inc, const SelectionDAG &DAG) {
16259 if (!CInc)
16260 return 0;
16261
16262 switch (Opcode) {
16263 case ARMISD::VLD1_UPD:
16264 case ISD::ADD:
16265 return CInc->getZExtValue();
16266 case ISD::OR: {
16267 if (DAG.haveNoCommonBitsSet(Ptr, Inc)) {
16268 // (OR ptr inc) is the same as (ADD ptr inc)
16269 return CInc->getZExtValue();
16270 }
16271 return 0;
16272 }
16273 default:
16274 return 0;
16275 }
16276}
16277
16279 switch (N->getOpcode()) {
16280 case ISD::ADD:
16281 case ISD::OR: {
16282 if (isa<ConstantSDNode>(N->getOperand(1))) {
16283 *Ptr = N->getOperand(0);
16284 *CInc = N->getOperand(1);
16285 return true;
16286 }
16287 return false;
16288 }
16289 case ARMISD::VLD1_UPD: {
16290 if (isa<ConstantSDNode>(N->getOperand(2))) {
16291 *Ptr = N->getOperand(1);
16292 *CInc = N->getOperand(2);
16293 return true;
16294 }
16295 return false;
16296 }
16297 default:
16298 return false;
16299 }
16300}
16301
16302/// CombineBaseUpdate - Target-specific DAG combine function for VLDDUP,
16303/// NEON load/store intrinsics, and generic vector load/stores, to merge
16304/// base address updates.
16305/// For generic load/stores, the memory type is assumed to be a vector.
16306/// The caller is assumed to have checked legality.
16309 const bool isIntrinsic = (N->getOpcode() == ISD::INTRINSIC_VOID ||
16310 N->getOpcode() == ISD::INTRINSIC_W_CHAIN);
16311 const bool isStore = N->getOpcode() == ISD::STORE;
16312 const unsigned AddrOpIdx = ((isIntrinsic || isStore) ? 2 : 1);
16313 BaseUpdateTarget Target = {N, isIntrinsic, isStore, AddrOpIdx};
16314
16315 // Limit the number of possible base-updates we look at to prevent degenerate
16316 // cases.
16317 unsigned MaxBaseUpdates = ArmMaxBaseUpdatesToCheck;
16318
16319 SDValue Addr = N->getOperand(AddrOpIdx);
16320
16322
16323 // Search for a use of the address operand that is an increment.
16324 for (SDUse &Use : Addr->uses()) {
16325 SDNode *User = Use.getUser();
16326 if (Use.getResNo() != Addr.getResNo() || User->getNumOperands() != 2)
16327 continue;
16328
16329 SDValue Inc = User->getOperand(Use.getOperandNo() == 1 ? 0 : 1);
16330 unsigned ConstInc =
16331 getPointerConstIncrement(User->getOpcode(), Addr, Inc, DCI.DAG);
16332
16333 if (ConstInc || User->getOpcode() == ISD::ADD) {
16334 BaseUpdates.push_back({User, Inc, ConstInc});
16335 if (BaseUpdates.size() >= MaxBaseUpdates)
16336 break;
16337 }
16338 }
16339
16340 // If the address is a constant pointer increment itself, find
16341 // another constant increment that has the same base operand
16342 SDValue Base;
16343 SDValue CInc;
16344 if (findPointerConstIncrement(Addr.getNode(), &Base, &CInc)) {
16345 unsigned Offset =
16346 getPointerConstIncrement(Addr->getOpcode(), Base, CInc, DCI.DAG);
16347 if (Offset) {
16348 for (SDUse &Use : Base->uses()) {
16349
16350 SDNode *User = Use.getUser();
16351 if (Use.getResNo() != Base.getResNo() || User == Addr.getNode() ||
16352 User->getNumOperands() != 2)
16353 continue;
16354
16355 SDValue UserInc = User->getOperand(Use.getOperandNo() == 0 ? 1 : 0);
16356 unsigned UserOffset =
16357 getPointerConstIncrement(User->getOpcode(), Base, UserInc, DCI.DAG);
16358
16359 if (!UserOffset || UserOffset <= Offset)
16360 continue;
16361
16362 unsigned NewConstInc = UserOffset - Offset;
16363 SDValue NewInc = DCI.DAG.getConstant(NewConstInc, SDLoc(N), MVT::i32);
16364 BaseUpdates.push_back({User, NewInc, NewConstInc});
16365 if (BaseUpdates.size() >= MaxBaseUpdates)
16366 break;
16367 }
16368 }
16369 }
16370
16371 // Try to fold the load/store with an update that matches memory
16372 // access size. This should work well for sequential loads.
16373 unsigned NumValidUpd = BaseUpdates.size();
16374 for (unsigned I = 0; I < NumValidUpd; I++) {
16375 BaseUpdateUser &User = BaseUpdates[I];
16376 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/true, DCI))
16377 return SDValue();
16378 }
16379
16380 // Try to fold with other users. Non-constant updates are considered
16381 // first, and constant updates are sorted to not break a sequence of
16382 // strided accesses (if there is any).
16383 llvm::stable_sort(BaseUpdates,
16384 [](const BaseUpdateUser &LHS, const BaseUpdateUser &RHS) {
16385 return LHS.ConstInc < RHS.ConstInc;
16386 });
16387 for (BaseUpdateUser &User : BaseUpdates) {
16388 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/false, DCI))
16389 return SDValue();
16390 }
16391 return SDValue();
16392}
16393
16396 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16397 return SDValue();
16398
16399 return CombineBaseUpdate(N, DCI);
16400}
16401
16404 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16405 return SDValue();
16406
16407 SelectionDAG &DAG = DCI.DAG;
16408 SDValue Addr = N->getOperand(2);
16409 MemSDNode *MemN = cast<MemSDNode>(N);
16410 SDLoc dl(N);
16411
16412 // For the stores, where there are multiple intrinsics we only actually want
16413 // to post-inc the last of the them.
16414 unsigned IntNo = N->getConstantOperandVal(1);
16415 if (IntNo == Intrinsic::arm_mve_vst2q && N->getConstantOperandVal(5) != 1)
16416 return SDValue();
16417 if (IntNo == Intrinsic::arm_mve_vst4q && N->getConstantOperandVal(7) != 3)
16418 return SDValue();
16419
16420 // Search for a use of the address operand that is an increment.
16421 for (SDUse &Use : Addr->uses()) {
16422 SDNode *User = Use.getUser();
16423 if (User->getOpcode() != ISD::ADD || Use.getResNo() != Addr.getResNo())
16424 continue;
16425
16426 // Check that the add is independent of the load/store. Otherwise, folding
16427 // it would create a cycle. We can avoid searching through Addr as it's a
16428 // predecessor to both.
16431 Visited.insert(Addr.getNode());
16432 Worklist.push_back(N);
16433 Worklist.push_back(User);
16434 const unsigned MaxSteps = 1024;
16435 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16436 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16437 continue;
16438
16439 // Find the new opcode for the updating load/store.
16440 bool isLoadOp = true;
16441 unsigned NewOpc = 0;
16442 unsigned NumVecs = 0;
16443 switch (IntNo) {
16444 default:
16445 llvm_unreachable("unexpected intrinsic for MVE VLDn combine");
16446 case Intrinsic::arm_mve_vld2q:
16447 NewOpc = ARMISD::VLD2_UPD;
16448 NumVecs = 2;
16449 break;
16450 case Intrinsic::arm_mve_vld4q:
16451 NewOpc = ARMISD::VLD4_UPD;
16452 NumVecs = 4;
16453 break;
16454 case Intrinsic::arm_mve_vst2q:
16455 NewOpc = ARMISD::VST2_UPD;
16456 NumVecs = 2;
16457 isLoadOp = false;
16458 break;
16459 case Intrinsic::arm_mve_vst4q:
16460 NewOpc = ARMISD::VST4_UPD;
16461 NumVecs = 4;
16462 isLoadOp = false;
16463 break;
16464 }
16465
16466 // Find the size of memory referenced by the load/store.
16467 EVT VecTy;
16468 if (isLoadOp) {
16469 VecTy = N->getValueType(0);
16470 } else {
16471 VecTy = N->getOperand(3).getValueType();
16472 }
16473
16474 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16475
16476 // If the increment is a constant, it must match the memory ref size.
16477 SDValue Inc = User->getOperand(User->getOperand(0) == Addr ? 1 : 0);
16479 if (!CInc || CInc->getZExtValue() != NumBytes)
16480 continue;
16481
16482 // Create the new updating load/store node.
16483 // First, create an SDVTList for the new updating node's results.
16484 EVT Tys[6];
16485 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16486 unsigned n;
16487 for (n = 0; n < NumResultVecs; ++n)
16488 Tys[n] = VecTy;
16489 Tys[n++] = MVT::i32;
16490 Tys[n] = MVT::Other;
16491 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16492
16493 // Then, gather the new node's operands.
16495 Ops.push_back(N->getOperand(0)); // incoming chain
16496 Ops.push_back(N->getOperand(2)); // ptr
16497 Ops.push_back(Inc);
16498
16499 for (unsigned i = 3; i < N->getNumOperands(); ++i)
16500 Ops.push_back(N->getOperand(i));
16501
16502 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, VecTy,
16503 MemN->getMemOperand());
16504
16505 // Update the uses.
16506 SmallVector<SDValue, 5> NewResults;
16507 for (unsigned i = 0; i < NumResultVecs; ++i)
16508 NewResults.push_back(SDValue(UpdN.getNode(), i));
16509
16510 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16511 DCI.CombineTo(N, NewResults);
16512 DCI.CombineTo(User, SDValue(UpdN.getNode(), NumResultVecs));
16513
16514 break;
16515 }
16516
16517 return SDValue();
16518}
16519
16520/// CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a
16521/// vldN-lane (N > 1) intrinsic, and if all the other uses of that intrinsic
16522/// are also VDUPLANEs. If so, combine them to a vldN-dup operation and
16523/// return true.
16525 SelectionDAG &DAG = DCI.DAG;
16526 EVT VT = N->getValueType(0);
16527 // vldN-dup instructions only support 64-bit vectors for N > 1.
16528 if (!VT.is64BitVector())
16529 return false;
16530
16531 // Check if the VDUPLANE operand is a vldN-dup intrinsic.
16532 SDNode *VLD = N->getOperand(0).getNode();
16533 if (VLD->getOpcode() != ISD::INTRINSIC_W_CHAIN)
16534 return false;
16535 unsigned NumVecs = 0;
16536 unsigned NewOpc = 0;
16537 unsigned IntNo = VLD->getConstantOperandVal(1);
16538 if (IntNo == Intrinsic::arm_neon_vld2lane) {
16539 NumVecs = 2;
16540 NewOpc = ARMISD::VLD2DUP;
16541 } else if (IntNo == Intrinsic::arm_neon_vld3lane) {
16542 NumVecs = 3;
16543 NewOpc = ARMISD::VLD3DUP;
16544 } else if (IntNo == Intrinsic::arm_neon_vld4lane) {
16545 NumVecs = 4;
16546 NewOpc = ARMISD::VLD4DUP;
16547 } else {
16548 return false;
16549 }
16550
16551 // First check that all the vldN-lane uses are VDUPLANEs and that the lane
16552 // numbers match the load.
16553 unsigned VLDLaneNo = VLD->getConstantOperandVal(NumVecs + 3);
16554 for (SDUse &Use : VLD->uses()) {
16555 // Ignore uses of the chain result.
16556 if (Use.getResNo() == NumVecs)
16557 continue;
16558 SDNode *User = Use.getUser();
16559 if (User->getOpcode() != ARMISD::VDUPLANE ||
16560 VLDLaneNo != User->getConstantOperandVal(1))
16561 return false;
16562 }
16563
16564 // Create the vldN-dup node.
16565 EVT Tys[5];
16566 unsigned n;
16567 for (n = 0; n < NumVecs; ++n)
16568 Tys[n] = VT;
16569 Tys[n] = MVT::Other;
16570 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumVecs + 1));
16571 SDValue Ops[] = { VLD->getOperand(0), VLD->getOperand(2) };
16573 SDValue VLDDup = DAG.getMemIntrinsicNode(NewOpc, SDLoc(VLD), SDTys,
16574 Ops, VLDMemInt->getMemoryVT(),
16575 VLDMemInt->getMemOperand());
16576
16577 // Update the uses.
16578 for (SDUse &Use : VLD->uses()) {
16579 unsigned ResNo = Use.getResNo();
16580 // Ignore uses of the chain result.
16581 if (ResNo == NumVecs)
16582 continue;
16583 DCI.CombineTo(Use.getUser(), SDValue(VLDDup.getNode(), ResNo));
16584 }
16585
16586 // Now the vldN-lane intrinsic is dead except for its chain result.
16587 // Update uses of the chain.
16588 std::vector<SDValue> VLDDupResults;
16589 for (unsigned n = 0; n < NumVecs; ++n)
16590 VLDDupResults.push_back(SDValue(VLDDup.getNode(), n));
16591 VLDDupResults.push_back(SDValue(VLDDup.getNode(), NumVecs));
16592 DCI.CombineTo(VLD, VLDDupResults);
16593
16594 return true;
16595}
16596
16597/// PerformVDUPLANECombine - Target-specific dag combine xforms for
16598/// ARMISD::VDUPLANE.
16601 const ARMSubtarget *Subtarget) {
16602 SDValue Op = N->getOperand(0);
16603 EVT VT = N->getValueType(0);
16604
16605 // On MVE, we just convert the VDUPLANE to a VDUP with an extract.
16606 if (Subtarget->hasMVEIntegerOps()) {
16607 EVT ExtractVT = VT.getVectorElementType();
16608 // We need to ensure we are creating a legal type.
16609 if (!DCI.DAG.getTargetLoweringInfo().isTypeLegal(ExtractVT))
16610 ExtractVT = MVT::i32;
16611 SDValue Extract = DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), ExtractVT,
16612 N->getOperand(0), N->getOperand(1));
16613 return DCI.DAG.getNode(ARMISD::VDUP, SDLoc(N), VT, Extract);
16614 }
16615
16616 // If the source is a vldN-lane (N > 1) intrinsic, and all the other uses
16617 // of that intrinsic are also VDUPLANEs, combine them to a vldN-dup operation.
16618 if (CombineVLDDUP(N, DCI))
16619 return SDValue(N, 0);
16620
16621 // If the source is already a VMOVIMM or VMVNIMM splat, the VDUPLANE is
16622 // redundant. Ignore bit_converts for now; element sizes are checked below.
16623 while (Op.getOpcode() == ISD::BITCAST)
16624 Op = Op.getOperand(0);
16625 if (Op.getOpcode() != ARMISD::VMOVIMM && Op.getOpcode() != ARMISD::VMVNIMM)
16626 return SDValue();
16627
16628 // Make sure the VMOV element size is not bigger than the VDUPLANE elements.
16629 unsigned EltSize = Op.getScalarValueSizeInBits();
16630 // The canonical VMOV for a zero vector uses a 32-bit element size.
16631 unsigned Imm = Op.getConstantOperandVal(0);
16632 unsigned EltBits;
16633 if (ARM_AM::decodeVMOVModImm(Imm, EltBits) == 0)
16634 EltSize = 8;
16635 if (EltSize > VT.getScalarSizeInBits())
16636 return SDValue();
16637
16638 return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
16639}
16640
16641/// PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
16643 const ARMSubtarget *Subtarget) {
16644 SDValue Op = N->getOperand(0);
16645 SDLoc dl(N);
16646
16647 if (Subtarget->hasMVEIntegerOps()) {
16648 // Convert VDUP f32 -> VDUP BITCAST i32 under MVE, as we know the value will
16649 // need to come from a GPR.
16650 if (Op.getValueType() == MVT::f32)
16651 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16652 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op));
16653 else if (Op.getValueType() == MVT::f16)
16654 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16655 DAG.getNode(ARMISD::VMOVrh, dl, MVT::i32, Op));
16656 }
16657
16658 if (!Subtarget->hasNEON())
16659 return SDValue();
16660
16661 // Match VDUP(LOAD) -> VLD1DUP.
16662 // We match this pattern here rather than waiting for isel because the
16663 // transform is only legal for unindexed loads.
16664 LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode());
16665 if (LD && Op.hasOneUse() && LD->isUnindexed() &&
16666 LD->getMemoryVT() == N->getValueType(0).getVectorElementType()) {
16667 SDValue Ops[] = {LD->getOperand(0), LD->getOperand(1),
16668 DAG.getConstant(LD->getAlign().value(), SDLoc(N), MVT::i32)};
16669 SDVTList SDTys = DAG.getVTList(N->getValueType(0), MVT::Other);
16670 SDValue VLDDup =
16672 LD->getMemoryVT(), LD->getMemOperand());
16673 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), VLDDup.getValue(1));
16674 return VLDDup;
16675 }
16676
16677 return SDValue();
16678}
16679
16682 const ARMSubtarget *Subtarget) {
16683 EVT VT = N->getValueType(0);
16684
16685 // If this is a legal vector load, try to combine it into a VLD1_UPD.
16686 if (Subtarget->hasNEON() && ISD::isNormalLoad(N) && VT.isVector() &&
16688 return CombineBaseUpdate(N, DCI);
16689
16690 return SDValue();
16691}
16692
16693// Optimize trunc store (of multiple scalars) to shuffle and store. First,
16694// pack all of the elements in one place. Next, store to memory in fewer
16695// chunks.
16697 SelectionDAG &DAG) {
16698 SDValue StVal = St->getValue();
16699 EVT VT = StVal.getValueType();
16700 if (!St->isTruncatingStore() || !VT.isVector())
16701 return SDValue();
16702 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
16703 EVT StVT = St->getMemoryVT();
16704 unsigned NumElems = VT.getVectorNumElements();
16705 assert(StVT != VT && "Cannot truncate to the same type");
16706 unsigned FromEltSz = VT.getScalarSizeInBits();
16707 unsigned ToEltSz = StVT.getScalarSizeInBits();
16708
16709 // From, To sizes and ElemCount must be pow of two
16710 if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz))
16711 return SDValue();
16712
16713 // We are going to use the original vector elt for storing.
16714 // Accumulated smaller vector elements must be a multiple of the store size.
16715 if (0 != (NumElems * FromEltSz) % ToEltSz)
16716 return SDValue();
16717
16718 unsigned SizeRatio = FromEltSz / ToEltSz;
16719 assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
16720
16721 // Create a type on which we perform the shuffle.
16722 EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
16723 NumElems * SizeRatio);
16724 assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
16725
16726 SDLoc DL(St);
16727 SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
16728 SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
16729 for (unsigned i = 0; i < NumElems; ++i)
16730 ShuffleVec[i] = DAG.getDataLayout().isBigEndian() ? (i + 1) * SizeRatio - 1
16731 : i * SizeRatio;
16732
16733 // Can't shuffle using an illegal type.
16734 if (!TLI.isTypeLegal(WideVecVT))
16735 return SDValue();
16736
16737 SDValue Shuff = DAG.getVectorShuffle(
16738 WideVecVT, DL, WideVec, DAG.getUNDEF(WideVec.getValueType()), ShuffleVec);
16739 // At this point all of the data is stored at the bottom of the
16740 // register. We now need to save it to mem.
16741
16742 // Find the largest store unit
16743 MVT StoreType = MVT::i8;
16744 for (MVT Tp : MVT::integer_valuetypes()) {
16745 if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
16746 StoreType = Tp;
16747 }
16748 // Didn't find a legal store type.
16749 if (!TLI.isTypeLegal(StoreType))
16750 return SDValue();
16751
16752 // Bitcast the original vector into a vector of store-size units
16753 EVT StoreVecVT =
16754 EVT::getVectorVT(*DAG.getContext(), StoreType,
16755 VT.getSizeInBits() / EVT(StoreType).getSizeInBits());
16756 assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
16757 SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
16759 SDValue Increment = DAG.getConstant(StoreType.getSizeInBits() / 8, DL,
16760 TLI.getPointerTy(DAG.getDataLayout()));
16761 SDValue BasePtr = St->getBasePtr();
16762
16763 // Perform one or more big stores into memory.
16764 unsigned E = (ToEltSz * NumElems) / StoreType.getSizeInBits();
16765 for (unsigned I = 0; I < E; I++) {
16766 SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreType,
16767 ShuffWide, DAG.getIntPtrConstant(I, DL));
16768 SDValue Ch =
16769 DAG.getStore(St->getChain(), DL, SubVec, BasePtr, St->getPointerInfo(),
16770 St->getAlign(), St->getMemOperand()->getFlags());
16771 BasePtr =
16772 DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr, Increment);
16773 Chains.push_back(Ch);
16774 }
16775 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
16776}
16777
16778// Try taking a single vector store from an fpround (which would otherwise turn
16779// into an expensive buildvector) and splitting it into a series of narrowing
16780// stores.
16782 SelectionDAG &DAG) {
16783 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16784 return SDValue();
16785 SDValue Trunc = St->getValue();
16786 if (Trunc->getOpcode() != ISD::FP_ROUND)
16787 return SDValue();
16788 EVT FromVT = Trunc->getOperand(0).getValueType();
16789 EVT ToVT = Trunc.getValueType();
16790 if (!ToVT.isVector())
16791 return SDValue();
16793 EVT ToEltVT = ToVT.getVectorElementType();
16794 EVT FromEltVT = FromVT.getVectorElementType();
16795
16796 if (FromEltVT != MVT::f32 || ToEltVT != MVT::f16)
16797 return SDValue();
16798
16799 unsigned NumElements = 4;
16800 if (FromVT.getVectorNumElements() % NumElements != 0)
16801 return SDValue();
16802
16803 // Test if the Trunc will be convertible to a VMOVN with a shuffle, and if so
16804 // use the VMOVN over splitting the store. We are looking for patterns of:
16805 // !rev: 0 N 1 N+1 2 N+2 ...
16806 // rev: N 0 N+1 1 N+2 2 ...
16807 // The shuffle may either be a single source (in which case N = NumElts/2) or
16808 // two inputs extended with concat to the same size (in which case N =
16809 // NumElts).
16810 auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
16811 ArrayRef<int> M = SVN->getMask();
16812 unsigned NumElts = ToVT.getVectorNumElements();
16813 if (SVN->getOperand(1).isUndef())
16814 NumElts /= 2;
16815
16816 unsigned Off0 = Rev ? NumElts : 0;
16817 unsigned Off1 = Rev ? 0 : NumElts;
16818
16819 for (unsigned I = 0; I < NumElts; I += 2) {
16820 if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
16821 return false;
16822 if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
16823 return false;
16824 }
16825
16826 return true;
16827 };
16828
16829 if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
16830 if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
16831 return SDValue();
16832
16833 LLVMContext &C = *DAG.getContext();
16834 SDLoc DL(St);
16835 // Details about the old store
16836 SDValue Ch = St->getChain();
16837 SDValue BasePtr = St->getBasePtr();
16838 Align Alignment = St->getBaseAlign();
16840 AAMDNodes AAInfo = St->getAAInfo();
16841
16842 // We split the store into slices of NumElements. fp16 trunc stores are vcvt
16843 // and then stored as truncating integer stores.
16844 EVT NewFromVT = EVT::getVectorVT(C, FromEltVT, NumElements);
16845 EVT NewToVT = EVT::getVectorVT(
16846 C, EVT::getIntegerVT(C, ToEltVT.getSizeInBits()), NumElements);
16847
16849 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
16850 unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
16851 SDValue NewPtr =
16852 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16853
16854 SDValue Extract =
16855 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
16856 DAG.getConstant(i * NumElements, DL, MVT::i32));
16857
16858 SDValue FPTrunc =
16859 DAG.getNode(ARMISD::VCVTN, DL, MVT::v8f16, DAG.getUNDEF(MVT::v8f16),
16860 Extract, DAG.getConstant(0, DL, MVT::i32));
16861 Extract = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v4i32, FPTrunc);
16862
16863 SDValue Store = DAG.getTruncStore(
16864 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16865 NewToVT, Alignment, MMOFlags, AAInfo);
16866 Stores.push_back(Store);
16867 }
16868 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16869}
16870
16871// Try taking a single vector store from an MVETRUNC (which would otherwise turn
16872// into an expensive buildvector) and splitting it into a series of narrowing
16873// stores.
16875 SelectionDAG &DAG) {
16876 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16877 return SDValue();
16878 SDValue Trunc = St->getValue();
16879 if (Trunc->getOpcode() != ARMISD::MVETRUNC)
16880 return SDValue();
16881 EVT FromVT = Trunc->getOperand(0).getValueType();
16882 EVT ToVT = Trunc.getValueType();
16883
16884 LLVMContext &C = *DAG.getContext();
16885 SDLoc DL(St);
16886 // Details about the old store
16887 SDValue Ch = St->getChain();
16888 SDValue BasePtr = St->getBasePtr();
16889 Align Alignment = St->getBaseAlign();
16891 AAMDNodes AAInfo = St->getAAInfo();
16892
16893 EVT NewToVT = EVT::getVectorVT(C, ToVT.getVectorElementType(),
16894 FromVT.getVectorNumElements());
16895
16897 for (unsigned i = 0; i < Trunc.getNumOperands(); i++) {
16898 unsigned NewOffset =
16899 i * FromVT.getVectorNumElements() * ToVT.getScalarSizeInBits() / 8;
16900 SDValue NewPtr =
16901 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16902
16903 SDValue Extract = Trunc.getOperand(i);
16904 SDValue Store = DAG.getTruncStore(
16905 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16906 NewToVT, Alignment, MMOFlags, AAInfo);
16907 Stores.push_back(Store);
16908 }
16909 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16910}
16911
16912// Given a floating point store from an extracted vector, with an integer
16913// VGETLANE that already exists, store the existing VGETLANEu directly. This can
16914// help reduce fp register pressure, doesn't require the fp extract and allows
16915// use of more integer post-inc stores not available with vstr.
16917 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16918 return SDValue();
16919 SDValue Extract = St->getValue();
16920 EVT VT = Extract.getValueType();
16921 // For now only uses f16. This may be useful for f32 too, but that will
16922 // be bitcast(extract), not the VGETLANEu we currently check here.
16923 if (VT != MVT::f16 || Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
16924 return SDValue();
16925
16926 SDNode *GetLane =
16927 DAG.getNodeIfExists(ARMISD::VGETLANEu, DAG.getVTList(MVT::i32),
16928 {Extract.getOperand(0), Extract.getOperand(1)});
16929 if (!GetLane)
16930 return SDValue();
16931
16932 LLVMContext &C = *DAG.getContext();
16933 SDLoc DL(St);
16934 // Create a new integer store to replace the existing floating point version.
16935 SDValue Ch = St->getChain();
16936 SDValue BasePtr = St->getBasePtr();
16937 Align Alignment = St->getBaseAlign();
16939 AAMDNodes AAInfo = St->getAAInfo();
16940 EVT NewToVT = EVT::getIntegerVT(C, VT.getSizeInBits());
16941 SDValue Store = DAG.getTruncStore(Ch, DL, SDValue(GetLane, 0), BasePtr,
16942 St->getPointerInfo(), NewToVT, Alignment,
16943 MMOFlags, AAInfo);
16944
16945 return Store;
16946}
16947
16948/// PerformSTORECombine - Target-specific dag combine xforms for
16949/// ISD::STORE.
16952 const ARMSubtarget *Subtarget) {
16954 if (St->isVolatile())
16955 return SDValue();
16956 SDValue StVal = St->getValue();
16957 EVT VT = StVal.getValueType();
16958
16959 if (Subtarget->hasNEON())
16960 if (SDValue Store = PerformTruncatingStoreCombine(St, DCI.DAG))
16961 return Store;
16962
16963 if (Subtarget->hasMVEFloatOps())
16964 if (SDValue NewToken = PerformSplittingToNarrowingStores(St, DCI.DAG))
16965 return NewToken;
16966
16967 if (Subtarget->hasMVEIntegerOps()) {
16968 if (SDValue NewChain = PerformExtractFpToIntStores(St, DCI.DAG))
16969 return NewChain;
16970 if (SDValue NewToken =
16972 return NewToken;
16973 }
16974
16975 if (!ISD::isNormalStore(St))
16976 return SDValue();
16977
16978 // Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
16979 // ARM stores of arguments in the same cache line.
16980 if (StVal.getOpcode() == ARMISD::VMOVDRR && StVal->hasOneUse()) {
16981 SelectionDAG &DAG = DCI.DAG;
16982 bool isBigEndian = DAG.getDataLayout().isBigEndian();
16983 SDLoc DL(St);
16984 SDValue BasePtr = St->getBasePtr();
16985 SDValue NewST1 =
16986 DAG.getStore(St->getChain(), DL, StVal.getOperand(isBigEndian ? 1 : 0),
16987 BasePtr, St->getPointerInfo(), St->getBaseAlign(),
16988 St->getMemOperand()->getFlags());
16989
16990 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
16991 DAG.getConstant(4, DL, MVT::i32));
16992 return DAG.getStore(NewST1.getValue(0), DL,
16993 StVal.getOperand(isBigEndian ? 0 : 1), OffsetPtr,
16995 St->getBaseAlign(), St->getMemOperand()->getFlags());
16996 }
16997
16998 if (StVal.getValueType() == MVT::i64 &&
17000 // Bitcast an i64 store extracted from a vector to f64.
17001 // Otherwise, the i64 value will be legalized to a pair of i32 values.
17002 SelectionDAG &DAG = DCI.DAG;
17003 SDLoc dl(StVal);
17004 SDValue IntVec = StVal.getOperand(0);
17005 EVT FloatVT =
17006 EVT::getVectorVT(*DAG.getContext(), MVT::f64,
17008 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
17009 SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Vec,
17010 StVal.getOperand(1));
17011 dl = SDLoc(N);
17012 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
17013 // Make the DAGCombiner fold the bitcasts.
17014 DCI.AddToWorklist(Vec.getNode());
17015 DCI.AddToWorklist(ExtElt.getNode());
17016 DCI.AddToWorklist(V.getNode());
17017 return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
17018 St->getPointerInfo(), St->getAlign(),
17019 St->getMemOperand()->getFlags(), St->getAAInfo());
17020 }
17021
17022 // If this is a legal vector store, try to combine it into a VST1_UPD.
17023 if (Subtarget->hasNEON() && ISD::isNormalStore(N) && VT.isVector() &&
17025 return CombineBaseUpdate(N, DCI);
17026
17027 return SDValue();
17028}
17029
17030/// PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD)
17031/// can replace combinations of VMUL and VCVT (floating-point to integer)
17032/// when the VMUL has a constant operand that is a power of 2.
17033///
17034/// Example (assume d17 = <float 8.000000e+00, float 8.000000e+00>):
17035/// vmul.f32 d16, d17, d16
17036/// vcvt.s32.f32 d16, d16
17037/// becomes:
17038/// vcvt.s32.f32 d16, d16, #3
17040 const ARMSubtarget *Subtarget) {
17041 if (!Subtarget->hasNEON())
17042 return SDValue();
17043
17044 SDValue Op = N->getOperand(0);
17045 if (!Op.getValueType().isVector() || !Op.getValueType().isSimple() ||
17046 Op.getOpcode() != ISD::FMUL)
17047 return SDValue();
17048
17049 SDValue ConstVec = Op->getOperand(1);
17050 if (!isa<BuildVectorSDNode>(ConstVec))
17051 return SDValue();
17052
17053 MVT FloatTy = Op.getSimpleValueType().getVectorElementType();
17054 uint32_t FloatBits = FloatTy.getSizeInBits();
17055 MVT IntTy = N->getSimpleValueType(0).getVectorElementType();
17056 uint32_t IntBits = IntTy.getSizeInBits();
17057 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17058 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17059 // These instructions only exist converting from f32 to i32. We can handle
17060 // smaller integers by generating an extra truncate, but larger ones would
17061 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17062 // these instructions only support v2i32/v4i32 types.
17063 return SDValue();
17064 }
17065
17066 BitVector UndefElements;
17068 int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33);
17069 if (C == -1 || C == 0 || C > 32)
17070 return SDValue();
17071
17072 SDLoc dl(N);
17073 bool isSigned = N->getOpcode() == ISD::FP_TO_SINT;
17074 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfp2fxs :
17075 Intrinsic::arm_neon_vcvtfp2fxu;
17076 SDValue FixConv = DAG.getNode(
17077 ISD::INTRINSIC_WO_CHAIN, dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32,
17078 DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), Op->getOperand(0),
17079 DAG.getConstant(C, dl, MVT::i32));
17080
17081 if (IntBits < FloatBits)
17082 FixConv = DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), FixConv);
17083
17084 return FixConv;
17085}
17086
17088 const ARMSubtarget *Subtarget) {
17089 if (!Subtarget->hasMVEFloatOps())
17090 return SDValue();
17091
17092 // Turn (fadd x, (vselect c, y, -0.0)) into (vselect c, (fadd x, y), x)
17093 // The second form can be more easily turned into a predicated vadd, and
17094 // possibly combined into a fma to become a predicated vfma.
17095 SDValue Op0 = N->getOperand(0);
17096 SDValue Op1 = N->getOperand(1);
17097 EVT VT = N->getValueType(0);
17098 SDLoc DL(N);
17099
17100 // The identity element for a fadd is -0.0 or +0.0 when the nsz flag is set,
17101 // which these VMOV's represent.
17102 auto isIdentitySplat = [&](SDValue Op, bool NSZ) {
17103 if (Op.getOpcode() != ISD::BITCAST ||
17104 Op.getOperand(0).getOpcode() != ARMISD::VMOVIMM)
17105 return false;
17106 uint64_t ImmVal = Op.getOperand(0).getConstantOperandVal(0);
17107 if (VT == MVT::v4f32 && (ImmVal == 1664 || (ImmVal == 0 && NSZ)))
17108 return true;
17109 if (VT == MVT::v8f16 && (ImmVal == 2688 || (ImmVal == 0 && NSZ)))
17110 return true;
17111 return false;
17112 };
17113
17114 if (Op0.getOpcode() == ISD::VSELECT && Op1.getOpcode() != ISD::VSELECT)
17115 std::swap(Op0, Op1);
17116
17117 if (Op1.getOpcode() != ISD::VSELECT)
17118 return SDValue();
17119
17120 SDNodeFlags FaddFlags = N->getFlags();
17121 bool NSZ = FaddFlags.hasNoSignedZeros();
17122 if (!isIdentitySplat(Op1.getOperand(2), NSZ))
17123 return SDValue();
17124
17125 SDValue FAdd =
17126 DAG.getNode(ISD::FADD, DL, VT, Op0, Op1.getOperand(1), FaddFlags);
17127 return DAG.getNode(ISD::VSELECT, DL, VT, Op1.getOperand(0), FAdd, Op0, FaddFlags);
17128}
17129
17131 SDValue LHS = N->getOperand(0);
17132 SDValue RHS = N->getOperand(1);
17133 EVT VT = N->getValueType(0);
17134 SDLoc DL(N);
17135
17136 if (!N->getFlags().hasAllowReassociation())
17137 return SDValue();
17138
17139 // Combine fadd(a, vcmla(b, c, d)) -> vcmla(fadd(a, b), b, c)
17140 auto ReassocComplex = [&](SDValue A, SDValue B) {
17141 if (A.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
17142 return SDValue();
17143 unsigned Opc = A.getConstantOperandVal(0);
17144 if (Opc != Intrinsic::arm_mve_vcmlaq)
17145 return SDValue();
17146 SDValue VCMLA = DAG.getNode(
17147 ISD::INTRINSIC_WO_CHAIN, DL, VT, A.getOperand(0), A.getOperand(1),
17148 DAG.getNode(ISD::FADD, DL, VT, A.getOperand(2), B, N->getFlags()),
17149 A.getOperand(3), A.getOperand(4));
17150 VCMLA->setFlags(A->getFlags());
17151 return VCMLA;
17152 };
17153 if (SDValue R = ReassocComplex(LHS, RHS))
17154 return R;
17155 if (SDValue R = ReassocComplex(RHS, LHS))
17156 return R;
17157
17158 return SDValue();
17159}
17160
17162 const ARMSubtarget *Subtarget) {
17163 if (SDValue S = PerformFAddVSelectCombine(N, DAG, Subtarget))
17164 return S;
17165 if (SDValue S = PerformFADDVCMLACombine(N, DAG))
17166 return S;
17167 return SDValue();
17168}
17169
17170/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD)
17171/// can replace combinations of VCVT (integer to floating-point) and VMUL
17172/// when the VMUL has a constant operand that is a power of 2.
17173///
17174/// Example (assume d17 = <float 0.125, float 0.125>):
17175/// vcvt.f32.s32 d16, d16
17176/// vmul.f32 d16, d16, d17
17177/// becomes:
17178/// vcvt.f32.s32 d16, d16, #3
17180 const ARMSubtarget *Subtarget) {
17181 if (!Subtarget->hasNEON())
17182 return SDValue();
17183
17184 SDValue Op = N->getOperand(0);
17185 unsigned OpOpcode = Op.getNode()->getOpcode();
17186 if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple() ||
17187 (OpOpcode != ISD::SINT_TO_FP && OpOpcode != ISD::UINT_TO_FP))
17188 return SDValue();
17189
17190 SDValue ConstVec = N->getOperand(1);
17191 if (!isa<BuildVectorSDNode>(ConstVec))
17192 return SDValue();
17193
17194 MVT FloatTy = N->getSimpleValueType(0).getVectorElementType();
17195 uint32_t FloatBits = FloatTy.getSizeInBits();
17196 MVT IntTy = Op.getOperand(0).getSimpleValueType().getVectorElementType();
17197 uint32_t IntBits = IntTy.getSizeInBits();
17198 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17199 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17200 // These instructions only exist converting from i32 to f32. We can handle
17201 // smaller integers by generating an extra extend, but larger ones would
17202 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17203 // these instructions only support v2i32/v4i32 types.
17204 return SDValue();
17205 }
17206
17207 ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true);
17208 APFloat Recip(0.0f);
17209 if (!CN || !CN->getValueAPF().getExactInverse(&Recip))
17210 return SDValue();
17211
17212 bool IsExact;
17213 APSInt IntVal(33);
17214 if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
17215 APFloat::opOK ||
17216 !IsExact)
17217 return SDValue();
17218
17219 int32_t C = IntVal.exactLogBase2();
17220 if (C == -1 || C == 0 || C > 32)
17221 return SDValue();
17222
17223 SDLoc DL(N);
17224 bool isSigned = OpOpcode == ISD::SINT_TO_FP;
17225 SDValue ConvInput = Op.getOperand(0);
17226 if (IntBits < FloatBits)
17228 NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput);
17229
17230 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp
17231 : Intrinsic::arm_neon_vcvtfxu2fp;
17232 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
17233 DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput,
17234 DAG.getConstant(C, DL, MVT::i32));
17235}
17236
17238 const ARMSubtarget *ST) {
17239 if (!ST->hasMVEIntegerOps())
17240 return SDValue();
17241
17242 assert(N->getOpcode() == ISD::VECREDUCE_ADD);
17243 EVT ResVT = N->getValueType(0);
17244 SDValue N0 = N->getOperand(0);
17245 SDLoc dl(N);
17246
17247 // Try to turn vecreduce_add(add(x, y)) into vecreduce(x) + vecreduce(y)
17248 if (ResVT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
17249 (N0.getValueType() == MVT::v4i32 || N0.getValueType() == MVT::v8i16 ||
17250 N0.getValueType() == MVT::v16i8)) {
17251 SDValue Red0 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(0));
17252 SDValue Red1 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(1));
17253 return DAG.getNode(ISD::ADD, dl, ResVT, Red0, Red1);
17254 }
17255
17256 // We are looking for something that will have illegal types if left alone,
17257 // but that we can convert to a single instruction under MVE. For example
17258 // vecreduce_add(sext(A, v8i32)) => VADDV.s16 A
17259 // or
17260 // vecreduce_add(mul(zext(A, v16i32), zext(B, v16i32))) => VMLADAV.u8 A, B
17261
17262 // The legal cases are:
17263 // VADDV u/s 8/16/32
17264 // VMLAV u/s 8/16/32
17265 // VADDLV u/s 32
17266 // VMLALV u/s 16/32
17267
17268 // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
17269 // extend it and use v4i32 instead.
17270 auto ExtTypeMatches = [](SDValue A, ArrayRef<MVT> ExtTypes) {
17271 EVT AVT = A.getValueType();
17272 return any_of(ExtTypes, [&](MVT Ty) {
17273 return AVT.getVectorNumElements() == Ty.getVectorNumElements() &&
17274 AVT.bitsLE(Ty);
17275 });
17276 };
17277 auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
17278 EVT AVT = A.getValueType();
17279 if (!AVT.is128BitVector())
17280 A = DAG.getNode(
17281 ExtendCode, dl,
17283 *DAG.getContext(),
17285 A);
17286 return A;
17287 };
17288 auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
17289 if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
17290 return SDValue();
17291 SDValue A = N0->getOperand(0);
17292 if (ExtTypeMatches(A, ExtTypes))
17293 return ExtendIfNeeded(A, ExtendCode);
17294 return SDValue();
17295 };
17296 auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
17297 ArrayRef<MVT> ExtTypes, SDValue &Mask) {
17298 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17300 return SDValue();
17301 Mask = N0->getOperand(0);
17302 SDValue Ext = N0->getOperand(1);
17303 if (Ext->getOpcode() != ExtendCode)
17304 return SDValue();
17305 SDValue A = Ext->getOperand(0);
17306 if (ExtTypeMatches(A, ExtTypes))
17307 return ExtendIfNeeded(A, ExtendCode);
17308 return SDValue();
17309 };
17310 auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17311 SDValue &A, SDValue &B) {
17312 // For a vmla we are trying to match a larger pattern:
17313 // ExtA = sext/zext A
17314 // ExtB = sext/zext B
17315 // Mul = mul ExtA, ExtB
17316 // vecreduce.add Mul
17317 // There might also be en extra extend between the mul and the addreduce, so
17318 // long as the bitwidth is high enough to make them equivalent (for example
17319 // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
17320 if (ResVT != RetTy)
17321 return false;
17322 SDValue Mul = N0;
17323 if (Mul->getOpcode() == ExtendCode &&
17324 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17325 ResVT.getScalarSizeInBits())
17326 Mul = Mul->getOperand(0);
17327 if (Mul->getOpcode() != ISD::MUL)
17328 return false;
17329 SDValue ExtA = Mul->getOperand(0);
17330 SDValue ExtB = Mul->getOperand(1);
17331 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17332 return false;
17333 A = ExtA->getOperand(0);
17334 B = ExtB->getOperand(0);
17335 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17336 A = ExtendIfNeeded(A, ExtendCode);
17337 B = ExtendIfNeeded(B, ExtendCode);
17338 return true;
17339 }
17340 return false;
17341 };
17342 auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17343 SDValue &A, SDValue &B, SDValue &Mask) {
17344 // Same as the pattern above with a select for the zero predicated lanes
17345 // ExtA = sext/zext A
17346 // ExtB = sext/zext B
17347 // Mul = mul ExtA, ExtB
17348 // N0 = select Mask, Mul, 0
17349 // vecreduce.add N0
17350 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17352 return false;
17353 Mask = N0->getOperand(0);
17354 SDValue Mul = N0->getOperand(1);
17355 if (Mul->getOpcode() == ExtendCode &&
17356 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17357 ResVT.getScalarSizeInBits())
17358 Mul = Mul->getOperand(0);
17359 if (Mul->getOpcode() != ISD::MUL)
17360 return false;
17361 SDValue ExtA = Mul->getOperand(0);
17362 SDValue ExtB = Mul->getOperand(1);
17363 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17364 return false;
17365 A = ExtA->getOperand(0);
17366 B = ExtB->getOperand(0);
17367 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17368 A = ExtendIfNeeded(A, ExtendCode);
17369 B = ExtendIfNeeded(B, ExtendCode);
17370 return true;
17371 }
17372 return false;
17373 };
17374 auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
17375 // Split illegal MVT::v16i8->i64 vector reductions into two legal v8i16->i64
17376 // reductions. The operands are extended with MVEEXT, but as they are
17377 // reductions the lane orders do not matter. MVEEXT may be combined with
17378 // loads to produce two extending loads, or else they will be expanded to
17379 // VREV/VMOVL.
17380 EVT VT = Ops[0].getValueType();
17381 if (VT == MVT::v16i8) {
17382 assert((Opcode == ARMISD::VMLALVs || Opcode == ARMISD::VMLALVu) &&
17383 "Unexpected illegal long reduction opcode");
17384 bool IsUnsigned = Opcode == ARMISD::VMLALVu;
17385
17386 SDValue Ext0 =
17387 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17388 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[0]);
17389 SDValue Ext1 =
17390 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17391 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[1]);
17392
17393 SDValue MLA0 = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
17394 Ext0, Ext1);
17395 SDValue MLA1 =
17396 DAG.getNode(IsUnsigned ? ARMISD::VMLALVAu : ARMISD::VMLALVAs, dl,
17397 DAG.getVTList(MVT::i32, MVT::i32), MLA0, MLA0.getValue(1),
17398 Ext0.getValue(1), Ext1.getValue(1));
17399 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, MLA1, MLA1.getValue(1));
17400 }
17401 SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
17402 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
17403 SDValue(Node.getNode(), 1));
17404 };
17405
17406 SDValue A, B;
17407 SDValue Mask;
17408 if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17409 return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
17410 if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17411 return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
17412 if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17413 A, B))
17414 return Create64bitNode(ARMISD::VMLALVs, {A, B});
17415 if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17416 A, B))
17417 return Create64bitNode(ARMISD::VMLALVu, {A, B});
17418 if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
17419 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17420 DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
17421 if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
17422 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17423 DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
17424
17425 if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17426 Mask))
17427 return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
17428 if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17429 Mask))
17430 return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
17431 if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17432 Mask))
17433 return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
17434 if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17435 Mask))
17436 return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
17437 if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
17438 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17439 DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
17440 if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
17441 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17442 DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
17443
17444 if (SDValue A = IsVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}))
17445 return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
17446 if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
17447 return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
17448 if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}))
17449 return Create64bitNode(ARMISD::VADDLVs, {A});
17450 if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}))
17451 return Create64bitNode(ARMISD::VADDLVu, {A});
17452 if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
17453 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17454 DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
17455 if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
17456 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17457 DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
17458
17459 if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17460 return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
17461 if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17462 return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
17463 if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}, Mask))
17464 return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
17465 if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}, Mask))
17466 return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
17467 if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
17468 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17469 DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
17470 if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
17471 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17472 DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
17473
17474 // Some complications. We can get a case where the two inputs of the mul are
17475 // the same, then the output sext will have been helpfully converted to a
17476 // zext. Turn it back.
17477 SDValue Op = N0;
17478 if (Op->getOpcode() == ISD::VSELECT)
17479 Op = Op->getOperand(1);
17480 if (Op->getOpcode() == ISD::ZERO_EXTEND &&
17481 Op->getOperand(0)->getOpcode() == ISD::MUL) {
17482 SDValue Mul = Op->getOperand(0);
17483 if (Mul->getOperand(0) == Mul->getOperand(1) &&
17484 Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
17485 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
17486 if (Op != N0)
17487 Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
17488 N0->getOperand(0), Ext, N0->getOperand(2));
17489 return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
17490 }
17491 }
17492
17493 return SDValue();
17494}
17495
17496// Looks for vaddv(shuffle) or vmlav(shuffle, shuffle), with a shuffle where all
17497// the lanes are used. Due to the reduction being commutative the shuffle can be
17498// removed.
17500 unsigned VecOp = N->getOperand(0).getValueType().isVector() ? 0 : 2;
17501 auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp));
17502 if (!Shuf || !Shuf->getOperand(1).isUndef())
17503 return SDValue();
17504
17505 // Check all elements are used once in the mask.
17506 ArrayRef<int> Mask = Shuf->getMask();
17507 APInt SetElts(Mask.size(), 0);
17508 for (int E : Mask) {
17509 if (E < 0 || E >= (int)Mask.size())
17510 return SDValue();
17511 SetElts.setBit(E);
17512 }
17513 if (!SetElts.isAllOnes())
17514 return SDValue();
17515
17516 if (N->getNumOperands() != VecOp + 1) {
17517 auto *Shuf2 = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp + 1));
17518 if (!Shuf2 || !Shuf2->getOperand(1).isUndef() || Shuf2->getMask() != Mask)
17519 return SDValue();
17520 }
17521
17523 for (SDValue Op : N->ops()) {
17524 if (Op.getValueType().isVector())
17525 Ops.push_back(Op.getOperand(0));
17526 else
17527 Ops.push_back(Op);
17528 }
17529 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Ops);
17530}
17531
17534 SDValue Op0 = N->getOperand(0);
17535 SDValue Op1 = N->getOperand(1);
17536 unsigned IsTop = N->getConstantOperandVal(2);
17537
17538 // VMOVNT a undef -> a
17539 // VMOVNB a undef -> a
17540 // VMOVNB undef a -> a
17541 if (Op1->isUndef())
17542 return Op0;
17543 if (Op0->isUndef() && !IsTop)
17544 return Op1;
17545
17546 // VMOVNt(c, VQMOVNb(a, b)) => VQMOVNt(c, b)
17547 // VMOVNb(c, VQMOVNb(a, b)) => VQMOVNb(c, b)
17548 if ((Op1->getOpcode() == ARMISD::VQMOVNs ||
17549 Op1->getOpcode() == ARMISD::VQMOVNu) &&
17550 Op1->getConstantOperandVal(2) == 0)
17551 return DCI.DAG.getNode(Op1->getOpcode(), SDLoc(Op1), N->getValueType(0),
17552 Op0, Op1->getOperand(1), N->getOperand(2));
17553
17554 // Only the bottom lanes from Qm (Op1) and either the top or bottom lanes from
17555 // Qd (Op0) are demanded from a VMOVN, depending on whether we are inserting
17556 // into the top or bottom lanes.
17557 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17558 APInt Op1DemandedElts = APInt::getSplat(NumElts, APInt::getLowBitsSet(2, 1));
17559 APInt Op0DemandedElts =
17560 IsTop ? Op1DemandedElts
17561 : APInt::getSplat(NumElts, APInt::getHighBitsSet(2, 1));
17562
17563 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17564 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17565 return SDValue(N, 0);
17566 if (TLI.SimplifyDemandedVectorElts(Op1, Op1DemandedElts, DCI))
17567 return SDValue(N, 0);
17568
17569 return SDValue();
17570}
17571
17574 SDValue Op0 = N->getOperand(0);
17575 unsigned IsTop = N->getConstantOperandVal(2);
17576
17577 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17578 APInt Op0DemandedElts =
17579 APInt::getSplat(NumElts, IsTop ? APInt::getLowBitsSet(2, 1)
17580 : APInt::getHighBitsSet(2, 1));
17581
17582 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17583 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17584 return SDValue(N, 0);
17585 return SDValue();
17586}
17587
17590 EVT VT = N->getValueType(0);
17591 SDValue LHS = N->getOperand(0);
17592 SDValue RHS = N->getOperand(1);
17593
17594 auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
17595 auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
17596 // Turn VQDMULH(shuffle, shuffle) -> shuffle(VQDMULH)
17597 if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&
17598 LHS.getOperand(1).isUndef() && RHS.getOperand(1).isUndef() &&
17599 (LHS.hasOneUse() || RHS.hasOneUse() || LHS == RHS)) {
17600 SDLoc DL(N);
17601 SDValue NewBinOp = DCI.DAG.getNode(N->getOpcode(), DL, VT,
17602 LHS.getOperand(0), RHS.getOperand(0));
17603 SDValue UndefV = LHS.getOperand(1);
17604 return DCI.DAG.getVectorShuffle(VT, DL, NewBinOp, UndefV, Shuf0->getMask());
17605 }
17606 return SDValue();
17607}
17608
17610 SDLoc DL(N);
17611 SDValue Op0 = N->getOperand(0);
17612 SDValue Op1 = N->getOperand(1);
17613
17614 // Turn X << -C -> X >> C and viceversa. The negative shifts can come up from
17615 // uses of the intrinsics.
17616 if (auto C = dyn_cast<ConstantSDNode>(N->getOperand(2))) {
17617 int ShiftAmt = C->getSExtValue();
17618 if (ShiftAmt == 0) {
17619 SDValue Merge = DAG.getMergeValues({Op0, Op1}, DL);
17620 DAG.ReplaceAllUsesWith(N, Merge.getNode());
17621 return SDValue();
17622 }
17623
17624 if (ShiftAmt >= -32 && ShiftAmt < 0) {
17625 unsigned NewOpcode =
17626 N->getOpcode() == ARMISD::LSLL ? ARMISD::LSRL : ARMISD::LSLL;
17627 SDValue NewShift = DAG.getNode(NewOpcode, DL, N->getVTList(), Op0, Op1,
17628 DAG.getConstant(-ShiftAmt, DL, MVT::i32));
17629 DAG.ReplaceAllUsesWith(N, NewShift.getNode());
17630 return NewShift;
17631 }
17632 }
17633
17634 return SDValue();
17635}
17636
17637/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
17639 DAGCombinerInfo &DCI) const {
17640 SelectionDAG &DAG = DCI.DAG;
17641 unsigned IntNo = N->getConstantOperandVal(0);
17642 switch (IntNo) {
17643 default:
17644 // Don't do anything for most intrinsics.
17645 break;
17646
17647 // Vector shifts: check for immediate versions and lower them.
17648 // Note: This is done during DAG combining instead of DAG legalizing because
17649 // the build_vectors for 64-bit vector element shift counts are generally
17650 // not legal, and it is hard to see their values after they get legalized to
17651 // loads from a constant pool.
17652 case Intrinsic::arm_neon_vshifts:
17653 case Intrinsic::arm_neon_vshiftu:
17654 case Intrinsic::arm_neon_vrshifts:
17655 case Intrinsic::arm_neon_vrshiftu:
17656 case Intrinsic::arm_neon_vrshiftn:
17657 case Intrinsic::arm_neon_vqshifts:
17658 case Intrinsic::arm_neon_vqshiftu:
17659 case Intrinsic::arm_neon_vqshiftsu:
17660 case Intrinsic::arm_neon_vqshiftns:
17661 case Intrinsic::arm_neon_vqshiftnu:
17662 case Intrinsic::arm_neon_vqshiftnsu:
17663 case Intrinsic::arm_neon_vqrshiftns:
17664 case Intrinsic::arm_neon_vqrshiftnu:
17665 case Intrinsic::arm_neon_vqrshiftnsu: {
17666 EVT VT = N->getOperand(1).getValueType();
17667 int64_t Cnt;
17668 unsigned VShiftOpc = 0;
17669
17670 switch (IntNo) {
17671 case Intrinsic::arm_neon_vshifts:
17672 case Intrinsic::arm_neon_vshiftu:
17673 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) {
17674 VShiftOpc = ARMISD::VSHLIMM;
17675 break;
17676 }
17677 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) {
17678 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? ARMISD::VSHRsIMM
17679 : ARMISD::VSHRuIMM);
17680 break;
17681 }
17682 return SDValue();
17683
17684 case Intrinsic::arm_neon_vrshifts:
17685 case Intrinsic::arm_neon_vrshiftu:
17686 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt))
17687 break;
17688 return SDValue();
17689
17690 case Intrinsic::arm_neon_vqshifts:
17691 case Intrinsic::arm_neon_vqshiftu:
17692 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17693 break;
17694 return SDValue();
17695
17696 case Intrinsic::arm_neon_vqshiftsu:
17697 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17698 break;
17699 llvm_unreachable("invalid shift count for vqshlu intrinsic");
17700
17701 case Intrinsic::arm_neon_vrshiftn:
17702 case Intrinsic::arm_neon_vqshiftns:
17703 case Intrinsic::arm_neon_vqshiftnu:
17704 case Intrinsic::arm_neon_vqshiftnsu:
17705 case Intrinsic::arm_neon_vqrshiftns:
17706 case Intrinsic::arm_neon_vqrshiftnu:
17707 case Intrinsic::arm_neon_vqrshiftnsu:
17708 // Narrowing shifts require an immediate right shift.
17709 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt))
17710 break;
17711 llvm_unreachable("invalid shift count for narrowing vector shift "
17712 "intrinsic");
17713
17714 default:
17715 llvm_unreachable("unhandled vector shift");
17716 }
17717
17718 switch (IntNo) {
17719 case Intrinsic::arm_neon_vshifts:
17720 case Intrinsic::arm_neon_vshiftu:
17721 // Opcode already set above.
17722 break;
17723 case Intrinsic::arm_neon_vrshifts:
17724 VShiftOpc = ARMISD::VRSHRsIMM;
17725 break;
17726 case Intrinsic::arm_neon_vrshiftu:
17727 VShiftOpc = ARMISD::VRSHRuIMM;
17728 break;
17729 case Intrinsic::arm_neon_vrshiftn:
17730 VShiftOpc = ARMISD::VRSHRNIMM;
17731 break;
17732 case Intrinsic::arm_neon_vqshifts:
17733 VShiftOpc = ARMISD::VQSHLsIMM;
17734 break;
17735 case Intrinsic::arm_neon_vqshiftu:
17736 VShiftOpc = ARMISD::VQSHLuIMM;
17737 break;
17738 case Intrinsic::arm_neon_vqshiftsu:
17739 VShiftOpc = ARMISD::VQSHLsuIMM;
17740 break;
17741 case Intrinsic::arm_neon_vqshiftns:
17742 VShiftOpc = ARMISD::VQSHRNsIMM;
17743 break;
17744 case Intrinsic::arm_neon_vqshiftnu:
17745 VShiftOpc = ARMISD::VQSHRNuIMM;
17746 break;
17747 case Intrinsic::arm_neon_vqshiftnsu:
17748 VShiftOpc = ARMISD::VQSHRNsuIMM;
17749 break;
17750 case Intrinsic::arm_neon_vqrshiftns:
17751 VShiftOpc = ARMISD::VQRSHRNsIMM;
17752 break;
17753 case Intrinsic::arm_neon_vqrshiftnu:
17754 VShiftOpc = ARMISD::VQRSHRNuIMM;
17755 break;
17756 case Intrinsic::arm_neon_vqrshiftnsu:
17757 VShiftOpc = ARMISD::VQRSHRNsuIMM;
17758 break;
17759 }
17760
17761 SDLoc dl(N);
17762 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17763 N->getOperand(1), DAG.getConstant(Cnt, dl, MVT::i32));
17764 }
17765
17766 case Intrinsic::arm_neon_vshiftins: {
17767 EVT VT = N->getOperand(1).getValueType();
17768 int64_t Cnt;
17769 unsigned VShiftOpc = 0;
17770
17771 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt))
17772 VShiftOpc = ARMISD::VSLIIMM;
17773 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt))
17774 VShiftOpc = ARMISD::VSRIIMM;
17775 else {
17776 llvm_unreachable("invalid shift count for vsli/vsri intrinsic");
17777 }
17778
17779 SDLoc dl(N);
17780 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17781 N->getOperand(1), N->getOperand(2),
17782 DAG.getConstant(Cnt, dl, MVT::i32));
17783 }
17784
17785 case Intrinsic::arm_neon_vqrshifts:
17786 case Intrinsic::arm_neon_vqrshiftu:
17787 // No immediate versions of these to check for.
17788 break;
17789
17790 case Intrinsic::arm_neon_vbsl: {
17791 SDLoc dl(N);
17792 return DAG.getNode(ARMISD::VBSP, dl, N->getValueType(0), N->getOperand(1),
17793 N->getOperand(2), N->getOperand(3));
17794 }
17795 case Intrinsic::arm_mve_vqdmlah:
17796 case Intrinsic::arm_mve_vqdmlash:
17797 case Intrinsic::arm_mve_vqrdmlah:
17798 case Intrinsic::arm_mve_vqrdmlash:
17799 case Intrinsic::arm_mve_vmla_n_predicated:
17800 case Intrinsic::arm_mve_vmlas_n_predicated:
17801 case Intrinsic::arm_mve_vqdmlah_predicated:
17802 case Intrinsic::arm_mve_vqdmlash_predicated:
17803 case Intrinsic::arm_mve_vqrdmlah_predicated:
17804 case Intrinsic::arm_mve_vqrdmlash_predicated: {
17805 // These intrinsics all take an i32 scalar operand which is narrowed to the
17806 // size of a single lane of the vector type they return. So we don't need
17807 // any bits of that operand above that point, which allows us to eliminate
17808 // uxth/sxth.
17809 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
17810 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17811 if (SimplifyDemandedBits(N->getOperand(3), DemandedMask, DCI))
17812 return SDValue();
17813 break;
17814 }
17815
17816 case Intrinsic::arm_mve_minv:
17817 case Intrinsic::arm_mve_maxv:
17818 case Intrinsic::arm_mve_minav:
17819 case Intrinsic::arm_mve_maxav:
17820 case Intrinsic::arm_mve_minv_predicated:
17821 case Intrinsic::arm_mve_maxv_predicated:
17822 case Intrinsic::arm_mve_minav_predicated:
17823 case Intrinsic::arm_mve_maxav_predicated: {
17824 // These intrinsics all take an i32 scalar operand which is narrowed to the
17825 // size of a single lane of the vector type they take as the other input.
17826 unsigned BitWidth = N->getOperand(2)->getValueType(0).getScalarSizeInBits();
17827 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17828 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
17829 return SDValue();
17830 break;
17831 }
17832
17833 case Intrinsic::arm_mve_addv: {
17834 // Turn this intrinsic straight into the appropriate ARMISD::VADDV node,
17835 // which allow PerformADDVecReduce to turn it into VADDLV when possible.
17836 bool Unsigned = N->getConstantOperandVal(2);
17837 unsigned Opc = Unsigned ? ARMISD::VADDVu : ARMISD::VADDVs;
17838 return DAG.getNode(Opc, SDLoc(N), N->getVTList(), N->getOperand(1));
17839 }
17840
17841 case Intrinsic::arm_mve_addlv:
17842 case Intrinsic::arm_mve_addlv_predicated: {
17843 // Same for these, but ARMISD::VADDLV has to be followed by a BUILD_PAIR
17844 // which recombines the two outputs into an i64
17845 bool Unsigned = N->getConstantOperandVal(2);
17846 unsigned Opc = IntNo == Intrinsic::arm_mve_addlv ?
17847 (Unsigned ? ARMISD::VADDLVu : ARMISD::VADDLVs) :
17848 (Unsigned ? ARMISD::VADDLVpu : ARMISD::VADDLVps);
17849
17851 for (unsigned i = 1, e = N->getNumOperands(); i < e; i++)
17852 if (i != 2) // skip the unsigned flag
17853 Ops.push_back(N->getOperand(i));
17854
17855 SDLoc dl(N);
17856 SDValue val = DAG.getNode(Opc, dl, {MVT::i32, MVT::i32}, Ops);
17857 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, val.getValue(0),
17858 val.getValue(1));
17859 }
17860 }
17861
17862 return SDValue();
17863}
17864
17866 EVT VT = Y.getValueType();
17867 if (!VT.isVector())
17868 return hasAndNotCompare(Y);
17869 if (Subtarget->hasMVEIntegerOps())
17870 return VT.is128BitVector();
17871 if (Subtarget->hasNEON())
17872 return VT.is64BitVector() || VT.is128BitVector();
17873 return false;
17874}
17875
17876/// PerformShiftCombine - Checks for immediate versions of vector shifts and
17877/// lowers them. As with the vector shift intrinsics, this is done during DAG
17878/// combining instead of DAG legalizing because the build_vectors for 64-bit
17879/// vector element shift counts are generally not legal, and it is hard to see
17880/// their values after they get legalized to loads from a constant pool.
17883 const ARMSubtarget *ST) {
17884 SelectionDAG &DAG = DCI.DAG;
17885 EVT VT = N->getValueType(0);
17886
17887 if (ST->isThumb1Only() && N->getOpcode() == ISD::SHL && VT == MVT::i32 &&
17888 N->getOperand(0)->getOpcode() == ISD::AND &&
17889 N->getOperand(0)->hasOneUse()) {
17890 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
17891 return SDValue();
17892 // Look for the pattern (shl (and x, AndMask), ShiftAmt). This doesn't
17893 // usually show up because instcombine prefers to canonicalize it to
17894 // (and (shl x, ShiftAmt) (shl AndMask, ShiftAmt)), but the shift can come
17895 // out of GEP lowering in some cases.
17896 SDValue N0 = N->getOperand(0);
17897 ConstantSDNode *ShiftAmtNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
17898 if (!ShiftAmtNode)
17899 return SDValue();
17900 uint32_t ShiftAmt = static_cast<uint32_t>(ShiftAmtNode->getZExtValue());
17901 ConstantSDNode *AndMaskNode = dyn_cast<ConstantSDNode>(N0->getOperand(1));
17902 if (!AndMaskNode)
17903 return SDValue();
17904 uint32_t AndMask = static_cast<uint32_t>(AndMaskNode->getZExtValue());
17905 // Don't transform uxtb/uxth.
17906 if (AndMask == 255 || AndMask == 65535)
17907 return SDValue();
17908 if (isMask_32(AndMask)) {
17909 uint32_t MaskedBits = llvm::countl_zero(AndMask);
17910 if (MaskedBits > ShiftAmt) {
17911 SDLoc DL(N);
17912 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
17913 DAG.getConstant(MaskedBits, DL, MVT::i32));
17914 return DAG.getNode(
17915 ISD::SRL, DL, MVT::i32, SHL,
17916 DAG.getConstant(MaskedBits - ShiftAmt, DL, MVT::i32));
17917 }
17918 }
17919 }
17920
17921 // Nothing to be done for scalar shifts.
17922 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
17923 if (!VT.isVector() || !TLI.isTypeLegal(VT))
17924 return SDValue();
17925 if (ST->hasMVEIntegerOps())
17926 return SDValue();
17927
17928 int64_t Cnt;
17929
17930 switch (N->getOpcode()) {
17931 default: llvm_unreachable("unexpected shift opcode");
17932
17933 case ISD::SHL:
17934 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) {
17935 SDLoc dl(N);
17936 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
17937 DAG.getConstant(Cnt, dl, MVT::i32));
17938 }
17939 break;
17940
17941 case ISD::SRA:
17942 case ISD::SRL:
17943 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
17944 unsigned VShiftOpc =
17945 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
17946 SDLoc dl(N);
17947 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
17948 DAG.getConstant(Cnt, dl, MVT::i32));
17949 }
17950 }
17951 return SDValue();
17952}
17953
17954// Look for a sign/zero/fpextend extend of a larger than legal load. This can be
17955// split into multiple extending loads, which are simpler to deal with than an
17956// arbitrary extend. For fp extends we use an integer extending load and a VCVTL
17957// to convert the type to an f32.
17959 SDValue N0 = N->getOperand(0);
17960 if (N0.getOpcode() != ISD::LOAD)
17961 return SDValue();
17963 if (!LD->isSimple() || !N0.hasOneUse() || LD->isIndexed() ||
17964 LD->getExtensionType() != ISD::NON_EXTLOAD)
17965 return SDValue();
17966 EVT FromVT = LD->getValueType(0);
17967 EVT ToVT = N->getValueType(0);
17968 if (!ToVT.isVector())
17969 return SDValue();
17971 EVT ToEltVT = ToVT.getVectorElementType();
17972 EVT FromEltVT = FromVT.getVectorElementType();
17973
17974 unsigned NumElements = 0;
17975 if (ToEltVT == MVT::i32 && FromEltVT == MVT::i8)
17976 NumElements = 4;
17977 if (ToEltVT == MVT::f32 && FromEltVT == MVT::f16)
17978 NumElements = 4;
17979 if (NumElements == 0 ||
17980 (FromEltVT != MVT::f16 && FromVT.getVectorNumElements() == NumElements) ||
17981 FromVT.getVectorNumElements() % NumElements != 0 ||
17982 !isPowerOf2_32(NumElements))
17983 return SDValue();
17984
17985 LLVMContext &C = *DAG.getContext();
17986 SDLoc DL(LD);
17987 // Details about the old load
17988 SDValue Ch = LD->getChain();
17989 SDValue BasePtr = LD->getBasePtr();
17990 Align Alignment = LD->getBaseAlign();
17991 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
17992 AAMDNodes AAInfo = LD->getAAInfo();
17993
17994 ISD::LoadExtType NewExtType =
17995 N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
17996 SDValue Offset = DAG.getUNDEF(BasePtr.getValueType());
17997 EVT NewFromVT = EVT::getVectorVT(
17998 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
17999 EVT NewToVT = EVT::getVectorVT(
18000 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18001
18004 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18005 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18006 SDValue NewPtr =
18007 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18008
18009 SDValue NewLoad =
18010 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18011 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18012 Alignment, MMOFlags, AAInfo);
18013 Loads.push_back(NewLoad);
18014 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18015 }
18016
18017 // Float truncs need to extended with VCVTB's into their floating point types.
18018 if (FromEltVT == MVT::f16) {
18020
18021 for (unsigned i = 0; i < Loads.size(); i++) {
18022 SDValue LoadBC =
18023 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v8f16, Loads[i]);
18024 SDValue FPExt = DAG.getNode(ARMISD::VCVTL, DL, MVT::v4f32, LoadBC,
18025 DAG.getConstant(0, DL, MVT::i32));
18026 Extends.push_back(FPExt);
18027 }
18028
18029 Loads = Extends;
18030 }
18031
18032 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18033 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18034 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Loads);
18035}
18036
18037/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND,
18038/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND.
18040 const ARMSubtarget *ST) {
18041 SDValue N0 = N->getOperand(0);
18042 EVT VT = N->getValueType(0);
18043 SDLoc DL(N);
18044
18045 // Check for sign- and zero-extensions of vector extract operations of 8- and
18046 // 16-bit vector elements. NEON and MVE support these directly. They are
18047 // handled during DAG combining because type legalization will promote them
18048 // to 32-bit types and it is messy to recognize the operations after that.
18049 if ((ST->hasNEON() || ST->hasMVEIntegerOps()) &&
18051 SDValue Vec = N0.getOperand(0);
18052 SDValue Lane = N0.getOperand(1);
18053 EVT EltVT = N0.getValueType();
18054 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18055
18056 if (VT == MVT::i32 &&
18057 (EltVT == MVT::i8 || EltVT == MVT::i16) &&
18058 TLI.isTypeLegal(Vec.getValueType()) &&
18059 isa<ConstantSDNode>(Lane)) {
18060
18061 unsigned Opc = 0;
18062 switch (N->getOpcode()) {
18063 default: llvm_unreachable("unexpected opcode");
18064 case ISD::SIGN_EXTEND:
18065 Opc = ARMISD::VGETLANEs;
18066 break;
18067 case ISD::ZERO_EXTEND:
18068 case ISD::ANY_EXTEND:
18069 Opc = ARMISD::VGETLANEu;
18070 break;
18071 }
18072 return DAG.getNode(Opc, DL, VT, Vec, Lane);
18073 }
18074 }
18075
18076 if (ST->hasMVEIntegerOps())
18077 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18078 return NewLoad;
18079
18080 // Combine sext(buildvector(..)) to buildvector(sext(..)) to help avoid
18081 // difficult to lower i1 buildvector.
18082 if (ST->hasMVEIntegerOps() && N0.getValueType().getScalarSizeInBits() == 1 &&
18083 N0.getOpcode() == ISD::BUILD_VECTOR && VT.getScalarSizeInBits() <= 32) {
18085 for (unsigned I = 0; I < N0.getNumOperands(); I++) {
18086 SDValue InReg = N0.getOperand(I);
18087 if (N->getOpcode() == ISD::ZERO_EXTEND)
18088 InReg = DAG.getNode(ISD::AND, DL, InReg.getValueType(), InReg,
18089 DAG.getConstant(1, DL, InReg.getValueType()));
18090 else if (N->getOpcode() == ISD::SIGN_EXTEND)
18091 InReg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InReg.getValueType(),
18092 InReg, DAG.getValueType(MVT::i1));
18093 SDValue Ext = DAG.getNode(N->getOpcode(), DL, MVT::i32, InReg);
18094 Ops.push_back(Ext);
18095 }
18096 return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
18097 }
18098
18099 return SDValue();
18100}
18101
18103 const ARMSubtarget *ST) {
18104 if (ST->hasMVEFloatOps())
18105 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18106 return NewLoad;
18107
18108 return SDValue();
18109}
18110
18111// Lower smin(smax(x, C1), C2) to ssat or usat, if they have saturating
18112// constant bounds.
18114 const ARMSubtarget *Subtarget) {
18115 if ((Subtarget->isThumb() || !Subtarget->hasV6Ops()) &&
18116 !Subtarget->isThumb2())
18117 return SDValue();
18118
18119 EVT VT = Op.getValueType();
18120 SDValue Op0 = Op.getOperand(0);
18121
18122 if (VT != MVT::i32 ||
18123 (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
18124 !isa<ConstantSDNode>(Op.getOperand(1)) ||
18126 return SDValue();
18127
18128 SDValue Min = Op;
18129 SDValue Max = Op0;
18130 SDValue Input = Op0.getOperand(0);
18131 if (Min.getOpcode() == ISD::SMAX)
18132 std::swap(Min, Max);
18133
18134 if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX)
18135 return SDValue();
18136
18137 APInt MinC = Min.getConstantOperandAPInt(1);
18138 APInt MaxC = Max.getConstantOperandAPInt(1);
18139 if (MaxC.sgt(MinC))
18140 return SDValue();
18141
18142 SDLoc DL(Op);
18143
18144 // A clamp whose bounds are already a saturation range maps to a single
18145 // SSAT / USAT.
18146 if ((MinC + 1).isPowerOf2()) {
18147 if (MinC == ~MaxC)
18148 return DAG.getNode(ARMISD::SSAT, DL, VT, Input,
18149 DAG.getConstant(MinC.countr_one(), DL, VT));
18150 if (MaxC == 0)
18151 return DAG.getNode(ARMISD::USAT, DL, VT, Input,
18152 DAG.getConstant(MinC.countr_one(), DL, VT));
18153 }
18154
18155 // For power-of-two clamp widths, convert the range to be zero-centered,
18156 // apply SSAT, and convert the result back.
18157 //
18158 // Width = Hi - Lo + 1
18159 // Center = Lo + Width / 2
18160 // Result = ssat(X - Center) + Center
18161 //
18162 // The idea is to shift the input so that the clamp range is centered
18163 // around zero, apply ssat, and then shift the result back.
18164 //
18165 // For example clamp(X, -118, 137) -> Width = 256, Center = 10, so it becomes
18166 // ssat(X - 10, 8) + 10
18167
18168 APInt Width = MinC - MaxC + 1;
18169 if (!Width.isPowerOf2() || Width.isOne())
18170 return SDValue();
18171 unsigned SatBit = Width.logBase2() - 1; // ssat to SatBit + 1 signed bits
18172 APInt Center = MaxC + Width.lshr(1);
18173
18174 // The rewrite is only valid when X - Center does not overflow;
18175 SDValue NegC = DAG.getConstant(-Center, DL, VT);
18177 return SDValue();
18178
18179 SDValue Shifted = DAG.getNode(ISD::ADD, DL, VT, Input, NegC);
18180 SDValue Sat = DAG.getNode(ARMISD::SSAT, DL, VT, Shifted,
18181 DAG.getConstant(SatBit, DL, VT));
18182 return DAG.getNode(ISD::ADD, DL, VT, Sat, DAG.getConstant(Center, DL, VT));
18183}
18184
18185/// PerformMinMaxCombine - Target-specific DAG combining for creating truncating
18186/// saturates.
18188 const ARMSubtarget *ST) {
18189 EVT VT = N->getValueType(0);
18190 SDValue N0 = N->getOperand(0);
18191
18192 if (VT == MVT::i32)
18193 return PerformMinMaxToSatCombine(SDValue(N, 0), DAG, ST);
18194
18195 if (!ST->hasMVEIntegerOps())
18196 return SDValue();
18197
18198 if (SDValue V = PerformVQDMULHCombine(N, DAG))
18199 return V;
18200
18201 if (VT != MVT::v4i32 && VT != MVT::v8i16)
18202 return SDValue();
18203
18204 auto IsSignedSaturate = [&](SDNode *Min, SDNode *Max) {
18205 // Check one is a smin and the other is a smax
18206 if (Min->getOpcode() != ISD::SMIN)
18207 std::swap(Min, Max);
18208 if (Min->getOpcode() != ISD::SMIN || Max->getOpcode() != ISD::SMAX)
18209 return false;
18210
18211 APInt SaturateC;
18212 if (VT == MVT::v4i32)
18213 SaturateC = APInt(32, (1 << 15) - 1, true);
18214 else //if (VT == MVT::v8i16)
18215 SaturateC = APInt(16, (1 << 7) - 1, true);
18216
18217 APInt MinC, MaxC;
18218 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18219 MinC != SaturateC)
18220 return false;
18221 if (!ISD::isConstantSplatVector(Max->getOperand(1).getNode(), MaxC) ||
18222 MaxC != ~SaturateC)
18223 return false;
18224 return true;
18225 };
18226
18227 if (IsSignedSaturate(N, N0.getNode())) {
18228 SDLoc DL(N);
18229 MVT ExtVT, HalfVT;
18230 if (VT == MVT::v4i32) {
18231 HalfVT = MVT::v8i16;
18232 ExtVT = MVT::v4i16;
18233 } else { // if (VT == MVT::v8i16)
18234 HalfVT = MVT::v16i8;
18235 ExtVT = MVT::v8i8;
18236 }
18237
18238 // Create a VQMOVNB with undef top lanes, then signed extended into the top
18239 // half. That extend will hopefully be removed if only the bottom bits are
18240 // demanded (though a truncating store, for example).
18241 SDValue VQMOVN =
18242 DAG.getNode(ARMISD::VQMOVNs, DL, HalfVT, DAG.getUNDEF(HalfVT),
18243 N0->getOperand(0), DAG.getConstant(0, DL, MVT::i32));
18244 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18245 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Bitcast,
18246 DAG.getValueType(ExtVT));
18247 }
18248
18249 auto IsUnsignedSaturate = [&](SDNode *Min) {
18250 // For unsigned, we just need to check for <= 0xffff
18251 if (Min->getOpcode() != ISD::UMIN)
18252 return false;
18253
18254 APInt SaturateC;
18255 if (VT == MVT::v4i32)
18256 SaturateC = APInt(32, (1 << 16) - 1, true);
18257 else //if (VT == MVT::v8i16)
18258 SaturateC = APInt(16, (1 << 8) - 1, true);
18259
18260 APInt MinC;
18261 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18262 MinC != SaturateC)
18263 return false;
18264 return true;
18265 };
18266
18267 if (IsUnsignedSaturate(N)) {
18268 SDLoc DL(N);
18269 MVT HalfVT;
18270 unsigned ExtConst;
18271 if (VT == MVT::v4i32) {
18272 HalfVT = MVT::v8i16;
18273 ExtConst = 0x0000FFFF;
18274 } else { //if (VT == MVT::v8i16)
18275 HalfVT = MVT::v16i8;
18276 ExtConst = 0x00FF;
18277 }
18278
18279 // Create a VQMOVNB with undef top lanes, then ZExt into the top half with
18280 // an AND. That extend will hopefully be removed if only the bottom bits are
18281 // demanded (though a truncating store, for example).
18282 SDValue VQMOVN =
18283 DAG.getNode(ARMISD::VQMOVNu, DL, HalfVT, DAG.getUNDEF(HalfVT), N0,
18284 DAG.getConstant(0, DL, MVT::i32));
18285 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18286 return DAG.getNode(ISD::AND, DL, VT, Bitcast,
18287 DAG.getConstant(ExtConst, DL, VT));
18288 }
18289
18290 return SDValue();
18291}
18292
18295 if (!C)
18296 return nullptr;
18297 const APInt *CV = &C->getAPIntValue();
18298 return CV->isPowerOf2() ? CV : nullptr;
18299}
18300
18302 // If we have a CMOV, OR and AND combination such as:
18303 // if (x & CN)
18304 // y |= CM;
18305 //
18306 // And:
18307 // * CN is a single bit;
18308 // * All bits covered by CM are known zero in y
18309 //
18310 // Then we can convert this into a sequence of BFI instructions. This will
18311 // always be a win if CM is a single bit, will always be no worse than the
18312 // TST&OR sequence if CM is two bits, and for thumb will be no worse if CM is
18313 // three bits (due to the extra IT instruction).
18314
18315 SDValue Op0 = CMOV->getOperand(0);
18316 SDValue Op1 = CMOV->getOperand(1);
18317 auto CC = CMOV->getConstantOperandAPInt(2).getLimitedValue();
18318 SDValue CmpZ = CMOV->getOperand(3);
18319
18320 // The compare must be against zero.
18321 if (!isNullConstant(CmpZ->getOperand(1)))
18322 return SDValue();
18323
18324 assert(CmpZ->getOpcode() == ARMISD::CMPZ);
18325 SDValue And = CmpZ->getOperand(0);
18326 if (And->getOpcode() != ISD::AND)
18327 return SDValue();
18328 const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
18329 if (!AndC)
18330 return SDValue();
18331 SDValue X = And->getOperand(0);
18332
18333 if (CC == ARMCC::EQ) {
18334 // We're performing an "equal to zero" compare. Swap the operands so we
18335 // canonicalize on a "not equal to zero" compare.
18336 std::swap(Op0, Op1);
18337 } else {
18338 assert(CC == ARMCC::NE && "How can a CMPZ node not be EQ or NE?");
18339 }
18340
18341 if (Op1->getOpcode() != ISD::OR)
18342 return SDValue();
18343
18345 if (!OrC)
18346 return SDValue();
18347 SDValue Y = Op1->getOperand(0);
18348
18349 if (Op0 != Y)
18350 return SDValue();
18351
18352 // Now, is it profitable to continue?
18353 APInt OrCI = OrC->getAPIntValue();
18354 unsigned Heuristic = Subtarget->isThumb() ? 3 : 2;
18355 if (OrCI.popcount() > Heuristic)
18356 return SDValue();
18357
18358 // Lastly, can we determine that the bits defined by OrCI
18359 // are zero in Y?
18361 if ((OrCI & Known.Zero) != OrCI)
18362 return SDValue();
18363
18364 // OK, we can do the combine.
18365 SDValue V = Y;
18366 SDLoc dl(X);
18367 EVT VT = X.getValueType();
18368 unsigned BitInX = AndC->logBase2();
18369
18370 if (BitInX != 0) {
18371 // We must shift X first.
18372 X = DAG.getNode(ISD::SRL, dl, VT, X,
18373 DAG.getConstant(BitInX, dl, VT));
18374 }
18375
18376 for (unsigned BitInY = 0, NumActiveBits = OrCI.getActiveBits();
18377 BitInY < NumActiveBits; ++BitInY) {
18378 if (OrCI[BitInY] == 0)
18379 continue;
18380 APInt Mask(VT.getSizeInBits(), 0);
18381 Mask.setBit(BitInY);
18382 V = DAG.getNode(ARMISD::BFI, dl, VT, V, X,
18383 // Confusingly, the operand is an *inverted* mask.
18384 DAG.getConstant(~Mask, dl, VT));
18385 }
18386
18387 return V;
18388}
18389
18390// Given N, the value controlling the conditional branch, search for the loop
18391// intrinsic, returning it, along with how the value is used. We need to handle
18392// patterns such as the following:
18393// (brcond (xor (setcc (loop.decrement), 0, ne), 1), exit)
18394// (brcond (setcc (loop.decrement), 0, eq), exit)
18395// (brcond (setcc (loop.decrement), 0, ne), header)
18397 bool &Negate) {
18398 switch (N->getOpcode()) {
18399 default:
18400 break;
18401 case ISD::XOR: {
18402 if (!isa<ConstantSDNode>(N.getOperand(1)))
18403 return SDValue();
18404 if (!cast<ConstantSDNode>(N.getOperand(1))->isOne())
18405 return SDValue();
18406 Negate = !Negate;
18407 return SearchLoopIntrinsic(N.getOperand(0), CC, Imm, Negate);
18408 }
18409 case ISD::SETCC: {
18410 auto *Const = dyn_cast<ConstantSDNode>(N.getOperand(1));
18411 if (!Const)
18412 return SDValue();
18413 if (Const->isZero())
18414 Imm = 0;
18415 else if (Const->isOne())
18416 Imm = 1;
18417 else
18418 return SDValue();
18419 CC = cast<CondCodeSDNode>(N.getOperand(2))->get();
18420 return SearchLoopIntrinsic(N->getOperand(0), CC, Imm, Negate);
18421 }
18423 unsigned IntOp = N.getConstantOperandVal(1);
18424 if (IntOp != Intrinsic::test_start_loop_iterations &&
18425 IntOp != Intrinsic::loop_decrement_reg)
18426 return SDValue();
18427 return N;
18428 }
18429 }
18430 return SDValue();
18431}
18432
18435 const ARMSubtarget *ST) {
18436
18437 // The hwloop intrinsics that we're interested are used for control-flow,
18438 // either for entering or exiting the loop:
18439 // - test.start.loop.iterations will test whether its operand is zero. If it
18440 // is zero, the proceeding branch should not enter the loop.
18441 // - loop.decrement.reg also tests whether its operand is zero. If it is
18442 // zero, the proceeding branch should not branch back to the beginning of
18443 // the loop.
18444 // So here, we need to check that how the brcond is using the result of each
18445 // of the intrinsics to ensure that we're branching to the right place at the
18446 // right time.
18447
18448 ISD::CondCode CC;
18449 SDValue Cond;
18450 int Imm = 1;
18451 bool Negate = false;
18452 SDValue Chain = N->getOperand(0);
18453 SDValue Dest;
18454
18455 if (N->getOpcode() == ISD::BRCOND) {
18456 CC = ISD::SETEQ;
18457 Cond = N->getOperand(1);
18458 Dest = N->getOperand(2);
18459 } else {
18460 assert(N->getOpcode() == ISD::BR_CC && "Expected BRCOND or BR_CC!");
18461 CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
18462 Cond = N->getOperand(2);
18463 Dest = N->getOperand(4);
18464 if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(3))) {
18465 if (!Const->isOne() && !Const->isZero())
18466 return SDValue();
18467 Imm = Const->getZExtValue();
18468 } else
18469 return SDValue();
18470 }
18471
18472 SDValue Int = SearchLoopIntrinsic(Cond, CC, Imm, Negate);
18473 if (!Int)
18474 return SDValue();
18475
18476 if (Negate)
18477 CC = ISD::getSetCCInverse(CC, /* Integer inverse */ MVT::i32);
18478
18479 auto IsTrueIfZero = [](ISD::CondCode CC, int Imm) {
18480 return (CC == ISD::SETEQ && Imm == 0) ||
18481 (CC == ISD::SETNE && Imm == 1) ||
18482 (CC == ISD::SETLT && Imm == 1) ||
18483 (CC == ISD::SETULT && Imm == 1);
18484 };
18485
18486 auto IsFalseIfZero = [](ISD::CondCode CC, int Imm) {
18487 return (CC == ISD::SETEQ && Imm == 1) ||
18488 (CC == ISD::SETNE && Imm == 0) ||
18489 (CC == ISD::SETGT && Imm == 0) ||
18490 (CC == ISD::SETUGT && Imm == 0) ||
18491 (CC == ISD::SETGE && Imm == 1) ||
18492 (CC == ISD::SETUGE && Imm == 1);
18493 };
18494
18495 assert((IsTrueIfZero(CC, Imm) || IsFalseIfZero(CC, Imm)) &&
18496 "unsupported condition");
18497
18498 SDLoc dl(Int);
18499 SelectionDAG &DAG = DCI.DAG;
18500 SDValue Elements = Int.getOperand(2);
18501 unsigned IntOp = Int->getConstantOperandVal(1);
18502 assert((N->hasOneUse() && N->user_begin()->getOpcode() == ISD::BR) &&
18503 "expected single br user");
18504 SDNode *Br = *N->user_begin();
18505 SDValue OtherTarget = Br->getOperand(1);
18506
18507 // Update the unconditional branch to branch to the given Dest.
18508 auto UpdateUncondBr = [](SDNode *Br, SDValue Dest, SelectionDAG &DAG) {
18509 SDValue NewBrOps[] = { Br->getOperand(0), Dest };
18510 SDValue NewBr = DAG.getNode(ISD::BR, SDLoc(Br), MVT::Other, NewBrOps);
18511 DAG.ReplaceAllUsesOfValueWith(SDValue(Br, 0), NewBr);
18512 };
18513
18514 if (IntOp == Intrinsic::test_start_loop_iterations) {
18515 SDValue Res;
18516 SDValue Setup = DAG.getNode(ARMISD::WLSSETUP, dl, MVT::i32, Elements);
18517 // We expect this 'instruction' to branch when the counter is zero.
18518 if (IsTrueIfZero(CC, Imm)) {
18519 SDValue Ops[] = {Chain, Setup, Dest};
18520 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18521 } else {
18522 // The logic is the reverse of what we need for WLS, so find the other
18523 // basic block target: the target of the proceeding br.
18524 UpdateUncondBr(Br, Dest, DAG);
18525
18526 SDValue Ops[] = {Chain, Setup, OtherTarget};
18527 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18528 }
18529 // Update LR count to the new value
18530 DAG.ReplaceAllUsesOfValueWith(Int.getValue(0), Setup);
18531 // Update chain
18532 DAG.ReplaceAllUsesOfValueWith(Int.getValue(2), Int.getOperand(0));
18533 return Res;
18534 } else {
18535 SDValue Size =
18536 DAG.getTargetConstant(Int.getConstantOperandVal(3), dl, MVT::i32);
18537 SDValue Args[] = { Int.getOperand(0), Elements, Size, };
18538 SDValue LoopDec = DAG.getNode(ARMISD::LOOP_DEC, dl,
18539 DAG.getVTList(MVT::i32, MVT::Other), Args);
18540 DAG.ReplaceAllUsesWith(Int.getNode(), LoopDec.getNode());
18541
18542 // We expect this instruction to branch when the count is not zero.
18543 SDValue Target = IsFalseIfZero(CC, Imm) ? Dest : OtherTarget;
18544
18545 // Update the unconditional branch to target the loop preheader if we've
18546 // found the condition has been reversed.
18547 if (Target == OtherTarget)
18548 UpdateUncondBr(Br, Dest, DAG);
18549
18550 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
18551 SDValue(LoopDec.getNode(), 1), Chain);
18552
18553 SDValue EndArgs[] = { Chain, SDValue(LoopDec.getNode(), 0), Target };
18554 return DAG.getNode(ARMISD::LE, dl, MVT::Other, EndArgs);
18555 }
18556 return SDValue();
18557}
18558
18559/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
18560SDValue
18562 SDValue Cmp = N->getOperand(3);
18563 if (Cmp.getOpcode() != ARMISD::CMPZ)
18564 // Only looking at NE cases.
18565 return SDValue();
18566
18567 SDLoc dl(N);
18568 SDValue LHS = Cmp.getOperand(0);
18569 SDValue RHS = Cmp.getOperand(1);
18570 SDValue Chain = N->getOperand(0);
18571 SDValue BB = N->getOperand(1);
18572 SDValue ARMcc = N->getOperand(2);
18574
18575 // (brcond Chain BB ne (cmpz (and (cmov 0 1 CC Flags) 1) 0))
18576 // -> (brcond Chain BB CC Flags)
18577 if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
18578 LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
18579 LHS->getOperand(0)->hasOneUse() &&
18580 isNullConstant(LHS->getOperand(0)->getOperand(0)) &&
18581 isOneConstant(LHS->getOperand(0)->getOperand(1)) &&
18582 isOneConstant(LHS->getOperand(1)) && isNullConstant(RHS)) {
18583 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, BB,
18584 LHS->getOperand(0)->getOperand(2),
18585 LHS->getOperand(0)->getOperand(3));
18586 }
18587
18588 return SDValue();
18589}
18590
18591/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
18592SDValue
18594 SDLoc dl(N);
18595 EVT VT = N->getValueType(0);
18596 SDValue FalseVal = N->getOperand(0);
18597 SDValue TrueVal = N->getOperand(1);
18598 SDValue ARMcc = N->getOperand(2);
18599 SDValue Cmp = N->getOperand(3);
18600
18601 // Try to form CSINV etc.
18602 unsigned Opcode;
18603 bool InvertCond;
18604 if (SDValue CSetOp =
18605 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
18606 if (InvertCond) {
18607 ARMCC::CondCodes CondCode =
18608 (ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
18609 CondCode = ARMCC::getOppositeCondition(CondCode);
18610 ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
18611 }
18612 return DAG.getNode(Opcode, dl, VT, CSetOp, CSetOp, ARMcc, Cmp);
18613 }
18614
18615 if (Cmp.getOpcode() != ARMISD::CMPZ)
18616 // Only looking at EQ and NE cases.
18617 return SDValue();
18618
18619 SDValue LHS = Cmp.getOperand(0);
18620 SDValue RHS = Cmp.getOperand(1);
18622
18623 // BFI is only available on V6T2+.
18624 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops()) {
18626 if (R)
18627 return R;
18628 }
18629
18630 // Simplify
18631 // mov r1, r0
18632 // cmp r1, x
18633 // mov r0, y
18634 // moveq r0, x
18635 // to
18636 // cmp r0, x
18637 // movne r0, y
18638 //
18639 // mov r1, r0
18640 // cmp r1, x
18641 // mov r0, x
18642 // movne r0, y
18643 // to
18644 // cmp r0, x
18645 // movne r0, y
18646 /// FIXME: Turn this into a target neutral optimization?
18647 SDValue Res;
18648 if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) {
18649 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, Cmp);
18650 } else if (CC == ARMCC::EQ && TrueVal == RHS) {
18651 SDValue ARMcc;
18652 SDValue NewCmp = getARMCmp(LHS, RHS, ISD::SETNE, ARMcc, DAG, dl);
18653 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, FalseVal, ARMcc, NewCmp);
18654 }
18655
18656 // (cmov F T ne (cmpz (cmov 0 1 CC Flags) 0))
18657 // -> (cmov F T CC Flags)
18658 if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse() &&
18659 isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
18660 isNullConstant(RHS)) {
18661 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
18662 LHS->getOperand(2), LHS->getOperand(3));
18663 }
18664
18665 if (!VT.isInteger())
18666 return SDValue();
18667
18668 // Fold away an unnecessary CMPZ/CMOV
18669 // CMOV A, B, C1, (CMPZ (CMOV 1, 0, C2, D), 0) ->
18670 // if C1==EQ -> CMOV A, B, C2, D
18671 // if C1==NE -> CMOV A, B, NOT(C2), D
18672 if (N->getConstantOperandVal(2) == ARMCC::EQ ||
18673 N->getConstantOperandVal(2) == ARMCC::NE) {
18675 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
18676 if (N->getConstantOperandVal(2) == ARMCC::NE)
18678 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
18679 N->getOperand(1),
18680 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
18681 }
18682 }
18683
18684 // Materialize a boolean comparison for integers so we can avoid branching.
18685 if (isNullConstant(FalseVal)) {
18686 if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
18687 if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
18688 // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
18689 // right 5 bits will make that 32 be 1, otherwise it will be 0.
18690 // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
18691 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18692 Res = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Sub),
18693 DAG.getConstant(5, dl, MVT::i32));
18694 } else {
18695 // CMOV 0, 1, ==, (CMPZ x, y) ->
18696 // (UADDO_CARRY (SUB x, y), t:0, t:1)
18697 // where t = (USUBO_CARRY 0, (SUB x, y), 0)
18698 //
18699 // The USUBO_CARRY computes 0 - (x - y) and this will give a borrow when
18700 // x != y. In other words, a carry C == 1 when x == y, C == 0
18701 // otherwise.
18702 // The final UADDO_CARRY computes
18703 // x - y + (0 - (x - y)) + C == C
18704 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18705 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18706 SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
18707 // ISD::USUBO_CARRY returns a borrow but we want the carry here
18708 // actually.
18709 SDValue Carry =
18710 DAG.getNode(ISD::SUB, dl, MVT::i32,
18711 DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
18712 Res = DAG.getNode(ISD::UADDO_CARRY, dl, VTs, Sub, Neg, Carry);
18713 }
18714 } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
18715 (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
18716 // This seems pointless but will allow us to combine it further below.
18717 // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18718 SDValue Sub =
18719 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18720 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
18721 Sub.getValue(1));
18722 FalseVal = Sub;
18723 }
18724 } else if (isNullConstant(TrueVal)) {
18725 if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
18726 (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
18727 // This seems pointless but will allow us to combine it further below
18728 // Note that we change == for != as this is the dual for the case above.
18729 // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18730 SDValue Sub =
18731 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18732 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
18733 DAG.getConstant(ARMCC::NE, dl, MVT::i32),
18734 Sub.getValue(1));
18735 FalseVal = Sub;
18736 }
18737 }
18738
18739 // On Thumb1, the DAG above may be further combined if z is a power of 2
18740 // (z == 2 ^ K).
18741 // CMOV (SUBC x, y), z, !=, (SUBC x, y):1 ->
18742 // t1 = (USUBO (SUB x, y), 1)
18743 // t2 = (USUBO_CARRY (SUB x, y), t1:0, t1:1)
18744 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18745 //
18746 // This also handles the special case of comparing against zero; it's
18747 // essentially, the same pattern, except there's no SUBC:
18748 // CMOV x, z, !=, (CMPZ x, 0) ->
18749 // t1 = (USUBO x, 1)
18750 // t2 = (USUBO_CARRY x, t1:0, t1:1)
18751 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18752 const APInt *TrueConst;
18753 if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
18754 ((FalseVal.getOpcode() == ARMISD::SUBC && FalseVal.getOperand(0) == LHS &&
18755 FalseVal.getOperand(1) == RHS) ||
18756 (FalseVal == LHS && isNullConstant(RHS))) &&
18757 (TrueConst = isPowerOf2Constant(TrueVal))) {
18758 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18759 unsigned ShiftAmount = TrueConst->logBase2();
18760 if (ShiftAmount)
18761 TrueVal = DAG.getConstant(1, dl, VT);
18762 SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
18763 Res = DAG.getNode(ISD::USUBO_CARRY, dl, VTs, FalseVal, Subc,
18764 Subc.getValue(1));
18765
18766 if (ShiftAmount)
18767 Res = DAG.getNode(ISD::SHL, dl, VT, Res,
18768 DAG.getConstant(ShiftAmount, dl, MVT::i32));
18769 }
18770
18771 if (Res.getNode()) {
18773 // Capture demanded bits information that would be otherwise lost.
18774 if (Known.Zero == 0xfffffffe)
18775 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18776 DAG.getValueType(MVT::i1));
18777 else if (Known.Zero == 0xffffff00)
18778 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18779 DAG.getValueType(MVT::i8));
18780 else if (Known.Zero == 0xffff0000)
18781 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18782 DAG.getValueType(MVT::i16));
18783 }
18784
18785 return Res;
18786}
18787
18790 const ARMSubtarget *ST) {
18791 SelectionDAG &DAG = DCI.DAG;
18792 SDValue Src = N->getOperand(0);
18793 EVT DstVT = N->getValueType(0);
18794
18795 // Convert v4f32 bitcast (v4i32 vdup (i32)) -> v4f32 vdup (i32) under MVE.
18796 if (ST->hasMVEIntegerOps() && Src.getOpcode() == ARMISD::VDUP) {
18797 EVT SrcVT = Src.getValueType();
18798 if (SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits())
18799 return DAG.getNode(ARMISD::VDUP, SDLoc(N), DstVT, Src.getOperand(0));
18800 }
18801
18802 // We may have a bitcast of something that has already had this bitcast
18803 // combine performed on it, so skip past any VECTOR_REG_CASTs.
18804 if (Src.getOpcode() == ARMISD::VECTOR_REG_CAST &&
18805 Src.getOperand(0).getValueType().getScalarSizeInBits() <=
18806 Src.getValueType().getScalarSizeInBits())
18807 Src = Src.getOperand(0);
18808
18809 // Bitcast from element-wise VMOV or VMVN doesn't need VREV if the VREV that
18810 // would be generated is at least the width of the element type.
18811 EVT SrcVT = Src.getValueType();
18812 if ((Src.getOpcode() == ARMISD::VMOVIMM ||
18813 Src.getOpcode() == ARMISD::VMVNIMM ||
18814 Src.getOpcode() == ARMISD::VMOVFPIMM) &&
18815 SrcVT.getScalarSizeInBits() <= DstVT.getScalarSizeInBits() &&
18816 DAG.getDataLayout().isBigEndian())
18817 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(N), DstVT, Src);
18818
18819 // bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD x
18820 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
18821 return R;
18822
18823 return SDValue();
18824}
18825
18826// Some combines for the MVETrunc truncations legalizer helper. Also lowers the
18827// node into stack operations after legalizeOps.
18830 SelectionDAG &DAG = DCI.DAG;
18831 EVT VT = N->getValueType(0);
18832 SDLoc DL(N);
18833
18834 // MVETrunc(Undef, Undef) -> Undef
18835 if (all_of(N->ops(), [](SDValue Op) { return Op.isUndef(); }))
18836 return DAG.getUNDEF(VT);
18837
18838 // MVETrunc(MVETrunc a b, MVETrunc c, d) -> MVETrunc
18839 if (N->getNumOperands() == 2 &&
18840 N->getOperand(0).getOpcode() == ARMISD::MVETRUNC &&
18841 N->getOperand(1).getOpcode() == ARMISD::MVETRUNC)
18842 return DAG.getNode(ARMISD::MVETRUNC, DL, VT, N->getOperand(0).getOperand(0),
18843 N->getOperand(0).getOperand(1),
18844 N->getOperand(1).getOperand(0),
18845 N->getOperand(1).getOperand(1));
18846
18847 // MVETrunc(shuffle, shuffle) -> VMOVN
18848 if (N->getNumOperands() == 2 &&
18849 N->getOperand(0).getOpcode() == ISD::VECTOR_SHUFFLE &&
18850 N->getOperand(1).getOpcode() == ISD::VECTOR_SHUFFLE) {
18851 auto *S0 = cast<ShuffleVectorSDNode>(N->getOperand(0).getNode());
18852 auto *S1 = cast<ShuffleVectorSDNode>(N->getOperand(1).getNode());
18853
18854 if (S0->getOperand(0) == S1->getOperand(0) &&
18855 S0->getOperand(1) == S1->getOperand(1)) {
18856 // Construct complete shuffle mask
18857 SmallVector<int, 8> Mask(S0->getMask());
18858 Mask.append(S1->getMask().begin(), S1->getMask().end());
18859
18860 if (isVMOVNTruncMask(Mask, VT, false))
18861 return DAG.getNode(
18862 ARMISD::VMOVN, DL, VT,
18863 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18864 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18865 DAG.getConstant(1, DL, MVT::i32));
18866 if (isVMOVNTruncMask(Mask, VT, true))
18867 return DAG.getNode(
18868 ARMISD::VMOVN, DL, VT,
18869 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18870 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18871 DAG.getConstant(1, DL, MVT::i32));
18872 }
18873 }
18874
18875 // For MVETrunc of a buildvector or shuffle, it can be beneficial to lower the
18876 // truncate to a buildvector to allow the generic optimisations to kick in.
18877 if (all_of(N->ops(), [](SDValue Op) {
18878 return Op.getOpcode() == ISD::BUILD_VECTOR ||
18879 Op.getOpcode() == ISD::VECTOR_SHUFFLE ||
18880 (Op.getOpcode() == ISD::BITCAST &&
18881 Op.getOperand(0).getOpcode() == ISD::BUILD_VECTOR);
18882 })) {
18883 SmallVector<SDValue, 8> Extracts;
18884 for (unsigned Op = 0; Op < N->getNumOperands(); Op++) {
18885 SDValue O = N->getOperand(Op);
18886 for (unsigned i = 0; i < O.getValueType().getVectorNumElements(); i++) {
18887 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, O,
18888 DAG.getConstant(i, DL, MVT::i32));
18889 Extracts.push_back(Ext);
18890 }
18891 }
18892 return DAG.getBuildVector(VT, DL, Extracts);
18893 }
18894
18895 // If we are late in the legalization process and nothing has optimised
18896 // the trunc to anything better, lower it to a stack store and reload,
18897 // performing the truncation whilst keeping the lanes in the correct order:
18898 // VSTRH.32 a, stack; VSTRH.32 b, stack+8; VLDRW.32 stack;
18899 if (!DCI.isAfterLegalizeDAG())
18900 return SDValue();
18901
18902 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
18903 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
18904 int NumIns = N->getNumOperands();
18905 assert((NumIns == 2 || NumIns == 4) &&
18906 "Expected 2 or 4 inputs to an MVETrunc");
18907 EVT StoreVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
18908 if (N->getNumOperands() == 4)
18909 StoreVT = StoreVT.getHalfNumVectorElementsVT(*DAG.getContext());
18910
18911 SmallVector<SDValue> Chains;
18912 for (int I = 0; I < NumIns; I++) {
18913 SDValue Ptr = DAG.getNode(
18914 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
18915 DAG.getConstant(I * 16 / NumIns, DL, StackPtr.getValueType()));
18917 DAG.getMachineFunction(), SPFI, I * 16 / NumIns);
18918 SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), DL, N->getOperand(I),
18919 Ptr, MPI, StoreVT, Align(4));
18920 Chains.push_back(Ch);
18921 }
18922
18923 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18924 MachinePointerInfo MPI =
18926 return DAG.getLoad(VT, DL, Chain, StackPtr, MPI, Align(4));
18927}
18928
18929// Take a MVEEXT(load x) and split that into (extload x, extload x+8)
18931 SelectionDAG &DAG) {
18932 SDValue N0 = N->getOperand(0);
18934 if (!LD || !LD->isSimple() || !N0.hasOneUse() || LD->isIndexed())
18935 return SDValue();
18936
18937 EVT FromVT = LD->getMemoryVT();
18938 EVT ToVT = N->getValueType(0);
18939 if (!ToVT.isVector())
18940 return SDValue();
18941 assert(FromVT.getVectorNumElements() == ToVT.getVectorNumElements() * 2);
18942 EVT ToEltVT = ToVT.getVectorElementType();
18943 EVT FromEltVT = FromVT.getVectorElementType();
18944
18945 unsigned NumElements = 0;
18946 if (ToEltVT == MVT::i32 && (FromEltVT == MVT::i16 || FromEltVT == MVT::i8))
18947 NumElements = 4;
18948 if (ToEltVT == MVT::i16 && FromEltVT == MVT::i8)
18949 NumElements = 8;
18950 assert(NumElements != 0);
18951
18952 ISD::LoadExtType NewExtType =
18953 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18954 if (LD->getExtensionType() != ISD::NON_EXTLOAD &&
18955 LD->getExtensionType() != ISD::EXTLOAD &&
18956 LD->getExtensionType() != NewExtType)
18957 return SDValue();
18958
18959 LLVMContext &C = *DAG.getContext();
18960 SDLoc DL(LD);
18961 // Details about the old load
18962 SDValue Ch = LD->getChain();
18963 SDValue BasePtr = LD->getBasePtr();
18964 Align Alignment = LD->getBaseAlign();
18965 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18966 AAMDNodes AAInfo = LD->getAAInfo();
18967
18968 SDValue Offset = DAG.getUNDEF(BasePtr.getValueType());
18969 EVT NewFromVT = EVT::getVectorVT(
18970 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
18971 EVT NewToVT = EVT::getVectorVT(
18972 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18973
18976 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18977 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18978 SDValue NewPtr =
18979 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18980
18981 SDValue NewLoad =
18982 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18983 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18984 Alignment, MMOFlags, AAInfo);
18985 Loads.push_back(NewLoad);
18986 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18987 }
18988
18989 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18990 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18991 return DAG.getMergeValues(Loads, DL);
18992}
18993
18994// Perform combines for MVEEXT. If it has not be optimized to anything better
18995// before lowering, it gets converted to stack store and extloads performing the
18996// extend whilst still keeping the same lane ordering.
18999 SelectionDAG &DAG = DCI.DAG;
19000 EVT VT = N->getValueType(0);
19001 SDLoc DL(N);
19002 assert(N->getNumValues() == 2 && "Expected MVEEXT with 2 elements");
19003 assert((VT == MVT::v4i32 || VT == MVT::v8i16) && "Unexpected MVEEXT type");
19004
19005 EVT ExtVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19006 *DAG.getContext());
19007 auto Extend = [&](SDValue V) {
19008 SDValue VVT = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, V);
19009 return N->getOpcode() == ARMISD::MVESEXT
19010 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, VVT,
19011 DAG.getValueType(ExtVT))
19012 : DAG.getZeroExtendInReg(VVT, DL, ExtVT);
19013 };
19014
19015 // MVEEXT(VDUP) -> SIGN_EXTEND_INREG(VDUP)
19016 if (N->getOperand(0).getOpcode() == ARMISD::VDUP) {
19017 SDValue Ext = Extend(N->getOperand(0));
19018 return DAG.getMergeValues({Ext, Ext}, DL);
19019 }
19020
19021 // MVEEXT(shuffle) -> SIGN_EXTEND_INREG/ZERO_EXTEND_INREG
19022 if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N->getOperand(0))) {
19023 ArrayRef<int> Mask = SVN->getMask();
19024 assert(Mask.size() == 2 * VT.getVectorNumElements());
19025 assert(Mask.size() == SVN->getValueType(0).getVectorNumElements());
19026 unsigned Rev = VT == MVT::v4i32 ? ARMISD::VREV32 : ARMISD::VREV16;
19027 SDValue Op0 = SVN->getOperand(0);
19028 SDValue Op1 = SVN->getOperand(1);
19029
19030 auto CheckInregMask = [&](int Start, int Offset) {
19031 for (int Idx = 0, E = VT.getVectorNumElements(); Idx < E; ++Idx)
19032 if (Mask[Start + Idx] >= 0 && Mask[Start + Idx] != Idx * 2 + Offset)
19033 return false;
19034 return true;
19035 };
19036 SDValue V0 = SDValue(N, 0);
19037 SDValue V1 = SDValue(N, 1);
19038 if (CheckInregMask(0, 0))
19039 V0 = Extend(Op0);
19040 else if (CheckInregMask(0, 1))
19041 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19042 else if (CheckInregMask(0, Mask.size()))
19043 V0 = Extend(Op1);
19044 else if (CheckInregMask(0, Mask.size() + 1))
19045 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19046
19047 if (CheckInregMask(VT.getVectorNumElements(), Mask.size()))
19048 V1 = Extend(Op1);
19049 else if (CheckInregMask(VT.getVectorNumElements(), Mask.size() + 1))
19050 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19051 else if (CheckInregMask(VT.getVectorNumElements(), 0))
19052 V1 = Extend(Op0);
19053 else if (CheckInregMask(VT.getVectorNumElements(), 1))
19054 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19055
19056 if (V0.getNode() != N || V1.getNode() != N)
19057 return DAG.getMergeValues({V0, V1}, DL);
19058 }
19059
19060 // MVEEXT(load) -> extload, extload
19061 if (N->getOperand(0)->getOpcode() == ISD::LOAD)
19063 return L;
19064
19065 if (!DCI.isAfterLegalizeDAG())
19066 return SDValue();
19067
19068 // Lower to a stack store and reload:
19069 // VSTRW.32 a, stack; VLDRH.32 stack; VLDRH.32 stack+8;
19070 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19071 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19072 int NumOuts = N->getNumValues();
19073 assert((NumOuts == 2 || NumOuts == 4) &&
19074 "Expected 2 or 4 outputs to an MVEEXT");
19075 EVT LoadVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19076 *DAG.getContext());
19077 if (N->getNumOperands() == 4)
19078 LoadVT = LoadVT.getHalfNumVectorElementsVT(*DAG.getContext());
19079
19080 MachinePointerInfo MPI =
19082 SDValue Chain = DAG.getStore(DAG.getEntryNode(), DL, N->getOperand(0),
19083 StackPtr, MPI, Align(4));
19084
19086 for (int I = 0; I < NumOuts; I++) {
19087 SDValue Ptr = DAG.getNode(
19088 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19089 DAG.getConstant(I * 16 / NumOuts, DL, StackPtr.getValueType()));
19091 DAG.getMachineFunction(), SPFI, I * 16 / NumOuts);
19092 SDValue Load = DAG.getExtLoad(
19093 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD, DL,
19094 VT, Chain, Ptr, MPI, LoadVT, Align(4));
19095 Loads.push_back(Load);
19096 }
19097
19098 return DAG.getMergeValues(Loads, DL);
19099}
19100
19102 DAGCombinerInfo &DCI) const {
19103 switch (N->getOpcode()) {
19104 default: break;
19105 case ISD::SELECT_CC:
19106 case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
19107 case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
19108 case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
19109 case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
19110 case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
19111 case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget);
19112 case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget);
19113 case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget);
19114 case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
19115 case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
19116 case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
19117 case ISD::BRCOND:
19118 case ISD::BR_CC: return PerformHWLoopCombine(N, DCI, Subtarget);
19119 case ARMISD::ADDC:
19120 case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
19121 case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI, Subtarget);
19122 case ARMISD::BFI: return PerformBFICombine(N, DCI.DAG);
19123 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
19124 case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG);
19125 case ARMISD::VMOVhr: return PerformVMOVhrCombine(N, DCI);
19126 case ARMISD::VMOVrh: return PerformVMOVrhCombine(N, DCI.DAG);
19127 case ISD::STORE: return PerformSTORECombine(N, DCI, Subtarget);
19128 case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI, Subtarget);
19131 return PerformExtractEltCombine(N, DCI, Subtarget);
19135 case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI, Subtarget);
19136 case ARMISD::VDUP: return PerformVDUPCombine(N, DCI.DAG, Subtarget);
19137 case ISD::FP_TO_SINT:
19138 case ISD::FP_TO_UINT:
19139 return PerformVCVTCombine(N, DCI.DAG, Subtarget);
19140 case ISD::FADD:
19141 return PerformFADDCombine(N, DCI.DAG, Subtarget);
19142 case ISD::FMUL:
19143 return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget);
19145 return PerformIntrinsicCombine(N, DCI);
19146 case ISD::SHL:
19147 case ISD::SRA:
19148 case ISD::SRL:
19149 return PerformShiftCombine(N, DCI, Subtarget);
19150 case ISD::SIGN_EXTEND:
19151 case ISD::ZERO_EXTEND:
19152 case ISD::ANY_EXTEND:
19153 return PerformExtendCombine(N, DCI.DAG, Subtarget);
19154 case ISD::FP_EXTEND:
19155 return PerformFPExtendCombine(N, DCI.DAG, Subtarget);
19156 case ISD::SMIN:
19157 case ISD::UMIN:
19158 case ISD::SMAX:
19159 case ISD::UMAX:
19160 return PerformMinMaxCombine(N, DCI.DAG, Subtarget);
19161 case ARMISD::CMOV:
19162 return PerformCMOVCombine(N, DCI.DAG);
19163 case ARMISD::BRCOND:
19164 return PerformBRCONDCombine(N, DCI.DAG);
19165 case ARMISD::CMPZ:
19166 return PerformCMPZCombine(N, DCI.DAG);
19167 case ARMISD::CSINC:
19168 case ARMISD::CSINV:
19169 case ARMISD::CSNEG:
19170 return PerformCSETCombine(N, DCI.DAG);
19171 case ISD::LOAD:
19172 return PerformLOADCombine(N, DCI, Subtarget);
19173 case ARMISD::VLD1DUP:
19174 case ARMISD::VLD2DUP:
19175 case ARMISD::VLD3DUP:
19176 case ARMISD::VLD4DUP:
19177 return PerformVLDCombine(N, DCI);
19179 return PerformARMBUILD_VECTORCombine(N, DCI);
19180 case ISD::BITCAST:
19181 return PerformBITCASTCombine(N, DCI, Subtarget);
19182 case ARMISD::PREDICATE_CAST:
19183 return PerformPREDICATE_CASTCombine(N, DCI);
19184 case ARMISD::VECTOR_REG_CAST:
19185 return PerformVECTOR_REG_CASTCombine(N, DCI.DAG, Subtarget);
19186 case ARMISD::MVETRUNC:
19187 return PerformMVETruncCombine(N, DCI);
19188 case ARMISD::MVESEXT:
19189 case ARMISD::MVEZEXT:
19190 return PerformMVEExtCombine(N, DCI);
19191 case ARMISD::VCMP:
19192 return PerformVCMPCombine(N, DCI.DAG, Subtarget);
19193 case ISD::VECREDUCE_ADD:
19194 return PerformVECREDUCE_ADDCombine(N, DCI.DAG, Subtarget);
19195 case ARMISD::VADDVs:
19196 case ARMISD::VADDVu:
19197 case ARMISD::VADDLVs:
19198 case ARMISD::VADDLVu:
19199 case ARMISD::VADDLVAs:
19200 case ARMISD::VADDLVAu:
19201 case ARMISD::VMLAVs:
19202 case ARMISD::VMLAVu:
19203 case ARMISD::VMLALVs:
19204 case ARMISD::VMLALVu:
19205 case ARMISD::VMLALVAs:
19206 case ARMISD::VMLALVAu:
19207 return PerformReduceShuffleCombine(N, DCI.DAG);
19208 case ARMISD::VMOVN:
19209 return PerformVMOVNCombine(N, DCI);
19210 case ARMISD::VQMOVNs:
19211 case ARMISD::VQMOVNu:
19212 return PerformVQMOVNCombine(N, DCI);
19213 case ARMISD::VQDMULH:
19214 return PerformVQDMULHCombine(N, DCI);
19215 case ARMISD::ASRL:
19216 case ARMISD::LSRL:
19217 case ARMISD::LSLL:
19218 return PerformLongShiftCombine(N, DCI.DAG);
19219 case ARMISD::SMULWB: {
19220 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19221 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19222 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19223 return SDValue();
19224 break;
19225 }
19226 case ARMISD::SMULWT: {
19227 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19228 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19229 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19230 return SDValue();
19231 break;
19232 }
19233 case ARMISD::SMLALBB:
19234 case ARMISD::QADD16b:
19235 case ARMISD::QSUB16b:
19236 case ARMISD::UQADD16b:
19237 case ARMISD::UQSUB16b: {
19238 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19239 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19240 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19241 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19242 return SDValue();
19243 break;
19244 }
19245 case ARMISD::SMLALBT: {
19246 unsigned LowWidth = N->getOperand(0).getValueType().getSizeInBits();
19247 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19248 unsigned HighWidth = N->getOperand(1).getValueType().getSizeInBits();
19249 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19250 if ((SimplifyDemandedBits(N->getOperand(0), LowMask, DCI)) ||
19251 (SimplifyDemandedBits(N->getOperand(1), HighMask, DCI)))
19252 return SDValue();
19253 break;
19254 }
19255 case ARMISD::SMLALTB: {
19256 unsigned HighWidth = N->getOperand(0).getValueType().getSizeInBits();
19257 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19258 unsigned LowWidth = N->getOperand(1).getValueType().getSizeInBits();
19259 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19260 if ((SimplifyDemandedBits(N->getOperand(0), HighMask, DCI)) ||
19261 (SimplifyDemandedBits(N->getOperand(1), LowMask, DCI)))
19262 return SDValue();
19263 break;
19264 }
19265 case ARMISD::SMLALTT: {
19266 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19267 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19268 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19269 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19270 return SDValue();
19271 break;
19272 }
19273 case ARMISD::QADD8b:
19274 case ARMISD::QSUB8b:
19275 case ARMISD::UQADD8b:
19276 case ARMISD::UQSUB8b: {
19277 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19278 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
19279 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19280 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19281 return SDValue();
19282 break;
19283 }
19284 case ARMISD::VBSP:
19285 if (N->getOperand(1) == N->getOperand(2))
19286 return N->getOperand(1);
19287 return SDValue();
19290 switch (N->getConstantOperandVal(1)) {
19291 case Intrinsic::arm_neon_vld1:
19292 case Intrinsic::arm_neon_vld1x2:
19293 case Intrinsic::arm_neon_vld1x3:
19294 case Intrinsic::arm_neon_vld1x4:
19295 case Intrinsic::arm_neon_vld2:
19296 case Intrinsic::arm_neon_vld3:
19297 case Intrinsic::arm_neon_vld4:
19298 case Intrinsic::arm_neon_vld2lane:
19299 case Intrinsic::arm_neon_vld3lane:
19300 case Intrinsic::arm_neon_vld4lane:
19301 case Intrinsic::arm_neon_vld2dup:
19302 case Intrinsic::arm_neon_vld3dup:
19303 case Intrinsic::arm_neon_vld4dup:
19304 case Intrinsic::arm_neon_vst1:
19305 case Intrinsic::arm_neon_vst1x2:
19306 case Intrinsic::arm_neon_vst1x3:
19307 case Intrinsic::arm_neon_vst1x4:
19308 case Intrinsic::arm_neon_vst2:
19309 case Intrinsic::arm_neon_vst3:
19310 case Intrinsic::arm_neon_vst4:
19311 case Intrinsic::arm_neon_vst2lane:
19312 case Intrinsic::arm_neon_vst3lane:
19313 case Intrinsic::arm_neon_vst4lane:
19314 return PerformVLDCombine(N, DCI);
19315 case Intrinsic::arm_mve_vld2q:
19316 case Intrinsic::arm_mve_vld4q:
19317 case Intrinsic::arm_mve_vst2q:
19318 case Intrinsic::arm_mve_vst4q:
19319 return PerformMVEVLDCombine(N, DCI);
19320 default: break;
19321 }
19322 break;
19323 }
19324 return SDValue();
19325}
19326
19328 EVT VT) const {
19329 return (VT == MVT::f32) && (Opc == ISD::LOAD || Opc == ISD::STORE);
19330}
19331
19333 Align Alignment,
19335 unsigned *Fast) const {
19336 // Depends what it gets converted into if the type is weird.
19337 if (!VT.isSimple())
19338 return false;
19339
19340 // The AllowsUnaligned flag models the SCTLR.A setting in ARM cpus
19341 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
19342 auto Ty = VT.getSimpleVT().SimpleTy;
19343
19344 if (Ty == MVT::i8 || Ty == MVT::i16 || Ty == MVT::i32) {
19345 // Unaligned access can use (for example) LRDB, LRDH, LDR
19346 if (AllowsUnaligned) {
19347 if (Fast)
19348 *Fast = Subtarget->hasV7Ops();
19349 return true;
19350 }
19351 }
19352
19353 if (Ty == MVT::f64 || Ty == MVT::v2f64) {
19354 // For any little-endian targets with neon, we can support unaligned ld/st
19355 // of D and Q (e.g. {D0,D1}) registers by using vld1.i8/vst1.i8.
19356 // A big-endian target may also explicitly support unaligned accesses
19357 if (Subtarget->hasNEON() && (AllowsUnaligned || Subtarget->isLittle())) {
19358 if (Fast)
19359 *Fast = 1;
19360 return true;
19361 }
19362 }
19363
19364 if (!Subtarget->hasMVEIntegerOps())
19365 return false;
19366
19367 // These are for predicates
19368 if ((Ty == MVT::v16i1 || Ty == MVT::v8i1 || Ty == MVT::v4i1 ||
19369 Ty == MVT::v2i1)) {
19370 if (Fast)
19371 *Fast = 1;
19372 return true;
19373 }
19374
19375 // These are for truncated stores/narrowing loads. They are fine so long as
19376 // the alignment is at least the size of the item being loaded
19377 if ((Ty == MVT::v4i8 || Ty == MVT::v8i8 || Ty == MVT::v4i16) &&
19378 Alignment >= VT.getScalarSizeInBits() / 8) {
19379 if (Fast)
19380 *Fast = true;
19381 return true;
19382 }
19383
19384 // In little-endian MVE, the store instructions VSTRB.U8, VSTRH.U16 and
19385 // VSTRW.U32 all store the vector register in exactly the same format, and
19386 // differ only in the range of their immediate offset field and the required
19387 // alignment. So there is always a store that can be used, regardless of
19388 // actual type.
19389 //
19390 // For big endian, that is not the case. But can still emit a (VSTRB.U8;
19391 // VREV64.8) pair and get the same effect. This will likely be better than
19392 // aligning the vector through the stack.
19393 if (Ty == MVT::v16i8 || Ty == MVT::v8i16 || Ty == MVT::v8f16 ||
19394 Ty == MVT::v4i32 || Ty == MVT::v4f32 || Ty == MVT::v2i64 ||
19395 Ty == MVT::v2f64) {
19396 if (Fast)
19397 *Fast = 1;
19398 return true;
19399 }
19400
19401 return false;
19402}
19403
19405 LLVMContext &Context, const MemOp &Op,
19406 const AttributeList &FuncAttributes) const {
19407 // See if we can use NEON instructions for this...
19408 if ((Op.isMemcpy() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
19409 !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
19410 unsigned Fast;
19411 if (Op.size() >= 16 &&
19412 (Op.isAligned(Align(16)) ||
19413 (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
19415 Fast))) {
19416 return MVT::v2f64;
19417 } else if (Op.size() >= 8 &&
19418 (Op.isAligned(Align(8)) ||
19420 MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
19421 Fast))) {
19422 return MVT::f64;
19423 }
19424 }
19425
19426 // Let the target-independent logic figure it out.
19427 return MVT::Other;
19428}
19429
19430// 64-bit integers are split into their high and low parts and held in two
19431// different registers, so the trunc is free since the low register can just
19432// be used.
19433bool ARMTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
19434 if (!SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
19435 return false;
19436 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
19437 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
19438 return (SrcBits == 64 && DestBits == 32);
19439}
19440
19442 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
19443 !DstVT.isInteger())
19444 return false;
19445 unsigned SrcBits = SrcVT.getSizeInBits();
19446 unsigned DestBits = DstVT.getSizeInBits();
19447 return (SrcBits == 64 && DestBits == 32);
19448}
19449
19451 if (Val.getOpcode() != ISD::LOAD)
19452 return false;
19453
19454 EVT VT1 = Val.getValueType();
19455 if (!VT1.isSimple() || !VT1.isInteger() ||
19456 !VT2.isSimple() || !VT2.isInteger())
19457 return false;
19458
19459 switch (VT1.getSimpleVT().SimpleTy) {
19460 default: break;
19461 case MVT::i1:
19462 case MVT::i8:
19463 case MVT::i16:
19464 // 8-bit and 16-bit loads implicitly zero-extend to 32-bits.
19465 return true;
19466 }
19467
19468 return false;
19469}
19470
19472 if (!VT.isSimple())
19473 return false;
19474
19475 // There are quite a few FP16 instructions (e.g. VNMLA, VNMLS, etc.) that
19476 // negate values directly (fneg is free). So, we don't want to let the DAG
19477 // combiner rewrite fneg into xors and some other instructions. For f16 and
19478 // FullFP16 argument passing, some bitcast nodes may be introduced,
19479 // triggering this DAG combine rewrite, so we are avoiding that with this.
19480 switch (VT.getSimpleVT().SimpleTy) {
19481 default: break;
19482 case MVT::f16:
19483 return Subtarget->hasFullFP16();
19484 }
19485
19486 return false;
19487}
19488
19490 if (!Subtarget->hasMVEIntegerOps())
19491 return nullptr;
19492 Type *SVIType = SVI->getType();
19493 Type *ScalarType = SVIType->getScalarType();
19494
19495 if (ScalarType->isFloatTy())
19496 return Type::getInt32Ty(SVIType->getContext());
19497 if (ScalarType->isHalfTy())
19498 return Type::getInt16Ty(SVIType->getContext());
19499 return nullptr;
19500}
19501
19503 EVT VT = ExtVal.getValueType();
19504
19505 if (!isTypeLegal(VT))
19506 return false;
19507
19508 if (auto *Ld = dyn_cast<MaskedLoadSDNode>(ExtVal.getOperand(0))) {
19509 if (Ld->isExpandingLoad())
19510 return false;
19511 }
19512
19513 if (Subtarget->hasMVEIntegerOps())
19514 return true;
19515
19516 // Don't create a loadext if we can fold the extension into a wide/long
19517 // instruction.
19518 // If there's more than one user instruction, the loadext is desirable no
19519 // matter what. There can be two uses by the same instruction.
19520 if (ExtVal->use_empty() ||
19521 !ExtVal->user_begin()->isOnlyUserOf(ExtVal.getNode()))
19522 return true;
19523
19524 SDNode *U = *ExtVal->user_begin();
19525 if ((U->getOpcode() == ISD::ADD || U->getOpcode() == ISD::SUB ||
19526 U->getOpcode() == ISD::SHL || U->getOpcode() == ARMISD::VSHLIMM))
19527 return false;
19528
19529 return true;
19530}
19531
19533 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
19534 return false;
19535
19536 if (!isTypeLegal(EVT::getEVT(Ty1)))
19537 return false;
19538
19539 assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");
19540
19541 // Assuming the caller doesn't have a zeroext or signext return parameter,
19542 // truncation all the way down to i1 is valid.
19543 return true;
19544}
19545
19546/// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
19547/// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
19548/// expanded to FMAs when this method returns true, otherwise fmuladd is
19549/// expanded to fmul + fadd.
19550///
19551/// ARM supports both fused and unfused multiply-add operations; we already
19552/// lower a pair of fmul and fadd to the latter so it's not clear that there
19553/// would be a gain or that the gain would be worthwhile enough to risk
19554/// correctness bugs.
19555///
19556/// For MVE, we set this to true as it helps simplify the need for some
19557/// patterns (and we don't have the non-fused floating point instruction).
19558bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
19559 EVT VT) const {
19560 if (Subtarget->useSoftFloat())
19561 return false;
19562
19563 if (!VT.isSimple())
19564 return false;
19565
19566 switch (VT.getSimpleVT().SimpleTy) {
19567 case MVT::v4f32:
19568 case MVT::v8f16:
19569 return Subtarget->hasMVEFloatOps();
19570 case MVT::f16:
19571 return Subtarget->useFPVFMx16();
19572 case MVT::f32:
19573 return Subtarget->useFPVFMx();
19574 case MVT::f64:
19575 return Subtarget->useFPVFMx64();
19576 default:
19577 break;
19578 }
19579
19580 return false;
19581}
19582
19583static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
19584 if (V < 0)
19585 return false;
19586
19587 unsigned Scale = 1;
19588 switch (VT.getSimpleVT().SimpleTy) {
19589 case MVT::i1:
19590 case MVT::i8:
19591 // Scale == 1;
19592 break;
19593 case MVT::i16:
19594 // Scale == 2;
19595 Scale = 2;
19596 break;
19597 default:
19598 // On thumb1 we load most things (i32, i64, floats, etc) with a LDR
19599 // Scale == 4;
19600 Scale = 4;
19601 break;
19602 }
19603
19604 if ((V & (Scale - 1)) != 0)
19605 return false;
19606 return isUInt<5>(V / Scale);
19607}
19608
19609static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
19610 const ARMSubtarget *Subtarget) {
19611 if (!VT.isInteger() && !VT.isFloatingPoint())
19612 return false;
19613 if (VT.isVector() && Subtarget->hasNEON())
19614 return false;
19615 if (VT.isVector() && VT.isFloatingPoint() && Subtarget->hasMVEIntegerOps() &&
19616 !Subtarget->hasMVEFloatOps())
19617 return false;
19618
19619 bool IsNeg = false;
19620 if (V < 0) {
19621 IsNeg = true;
19622 V = -V;
19623 }
19624
19625 unsigned NumBytes = std::max((unsigned)VT.getSizeInBits() / 8, 1U);
19626
19627 // MVE: size * imm7
19628 if (VT.isVector() && Subtarget->hasMVEIntegerOps()) {
19629 switch (VT.getSimpleVT().getVectorElementType().SimpleTy) {
19630 case MVT::i32:
19631 case MVT::f32:
19632 return isShiftedUInt<7,2>(V);
19633 case MVT::i16:
19634 case MVT::f16:
19635 return isShiftedUInt<7,1>(V);
19636 case MVT::i8:
19637 return isUInt<7>(V);
19638 default:
19639 return false;
19640 }
19641 }
19642
19643 // half VLDR: 2 * imm8
19644 if (VT.isFloatingPoint() && NumBytes == 2 && Subtarget->hasFPRegs16())
19645 return isShiftedUInt<8, 1>(V);
19646 // VLDR and LDRD: 4 * imm8
19647 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
19648 return isShiftedUInt<8, 2>(V);
19649
19650 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
19651 // + imm12 or - imm8
19652 if (IsNeg)
19653 return isUInt<8>(V);
19654 return isUInt<12>(V);
19655 }
19656
19657 return false;
19658}
19659
19660/// isLegalAddressImmediate - Return true if the integer value can be used
19661/// as the offset of the target addressing mode for load / store of the
19662/// given type.
19663static bool isLegalAddressImmediate(int64_t V, EVT VT,
19664 const ARMSubtarget *Subtarget) {
19665 if (V == 0)
19666 return true;
19667
19668 if (!VT.isSimple())
19669 return false;
19670
19671 if (Subtarget->isThumb1Only())
19672 return isLegalT1AddressImmediate(V, VT);
19673 else if (Subtarget->isThumb2())
19674 return isLegalT2AddressImmediate(V, VT, Subtarget);
19675
19676 // ARM mode.
19677 if (V < 0)
19678 V = - V;
19679 switch (VT.getSimpleVT().SimpleTy) {
19680 default: return false;
19681 case MVT::i1:
19682 case MVT::i8:
19683 case MVT::i32:
19684 // +- imm12
19685 return isUInt<12>(V);
19686 case MVT::i16:
19687 // +- imm8
19688 return isUInt<8>(V);
19689 case MVT::f32:
19690 case MVT::f64:
19691 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
19692 return false;
19693 return isShiftedUInt<8, 2>(V);
19694 }
19695}
19696
19698 EVT VT) const {
19699 int Scale = AM.Scale;
19700 if (Scale < 0)
19701 return false;
19702
19703 switch (VT.getSimpleVT().SimpleTy) {
19704 default: return false;
19705 case MVT::i1:
19706 case MVT::i8:
19707 case MVT::i16:
19708 case MVT::i32:
19709 if (Scale == 1)
19710 return true;
19711 // r + r << imm
19712 Scale = Scale & ~1;
19713 return Scale == 2 || Scale == 4 || Scale == 8;
19714 case MVT::i64:
19715 // FIXME: What are we trying to model here? ldrd doesn't have an r + r
19716 // version in Thumb mode.
19717 // r + r
19718 if (Scale == 1)
19719 return true;
19720 // r * 2 (this can be lowered to r + r).
19721 if (!AM.HasBaseReg && Scale == 2)
19722 return true;
19723 return false;
19724 case MVT::isVoid:
19725 // Note, we allow "void" uses (basically, uses that aren't loads or
19726 // stores), because arm allows folding a scale into many arithmetic
19727 // operations. This should be made more precise and revisited later.
19728
19729 // Allow r << imm, but the imm has to be a multiple of two.
19730 if (Scale & 1) return false;
19731 return isPowerOf2_32(Scale);
19732 }
19733}
19734
19736 EVT VT) const {
19737 const int Scale = AM.Scale;
19738
19739 // Negative scales are not supported in Thumb1.
19740 if (Scale < 0)
19741 return false;
19742
19743 // Thumb1 addressing modes do not support register scaling excepting the
19744 // following cases:
19745 // 1. Scale == 1 means no scaling.
19746 // 2. Scale == 2 this can be lowered to r + r if there is no base register.
19747 return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
19748}
19749
19750/// isLegalAddressingMode - Return true if the addressing mode represented
19751/// by AM is legal for this target, for a load/store of the specified type.
19753 const AddrMode &AM, Type *Ty,
19754 unsigned AS, Instruction *I) const {
19755 EVT VT = getValueType(DL, Ty, true);
19756 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget))
19757 return false;
19758
19759 // Can never fold addr of global into load/store.
19760 if (AM.BaseGV)
19761 return false;
19762
19763 switch (AM.Scale) {
19764 case 0: // no scale reg, must be "r+i" or "r", or "i".
19765 break;
19766 default:
19767 // ARM doesn't support any R+R*scale+imm addr modes.
19768 if (AM.BaseOffs)
19769 return false;
19770
19771 if (!VT.isSimple())
19772 return false;
19773
19774 if (Subtarget->isThumb1Only())
19775 return isLegalT1ScaledAddressingMode(AM, VT);
19776
19777 if (Subtarget->isThumb2())
19778 return isLegalT2ScaledAddressingMode(AM, VT);
19779
19780 int Scale = AM.Scale;
19781 switch (VT.getSimpleVT().SimpleTy) {
19782 default: return false;
19783 case MVT::i1:
19784 case MVT::i8:
19785 case MVT::i32:
19786 if (Scale < 0) Scale = -Scale;
19787 if (Scale == 1)
19788 return true;
19789 // r + r << imm
19790 return isPowerOf2_32(Scale & ~1);
19791 case MVT::i16:
19792 case MVT::i64:
19793 // r +/- r
19794 if (Scale == 1 || (AM.HasBaseReg && Scale == -1))
19795 return true;
19796 // r * 2 (this can be lowered to r + r).
19797 if (!AM.HasBaseReg && Scale == 2)
19798 return true;
19799 return false;
19800
19801 case MVT::isVoid:
19802 // Note, we allow "void" uses (basically, uses that aren't loads or
19803 // stores), because arm allows folding a scale into many arithmetic
19804 // operations. This should be made more precise and revisited later.
19805
19806 // Allow r << imm, but the imm has to be a multiple of two.
19807 if (Scale & 1) return false;
19808 return isPowerOf2_32(Scale);
19809 }
19810 }
19811 return true;
19812}
19813
19814/// isLegalICmpImmediate - Return true if the specified immediate is legal
19815/// icmp immediate, that is the target has icmp instructions which can compare
19816/// a register against the immediate without having to materialize the
19817/// immediate into a register.
19819 // Thumb2 and ARM modes can use cmn for negative immediates.
19820 if (!Subtarget->isThumb())
19821 return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
19822 ARM_AM::getSOImmVal(-(uint32_t)Imm) != -1;
19823 if (Subtarget->isThumb2())
19824 return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
19825 ARM_AM::getT2SOImmVal(-(uint32_t)Imm) != -1;
19826 // Thumb1 doesn't have cmn, and only 8-bit immediates.
19827 return Imm >= 0 && Imm <= 255;
19828}
19829
19830/// isLegalAddImmediate - Return true if the specified immediate is a legal add
19831/// *or sub* immediate, that is the target has add or sub instructions which can
19832/// add a register with the immediate without having to materialize the
19833/// immediate into a register.
19835 // Same encoding for add/sub, just flip the sign.
19836 uint64_t AbsImm = AbsoluteValue(Imm);
19837 if (!Subtarget->isThumb())
19838 return ARM_AM::getSOImmVal(AbsImm) != -1;
19839 if (Subtarget->isThumb2())
19840 return ARM_AM::getT2SOImmVal(AbsImm) != -1;
19841 // Thumb1 only has 8-bit unsigned immediate.
19842 return AbsImm <= 255;
19843}
19844
19845// Return false to prevent folding
19846// (mul (add r, c0), c1) -> (add (mul r, c1), c0*c1) in DAGCombine,
19847// if the folding leads to worse code.
19849 SDValue ConstNode) const {
19850 // Let the DAGCombiner decide for vector types and large types.
19851 const EVT VT = AddNode.getValueType();
19852 if (VT.isVector() || VT.getScalarSizeInBits() > 32)
19853 return true;
19854
19855 // It is worse if c0 is legal add immediate, while c1*c0 is not
19856 // and has to be composed by at least two instructions.
19857 const ConstantSDNode *C0Node = cast<ConstantSDNode>(AddNode.getOperand(1));
19858 const ConstantSDNode *C1Node = cast<ConstantSDNode>(ConstNode);
19859 const int64_t C0 = C0Node->getSExtValue();
19860 APInt CA = C0Node->getAPIntValue() * C1Node->getAPIntValue();
19862 return true;
19863 if (ConstantMaterializationCost((unsigned)CA.getZExtValue(), Subtarget) > 1)
19864 return false;
19865
19866 // Default to true and let the DAGCombiner decide.
19867 return true;
19868}
19869
19871 bool isSEXTLoad, SDValue &Base,
19872 SDValue &Offset, bool &isInc,
19873 SelectionDAG &DAG) {
19874 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19875 return false;
19876
19877 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
19878 // AddressingMode 3
19879 Base = Ptr->getOperand(0);
19881 int RHSC = (int)RHS->getZExtValue();
19882 if (RHSC < 0 && RHSC > -256) {
19883 assert(Ptr->getOpcode() == ISD::ADD);
19884 isInc = false;
19885 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19886 return true;
19887 }
19888 }
19889 isInc = (Ptr->getOpcode() == ISD::ADD);
19890 Offset = Ptr->getOperand(1);
19891 return true;
19892 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
19893 // AddressingMode 2
19895 int RHSC = (int)RHS->getZExtValue();
19896 if (RHSC < 0 && RHSC > -0x1000) {
19897 assert(Ptr->getOpcode() == ISD::ADD);
19898 isInc = false;
19899 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19900 Base = Ptr->getOperand(0);
19901 return true;
19902 }
19903 }
19904
19905 if (Ptr->getOpcode() == ISD::ADD) {
19906 isInc = true;
19907 ARM_AM::ShiftOpc ShOpcVal=
19909 if (ShOpcVal != ARM_AM::no_shift) {
19910 Base = Ptr->getOperand(1);
19911 Offset = Ptr->getOperand(0);
19912 } else {
19913 Base = Ptr->getOperand(0);
19914 Offset = Ptr->getOperand(1);
19915 }
19916 return true;
19917 }
19918
19919 isInc = (Ptr->getOpcode() == ISD::ADD);
19920 Base = Ptr->getOperand(0);
19921 Offset = Ptr->getOperand(1);
19922 return true;
19923 }
19924
19925 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
19926 return false;
19927}
19928
19930 bool isSEXTLoad, SDValue &Base,
19931 SDValue &Offset, bool &isInc,
19932 SelectionDAG &DAG) {
19933 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19934 return false;
19935
19936 Base = Ptr->getOperand(0);
19938 int RHSC = (int)RHS->getZExtValue();
19939 if (RHSC < 0 && RHSC > -0x100) { // 8 bits.
19940 assert(Ptr->getOpcode() == ISD::ADD);
19941 isInc = false;
19942 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19943 return true;
19944 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero.
19945 isInc = Ptr->getOpcode() == ISD::ADD;
19946 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
19947 return true;
19948 }
19949 }
19950
19951 return false;
19952}
19953
19954static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment,
19955 bool isSEXTLoad, bool IsMasked, bool isLE,
19957 bool &isInc, SelectionDAG &DAG) {
19958 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19959 return false;
19960 if (!isa<ConstantSDNode>(Ptr->getOperand(1)))
19961 return false;
19962
19963 // We allow LE non-masked loads to change the type (for example use a vldrb.8
19964 // as opposed to a vldrw.32). This can allow extra addressing modes or
19965 // alignments for what is otherwise an equivalent instruction.
19966 bool CanChangeType = isLE && !IsMasked;
19967
19969 int RHSC = (int)RHS->getZExtValue();
19970
19971 auto IsInRange = [&](int RHSC, int Limit, int Scale) {
19972 if (RHSC < 0 && RHSC > -Limit * Scale && RHSC % Scale == 0) {
19973 assert(Ptr->getOpcode() == ISD::ADD);
19974 isInc = false;
19975 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19976 return true;
19977 } else if (RHSC > 0 && RHSC < Limit * Scale && RHSC % Scale == 0) {
19978 isInc = Ptr->getOpcode() == ISD::ADD;
19979 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
19980 return true;
19981 }
19982 return false;
19983 };
19984
19985 // Try to find a matching instruction based on s/zext, Alignment, Offset and
19986 // (in BE/masked) type.
19987 Base = Ptr->getOperand(0);
19988 if (VT == MVT::v4i16) {
19989 if (Alignment >= 2 && IsInRange(RHSC, 0x80, 2))
19990 return true;
19991 } else if (VT == MVT::v4i8 || VT == MVT::v8i8) {
19992 if (IsInRange(RHSC, 0x80, 1))
19993 return true;
19994 } else if (Alignment >= 4 &&
19995 (CanChangeType || VT == MVT::v4i32 || VT == MVT::v4f32) &&
19996 IsInRange(RHSC, 0x80, 4))
19997 return true;
19998 else if (Alignment >= 2 &&
19999 (CanChangeType || VT == MVT::v8i16 || VT == MVT::v8f16) &&
20000 IsInRange(RHSC, 0x80, 2))
20001 return true;
20002 else if ((CanChangeType || VT == MVT::v16i8) && IsInRange(RHSC, 0x80, 1))
20003 return true;
20004 return false;
20005}
20006
20007/// getPreIndexedAddressParts - returns true by value, base pointer and
20008/// offset pointer and addressing mode by reference if the node's address
20009/// can be legally represented as pre-indexed load / store address.
20010bool
20012 SDValue &Offset,
20014 SelectionDAG &DAG) const {
20015 if (Subtarget->isThumb1Only())
20016 return false;
20017
20018 EVT VT;
20019 SDValue Ptr;
20020 Align Alignment;
20021 unsigned AS = 0;
20022 bool isSEXTLoad = false;
20023 bool IsMasked = false;
20024 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20025 Ptr = LD->getBasePtr();
20026 VT = LD->getMemoryVT();
20027 Alignment = LD->getAlign();
20028 AS = LD->getAddressSpace();
20029 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20030 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20031 Ptr = ST->getBasePtr();
20032 VT = ST->getMemoryVT();
20033 Alignment = ST->getAlign();
20034 AS = ST->getAddressSpace();
20035 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20036 Ptr = LD->getBasePtr();
20037 VT = LD->getMemoryVT();
20038 Alignment = LD->getAlign();
20039 AS = LD->getAddressSpace();
20040 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20041 IsMasked = true;
20043 Ptr = ST->getBasePtr();
20044 VT = ST->getMemoryVT();
20045 Alignment = ST->getAlign();
20046 AS = ST->getAddressSpace();
20047 IsMasked = true;
20048 } else
20049 return false;
20050
20051 unsigned Fast = 0;
20052 if (!allowsMisalignedMemoryAccesses(VT, AS, Alignment,
20054 // Only generate post-increment or pre-increment forms when a real
20055 // hardware instruction exists for them. Do not emit postinc/preinc
20056 // if the operation will end up as a libcall.
20057 return false;
20058 }
20059
20060 bool isInc;
20061 bool isLegal = false;
20062 if (VT.isVector())
20063 isLegal = Subtarget->hasMVEIntegerOps() &&
20065 Ptr.getNode(), VT, Alignment, isSEXTLoad, IsMasked,
20066 Subtarget->isLittle(), Base, Offset, isInc, DAG);
20067 else {
20068 if (Subtarget->isThumb2())
20069 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20070 Offset, isInc, DAG);
20071 else
20072 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20073 Offset, isInc, DAG);
20074 }
20075 if (!isLegal)
20076 return false;
20077
20078 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
20079 return true;
20080}
20081
20082/// getPostIndexedAddressParts - returns true by value, base pointer and
20083/// offset pointer and addressing mode by reference if this node can be
20084/// combined with a load / store to form a post-indexed load / store.
20086 SDValue &Base,
20087 SDValue &Offset,
20089 SelectionDAG &DAG) const {
20090 EVT VT;
20091 SDValue Ptr;
20092 Align Alignment;
20093 bool isSEXTLoad = false, isNonExt;
20094 bool IsMasked = false;
20095 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20096 VT = LD->getMemoryVT();
20097 Ptr = LD->getBasePtr();
20098 Alignment = LD->getAlign();
20099 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20100 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20101 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20102 VT = ST->getMemoryVT();
20103 Ptr = ST->getBasePtr();
20104 Alignment = ST->getAlign();
20105 isNonExt = !ST->isTruncatingStore();
20106 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20107 VT = LD->getMemoryVT();
20108 Ptr = LD->getBasePtr();
20109 Alignment = LD->getAlign();
20110 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20111 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20112 IsMasked = true;
20114 VT = ST->getMemoryVT();
20115 Ptr = ST->getBasePtr();
20116 Alignment = ST->getAlign();
20117 isNonExt = !ST->isTruncatingStore();
20118 IsMasked = true;
20119 } else
20120 return false;
20121
20122 if (Subtarget->isThumb1Only()) {
20123 // Thumb-1 can do a limited post-inc load or store as an updating LDM. It
20124 // must be non-extending/truncating, i32, with an offset of 4.
20125 assert(Op->getValueType(0) == MVT::i32 && "Non-i32 post-inc op?!");
20126 if (Op->getOpcode() != ISD::ADD || !isNonExt)
20127 return false;
20128 auto *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1));
20129 if (!RHS || RHS->getZExtValue() != 4)
20130 return false;
20131 if (Alignment < Align(4))
20132 return false;
20133
20134 Offset = Op->getOperand(1);
20135 Base = Op->getOperand(0);
20136 AM = ISD::POST_INC;
20137 return true;
20138 }
20139
20140 bool isInc;
20141 bool isLegal = false;
20142 if (VT.isVector())
20143 isLegal = Subtarget->hasMVEIntegerOps() &&
20144 getMVEIndexedAddressParts(Op, VT, Alignment, isSEXTLoad, IsMasked,
20145 Subtarget->isLittle(), Base, Offset,
20146 isInc, DAG);
20147 else {
20148 if (Subtarget->isThumb2())
20149 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20150 isInc, DAG);
20151 else
20152 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20153 isInc, DAG);
20154 }
20155 if (!isLegal)
20156 return false;
20157
20158 if (Ptr != Base) {
20159 // Swap base ptr and offset to catch more post-index load / store when
20160 // it's legal. In Thumb2 mode, offset must be an immediate.
20161 if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
20162 !Subtarget->isThumb2())
20164
20165 // Post-indexed load / store update the base pointer.
20166 if (Ptr != Base)
20167 return false;
20168 }
20169
20170 AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
20171 return true;
20172}
20173
20176 const APInt &DemandedElts,
20177 const SelectionDAG &DAG,
20178 unsigned Depth) const {
20179 unsigned BitWidth = Known.getBitWidth();
20180 Known.resetAll();
20181 switch (Op.getOpcode()) {
20182 default: break;
20183 case ARMISD::ADDC:
20184 case ARMISD::ADDE:
20185 case ARMISD::SUBC:
20186 case ARMISD::SUBE:
20187 // Special cases when we convert a carry to a boolean.
20188 if (Op.getResNo() == 0) {
20189 SDValue LHS = Op.getOperand(0);
20190 SDValue RHS = Op.getOperand(1);
20191 // (ADDE 0, 0, C) will give us a single bit.
20192 if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
20193 isNullConstant(RHS)) {
20195 return;
20196 }
20197 }
20198 break;
20199 case ARMISD::CMOV: {
20200 // Bits are known zero/one if known on the LHS and RHS.
20201 Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
20202 if (Known.isUnknown())
20203 return;
20204
20205 KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
20206 Known = Known.intersectWith(KnownRHS);
20207 return;
20208 }
20210 Intrinsic::ID IntID =
20211 static_cast<Intrinsic::ID>(Op->getConstantOperandVal(1));
20212 switch (IntID) {
20213 default: return;
20214 case Intrinsic::arm_ldaex:
20215 case Intrinsic::arm_ldrex: {
20216 EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
20217 unsigned MemBits = VT.getScalarSizeInBits();
20218 Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20219 return;
20220 }
20221 }
20222 }
20223 case ARMISD::BFI: {
20224 // Conservatively, we can recurse down the first operand
20225 // and just mask out all affected bits.
20226 Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20227
20228 // The operand to BFI is already a mask suitable for removing the bits it
20229 // sets.
20230 const APInt &Mask = Op.getConstantOperandAPInt(2);
20231 Known.Zero &= Mask;
20232 Known.One &= Mask;
20233 return;
20234 }
20235 case ARMISD::VGETLANEs:
20236 case ARMISD::VGETLANEu: {
20237 const SDValue &SrcSV = Op.getOperand(0);
20238 EVT VecVT = SrcSV.getValueType();
20239 assert(VecVT.isVector() && "VGETLANE expected a vector type");
20240 const unsigned NumSrcElts = VecVT.getVectorNumElements();
20241 ConstantSDNode *Pos = cast<ConstantSDNode>(Op.getOperand(1).getNode());
20242 assert(Pos->getAPIntValue().ult(NumSrcElts) &&
20243 "VGETLANE index out of bounds");
20244 unsigned Idx = Pos->getZExtValue();
20245 APInt DemandedElt = APInt::getOneBitSet(NumSrcElts, Idx);
20246 Known = DAG.computeKnownBits(SrcSV, DemandedElt, Depth + 1);
20247
20248 EVT VT = Op.getValueType();
20249 const unsigned DstSz = VT.getScalarSizeInBits();
20250 const unsigned SrcSz = VecVT.getVectorElementType().getSizeInBits();
20251 (void)SrcSz;
20252 assert(SrcSz == Known.getBitWidth());
20253 assert(DstSz > SrcSz);
20254 if (Op.getOpcode() == ARMISD::VGETLANEs)
20255 Known = Known.sext(DstSz);
20256 else {
20257 Known = Known.zext(DstSz);
20258 }
20259 assert(DstSz == Known.getBitWidth());
20260 break;
20261 }
20262 case ARMISD::VMOVrh: {
20263 KnownBits KnownOp = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20264 assert(KnownOp.getBitWidth() == 16);
20265 Known = KnownOp.zext(32);
20266 break;
20267 }
20268 case ARMISD::CSINC:
20269 case ARMISD::CSINV:
20270 case ARMISD::CSNEG: {
20271 KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20272 KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
20273
20274 // The result is either:
20275 // CSINC: KnownOp0 or KnownOp1 + 1
20276 // CSINV: KnownOp0 or ~KnownOp1
20277 // CSNEG: KnownOp0 or KnownOp1 * -1
20278 if (Op.getOpcode() == ARMISD::CSINC)
20279 KnownOp1 =
20280 KnownBits::add(KnownOp1, KnownBits::makeConstant(APInt(32, 1)));
20281 else if (Op.getOpcode() == ARMISD::CSINV)
20282 std::swap(KnownOp1.Zero, KnownOp1.One);
20283 else if (Op.getOpcode() == ARMISD::CSNEG)
20284 KnownOp1 = KnownBits::mul(KnownOp1,
20286
20287 Known = KnownOp0.intersectWith(KnownOp1);
20288 break;
20289 }
20290 case ARMISD::VORRIMM:
20291 case ARMISD::VBICIMM: {
20292 unsigned Encoded = Op.getConstantOperandVal(1);
20293 unsigned DecEltBits = 0;
20294 uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
20295
20296 unsigned EltBits = Op.getScalarValueSizeInBits();
20297 if (EltBits != DecEltBits) {
20298 // Be conservative: only update Known when EltBits == DecEltBits.
20299 // This is believed to always be true for VORRIMM/VBICIMM today, but if
20300 // that changes in the future, doing nothing here is safer than risking
20301 // subtle bugs.
20302 break;
20303 }
20304
20305 KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20306 bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
20307 APInt Imm(DecEltBits, DecodedVal);
20308
20309 Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
20310 Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
20311 break;
20312 }
20313 }
20314}
20315
20316static bool isLegalLogicalImmediate(unsigned Imm,
20317 const ARMSubtarget *Subtarget) {
20318 if (!Subtarget->isThumb())
20319 return ARM_AM::getSOImmVal(Imm) != -1;
20320 if (Subtarget->isThumb2())
20321 return ARM_AM::getT2SOImmVal(Imm) != -1;
20322 // Thumb1 only has 8-bit unsigned immediate.
20323 return Imm <= 255;
20324}
20325
20326/// Refine i32 AND/OR/XOR with a constant RHS using demanded bits: replace the
20327/// immediate with an equivalent constant that ARM/Thumb can encode as a
20328/// logical immediate (or that selects better lowering), without changing the
20329/// computed result on those demanded bits.
20330static bool optimizeLogicalImm(SDValue Op, unsigned Imm,
20331 const APInt &DemandedBits,
20332 const ARMSubtarget *Subtarget,
20334
20335 if (Imm == 0 || Imm == ~0U)
20336 return false;
20337
20338 unsigned Opc = Op.getOpcode();
20339 unsigned Demanded = DemandedBits.getZExtValue();
20340 EVT VT = Op.getValueType();
20341
20342 unsigned ShrunkImm = Imm & Demanded;
20343 unsigned ExpandedImm = Imm | ~Demanded;
20344
20345 auto IsLegalImm = [ShrunkImm, ExpandedImm](unsigned CandidateImm) -> bool {
20346 return (ShrunkImm & CandidateImm) == ShrunkImm &&
20347 (~ExpandedImm & CandidateImm) == 0;
20348 };
20349 auto UseImm = [Imm, Opc, Op, VT, &TLO](unsigned NewImm) -> bool {
20350 if (NewImm == Imm)
20351 return true;
20352 SDLoc DL(Op);
20353 SDValue NewC = TLO.DAG.getConstant(NewImm, DL, VT);
20354 SDValue NewOp =
20355 TLO.DAG.getNode(Opc, DL, VT, Op.getOperand(0), NewC, Op->getFlags());
20356 return TLO.CombineTo(Op, NewOp);
20357 };
20358
20359 // Shrunk immediate is 0: AND becomes zero; OR/XOR with 0 leaves the other
20360 // operand (still valid on demanded bits).
20361 if (ShrunkImm == 0) {
20362 ++NumOptimizedImms;
20363 return UseImm(ShrunkImm);
20364 }
20365
20366 // If the immediate is all ones: for AND this removes the operation; for
20367 // OR/XOR it remains a transform valid on demanded bits. (Target-independent
20368 // shrink may not fold this, so keep it to avoid obscure combine loops.)
20369 if (ExpandedImm == ~0U) {
20370 ++NumOptimizedImms;
20371 return UseImm(ExpandedImm);
20372 }
20373
20374 // Thumb1: prefer 0xFF / 0xFFFF when they fit the demanded-bit envelope so
20375 // lowering can match uxtb / uxth (AND immediates only; OR/XOR do not use
20376 // that). Run this before strict ShrunkImm: a tight 8-bit ShrunkImm can be
20377 // legal while 0xFF still matches the envelope and yields better isel (uxtb).
20378 if (Opc == ISD::AND && Subtarget->hasV6Ops()) {
20379 if (IsLegalImm(0xFF)) {
20380 ++NumOptimizedImms;
20381 return UseImm(0xFF);
20382 }
20383
20384 if (IsLegalImm(0xFFFF)) {
20385 ++NumOptimizedImms;
20386 return UseImm(0xFFFF);
20387 }
20388 }
20389
20390 // Don't optimize if it is legal.
20391 if (isLegalLogicalImmediate(Imm, Subtarget))
20392 return false;
20393
20394 // FIXME: Check for BIC being legal causes infinite loop due to target
20395 // independent DAG combine undoing this.
20396
20397 // Prefer strict shrink when ShrunkImm encodes for this target, before
20398 // complement expansion.
20399 if (isLegalLogicalImmediate(ShrunkImm, Subtarget)) {
20400 ++NumOptimizedImms;
20401 return UseImm(ShrunkImm);
20402 }
20403
20404 // Complement expansion: if all undemanded bits are already one, ExpandedImm
20405 // is Imm with every non-demanded bit set. When (~ExpandedImm) < 256, the
20406 // complement fits in an 8-bit unsigned value, i.e. bits 8–31 of ExpandedImm
20407 // are all ones; only the low byte may differ from ~0. Use that expanded
20408 // constant so isel sees a mask shape that fits logical-immediate patterns.
20409 if ((~ExpandedImm) < 256) {
20410 ++NumOptimizedImms;
20411 return UseImm(ExpandedImm);
20412 }
20413
20414 // FIXME: The check for v6 is because this interferes with some ubfx
20415 // optimizations.
20416 if (Opc == ISD::AND && isLegalLogicalImmediate(~ExpandedImm, Subtarget) &&
20417 !Subtarget->hasV6Ops()) {
20418 ++NumOptimizedImms;
20419 return UseImm(ExpandedImm);
20420 }
20421
20422 // Potential improvements:
20423 //
20424 // We could try to recognize lsls+lsrs or lsrs+lsls pairs here.
20425 // We could try to prefer Thumb1 immediates which can be lowered to a
20426 // two-instruction sequence.
20427
20428 return false;
20429}
20430
20432 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
20433 TargetLoweringOpt &TLO) const {
20434 // Delay this optimization to as late as possible.
20435 if (!TLO.LegalOps)
20436 return false;
20437
20438 EVT VT = Op.getValueType();
20439
20440 // Ignore vectors.
20441 if (VT.isVector())
20442 return false;
20443
20444 unsigned Size = VT.getSizeInBits();
20445
20446 if (Size != 32)
20447 return false;
20448
20449 // Exit early if we demand all bits.
20450 if (DemandedBits.isAllOnes())
20451 return false;
20452
20453 switch (Op.getOpcode()) {
20454 default:
20455 return false;
20456 case ISD::AND:
20457 case ISD::OR:
20458 case ISD::XOR:
20459 break;
20460 }
20461 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20462 if (!C)
20463 return false;
20464 unsigned Imm = C->getZExtValue();
20465 return optimizeLogicalImm(Op, Imm, DemandedBits, Subtarget, TLO);
20466}
20467
20469 SDValue Op, const APInt &OriginalDemandedBits,
20470 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
20471 unsigned Depth) const {
20472 unsigned Opc = Op.getOpcode();
20473
20474 switch (Opc) {
20475 case ARMISD::ASRL:
20476 case ARMISD::LSRL: {
20477 // If this is result 0 and the other result is unused, see if the demand
20478 // bits allow us to shrink this long shift into a standard small shift in
20479 // the opposite direction.
20480 if (Op.getResNo() == 0 && !Op->hasAnyUseOfValue(1) &&
20481 isa<ConstantSDNode>(Op->getOperand(2))) {
20482 unsigned ShAmt = Op->getConstantOperandVal(2);
20483 if (ShAmt < 32 && OriginalDemandedBits.isSubsetOf(APInt::getAllOnes(32)
20484 << (32 - ShAmt)))
20485 return TLO.CombineTo(
20486 Op, TLO.DAG.getNode(
20487 ISD::SHL, SDLoc(Op), MVT::i32, Op.getOperand(1),
20488 TLO.DAG.getConstant(32 - ShAmt, SDLoc(Op), MVT::i32)));
20489 }
20490 break;
20491 }
20492 case ARMISD::VBICIMM: {
20493 SDValue Op0 = Op.getOperand(0);
20494 unsigned ModImm = Op.getConstantOperandVal(1);
20495 unsigned EltBits = 0;
20496 uint64_t Mask = ARM_AM::decodeVMOVModImm(ModImm, EltBits);
20497 if ((OriginalDemandedBits & Mask) == 0)
20498 return TLO.CombineTo(Op, Op0);
20499 }
20500 }
20501
20503 Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
20504}
20505
20506//===----------------------------------------------------------------------===//
20507// ARM Inline Assembly Support
20508//===----------------------------------------------------------------------===//
20509
20510const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
20511 // At this point, we have to lower this constraint to something else, so we
20512 // lower it to an "r" or "w". However, by doing this we will force the result
20513 // to be in register, while the X constraint is much more permissive.
20514 //
20515 // Although we are correct (we are free to emit anything, without
20516 // constraints), we might break use cases that would expect us to be more
20517 // efficient and emit something else.
20518 if (!Subtarget->hasVFP2Base())
20519 return "r";
20520 if (ConstraintVT.isFloatingPoint())
20521 return "w";
20522 if (ConstraintVT.isVector() && Subtarget->hasNEON() &&
20523 (ConstraintVT.getSizeInBits() == 64 ||
20524 ConstraintVT.getSizeInBits() == 128))
20525 return "w";
20526
20527 return "r";
20528}
20529
20530/// getConstraintType - Given a constraint letter, return the type of
20531/// constraint it is for this target.
20534 unsigned S = Constraint.size();
20535 if (S == 1) {
20536 switch (Constraint[0]) {
20537 default: break;
20538 case 'l': return C_RegisterClass;
20539 case 'w': return C_RegisterClass;
20540 case 'h': return C_RegisterClass;
20541 case 'x': return C_RegisterClass;
20542 case 't': return C_RegisterClass;
20543 case 'j': return C_Immediate; // Constant for movw.
20544 // An address with a single base register. Due to the way we
20545 // currently handle addresses it is the same as an 'r' memory constraint.
20546 case 'Q': return C_Memory;
20547 }
20548 } else if (S == 2) {
20549 switch (Constraint[0]) {
20550 default: break;
20551 case 'T': return C_RegisterClass;
20552 // All 'U+' constraints are addresses.
20553 case 'U': return C_Memory;
20554 }
20555 }
20556 return TargetLowering::getConstraintType(Constraint);
20557}
20558
20559/// Examine constraint type and operand type and determine a weight value.
20560/// This object must already have been set up with the operand type
20561/// and the current alternative constraint selected.
20564 AsmOperandInfo &info, const char *constraint) const {
20566 Value *CallOperandVal = info.CallOperandVal;
20567 // If we don't have a value, we can't do a match,
20568 // but allow it at the lowest weight.
20569 if (!CallOperandVal)
20570 return CW_Default;
20571 Type *type = CallOperandVal->getType();
20572 // Look at the constraint type.
20573 switch (*constraint) {
20574 default:
20576 break;
20577 case 'l':
20578 if (type->isIntegerTy()) {
20579 if (Subtarget->isThumb())
20580 weight = CW_SpecificReg;
20581 else
20582 weight = CW_Register;
20583 }
20584 break;
20585 case 'w':
20586 if (type->isFloatingPointTy())
20587 weight = CW_Register;
20588 break;
20589 }
20590 return weight;
20591}
20592
20593static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
20594 if (PR == 0 || VT == MVT::Other)
20595 return false;
20596 if (ARM::SPRRegClass.contains(PR))
20597 return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32;
20598 if (ARM::DPRRegClass.contains(PR))
20599 return VT != MVT::f64 && !VT.is64BitVector();
20600 return false;
20601}
20602
20603using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
20604
20606 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
20607 switch (Constraint.size()) {
20608 case 1:
20609 // GCC ARM Constraint Letters
20610 switch (Constraint[0]) {
20611 case 'l': // Low regs or general regs.
20612 if (Subtarget->isThumb())
20613 return RCPair(0U, &ARM::tGPRRegClass);
20614 return RCPair(0U, &ARM::GPRRegClass);
20615 case 'h': // High regs or no regs.
20616 if (Subtarget->isThumb())
20617 return RCPair(0U, &ARM::hGPRRegClass);
20618 break;
20619 case 'r':
20620 if (Subtarget->isThumb1Only())
20621 return RCPair(0U, &ARM::tGPRRegClass);
20622 return RCPair(0U, &ARM::GPRRegClass);
20623 case 'w':
20624 if (VT == MVT::Other)
20625 break;
20626 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20627 return RCPair(0U, &ARM::SPRRegClass);
20628 if (VT.getSizeInBits() == 64)
20629 return RCPair(0U, &ARM::DPRRegClass);
20630 if (VT.getSizeInBits() == 128)
20631 return RCPair(0U, &ARM::QPRRegClass);
20632 break;
20633 case 'x':
20634 if (VT == MVT::Other)
20635 break;
20636 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20637 return RCPair(0U, &ARM::SPR_8RegClass);
20638 if (VT.getSizeInBits() == 64)
20639 return RCPair(0U, &ARM::DPR_8RegClass);
20640 if (VT.getSizeInBits() == 128)
20641 return RCPair(0U, &ARM::QPR_8RegClass);
20642 break;
20643 case 't':
20644 if (VT == MVT::Other)
20645 break;
20646 if (VT == MVT::f32 || VT == MVT::i32 || VT == MVT::f16 || VT == MVT::bf16)
20647 return RCPair(0U, &ARM::SPRRegClass);
20648 if (VT.getSizeInBits() == 64)
20649 return RCPair(0U, &ARM::DPR_VFP2RegClass);
20650 if (VT.getSizeInBits() == 128)
20651 return RCPair(0U, &ARM::QPR_VFP2RegClass);
20652 break;
20653 }
20654 break;
20655
20656 case 2:
20657 if (Constraint[0] == 'T') {
20658 switch (Constraint[1]) {
20659 default:
20660 break;
20661 case 'e':
20662 return RCPair(0U, &ARM::tGPREvenRegClass);
20663 case 'o':
20664 return RCPair(0U, &ARM::tGPROddRegClass);
20665 }
20666 }
20667 break;
20668
20669 default:
20670 break;
20671 }
20672
20673 if (StringRef("{cc}").equals_insensitive(Constraint))
20674 return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
20675
20676 // r14 is an alias of lr.
20677 if (StringRef("{r14}").equals_insensitive(Constraint))
20678 return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32));
20679
20680 auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
20681 if (isIncompatibleReg(RCP.first, VT))
20682 return {0, nullptr};
20683 return RCP;
20684}
20685
20686/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
20687/// vector. If it is invalid, don't add anything to Ops.
20689 StringRef Constraint,
20690 std::vector<SDValue> &Ops,
20691 SelectionDAG &DAG) const {
20692 SDValue Result;
20693
20694 // Currently only support length 1 constraints.
20695 if (Constraint.size() != 1)
20696 return;
20697
20698 char ConstraintLetter = Constraint[0];
20699 switch (ConstraintLetter) {
20700 default: break;
20701 case 'j':
20702 case 'I': case 'J': case 'K': case 'L':
20703 case 'M': case 'N': case 'O':
20705 if (!C)
20706 return;
20707
20708 int64_t CVal64 = C->getSExtValue();
20709 int CVal = (int) CVal64;
20710 // None of these constraints allow values larger than 32 bits. Check
20711 // that the value fits in an int.
20712 if (CVal != CVal64)
20713 return;
20714
20715 switch (ConstraintLetter) {
20716 case 'j':
20717 // Constant suitable for movw, must be between 0 and
20718 // 65535.
20719 if (Subtarget->hasV6T2Ops() || (Subtarget->hasV8MBaselineOps()))
20720 if (CVal >= 0 && CVal <= 65535)
20721 break;
20722 return;
20723 case 'I':
20724 if (Subtarget->isThumb1Only()) {
20725 // This must be a constant between 0 and 255, for ADD
20726 // immediates.
20727 if (CVal >= 0 && CVal <= 255)
20728 break;
20729 } else if (Subtarget->isThumb2()) {
20730 // A constant that can be used as an immediate value in a
20731 // data-processing instruction.
20732 if (ARM_AM::getT2SOImmVal(CVal) != -1)
20733 break;
20734 } else {
20735 // A constant that can be used as an immediate value in a
20736 // data-processing instruction.
20737 if (ARM_AM::getSOImmVal(CVal) != -1)
20738 break;
20739 }
20740 return;
20741
20742 case 'J':
20743 if (Subtarget->isThumb1Only()) {
20744 // This must be a constant between -255 and -1, for negated ADD
20745 // immediates. This can be used in GCC with an "n" modifier that
20746 // prints the negated value, for use with SUB instructions. It is
20747 // not useful otherwise but is implemented for compatibility.
20748 if (CVal >= -255 && CVal <= -1)
20749 break;
20750 } else {
20751 // This must be a constant between -4095 and 4095. This is suitable
20752 // for use as the immediate offset field in LDR and STR instructions
20753 // such as LDR r0,[r1,#offset].
20754 if (CVal >= -4095 && CVal <= 4095)
20755 break;
20756 }
20757 return;
20758
20759 case 'K':
20760 if (Subtarget->isThumb1Only()) {
20761 // A 32-bit value where only one byte has a nonzero value. Exclude
20762 // zero to match GCC. This constraint is used by GCC internally for
20763 // constants that can be loaded with a move/shift combination.
20764 // It is not useful otherwise but is implemented for compatibility.
20765 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal))
20766 break;
20767 } else if (Subtarget->isThumb2()) {
20768 // A constant whose bitwise inverse can be used as an immediate
20769 // value in a data-processing instruction. This can be used in GCC
20770 // with a "B" modifier that prints the inverted value, for use with
20771 // BIC and MVN instructions. It is not useful otherwise but is
20772 // implemented for compatibility.
20773 if (ARM_AM::getT2SOImmVal(~CVal) != -1)
20774 break;
20775 } else {
20776 // A constant whose bitwise inverse can be used as an immediate
20777 // value in a data-processing instruction. This can be used in GCC
20778 // with a "B" modifier that prints the inverted value, for use with
20779 // BIC and MVN instructions. It is not useful otherwise but is
20780 // implemented for compatibility.
20781 if (ARM_AM::getSOImmVal(~CVal) != -1)
20782 break;
20783 }
20784 return;
20785
20786 case 'L':
20787 if (Subtarget->isThumb1Only()) {
20788 // This must be a constant between -7 and 7,
20789 // for 3-operand ADD/SUB immediate instructions.
20790 if (CVal >= -7 && CVal < 7)
20791 break;
20792 } else if (Subtarget->isThumb2()) {
20793 // A constant whose negation can be used as an immediate value in a
20794 // data-processing instruction. This can be used in GCC with an "n"
20795 // modifier that prints the negated value, for use with SUB
20796 // instructions. It is not useful otherwise but is implemented for
20797 // compatibility.
20798 if (ARM_AM::getT2SOImmVal(-CVal) != -1)
20799 break;
20800 } else {
20801 // A constant whose negation can be used as an immediate value in a
20802 // data-processing instruction. This can be used in GCC with an "n"
20803 // modifier that prints the negated value, for use with SUB
20804 // instructions. It is not useful otherwise but is implemented for
20805 // compatibility.
20806 if (ARM_AM::getSOImmVal(-CVal) != -1)
20807 break;
20808 }
20809 return;
20810
20811 case 'M':
20812 if (Subtarget->isThumb1Only()) {
20813 // This must be a multiple of 4 between 0 and 1020, for
20814 // ADD sp + immediate.
20815 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0))
20816 break;
20817 } else {
20818 // A power of two or a constant between 0 and 32. This is used in
20819 // GCC for the shift amount on shifted register operands, but it is
20820 // useful in general for any shift amounts.
20821 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0))
20822 break;
20823 }
20824 return;
20825
20826 case 'N':
20827 if (Subtarget->isThumb1Only()) {
20828 // This must be a constant between 0 and 31, for shift amounts.
20829 if (CVal >= 0 && CVal <= 31)
20830 break;
20831 }
20832 return;
20833
20834 case 'O':
20835 if (Subtarget->isThumb1Only()) {
20836 // This must be a multiple of 4 between -508 and 508, for
20837 // ADD/SUB sp = sp + immediate.
20838 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0))
20839 break;
20840 }
20841 return;
20842 }
20843 Result = DAG.getSignedTargetConstant(CVal, SDLoc(Op), Op.getValueType());
20844 break;
20845 }
20846
20847 if (Result.getNode()) {
20848 Ops.push_back(Result);
20849 return;
20850 }
20851 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
20852}
20853
20854static RTLIB::Libcall getDivRemLibcall(
20855 const SDNode *N, MVT::SimpleValueType SVT) {
20856 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20857 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20858 "Unhandled Opcode in getDivRemLibcall");
20859 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20860 N->getOpcode() == ISD::SREM;
20861 RTLIB::Libcall LC;
20862 switch (SVT) {
20863 default: llvm_unreachable("Unexpected request for libcall!");
20864 case MVT::i8: LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break;
20865 case MVT::i16: LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break;
20866 case MVT::i32: LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break;
20867 case MVT::i64: LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break;
20868 }
20869 return LC;
20870}
20871
20873 const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
20874 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20875 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20876 "Unhandled Opcode in getDivRemArgList");
20877 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20878 N->getOpcode() == ISD::SREM;
20880 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
20881 EVT ArgVT = N->getOperand(i).getValueType();
20882 Type *ArgTy = ArgVT.getTypeForEVT(*Context);
20883 TargetLowering::ArgListEntry Entry(N->getOperand(i), ArgTy);
20884 Entry.IsSExt = isSigned;
20885 Entry.IsZExt = !isSigned;
20886 Args.push_back(Entry);
20887 }
20888 if (Subtarget->getTargetTriple().isOSWindows() && Args.size() >= 2)
20889 std::swap(Args[0], Args[1]);
20890 return Args;
20891}
20892
20893SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
20894 assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
20895 Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
20896 Subtarget->isTargetFuchsia() || Subtarget->isTargetWindows()) &&
20897 "Register-based DivRem lowering only");
20898 unsigned Opcode = Op->getOpcode();
20899 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
20900 "Invalid opcode for Div/Rem lowering");
20901 bool isSigned = (Opcode == ISD::SDIVREM);
20902 EVT VT = Op->getValueType(0);
20903 SDLoc dl(Op);
20904
20905 if (VT == MVT::i64 && isa<ConstantSDNode>(Op.getOperand(1))) {
20907 if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i32, DAG)) {
20908 SDValue Res0 =
20909 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[0], Result[1]);
20910 SDValue Res1 =
20911 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[2], Result[3]);
20912 return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
20913 {Res0, Res1});
20914 }
20915 }
20916
20917 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
20918
20919 // If the target has hardware divide, use divide + multiply + subtract:
20920 // div = a / b
20921 // rem = a - b * div
20922 // return {div, rem}
20923 // This should be lowered into UDIV/SDIV + MLS later on.
20924 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
20925 : Subtarget->hasDivideInARMMode();
20926 if (hasDivide && Op->getValueType(0).isSimple() &&
20927 Op->getSimpleValueType(0) == MVT::i32) {
20928 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
20929 const SDValue Dividend = Op->getOperand(0);
20930 const SDValue Divisor = Op->getOperand(1);
20931 SDValue Div = DAG.getNode(DivOpcode, dl, VT, Dividend, Divisor);
20932 SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Div, Divisor);
20933 SDValue Rem = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
20934
20935 SDValue Values[2] = {Div, Rem};
20936 return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VT, VT), Values);
20937 }
20938
20939 RTLIB::Libcall LC = getDivRemLibcall(Op.getNode(),
20940 VT.getSimpleVT().SimpleTy);
20941 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
20942
20943 SDValue InChain = DAG.getEntryNode();
20944
20946 DAG.getContext(),
20947 Subtarget);
20948
20949 SDValue Callee =
20950 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
20951
20952 Type *RetTy = StructType::get(Ty, Ty);
20953
20954 if (getTM().getTargetTriple().isOSWindows())
20955 InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
20956
20957 TargetLowering::CallLoweringInfo CLI(DAG);
20958 CLI.setDebugLoc(dl)
20959 .setChain(InChain)
20960 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
20961 Callee, std::move(Args))
20962 .setInRegister()
20965
20966 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
20967 return CallInfo.first;
20968}
20969
20970// Lowers REM using divmod helpers
20971// see RTABI section 4.2/4.3
20972SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
20973 EVT VT = N->getValueType(0);
20974
20975 if (VT == MVT::i64 && isa<ConstantSDNode>(N->getOperand(1))) {
20977 if (expandDIVREMByConstant(N, Result, MVT::i32, DAG))
20978 return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), N->getValueType(0),
20979 Result[0], Result[1]);
20980 }
20981
20982 // Build return types (div and rem)
20983 std::vector<Type*> RetTyParams;
20984 Type *RetTyElement;
20985
20986 switch (VT.getSimpleVT().SimpleTy) {
20987 default: llvm_unreachable("Unexpected request for libcall!");
20988 case MVT::i8: RetTyElement = Type::getInt8Ty(*DAG.getContext()); break;
20989 case MVT::i16: RetTyElement = Type::getInt16Ty(*DAG.getContext()); break;
20990 case MVT::i32: RetTyElement = Type::getInt32Ty(*DAG.getContext()); break;
20991 case MVT::i64: RetTyElement = Type::getInt64Ty(*DAG.getContext()); break;
20992 }
20993
20994 RetTyParams.push_back(RetTyElement);
20995 RetTyParams.push_back(RetTyElement);
20996 ArrayRef<Type*> ret = ArrayRef<Type*>(RetTyParams);
20997 Type *RetTy = StructType::get(*DAG.getContext(), ret);
20998
20999 RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
21000 SimpleTy);
21001 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21002 SDValue InChain = DAG.getEntryNode();
21004 Subtarget);
21005 bool isSigned = N->getOpcode() == ISD::SREM;
21006
21007 SDValue Callee =
21008 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21009
21010 if (getTM().getTargetTriple().isOSWindows())
21011 InChain = WinDBZCheckDenominator(DAG, N, InChain);
21012
21013 // Lower call
21014 CallLoweringInfo CLI(DAG);
21015 CLI.setChain(InChain)
21016 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21017 Callee, std::move(Args))
21020 .setDebugLoc(SDLoc(N));
21021 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
21022
21023 // Return second (rem) result operand (first contains div)
21024 SDNode *ResNode = CallResult.first.getNode();
21025 assert(ResNode->getNumOperands() == 2 && "divmod should return two operands");
21026 return ResNode->getOperand(1);
21027}
21028
21029SDValue
21030ARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
21031 assert(getTM().getTargetTriple().isOSWindows() &&
21032 "unsupported target platform");
21033 SDLoc DL(Op);
21034
21035 // Get the inputs.
21036 SDValue Chain = Op.getOperand(0);
21037 SDValue Size = Op.getOperand(1);
21038
21040 "no-stack-arg-probe")) {
21041 MaybeAlign Align =
21042 cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
21043 SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21044 Chain = SP.getValue(1);
21045 SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
21046 if (Align)
21047 SP = DAG.getNode(ISD::AND, DL, MVT::i32, SP.getValue(0),
21048 DAG.getSignedConstant(-Align->value(), DL, MVT::i32));
21049 Chain = DAG.getCopyToReg(Chain, DL, ARM::SP, SP);
21050 SDValue Ops[2] = { SP, Chain };
21051 return DAG.getMergeValues(Ops, DL);
21052 }
21053
21054 SDValue Words = DAG.getNode(ISD::SRL, DL, MVT::i32, Size,
21055 DAG.getConstant(2, DL, MVT::i32));
21056
21057 SDValue Glue;
21058 Chain = DAG.getCopyToReg(Chain, DL, ARM::R4, Words, Glue);
21059 Glue = Chain.getValue(1);
21060
21061 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
21062 Chain = DAG.getNode(ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Glue);
21063
21064 SDValue NewSP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21065 Chain = NewSP.getValue(1);
21066
21067 SDValue Ops[2] = { NewSP, Chain };
21068 return DAG.getMergeValues(Ops, DL);
21069}
21070
21071SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
21072 bool IsStrict = Op->isStrictFPOpcode();
21073 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21074 const unsigned DstSz = Op.getValueType().getSizeInBits();
21075 const unsigned SrcSz = SrcVal.getValueType().getSizeInBits();
21076 assert(DstSz > SrcSz && DstSz <= 64 && SrcSz >= 16 &&
21077 "Unexpected type for custom-lowering FP_EXTEND");
21078
21079 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21080 "With both FP DP and 16, any FP conversion is legal!");
21081
21082 assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
21083 "With FP16, 16 to 32 conversion is legal!");
21084
21085 // Converting from 32 -> 64 is valid if we have FP64.
21086 if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
21087 // FIXME: Remove this when we have strict fp instruction selection patterns
21088 if (IsStrict) {
21089 SDLoc Loc(Op);
21091 Loc, Op.getValueType(), SrcVal);
21092 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
21093 }
21094 return Op;
21095 }
21096
21097 // Either we are converting from 16 -> 64, without FP16 and/or
21098 // FP.double-precision or without Armv8-fp. So we must do it in two
21099 // steps.
21100 // Or we are converting from 32 -> 64 without fp.double-precision or 16 -> 32
21101 // without FP16. So we must do a function call.
21102 SDLoc Loc(Op);
21103 RTLIB::Libcall LC;
21104 MakeLibCallOptions CallOptions;
21105 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21106 for (unsigned Sz = SrcSz; Sz <= 32 && Sz < DstSz; Sz *= 2) {
21107 bool Supported = (Sz == 16 ? Subtarget->hasFP16() : Subtarget->hasFP64());
21108 MVT SrcVT = (Sz == 16 ? MVT::f16 : MVT::f32);
21109 MVT DstVT = (Sz == 16 ? MVT::f32 : MVT::f64);
21110 if (Supported) {
21111 if (IsStrict) {
21112 SrcVal = DAG.getNode(ISD::STRICT_FP_EXTEND, Loc,
21113 {DstVT, MVT::Other}, {Chain, SrcVal});
21114 Chain = SrcVal.getValue(1);
21115 } else {
21116 SrcVal = DAG.getNode(ISD::FP_EXTEND, Loc, DstVT, SrcVal);
21117 }
21118 } else {
21119 LC = RTLIB::getFPEXT(SrcVT, DstVT);
21120 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21121 "Unexpected type for custom-lowering FP_EXTEND");
21122 std::tie(SrcVal, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21123 Loc, Chain);
21124 }
21125 }
21126
21127 return IsStrict ? DAG.getMergeValues({SrcVal, Chain}, Loc) : SrcVal;
21128}
21129
21130SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
21131 bool IsStrict = Op->isStrictFPOpcode();
21132
21133 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21134 EVT SrcVT = SrcVal.getValueType();
21135 EVT DstVT = Op.getValueType();
21136
21137 if (DstVT == MVT::bf16) {
21138 if (Subtarget->hasBF16() && SrcVT == MVT::f32)
21139 return Op;
21140 return SDValue();
21141 }
21142
21143 const unsigned DstSz = Op.getValueType().getSizeInBits();
21144 const unsigned SrcSz = SrcVT.getSizeInBits();
21145 (void)DstSz;
21146 assert(DstSz < SrcSz && SrcSz <= 64 && DstSz >= 16 &&
21147 "Unexpected type for custom-lowering FP_ROUND");
21148
21149 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21150 "With both FP DP and 16, any FP conversion is legal!");
21151
21152 SDLoc Loc(Op);
21153
21154 // Instruction from 32 -> 16 if hasFP16 is valid
21155 if (SrcSz == 32 && Subtarget->hasFP16())
21156 return Op;
21157
21158 // Lib call from 32 -> 16 / 64 -> [32, 16]
21159 RTLIB::Libcall LC = RTLIB::getFPROUND(SrcVT, DstVT);
21160 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21161 "Unexpected type for custom-lowering FP_ROUND");
21162 MakeLibCallOptions CallOptions;
21163 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21165 std::tie(Result, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21166 Loc, Chain);
21167 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
21168}
21169
21170bool
21172 // The ARM target isn't yet aware of offsets.
21173 return false;
21174}
21175
21177 if (v == 0xffffffff)
21178 return false;
21179
21180 // there can be 1's on either or both "outsides", all the "inside"
21181 // bits must be 0's
21182 return isShiftedMask_32(~v);
21183}
21184
21185/// isFPImmLegal - Returns true if the target can instruction select the
21186/// specified FP immediate natively. If false, the legalizer will
21187/// materialize the FP immediate as a load from a constant pool.
21189 bool ForCodeSize) const {
21190 if (!Subtarget->hasVFP3Base())
21191 return false;
21192 if (VT == MVT::f16 && Subtarget->hasFullFP16())
21193 return ARM_AM::getFP16Imm(Imm) != -1;
21194 if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
21195 ARM_AM::getFP32FP16Imm(Imm) != -1)
21196 return true;
21197 if (VT == MVT::f32)
21198 return ARM_AM::getFP32Imm(Imm) != -1;
21199 if (VT == MVT::f64 && Subtarget->hasFP64())
21200 return ARM_AM::getFP64Imm(Imm) != -1;
21201 return false;
21202}
21203
21204/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
21205/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
21206/// specified in the intrinsic calls.
21209 MachineFunction &MF, unsigned Intrinsic) const {
21210 IntrinsicInfo Info;
21211 switch (Intrinsic) {
21212 case Intrinsic::arm_neon_vld1:
21213 case Intrinsic::arm_neon_vld2:
21214 case Intrinsic::arm_neon_vld3:
21215 case Intrinsic::arm_neon_vld4:
21216 case Intrinsic::arm_neon_vld2lane:
21217 case Intrinsic::arm_neon_vld3lane:
21218 case Intrinsic::arm_neon_vld4lane:
21219 case Intrinsic::arm_neon_vld2dup:
21220 case Intrinsic::arm_neon_vld3dup:
21221 case Intrinsic::arm_neon_vld4dup: {
21222 Info.opc = ISD::INTRINSIC_W_CHAIN;
21223 // Conservatively set memVT to the entire set of vectors loaded.
21224 auto &DL = I.getDataLayout();
21225 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21226 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21227 Info.ptrVal = I.getArgOperand(0);
21228 Info.offset = 0;
21229 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21230 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21231 // volatile loads with NEON intrinsics not supported
21232 Info.flags = MachineMemOperand::MOLoad;
21233 Infos.push_back(Info);
21234 return;
21235 }
21236 case Intrinsic::arm_neon_vld1x2:
21237 case Intrinsic::arm_neon_vld1x3:
21238 case Intrinsic::arm_neon_vld1x4: {
21239 Info.opc = ISD::INTRINSIC_W_CHAIN;
21240 // Conservatively set memVT to the entire set of vectors loaded.
21241 auto &DL = I.getDataLayout();
21242 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21243 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21244 Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
21245 Info.offset = 0;
21246 Info.align = I.getParamAlign(I.arg_size() - 1).valueOrOne();
21247 // volatile loads with NEON intrinsics not supported
21248 Info.flags = MachineMemOperand::MOLoad;
21249 Infos.push_back(Info);
21250 return;
21251 }
21252 case Intrinsic::arm_neon_vst1:
21253 case Intrinsic::arm_neon_vst2:
21254 case Intrinsic::arm_neon_vst3:
21255 case Intrinsic::arm_neon_vst4:
21256 case Intrinsic::arm_neon_vst2lane:
21257 case Intrinsic::arm_neon_vst3lane:
21258 case Intrinsic::arm_neon_vst4lane: {
21259 Info.opc = ISD::INTRINSIC_VOID;
21260 // Conservatively set memVT to the entire set of vectors stored.
21261 auto &DL = I.getDataLayout();
21262 unsigned NumElts = 0;
21263 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21264 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21265 if (!ArgTy->isVectorTy())
21266 break;
21267 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21268 }
21269 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21270 Info.ptrVal = I.getArgOperand(0);
21271 Info.offset = 0;
21272 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21273 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21274 // volatile stores with NEON intrinsics not supported
21275 Info.flags = MachineMemOperand::MOStore;
21276 Infos.push_back(Info);
21277 return;
21278 }
21279 case Intrinsic::arm_neon_vst1x2:
21280 case Intrinsic::arm_neon_vst1x3:
21281 case Intrinsic::arm_neon_vst1x4: {
21282 Info.opc = ISD::INTRINSIC_VOID;
21283 // Conservatively set memVT to the entire set of vectors stored.
21284 auto &DL = I.getDataLayout();
21285 unsigned NumElts = 0;
21286 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21287 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21288 if (!ArgTy->isVectorTy())
21289 break;
21290 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21291 }
21292 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21293 Info.ptrVal = I.getArgOperand(0);
21294 Info.offset = 0;
21295 Info.align = I.getParamAlign(0).valueOrOne();
21296 // volatile stores with NEON intrinsics not supported
21297 Info.flags = MachineMemOperand::MOStore;
21298 Infos.push_back(Info);
21299 return;
21300 }
21301 case Intrinsic::arm_mve_vld2q:
21302 case Intrinsic::arm_mve_vld4q: {
21303 Info.opc = ISD::INTRINSIC_W_CHAIN;
21304 // Conservatively set memVT to the entire set of vectors loaded.
21305 Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
21306 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
21307 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21308 Info.ptrVal = I.getArgOperand(0);
21309 Info.offset = 0;
21310 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21311 // volatile loads with MVE intrinsics not supported
21312 Info.flags = MachineMemOperand::MOLoad;
21313 Infos.push_back(Info);
21314 return;
21315 }
21316 case Intrinsic::arm_mve_vst2q:
21317 case Intrinsic::arm_mve_vst4q: {
21318 Info.opc = ISD::INTRINSIC_VOID;
21319 // Conservatively set memVT to the entire set of vectors stored.
21320 Type *VecTy = I.getArgOperand(1)->getType();
21321 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vst2q ? 2 : 4;
21322 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21323 Info.ptrVal = I.getArgOperand(0);
21324 Info.offset = 0;
21325 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21326 // volatile stores with MVE intrinsics not supported
21327 Info.flags = MachineMemOperand::MOStore;
21328 Infos.push_back(Info);
21329 return;
21330 }
21331 case Intrinsic::arm_mve_vldr_gather_base:
21332 case Intrinsic::arm_mve_vldr_gather_base_predicated: {
21333 Info.opc = ISD::INTRINSIC_W_CHAIN;
21334 Info.ptrVal = nullptr;
21335 Info.memVT = MVT::getVT(I.getType());
21336 Info.align = Align(1);
21337 Info.flags |= MachineMemOperand::MOLoad;
21338 Infos.push_back(Info);
21339 return;
21340 }
21341 case Intrinsic::arm_mve_vldr_gather_base_wb:
21342 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: {
21343 Info.opc = ISD::INTRINSIC_W_CHAIN;
21344 Info.ptrVal = nullptr;
21345 Info.memVT = MVT::getVT(I.getType()->getContainedType(0));
21346 Info.align = Align(1);
21347 Info.flags |= MachineMemOperand::MOLoad;
21348 Infos.push_back(Info);
21349 return;
21350 }
21351 case Intrinsic::arm_mve_vldr_gather_offset:
21352 case Intrinsic::arm_mve_vldr_gather_offset_predicated: {
21353 Info.opc = ISD::INTRINSIC_W_CHAIN;
21354 Info.ptrVal = nullptr;
21355 MVT DataVT = MVT::getVT(I.getType());
21356 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
21357 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21358 DataVT.getVectorNumElements());
21359 Info.align = Align(1);
21360 Info.flags |= MachineMemOperand::MOLoad;
21361 Infos.push_back(Info);
21362 return;
21363 }
21364 case Intrinsic::arm_mve_vstr_scatter_base:
21365 case Intrinsic::arm_mve_vstr_scatter_base_predicated: {
21366 Info.opc = ISD::INTRINSIC_VOID;
21367 Info.ptrVal = nullptr;
21368 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21369 Info.align = Align(1);
21370 Info.flags |= MachineMemOperand::MOStore;
21371 Infos.push_back(Info);
21372 return;
21373 }
21374 case Intrinsic::arm_mve_vstr_scatter_base_wb:
21375 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated: {
21376 Info.opc = ISD::INTRINSIC_W_CHAIN;
21377 Info.ptrVal = nullptr;
21378 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21379 Info.align = Align(1);
21380 Info.flags |= MachineMemOperand::MOStore;
21381 Infos.push_back(Info);
21382 return;
21383 }
21384 case Intrinsic::arm_mve_vstr_scatter_offset:
21385 case Intrinsic::arm_mve_vstr_scatter_offset_predicated: {
21386 Info.opc = ISD::INTRINSIC_VOID;
21387 Info.ptrVal = nullptr;
21388 MVT DataVT = MVT::getVT(I.getArgOperand(2)->getType());
21389 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
21390 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21391 DataVT.getVectorNumElements());
21392 Info.align = Align(1);
21393 Info.flags |= MachineMemOperand::MOStore;
21394 Infos.push_back(Info);
21395 return;
21396 }
21397 case Intrinsic::arm_ldaex:
21398 case Intrinsic::arm_ldrex: {
21399 auto &DL = I.getDataLayout();
21400 Type *ValTy = I.getParamElementType(0);
21401 Info.opc = ISD::INTRINSIC_W_CHAIN;
21402 Info.memVT = MVT::getVT(ValTy);
21403 Info.ptrVal = I.getArgOperand(0);
21404 Info.offset = 0;
21405 Info.align = DL.getABITypeAlign(ValTy);
21407 Infos.push_back(Info);
21408 return;
21409 }
21410 case Intrinsic::arm_stlex:
21411 case Intrinsic::arm_strex: {
21412 auto &DL = I.getDataLayout();
21413 Type *ValTy = I.getParamElementType(1);
21414 Info.opc = ISD::INTRINSIC_W_CHAIN;
21415 Info.memVT = MVT::getVT(ValTy);
21416 Info.ptrVal = I.getArgOperand(1);
21417 Info.offset = 0;
21418 Info.align = DL.getABITypeAlign(ValTy);
21420 Infos.push_back(Info);
21421 return;
21422 }
21423 case Intrinsic::arm_stlexd:
21424 case Intrinsic::arm_strexd:
21425 Info.opc = ISD::INTRINSIC_W_CHAIN;
21426 Info.memVT = MVT::i64;
21427 Info.ptrVal = I.getArgOperand(2);
21428 Info.offset = 0;
21429 Info.align = Align(8);
21431 Infos.push_back(Info);
21432 return;
21433
21434 case Intrinsic::arm_ldaexd:
21435 case Intrinsic::arm_ldrexd:
21436 Info.opc = ISD::INTRINSIC_W_CHAIN;
21437 Info.memVT = MVT::i64;
21438 Info.ptrVal = I.getArgOperand(0);
21439 Info.offset = 0;
21440 Info.align = Align(8);
21442 Infos.push_back(Info);
21443 return;
21444
21445 default:
21446 break;
21447 }
21448}
21449
21450/// Returns true if it is beneficial to convert a load of a constant
21451/// to just the constant itself.
21453 Type *Ty) const {
21454 assert(Ty->isIntegerTy());
21455
21456 unsigned Bits = Ty->getPrimitiveSizeInBits();
21457 if (Bits == 0 || Bits > 32)
21458 return false;
21459 return true;
21460}
21461
21463 unsigned Index) const {
21465 return false;
21466
21467 return (Index == 0 || Index == ResVT.getVectorNumElements());
21468}
21469
21471 ARM_MB::MemBOpt Domain) const {
21472 // First, if the target has no DMB, see what fallback we can use.
21473 if (!Subtarget->hasDataBarrier()) {
21474 // Some ARMv6 cpus can support data barriers with an mcr instruction.
21475 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
21476 // here.
21477 if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
21478 Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
21479 Builder.getInt32(0), Builder.getInt32(7),
21480 Builder.getInt32(10), Builder.getInt32(5)};
21481 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_mcr, args);
21482 }
21483 // Instead of using barriers, atomic accesses on these subtargets use
21484 // libcalls.
21485 llvm_unreachable("makeDMB on a target so old that it has no barriers");
21486 } else {
21487 // Only a full system barrier exists in the M-class architectures.
21488 Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
21489 Constant *CDomain = Builder.getInt32(Domain);
21490 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_dmb, CDomain);
21491 }
21492}
21493
21494// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
21496 Instruction *Inst,
21497 AtomicOrdering Ord) const {
21498 switch (Ord) {
21501 llvm_unreachable("Invalid fence: unordered/non-atomic");
21504 return nullptr; // Nothing to do
21506 if (!Inst->hasAtomicStore())
21507 return nullptr; // Nothing to do
21508 [[fallthrough]];
21511 if (Subtarget->preferISHSTBarriers())
21512 return makeDMB(Builder, ARM_MB::ISHST);
21513 // FIXME: add a comment with a link to documentation justifying this.
21514 else
21515 return makeDMB(Builder, ARM_MB::ISH);
21516 }
21517 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
21518}
21519
21521 Instruction *Inst,
21522 AtomicOrdering Ord) const {
21523 switch (Ord) {
21526 llvm_unreachable("Invalid fence: unordered/not-atomic");
21529 return nullptr; // Nothing to do
21533 return makeDMB(Builder, ARM_MB::ISH);
21534 }
21535 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
21536}
21537
21538// Loads and stores less than 64-bits are already atomic; ones above that
21539// are doomed anyway, so defer to the default libcall and blame the OS when
21540// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21541// anything for those.
21544 bool has64BitAtomicStore;
21545 if (Subtarget->isMClass())
21546 has64BitAtomicStore = false;
21547 else if (Subtarget->isThumb())
21548 has64BitAtomicStore = Subtarget->hasV7Ops();
21549 else
21550 has64BitAtomicStore = Subtarget->hasV6Ops();
21551
21552 unsigned Size = SI->getValueOperand()->getType()->getPrimitiveSizeInBits();
21553 return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind::Expand
21555}
21556
21557// Loads and stores less than 64-bits are already atomic; ones above that
21558// are doomed anyway, so defer to the default libcall and blame the OS when
21559// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21560// anything for those.
21561// FIXME: ldrd and strd are atomic if the CPU has LPAE (e.g. A15 has that
21562// guarantee, see DDI0406C ARM architecture reference manual,
21563// sections A8.8.72-74 LDRD)
21566 bool has64BitAtomicLoad;
21567 if (Subtarget->isMClass())
21568 has64BitAtomicLoad = false;
21569 else if (Subtarget->isThumb())
21570 has64BitAtomicLoad = Subtarget->hasV7Ops();
21571 else
21572 has64BitAtomicLoad = Subtarget->hasV6Ops();
21573
21574 unsigned Size = LI->getType()->getPrimitiveSizeInBits();
21575 return (Size == 64 && has64BitAtomicLoad) ? AtomicExpansionKind::LLOnly
21577}
21578
21579// For the real atomic operations, we have ldrex/strex up to 32 bits,
21580// and up to 64 bits on the non-M profiles
21583 if (AI->isFloatingPointOperation())
21585
21586 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
21587 bool hasAtomicRMW;
21588 if (Subtarget->isMClass())
21589 hasAtomicRMW = Subtarget->hasV8MBaselineOps();
21590 else if (Subtarget->isThumb())
21591 hasAtomicRMW = Subtarget->hasV7Ops();
21592 else
21593 hasAtomicRMW = Subtarget->hasV6Ops();
21594 if (Size <= (Subtarget->isMClass() ? 32U : 64U) && hasAtomicRMW) {
21595 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21596 // implement atomicrmw without spilling. If the target address is also on
21597 // the stack and close enough to the spill slot, this can lead to a
21598 // situation where the monitor always gets cleared and the atomic operation
21599 // can never succeed. So at -O0 lower this operation to a CAS loop.
21600 if (getTargetMachine().getOptLevel() == CodeGenOptLevel::None)
21603 }
21605}
21606
21607// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
21608// bits, and up to 64 bits on the non-M profiles.
21611 const AtomicCmpXchgInst *AI) const {
21612 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21613 // implement cmpxchg without spilling. If the address being exchanged is also
21614 // on the stack and close enough to the spill slot, this can lead to a
21615 // situation where the monitor always gets cleared and the atomic operation
21616 // can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
21617 unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
21618 bool HasAtomicCmpXchg;
21619 if (Subtarget->isMClass())
21620 HasAtomicCmpXchg = Subtarget->hasV8MBaselineOps();
21621 else if (Subtarget->isThumb())
21622 HasAtomicCmpXchg = Subtarget->hasV7Ops();
21623 else
21624 HasAtomicCmpXchg = Subtarget->hasV6Ops();
21625 if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None &&
21626 HasAtomicCmpXchg && Size <= (Subtarget->isMClass() ? 32U : 64U))
21629}
21630
21632 const Instruction *I) const {
21633 return InsertFencesForAtomic;
21634}
21635
21637 // ROPI/RWPI are not supported currently.
21638 return !Subtarget->isROPI() && !Subtarget->isRWPI();
21639}
21640
21642 Module &M, const LibcallLoweringInfo &Libcalls) const {
21643 // MSVC CRT provides functionalities for stack protection.
21644 RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21645 Libcalls.getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21646
21647 RTLIB::LibcallImpl SecurityCookieVar =
21648 Libcalls.getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
21649 if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
21650 SecurityCookieVar != RTLIB::Unsupported) {
21651 // MSVC CRT has a global variable holding security cookie.
21652 M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
21653 PointerType::getUnqual(M.getContext()));
21654
21655 // MSVC CRT has a function to validate security cookie.
21656 FunctionCallee SecurityCheckCookie =
21657 M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall),
21658 Type::getVoidTy(M.getContext()),
21659 PointerType::getUnqual(M.getContext()));
21660 if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee()))
21661 F->addParamAttr(0, Attribute::AttrKind::InReg);
21662 }
21663
21665}
21666
21668 unsigned &Cost) const {
21669 // If we do not have NEON, vector types are not natively supported.
21670 if (!Subtarget->hasNEON())
21671 return false;
21672
21673 // Floating point values and vector values map to the same register file.
21674 // Therefore, although we could do a store extract of a vector type, this is
21675 // better to leave at float as we have more freedom in the addressing mode for
21676 // those.
21677 if (VectorTy->isFPOrFPVectorTy())
21678 return false;
21679
21680 // If the index is unknown at compile time, this is very expensive to lower
21681 // and it is not possible to combine the store with the extract.
21682 if (!isa<ConstantInt>(Idx))
21683 return false;
21684
21685 assert(VectorTy->isVectorTy() && "VectorTy is not a vector type");
21686 unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
21687 // We can do a store + vector extract on any vector that fits perfectly in a D
21688 // or Q register.
21689 if (BitWidth == 64 || BitWidth == 128) {
21690 Cost = 0;
21691 return true;
21692 }
21693 return false;
21694}
21695
21697 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
21698 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
21699 unsigned Opcode = Op.getOpcode();
21700 switch (Opcode) {
21701 case ARMISD::VORRIMM:
21702 case ARMISD::VBICIMM:
21703 return false;
21704 }
21706 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
21707}
21708
21710 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21711}
21712
21714 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21715}
21716
21718 const Instruction &AndI) const {
21719 if (!Subtarget->hasV7Ops())
21720 return false;
21721
21722 // Sink the `and` instruction only if the mask would fit into a modified
21723 // immediate operand.
21725 if (!Mask || Mask->getValue().getBitWidth() > 32u)
21726 return false;
21727 auto MaskVal = unsigned(Mask->getValue().getZExtValue());
21728 return (Subtarget->isThumb2() ? ARM_AM::getT2SOImmVal(MaskVal)
21729 : ARM_AM::getSOImmVal(MaskVal)) != -1;
21730}
21731
21734 SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const {
21735 if (Subtarget->hasMinSize() && !getTM().getTargetTriple().isOSWindows())
21738 ExpansionFactor);
21739}
21740
21742 Value *Addr,
21743 AtomicOrdering Ord) const {
21744 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21745 bool IsAcquire = isAcquireOrStronger(Ord);
21746
21747 // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd
21748 // intrinsic must return {i32, i32} and we have to recombine them into a
21749 // single i64 here.
21750 if (ValueTy->getPrimitiveSizeInBits() == 64) {
21752 IsAcquire ? Intrinsic::arm_ldaexd : Intrinsic::arm_ldrexd;
21753
21754 Value *LoHi =
21755 Builder.CreateIntrinsic(Int, Addr, /*FMFSource=*/nullptr, "lohi");
21756
21757 Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
21758 Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
21759 if (!Subtarget->isLittle())
21760 std::swap (Lo, Hi);
21761 Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
21762 Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
21763 return Builder.CreateOr(
21764 Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 32)), "val64");
21765 }
21766
21767 Type *Tys[] = { Addr->getType() };
21768 Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex;
21769 CallInst *CI = Builder.CreateIntrinsicWithoutFolding(Int, Tys, Addr);
21770
21771 CI->addParamAttr(
21772 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy));
21773 return Builder.CreateTruncOrBitCast(CI, ValueTy);
21774}
21775
21777 IRBuilderBase &Builder) const {
21778 if (!Subtarget->hasV7Ops())
21779 return;
21780 Builder.CreateIntrinsic(Intrinsic::arm_clrex, {});
21781}
21782
21784 Value *Val, Value *Addr,
21785 AtomicOrdering Ord) const {
21786 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21787 bool IsRelease = isReleaseOrStronger(Ord);
21788
21789 // Since the intrinsics must have legal type, the i64 intrinsics take two
21790 // parameters: "i32, i32". We must marshal Val into the appropriate form
21791 // before the call.
21792 if (Val->getType()->getPrimitiveSizeInBits() == 64) {
21794 IsRelease ? Intrinsic::arm_stlexd : Intrinsic::arm_strexd;
21795 Type *Int32Ty = Type::getInt32Ty(M->getContext());
21796
21797 Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
21798 Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
21799 if (!Subtarget->isLittle())
21800 std::swap(Lo, Hi);
21801 return Builder.CreateIntrinsic(Int, {Lo, Hi, Addr});
21802 }
21803
21804 Intrinsic::ID Int = IsRelease ? Intrinsic::arm_stlex : Intrinsic::arm_strex;
21805 Type *Tys[] = { Addr->getType() };
21807
21808 CallInst *CI = Builder.CreateCall(
21809 Strex, {Builder.CreateZExtOrBitCast(
21810 Val, Strex->getFunctionType()->getParamType(0)),
21811 Addr});
21812 CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType,
21813 Val->getType()));
21814 return CI;
21815}
21816
21817
21819 return Subtarget->isMClass();
21820}
21821
21822/// A helper function for determining the number of interleaved accesses we
21823/// will generate when lowering accesses of the given type.
21824unsigned
21826 const DataLayout &DL) const {
21827 return (DL.getTypeSizeInBits(VecTy) + 127) / 128;
21828}
21829
21831 unsigned Factor, FixedVectorType *VecTy, Align Alignment,
21832 const DataLayout &DL) const {
21833
21834 unsigned VecSize = DL.getTypeSizeInBits(VecTy);
21835 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
21836
21837 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
21838 return false;
21839
21840 // Ensure the vector doesn't have f16 elements. Even though we could do an
21841 // i16 vldN, we can't hold the f16 vectors and will end up converting via
21842 // f32.
21843 if (Subtarget->hasNEON() && VecTy->getElementType()->isHalfTy())
21844 return false;
21845 if (Subtarget->hasMVEIntegerOps() && Factor == 3)
21846 return false;
21847
21848 // Ensure the number of vector elements is greater than 1.
21849 if (VecTy->getNumElements() < 2)
21850 return false;
21851
21852 // Ensure the element type is legal.
21853 if (ElSize != 8 && ElSize != 16 && ElSize != 32)
21854 return false;
21855 // And the alignment if high enough under MVE.
21856 if (Subtarget->hasMVEIntegerOps() && Alignment < ElSize / 8)
21857 return false;
21858
21859 // Ensure the total vector size is 64 or a multiple of 128. Types larger than
21860 // 128 will be split into multiple interleaved accesses.
21861 if (Subtarget->hasNEON() && VecSize == 64)
21862 return true;
21863 return VecSize % 128 == 0;
21864}
21865
21867 if (Subtarget->hasNEON())
21868 return 4;
21869 if (Subtarget->hasMVEIntegerOps())
21872}
21873
21874/// Lower an interleaved load into a vldN intrinsic.
21875///
21876/// E.g. Lower an interleaved load (Factor = 2):
21877/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr, align 4
21878/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
21879/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
21880///
21881/// Into:
21882/// %vld2 = { <4 x i32>, <4 x i32> } call llvm.arm.neon.vld2(%ptr, 4)
21883/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 0
21884/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 1
21886 Instruction *Load, Value *Mask, ArrayRef<ShuffleVectorInst *> Shuffles,
21887 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
21888 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
21889 "Invalid interleave factor");
21890 assert(!Shuffles.empty() && "Empty shufflevector input");
21891 assert(Shuffles.size() == Indices.size() &&
21892 "Unmatched number of shufflevectors and indices");
21893
21894 auto *LI = dyn_cast<LoadInst>(Load);
21895 if (!LI)
21896 return false;
21897 assert(!Mask && GapMask.popcount() == Factor && "Unexpected mask on a load");
21898
21899 auto *VecTy = cast<FixedVectorType>(Shuffles[0]->getType());
21900 Type *EltTy = VecTy->getElementType();
21901
21902 const DataLayout &DL = LI->getDataLayout();
21903 Align Alignment = LI->getAlign();
21904
21905 // Skip if we do not have NEON and skip illegal vector types. We can
21906 // "legalize" wide vector types into multiple interleaved accesses as long as
21907 // the vector types are divisible by 128.
21908 if (!isLegalInterleavedAccessType(Factor, VecTy, Alignment, DL))
21909 return false;
21910
21911 unsigned NumLoads = getNumInterleavedAccesses(VecTy, DL);
21912
21913 // A pointer vector can not be the return type of the ldN intrinsics. Need to
21914 // load integer vectors first and then convert to pointer vectors.
21915 if (EltTy->isPointerTy())
21916 VecTy = FixedVectorType::get(DL.getIntPtrType(EltTy), VecTy);
21917
21918 IRBuilder<> Builder(LI);
21919
21920 // The base address of the load.
21921 Value *BaseAddr = LI->getPointerOperand();
21922
21923 if (NumLoads > 1) {
21924 // If we're going to generate more than one load, reset the sub-vector type
21925 // to something legal.
21926 VecTy = FixedVectorType::get(VecTy->getElementType(),
21927 VecTy->getNumElements() / NumLoads);
21928 }
21929
21930 assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!");
21931
21932 auto createLoadIntrinsic = [&](Value *BaseAddr) {
21933 if (Subtarget->hasNEON()) {
21934 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21935 Type *Tys[] = {VecTy, PtrTy};
21936 static const Intrinsic::ID LoadInts[3] = {Intrinsic::arm_neon_vld2,
21937 Intrinsic::arm_neon_vld3,
21938 Intrinsic::arm_neon_vld4};
21939
21941 Ops.push_back(BaseAddr);
21942 Ops.push_back(Builder.getInt32(LI->getAlign().value()));
21943
21944 return Builder.CreateIntrinsic(LoadInts[Factor - 2], Tys, Ops,
21945 /*FMFSource=*/nullptr, "vldN");
21946 } else {
21947 assert((Factor == 2 || Factor == 4) &&
21948 "expected interleave factor of 2 or 4 for MVE");
21949 Intrinsic::ID LoadInts =
21950 Factor == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
21951 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21952 Type *Tys[] = {VecTy, PtrTy};
21953
21955 Ops.push_back(BaseAddr);
21956 return Builder.CreateIntrinsic(LoadInts, Tys, Ops, /*FMFSource=*/nullptr,
21957 "vldN");
21958 }
21959 };
21960
21961 // Holds sub-vectors extracted from the load intrinsic return values. The
21962 // sub-vectors are associated with the shufflevector instructions they will
21963 // replace.
21965
21966 for (unsigned LoadCount = 0; LoadCount < NumLoads; ++LoadCount) {
21967 // If we're generating more than one load, compute the base address of
21968 // subsequent loads as an offset from the previous.
21969 if (LoadCount > 0)
21970 BaseAddr = Builder.CreateConstGEP1_32(VecTy->getElementType(), BaseAddr,
21971 VecTy->getNumElements() * Factor);
21972
21973 Value *VldN = createLoadIntrinsic(BaseAddr);
21974
21975 // Replace uses of each shufflevector with the corresponding vector loaded
21976 // by ldN.
21977 for (unsigned i = 0; i < Shuffles.size(); i++) {
21978 ShuffleVectorInst *SV = Shuffles[i];
21979 unsigned Index = Indices[i];
21980
21981 Value *SubVec = Builder.CreateExtractValue(VldN, Index);
21982
21983 // Convert the integer vector to pointer vector if the element is pointer.
21984 if (EltTy->isPointerTy())
21985 SubVec = Builder.CreateIntToPtr(
21986 SubVec,
21988
21989 SubVecs[SV].push_back(SubVec);
21990 }
21991 }
21992
21993 // Replace uses of the shufflevector instructions with the sub-vectors
21994 // returned by the load intrinsic. If a shufflevector instruction is
21995 // associated with more than one sub-vector, those sub-vectors will be
21996 // concatenated into a single wide vector.
21997 for (ShuffleVectorInst *SVI : Shuffles) {
21998 auto &SubVec = SubVecs[SVI];
21999 auto *WideVec =
22000 SubVec.size() > 1 ? concatenateVectors(Builder, SubVec) : SubVec[0];
22001 SVI->replaceAllUsesWith(WideVec);
22002 }
22003
22004 return true;
22005}
22006
22007/// Lower an interleaved store into a vstN intrinsic.
22008///
22009/// E.g. Lower an interleaved store (Factor = 3):
22010/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
22011/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
22012/// store <12 x i32> %i.vec, <12 x i32>* %ptr, align 4
22013///
22014/// Into:
22015/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
22016/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
22017/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
22018/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22019///
22020/// Note that the new shufflevectors will be removed and we'll only generate one
22021/// vst3 instruction in CodeGen.
22022///
22023/// Example for a more general valid mask (Factor 3). Lower:
22024/// %i.vec = shuffle <32 x i32> %v0, <32 x i32> %v1,
22025/// <4, 32, 16, 5, 33, 17, 6, 34, 18, 7, 35, 19>
22026/// store <12 x i32> %i.vec, <12 x i32>* %ptr
22027///
22028/// Into:
22029/// %sub.v0 = shuffle <32 x i32> %v0, <32 x i32> v1, <4, 5, 6, 7>
22030/// %sub.v1 = shuffle <32 x i32> %v0, <32 x i32> v1, <32, 33, 34, 35>
22031/// %sub.v2 = shuffle <32 x i32> %v0, <32 x i32> v1, <16, 17, 18, 19>
22032/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22034 Value *LaneMask,
22035 ShuffleVectorInst *SVI,
22036 unsigned Factor,
22037 const APInt &GapMask) const {
22038 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22039 "Invalid interleave factor");
22040 auto *SI = dyn_cast<StoreInst>(Store);
22041 if (!SI)
22042 return false;
22043 assert(!LaneMask && GapMask.popcount() == Factor &&
22044 "Unexpected mask on store");
22045
22046 auto *VecTy = cast<FixedVectorType>(SVI->getType());
22047 assert(VecTy->getNumElements() % Factor == 0 && "Invalid interleaved store");
22048
22049 unsigned LaneLen = VecTy->getNumElements() / Factor;
22050 Type *EltTy = VecTy->getElementType();
22051 auto *SubVecTy = FixedVectorType::get(EltTy, LaneLen);
22052
22053 const DataLayout &DL = SI->getDataLayout();
22054 Align Alignment = SI->getAlign();
22055
22056 // Skip if we do not have NEON and skip illegal vector types. We can
22057 // "legalize" wide vector types into multiple interleaved accesses as long as
22058 // the vector types are divisible by 128.
22059 if (!isLegalInterleavedAccessType(Factor, SubVecTy, Alignment, DL))
22060 return false;
22061
22062 unsigned NumStores = getNumInterleavedAccesses(SubVecTy, DL);
22063
22064 Value *Op0 = SVI->getOperand(0);
22065 Value *Op1 = SVI->getOperand(1);
22066 IRBuilder<> Builder(SI);
22067
22068 // StN intrinsics don't support pointer vectors as arguments. Convert pointer
22069 // vectors to integer vectors.
22070 if (EltTy->isPointerTy()) {
22071 Type *IntTy = DL.getIntPtrType(EltTy);
22072
22073 // Convert to the corresponding integer vector.
22074 auto *IntVecTy =
22076 Op0 = Builder.CreatePtrToInt(Op0, IntVecTy);
22077 Op1 = Builder.CreatePtrToInt(Op1, IntVecTy);
22078
22079 SubVecTy = FixedVectorType::get(IntTy, LaneLen);
22080 }
22081
22082 // The base address of the store.
22083 Value *BaseAddr = SI->getPointerOperand();
22084
22085 if (NumStores > 1) {
22086 // If we're going to generate more than one store, reset the lane length
22087 // and sub-vector type to something legal.
22088 LaneLen /= NumStores;
22089 SubVecTy = FixedVectorType::get(SubVecTy->getElementType(), LaneLen);
22090 }
22091
22092 assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!");
22093
22094 auto Mask = SVI->getShuffleMask();
22095
22096 auto createStoreIntrinsic = [&](Value *BaseAddr,
22097 SmallVectorImpl<Value *> &Shuffles) {
22098 if (Subtarget->hasNEON()) {
22099 static const Intrinsic::ID StoreInts[3] = {Intrinsic::arm_neon_vst2,
22100 Intrinsic::arm_neon_vst3,
22101 Intrinsic::arm_neon_vst4};
22102 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22103 Type *Tys[] = {PtrTy, SubVecTy};
22104
22106 Ops.push_back(BaseAddr);
22107 append_range(Ops, Shuffles);
22108 Ops.push_back(Builder.getInt32(SI->getAlign().value()));
22109 Builder.CreateIntrinsic(StoreInts[Factor - 2], Tys, Ops);
22110 } else {
22111 assert((Factor == 2 || Factor == 4) &&
22112 "expected interleave factor of 2 or 4 for MVE");
22113 Intrinsic::ID StoreInts =
22114 Factor == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
22115 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22116 Type *Tys[] = {PtrTy, SubVecTy};
22117
22119 Ops.push_back(BaseAddr);
22120 append_range(Ops, Shuffles);
22121 for (unsigned F = 0; F < Factor; F++) {
22122 Ops.push_back(Builder.getInt32(F));
22123 Builder.CreateIntrinsic(StoreInts, Tys, Ops);
22124 Ops.pop_back();
22125 }
22126 }
22127 };
22128
22129 for (unsigned StoreCount = 0; StoreCount < NumStores; ++StoreCount) {
22130 // If we generating more than one store, we compute the base address of
22131 // subsequent stores as an offset from the previous.
22132 if (StoreCount > 0)
22133 BaseAddr = Builder.CreateConstGEP1_32(SubVecTy->getElementType(),
22134 BaseAddr, LaneLen * Factor);
22135
22136 SmallVector<Value *, 4> Shuffles;
22137
22138 // Split the shufflevector operands into sub vectors for the new vstN call.
22139 for (unsigned i = 0; i < Factor; i++) {
22140 unsigned IdxI = StoreCount * LaneLen * Factor + i;
22141 if (Mask[IdxI] >= 0) {
22142 Shuffles.push_back(Builder.CreateShuffleVector(
22143 Op0, Op1, createSequentialMask(Mask[IdxI], LaneLen, 0)));
22144 } else {
22145 unsigned StartMask = 0;
22146 for (unsigned j = 1; j < LaneLen; j++) {
22147 unsigned IdxJ = StoreCount * LaneLen * Factor + j;
22148 if (Mask[IdxJ * Factor + IdxI] >= 0) {
22149 StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
22150 break;
22151 }
22152 }
22153 // Note: If all elements in a chunk are undefs, StartMask=0!
22154 // Note: Filling undef gaps with random elements is ok, since
22155 // those elements were being written anyway (with undefs).
22156 // In the case of all undefs we're defaulting to using elems from 0
22157 // Note: StartMask cannot be negative, it's checked in
22158 // isReInterleaveMask
22159 Shuffles.push_back(Builder.CreateShuffleVector(
22160 Op0, Op1, createSequentialMask(StartMask, LaneLen, 0)));
22161 }
22162 }
22163
22164 createStoreIntrinsic(BaseAddr, Shuffles);
22165 }
22166 return true;
22167}
22168
22176
22178 uint64_t &Members) {
22179 if (auto *ST = dyn_cast<StructType>(Ty)) {
22180 for (unsigned i = 0; i < ST->getNumElements(); ++i) {
22181 uint64_t SubMembers = 0;
22182 if (!isHomogeneousAggregate(ST->getElementType(i), Base, SubMembers))
22183 return false;
22184 Members += SubMembers;
22185 }
22186 } else if (auto *AT = dyn_cast<ArrayType>(Ty)) {
22187 uint64_t SubMembers = 0;
22188 if (!isHomogeneousAggregate(AT->getElementType(), Base, SubMembers))
22189 return false;
22190 Members += SubMembers * AT->getNumElements();
22191 } else if (Ty->isFloatTy()) {
22192 if (Base != HA_UNKNOWN && Base != HA_FLOAT)
22193 return false;
22194 Members = 1;
22195 Base = HA_FLOAT;
22196 } else if (Ty->isDoubleTy()) {
22197 if (Base != HA_UNKNOWN && Base != HA_DOUBLE)
22198 return false;
22199 Members = 1;
22200 Base = HA_DOUBLE;
22201 } else if (auto *VT = dyn_cast<VectorType>(Ty)) {
22202 Members = 1;
22203 switch (Base) {
22204 case HA_FLOAT:
22205 case HA_DOUBLE:
22206 return false;
22207 case HA_VECT64:
22208 return VT->getPrimitiveSizeInBits().getFixedValue() == 64;
22209 case HA_VECT128:
22210 return VT->getPrimitiveSizeInBits().getFixedValue() == 128;
22211 case HA_UNKNOWN:
22212 switch (VT->getPrimitiveSizeInBits().getFixedValue()) {
22213 case 64:
22214 Base = HA_VECT64;
22215 return true;
22216 case 128:
22217 Base = HA_VECT128;
22218 return true;
22219 default:
22220 return false;
22221 }
22222 }
22223 }
22224
22225 return (Members > 0 && Members <= 4);
22226}
22227
22228/// Return the correct alignment for the current calling convention.
22230 Type *ArgTy, const DataLayout &DL) const {
22231 const Align ABITypeAlign = DL.getABITypeAlign(ArgTy);
22232 if (!ArgTy->isVectorTy())
22233 return ABITypeAlign;
22234
22235 // Avoid over-aligning vector parameters. It would require realigning the
22236 // stack and waste space for no real benefit.
22237 MaybeAlign StackAlign = DL.getStackAlignment();
22238 assert(StackAlign && "data layout string is missing stack alignment");
22239 return std::min(ABITypeAlign, *StackAlign);
22240}
22241
22242/// Return true if a type is an AAPCS-VFP homogeneous aggregate or one of
22243/// [N x i32] or [N x i64]. This allows front-ends to skip emitting padding when
22244/// passing according to AAPCS rules.
22246 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
22247 const DataLayout &DL) const {
22248 if (getEffectiveCallingConv(CallConv, isVarArg) !=
22250 return false;
22251
22253 uint64_t Members = 0;
22254 bool IsHA = isHomogeneousAggregate(Ty, Base, Members);
22255 LLVM_DEBUG(dbgs() << "isHA: " << IsHA << " "; Ty->dump());
22256
22257 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
22258 return IsHA || IsIntArray;
22259}
22260
22262 const Constant *PersonalityFn) const {
22263 // Platforms which do not use SjLj EH may return values in these registers
22264 // via the personality function.
22266 return EM == ExceptionHandling::SjLj ? Register() : ARM::R0;
22267}
22268
22270 const Constant *PersonalityFn) const {
22271 // Platforms which do not use SjLj EH may return values in these registers
22272 // via the personality function.
22274 return EM == ExceptionHandling::SjLj ? Register() : ARM::R1;
22275}
22276
22277void ARMTargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
22278 // Update IsSplitCSR in ARMFunctionInfo.
22279 ARMFunctionInfo *AFI = Entry->getParent()->getInfo<ARMFunctionInfo>();
22280 AFI->setIsSplitCSR(true);
22281}
22282
22283void ARMTargetLowering::insertCopiesSplitCSR(
22284 MachineBasicBlock *Entry,
22285 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
22286 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
22287 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
22288 if (!IStart)
22289 return;
22290
22291 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
22292 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
22293 MachineBasicBlock::iterator MBBI = Entry->begin();
22294 for (const MCPhysReg *I = IStart; *I; ++I) {
22295 const TargetRegisterClass *RC = nullptr;
22296 if (ARM::GPRRegClass.contains(*I))
22297 RC = &ARM::GPRRegClass;
22298 else if (ARM::DPRRegClass.contains(*I))
22299 RC = &ARM::DPRRegClass;
22300 else
22301 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
22302
22303 Register NewVR = MRI->createVirtualRegister(RC);
22304 // Create copy from CSR to a virtual register.
22305 // FIXME: this currently does not emit CFI pseudo-instructions, it works
22306 // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
22307 // nounwind. If we want to generalize this later, we may need to emit
22308 // CFI pseudo-instructions.
22309 assert(Entry->getParent()->getFunction().hasFnAttribute(
22310 Attribute::NoUnwind) &&
22311 "Function should be nounwind in insertCopiesSplitCSR!");
22312 Entry->addLiveIn(*I);
22313 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
22314 .addReg(*I);
22315
22316 // Insert the copy-back instructions right before the terminator.
22317 for (auto *Exit : Exits)
22318 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
22319 TII->get(TargetOpcode::COPY), *I)
22320 .addReg(NewVR);
22321 }
22322}
22323
22328
22330 return Subtarget->hasMVEIntegerOps();
22331}
22332
22335 auto *VTy = dyn_cast<FixedVectorType>(Ty);
22336 if (!VTy)
22337 return false;
22338
22339 auto *ScalarTy = VTy->getScalarType();
22340 unsigned NumElements = VTy->getNumElements();
22341
22342 unsigned VTyWidth = VTy->getScalarSizeInBits() * NumElements;
22343 if (VTyWidth < 128 || !llvm::isPowerOf2_32(VTyWidth))
22344 return false;
22345
22346 // Both VCADD and VCMUL/VCMLA support the same types, F16 and F32
22347 if (ScalarTy->isHalfTy() || ScalarTy->isFloatTy())
22348 return Subtarget->hasMVEFloatOps();
22349
22351 return false;
22352
22353 return Subtarget->hasMVEIntegerOps() &&
22354 (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
22355 ScalarTy->isIntegerTy(32));
22356}
22357
22359 static const MCPhysReg RCRegs[] = {ARM::FPSCR_RM};
22360 return RCRegs;
22361}
22362
22365 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
22366 Value *Accumulator) const {
22367
22369
22370 unsigned TyWidth = Ty->getScalarSizeInBits() * Ty->getNumElements();
22371
22372 assert(TyWidth >= 128 && "Width of vector type must be at least 128 bits");
22373
22374 if (TyWidth > 128) {
22375 int Stride = Ty->getNumElements() / 2;
22376 auto SplitSeq = llvm::seq<int>(0, Ty->getNumElements());
22377 auto SplitSeqVec = llvm::to_vector(SplitSeq);
22378 ArrayRef<int> LowerSplitMask(&SplitSeqVec[0], Stride);
22379 ArrayRef<int> UpperSplitMask(&SplitSeqVec[Stride], Stride);
22380
22381 auto *LowerSplitA = B.CreateShuffleVector(InputA, LowerSplitMask);
22382 auto *LowerSplitB = B.CreateShuffleVector(InputB, LowerSplitMask);
22383 auto *UpperSplitA = B.CreateShuffleVector(InputA, UpperSplitMask);
22384 auto *UpperSplitB = B.CreateShuffleVector(InputB, UpperSplitMask);
22385 Value *LowerSplitAcc = nullptr;
22386 Value *UpperSplitAcc = nullptr;
22387
22388 if (Accumulator) {
22389 LowerSplitAcc = B.CreateShuffleVector(Accumulator, LowerSplitMask);
22390 UpperSplitAcc = B.CreateShuffleVector(Accumulator, UpperSplitMask);
22391 }
22392
22393 auto *LowerSplitInt = createComplexDeinterleavingIR(
22394 B, OperationType, Rotation, LowerSplitA, LowerSplitB, LowerSplitAcc);
22395 auto *UpperSplitInt = createComplexDeinterleavingIR(
22396 B, OperationType, Rotation, UpperSplitA, UpperSplitB, UpperSplitAcc);
22397
22398 ArrayRef<int> JoinMask(&SplitSeqVec[0], Ty->getNumElements());
22399 return B.CreateShuffleVector(LowerSplitInt, UpperSplitInt, JoinMask);
22400 }
22401
22402 auto *IntTy = Type::getInt32Ty(B.getContext());
22403
22404 ConstantInt *ConstRotation = nullptr;
22405 if (OperationType == ComplexDeinterleavingOperation::CMulPartial) {
22406 ConstRotation = ConstantInt::get(IntTy, (int)Rotation);
22407
22408 if (Accumulator)
22409 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmlaq, Ty,
22410 {ConstRotation, Accumulator, InputB, InputA});
22411 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmulq, Ty,
22412 {ConstRotation, InputB, InputA});
22413 }
22414
22415 if (OperationType == ComplexDeinterleavingOperation::CAdd) {
22416 // 1 means the value is not halved.
22417 auto *ConstHalving = ConstantInt::get(IntTy, 1);
22418
22420 ConstRotation = ConstantInt::get(IntTy, 0);
22422 ConstRotation = ConstantInt::get(IntTy, 1);
22423
22424 if (!ConstRotation)
22425 return nullptr; // Invalid rotation for arm_mve_vcaddq
22426
22427 return B.CreateIntrinsic(Intrinsic::arm_mve_vcaddq, Ty,
22428 {ConstHalving, ConstRotation, InputA, InputB});
22429 }
22430
22431 return nullptr;
22432}
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)
return SDValue()
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
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:856
This file implements the BitVector class.
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:349
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:5862
APInt bitcastToAPInt() const
Definition APFloat.h:1457
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1418
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:235
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition APInt.h:424
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1565
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1695
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1076
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1537
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:968
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1355
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1210
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:372
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1513
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1120
unsigned countr_zero() const
Count the number of trailing zero bits.
Definition APInt.h:1664
unsigned countl_zero() const
The APInt version of std::countl_zero.
Definition APInt.h:1623
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
Definition APInt.cpp:652
unsigned logBase2() const
Definition APInt.h:1786
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:476
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition APInt.h:1266
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:441
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:307
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:297
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:390
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:240
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1587
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
Definition APInt.h:865
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:858
unsigned countr_one() const
Count the number of trailing one bits.
Definition APInt.h:1681
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1230
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)
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,...
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
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 isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, unsigned Index) const override
Return true if EXTRACT_SUBVECTOR is cheap for this result type with this index.
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...
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...
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.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
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 from min(max(fptoi)) satur...
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:223
unsigned size() const
Definition DenseMap.h:172
bool empty() const
Definition DenseMap.h:171
iterator begin()
Definition DenseMap.h:137
iterator end()
Definition DenseMap.h:141
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:867
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:211
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:685
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
arg_iterator arg_begin()
Definition Function.h:842
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:353
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:669
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:229
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
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.
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
@ 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:2893
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 isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
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.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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...
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.
Flags getFlags() const
Return the raw flags of the source value,.
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 getBaseAlign() const
Returns alignment and volatility of the memory access.
Align getAlign() const
bool isVolatile() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
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 MachinePointerInfo & getPointerInfo() const
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:67
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
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...
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 AAMDNodes &AAInfo=AAMDNodes())
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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
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 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 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 SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
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 getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
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 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
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.
const SDValue & getBasePtr() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
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:477
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 ...
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.
ExceptionHandling getExceptionModel() const
Return the ExceptionHandling to use, considering TargetOptions and the Triple's default.
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:47
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition Triple.h:535
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:774
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
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:310
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
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:282
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:308
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:232
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:257
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:227
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:36
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:255
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
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.
@ 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:829
@ 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:513
@ 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:540
@ 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:602
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ 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:863
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:520
@ 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:890
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:586
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ 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:438
@ 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:798
@ SET_ROUNDING
Set rounding mode.
Definition ISDOpcodes.h:985
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:717
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:667
@ 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:837
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:352
@ 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:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ 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:348
@ CTLS
Count leading redundant sign bits.
Definition ISDOpcodes.h:802
@ 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:980
@ STRICT_FP_TO_FP16
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ 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:771
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:651
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:616
@ 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:578
@ 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:860
@ 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:821
@ 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:356
@ 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:898
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:815
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:328
@ STRICT_FROUNDEVEN
Definition ISDOpcodes.h:466
@ 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:480
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:502
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:479
@ 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:936
@ 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:507
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ 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:737
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:712
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:427
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:567
@ 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:797
@ 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:969
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
Definition ISDOpcodes.h:122
@ STRICT_FNEARBYINT
Definition ISDOpcodes.h:458
@ 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:955
@ 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:866
@ 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:843
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
Definition ISDOpcodes.h:724
@ SADDO_CARRY
Carry-using overflow-aware nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:338
@ 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:558
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:315
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:573
@ Length
Definition DWP.cpp:573
void stable_sort(R &&Range)
Definition STLExtras.h:2116
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:1765
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:1739
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:255
ExceptionHandling
Definition CodeGen.h:53
@ SjLj
setjmp/longjmp based exceptions
Definition CodeGen.h:56
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:2208
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:243
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:284
void shuffle(Iterator first, Iterator last, RNG &&g)
Definition STLExtras.h:1530
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:267
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:1746
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:331
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:279
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:189
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
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:592
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr unsigned BitWidth
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:2019
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:1772
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:248
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...
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
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:198
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:862
#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:763
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
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.
MachinePointerInfo getWithOffset(int64_t O) const
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...