LLVM 24.0.0git
ARMISelLowering.cpp
Go to the documentation of this file.
1//===- ARMISelLowering.cpp - ARM DAG Lowering Implementation --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that ARM uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMISelLowering.h"
15#include "ARMBaseInstrInfo.h"
16#include "ARMBaseRegisterInfo.h"
17#include "ARMCallingConv.h"
20#include "ARMPerfectShuffle.h"
21#include "ARMRegisterInfo.h"
22#include "ARMSelectionDAGInfo.h"
23#include "ARMSubtarget.h"
27#include "Utils/ARMBaseInfo.h"
28#include "llvm/ADT/APFloat.h"
29#include "llvm/ADT/APInt.h"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/BitVector.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/STLExtras.h"
36#include "llvm/ADT/Statistic.h"
38#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/Twine.h"
66#include "llvm/IR/Attributes.h"
67#include "llvm/IR/CallingConv.h"
68#include "llvm/IR/Constant.h"
69#include "llvm/IR/Constants.h"
70#include "llvm/IR/DataLayout.h"
71#include "llvm/IR/DebugLoc.h"
73#include "llvm/IR/Function.h"
74#include "llvm/IR/GlobalAlias.h"
75#include "llvm/IR/GlobalValue.h"
77#include "llvm/IR/IRBuilder.h"
78#include "llvm/IR/InlineAsm.h"
79#include "llvm/IR/Instruction.h"
82#include "llvm/IR/Intrinsics.h"
83#include "llvm/IR/IntrinsicsARM.h"
84#include "llvm/IR/Module.h"
85#include "llvm/IR/Type.h"
86#include "llvm/IR/User.h"
87#include "llvm/IR/Value.h"
88#include "llvm/MC/MCInstrDesc.h"
90#include "llvm/MC/MCSchedule.h"
97#include "llvm/Support/Debug.h"
105#include <algorithm>
106#include <cassert>
107#include <cstdint>
108#include <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
883 // STRICT_(U/S)INT_TO_FP specifically use the input MVT to register with
884 // setOperationAction() as opposed to other opcodes that use the output MVT
885 // All inputs should be i32 due to type legalization
888
891
892 if (!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) {
895 if (Subtarget->hasFullFP16()) {
898 }
899 } else {
901 }
902
903 if (!Subtarget->hasFP16()) {
906 } else {
909 }
910
911 computeRegisterProperties(Subtarget->getRegisterInfo());
912
913 // ARM does not have floating-point extending loads.
914 for (MVT VT : MVT::fp_valuetypes()) {
915 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
916 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
917 setLoadExtAction(ISD::EXTLOAD, VT, MVT::bf16, Expand);
918 }
919
920 // ... or truncating stores
921 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
922 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
923 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
924 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
925 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
926
927 // ARM does not have i1 sign extending load.
928 for (MVT VT : MVT::integer_valuetypes())
930
931 // ARM supports all 4 flavors of integer indexed load / store.
932 if (!Subtarget->isThumb1Only()) {
933 for (unsigned im = (unsigned)ISD::PRE_INC;
935 setIndexedLoadAction(im, MVT::i1, Legal);
936 setIndexedLoadAction(im, MVT::i8, Legal);
937 setIndexedLoadAction(im, MVT::i16, Legal);
938 setIndexedLoadAction(im, MVT::i32, Legal);
939 setIndexedStoreAction(im, MVT::i1, Legal);
940 setIndexedStoreAction(im, MVT::i8, Legal);
941 setIndexedStoreAction(im, MVT::i16, Legal);
942 setIndexedStoreAction(im, MVT::i32, Legal);
943 }
944 } else {
945 // Thumb-1 has limited post-inc load/store support - LDM r0!, {r1}.
948 }
949
950 // Custom loads/stores to possible use __aeabi_uread/write*
951 if (TT.isTargetAEABI() && !Subtarget->allowsUnalignedMem()) {
956 }
957
962
963 if (!Subtarget->isThumb1Only()) {
966 }
967
972 if (Subtarget->hasDSP()) {
981 }
982 if (Subtarget->hasBaseDSP()) {
985 }
986
987 // i64 operation support.
990 if (Subtarget->isThumb1Only()) {
993 }
994 if (Subtarget->isThumb1Only() || !Subtarget->hasV6Ops()
995 || (Subtarget->isThumb2() && !Subtarget->hasDSP()))
997
1007
1008 // MVE lowers 64 bit shifts to lsll and lsrl
1009 // assuming that ISD::SRL and SRA of i64 are already marked custom
1010 if (Subtarget->hasMVEIntegerOps())
1012
1013 // Expand to __aeabi_l{lsl,lsr,asr} calls for Thumb1.
1014 if (Subtarget->isThumb1Only()) {
1018 }
1019
1020 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops())
1022
1023 // ARM does not have ROTL.
1028 }
1030 // TODO: These two should be set to LibCall, but this currently breaks
1031 // the Linux kernel build. See #101786.
1034 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
1037 }
1038
1039 // @llvm.readcyclecounter requires the Performance Monitors extension.
1040 // Default to the 0 expansion on unsupported platforms.
1041 // FIXME: Technically there are older ARM CPUs that have
1042 // implementation-specific ways of obtaining this information.
1043 if (Subtarget->hasPerfMon())
1045
1046 // Only ARMv6 has BSWAP.
1047 if (!Subtarget->hasV6Ops())
1049
1050 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
1051 : Subtarget->hasDivideInARMMode();
1052 if (!hasDivide) {
1053 // These are expanded into libcalls if the cpu doesn't have HW divider.
1056 }
1057
1058 if (TT.isOSWindows() && !Subtarget->hasDivideInThumbMode()) {
1061
1064 }
1065
1068
1069 // Register based DivRem for AEABI (RTABI 4.2)
1070 if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
1071 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isOSWindows()) {
1074 HasStandaloneRem = false;
1075
1080 } else {
1083 }
1084
1089
1090 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1092
1093 // Use the default implementation.
1095 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1097 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1100
1101 if (TT.isOSWindows())
1103 else
1105
1106 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
1107 // the default expansion.
1108 InsertFencesForAtomic = false;
1109 if (Subtarget->hasAnyDataBarrier() &&
1110 (!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps())) {
1111 // ATOMIC_FENCE needs custom lowering; the others should have been expanded
1112 // to ldrex/strex loops already.
1114 if (!Subtarget->isThumb() || !Subtarget->isMClass())
1116
1117 // On v8, we have particularly efficient implementations of atomic fences
1118 // if they can be combined with nearby atomic loads and stores.
1119 if (!Subtarget->hasAcquireRelease() ||
1120 getTargetMachine().getOptLevel() == CodeGenOptLevel::None) {
1121 // Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
1122 InsertFencesForAtomic = true;
1123 }
1124 } else {
1125 // If there's anything we can use as a barrier, go through custom lowering
1126 // for ATOMIC_FENCE.
1127 // If target has DMB in thumb, Fences can be inserted.
1128 if (Subtarget->hasDataBarrier())
1129 InsertFencesForAtomic = true;
1130
1132 Subtarget->hasAnyDataBarrier() ? Custom : Expand);
1133
1134 // Set them all for libcall, which will force libcalls.
1147 // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the
1148 // Unordered/Monotonic case.
1149 if (!InsertFencesForAtomic) {
1152 }
1153 }
1154
1155 // Compute supported atomic widths.
1156 if (TT.isOSLinux() || (!Subtarget->isMClass() && Subtarget->hasV6Ops())) {
1157 // For targets where __sync_* routines are reliably available, we use them
1158 // if necessary.
1159 //
1160 // ARM Linux always supports 64-bit atomics through kernel-assisted atomic
1161 // routines (kernel 3.1 or later). FIXME: Not with compiler-rt?
1162 //
1163 // ARMv6 targets have native instructions in ARM mode. For Thumb mode,
1164 // such targets should provide __sync_* routines, which use the ARM mode
1165 // instructions. (ARMv6 doesn't have dmb, but it has an equivalent
1166 // encoding; see ARMISD::MEMBARRIER_MCR.)
1168 } else if ((Subtarget->isMClass() && Subtarget->hasV8MBaselineOps()) ||
1169 Subtarget->hasForced32BitAtomics()) {
1170 // Cortex-M (besides Cortex-M0) have 32-bit atomics.
1172 } else {
1173 // We can't assume anything about other targets; just use libatomic
1174 // routines.
1176 }
1177
1179
1181
1182 // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
1183 if (!Subtarget->hasV6Ops()) {
1186 }
1188
1189 if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() &&
1190 !Subtarget->isThumb1Only()) {
1191 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
1192 // iff target supports vfp2.
1202 }
1203
1204 // We want to custom lower some of our intrinsics.
1209
1219 if (Subtarget->hasFullFP16()) {
1223 }
1224
1226
1229 if (Subtarget->hasFullFP16())
1233 setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1234
1235 // We don't support sin/cos/fmod/copysign/pow
1244 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
1245 !Subtarget->isThumb1Only()) {
1248 }
1251
1252 if (!Subtarget->hasVFP4Base()) {
1255 }
1256
1257 // Various VFP goodness
1258 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
1259 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1260 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
1265 }
1266
1267 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
1268 if (!Subtarget->hasFP16()) {
1273 }
1274
1275 // Strict floating-point comparisons need custom lowering.
1282 }
1283
1284 // FP-ARMv8 implements a lot of rounding-like FP operations.
1285 if (Subtarget->hasFPARMv8Base()) {
1286 for (auto Op :
1293 setOperationAction(Op, MVT::f32, Legal);
1294
1295 if (Subtarget->hasFP64())
1296 setOperationAction(Op, MVT::f64, Legal);
1297 }
1298
1299 if (Subtarget->hasNEON()) {
1304 }
1305 }
1306
1307 // FP16 often need to be promoted to call lib functions
1308 // clang-format off
1309 if (Subtarget->hasFullFP16()) {
1313
1314 for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1328 setOperationAction(Op, MVT::f16, Promote);
1329 }
1330
1331 // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1332 // because the result type is integer.
1334 setOperationAction(Op, MVT::f16, Custom);
1335
1341 setOperationAction(Op, MVT::f16, Legal);
1342 }
1343 // clang-format on
1344 }
1345
1346 if (Subtarget->hasNEON()) {
1347 // vmin and vmax aren't available in a scalar form, so we can use
1348 // a NEON instruction with an undef lane instead.
1357
1358 if (Subtarget->hasV8Ops()) {
1363 setOperationAction(Op, MVT::v2f32, Legal);
1364 setOperationAction(Op, MVT::v4f32, Legal);
1365 }
1366 }
1367
1368 if (Subtarget->hasFullFP16()) {
1373
1378
1383 setOperationAction(Op, MVT::v4f16, Legal);
1384 setOperationAction(Op, MVT::v8f16, Legal);
1385 }
1386 }
1387 }
1388
1389 // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined. MinGW has
1390 // it, but it's just a wrapper around ldexp.
1391 if (TT.isOSWindows()) {
1393 if (isOperationExpand(Op, MVT::f32))
1394 setOperationAction(Op, MVT::f32, Promote);
1395 }
1396
1397 // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
1398 // isn't legal.
1400 if (isOperationExpand(Op, MVT::f16))
1401 setOperationAction(Op, MVT::f16, Promote);
1402
1403 // We have target-specific dag combine patterns for the following nodes:
1404 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
1407
1408 if (Subtarget->hasMVEIntegerOps())
1410
1411 if (Subtarget->hasV6Ops())
1413 if (Subtarget->isThumb1Only())
1415 // Attempt to lower smin/smax to ssat/usat
1416 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) ||
1417 Subtarget->isThumb2()) {
1419 }
1420
1422
1423 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1424 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
1426 else
1428
1429 //// temporary - rewrite interface to use type
1432 MaxStoresPerMemcpy = 4; // For @llvm.memcpy -> sequence of stores
1434 MaxStoresPerMemmove = 4; // For @llvm.memmove -> sequence of stores
1436
1437 // On ARM arguments smaller than 4 bytes are extended, so all arguments
1438 // are at least 4 bytes aligned.
1440
1441 // Prefer likely predicted branches to selects on out-of-order cores.
1442 PredictableSelectIsExpensive = Subtarget->getSchedModel().isOutOfOrder();
1443
1444 setPrefLoopAlignment(Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1446 Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1447
1448 setMinFunctionAlignment(Subtarget->isThumb() ? Align(2) : Align(4));
1449
1450 IsStrictFPEnabled = true;
1451}
1452
1454 return Subtarget->useSoftFloat();
1455}
1456
1458 return !Subtarget->isThumb1Only() && VT.getSizeInBits() <= 32;
1459}
1460
1461// FIXME: It might make sense to define the representative register class as the
1462// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
1463// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
1464// SPR's representative would be DPR_VFP2. This should work well if register
1465// pressure tracking were modified such that a register use would increment the
1466// pressure of the register class's representative and all of it's super
1467// classes' representatives transitively. We have not implemented this because
1468// of the difficulty prior to coalescing of modeling operand register classes
1469// due to the common occurrence of cross class copies and subregister insertions
1470// and extractions.
1471std::pair<const TargetRegisterClass *, uint8_t>
1473 MVT VT) const {
1474 const TargetRegisterClass *RRC = nullptr;
1475 uint8_t Cost = 1;
1476 switch (VT.SimpleTy) {
1477 default:
1479 // Use DPR as representative register class for all floating point
1480 // and vector types. Since there are 32 SPR registers and 32 DPR registers so
1481 // the cost is 1 for both f32 and f64.
1482 case MVT::f32: case MVT::f64: case MVT::v8i8: case MVT::v4i16:
1483 case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
1484 RRC = &ARM::DPRRegClass;
1485 // When NEON is used for SP, only half of the register file is available
1486 // because operations that define both SP and DP results will be constrained
1487 // to the VFP2 class (D0-D15). We currently model this constraint prior to
1488 // coalescing by double-counting the SP regs. See the FIXME above.
1489 if (Subtarget->useNEONForSinglePrecisionFP())
1490 Cost = 2;
1491 break;
1492 case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
1493 case MVT::v4f32: case MVT::v2f64:
1494 RRC = &ARM::DPRRegClass;
1495 Cost = 2;
1496 break;
1497 case MVT::v4i64:
1498 RRC = &ARM::DPRRegClass;
1499 Cost = 4;
1500 break;
1501 case MVT::v8i64:
1502 RRC = &ARM::DPRRegClass;
1503 Cost = 8;
1504 break;
1505 }
1506 return std::make_pair(RRC, Cost);
1507}
1508
1510 EVT VT) const {
1511 if (!VT.isVector())
1512 return getPointerTy(DL);
1513
1514 // MVE has a predicate register.
1515 if (Subtarget->hasMVEIntegerOps())
1516 return EVT::getVectorVT(C, MVT::i1, VT.getVectorElementCount());
1517
1519}
1520
1521/// getRegClassFor - Return the register class that should be used for the
1522/// specified value type.
1523const TargetRegisterClass *
1524ARMTargetLowering::getRegClassFor(MVT VT, bool isDivergent) const {
1525 (void)isDivergent;
1526 // Map v4i64 to QQ registers but do not make the type legal. Similarly map
1527 // v8i64 to QQQQ registers. v4i64 and v8i64 are only used for REG_SEQUENCE to
1528 // load / store 4 to 8 consecutive NEON D registers, or 2 to 4 consecutive
1529 // MVE Q registers.
1530 if (Subtarget->hasNEON()) {
1531 if (VT == MVT::v4i64)
1532 return &ARM::QQPRRegClass;
1533 if (VT == MVT::v8i64)
1534 return &ARM::QQQQPRRegClass;
1535 }
1536 if (Subtarget->hasMVEIntegerOps()) {
1537 if (VT == MVT::v4i64)
1538 return &ARM::MQQPRRegClass;
1539 if (VT == MVT::v8i64)
1540 return &ARM::MQQQQPRRegClass;
1541 }
1543}
1544
1545// memcpy, and other memory intrinsics, typically tries to use LDM/STM if the
1546// source/dest is aligned and the copy size is large enough. We therefore want
1547// to align such objects passed to memory intrinsics.
1549 Align &PrefAlign) const {
1550 if (!isa<MemIntrinsic>(CI))
1551 return false;
1552 MinSize = 8;
1553 // On ARM11 onwards (excluding M class) 8-byte aligned LDM is typically 1
1554 // cycle faster than 4-byte aligned LDM.
1555 PrefAlign =
1556 (Subtarget->hasV6Ops() && !Subtarget->isMClass() ? Align(8) : Align(4));
1557 return true;
1558}
1559
1560// Create a fast isel object.
1562 FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo,
1563 const LibcallLoweringInfo *libcallLowering) const {
1564 return ARM::createFastISel(funcInfo, libInfo, libcallLowering);
1565}
1566
1568 unsigned NumVals = N->getNumValues();
1569 if (!NumVals)
1570 return Sched::RegPressure;
1571
1572 for (unsigned i = 0; i != NumVals; ++i) {
1573 EVT VT = N->getValueType(i);
1574 if (VT == MVT::Glue || VT == MVT::Other)
1575 continue;
1576 if (VT.isFloatingPoint() || VT.isVector())
1577 return Sched::ILP;
1578 }
1579
1580 if (!N->isMachineOpcode())
1581 return Sched::RegPressure;
1582
1583 // Load are scheduled for latency even if there instruction itinerary
1584 // is not available.
1585 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
1586 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1587
1588 if (MCID.getNumDefs() == 0)
1589 return Sched::RegPressure;
1590 if (!Itins->isEmpty() &&
1591 Itins->getOperandCycle(MCID.getSchedClass(), 0) > 2U)
1592 return Sched::ILP;
1593
1594 return Sched::RegPressure;
1595}
1596
1597//===----------------------------------------------------------------------===//
1598// Lowering Code
1599//===----------------------------------------------------------------------===//
1600
1601static bool isSRL16(const SDValue &Op) {
1602 if (Op.getOpcode() != ISD::SRL)
1603 return false;
1604 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1605 return Const->getZExtValue() == 16;
1606 return false;
1607}
1608
1609static bool isSRA16(const SDValue &Op) {
1610 if (Op.getOpcode() != ISD::SRA)
1611 return false;
1612 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1613 return Const->getZExtValue() == 16;
1614 return false;
1615}
1616
1617static bool isSHL16(const SDValue &Op) {
1618 if (Op.getOpcode() != ISD::SHL)
1619 return false;
1620 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1621 return Const->getZExtValue() == 16;
1622 return false;
1623}
1624
1625// Check for a signed 16-bit value. We special case SRA because it makes it
1626// more simple when also looking for SRAs that aren't sign extending a
1627// smaller value. Without the check, we'd need to take extra care with
1628// checking order for some operations.
1629static bool isS16(const SDValue &Op, SelectionDAG &DAG) {
1630 if (isSRA16(Op))
1631 return isSHL16(Op.getOperand(0));
1632 return DAG.ComputeNumSignBits(Op) == 17;
1633}
1634
1635/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
1637 switch (CC) {
1638 default: llvm_unreachable("Unknown condition code!");
1639 case ISD::SETNE: return ARMCC::NE;
1640 case ISD::SETEQ: return ARMCC::EQ;
1641 case ISD::SETGT: return ARMCC::GT;
1642 case ISD::SETGE: return ARMCC::GE;
1643 case ISD::SETLT: return ARMCC::LT;
1644 case ISD::SETLE: return ARMCC::LE;
1645 case ISD::SETUGT: return ARMCC::HI;
1646 case ISD::SETUGE: return ARMCC::HS;
1647 case ISD::SETULT: return ARMCC::LO;
1648 case ISD::SETULE: return ARMCC::LS;
1649 }
1650}
1651
1652/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
1654 ARMCC::CondCodes &CondCode2) {
1655 CondCode2 = ARMCC::AL;
1656 switch (CC) {
1657 default: llvm_unreachable("Unknown FP condition!");
1658 case ISD::SETEQ:
1659 case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
1660 case ISD::SETGT:
1661 case ISD::SETOGT: CondCode = ARMCC::GT; break;
1662 case ISD::SETGE:
1663 case ISD::SETOGE: CondCode = ARMCC::GE; break;
1664 case ISD::SETOLT: CondCode = ARMCC::MI; break;
1665 case ISD::SETOLE: CondCode = ARMCC::LS; break;
1666 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
1667 case ISD::SETO: CondCode = ARMCC::VC; break;
1668 case ISD::SETUO: CondCode = ARMCC::VS; break;
1669 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
1670 case ISD::SETUGT: CondCode = ARMCC::HI; break;
1671 case ISD::SETUGE: CondCode = ARMCC::PL; break;
1672 case ISD::SETLT:
1673 case ISD::SETULT: CondCode = ARMCC::LT; break;
1674 case ISD::SETLE:
1675 case ISD::SETULE: CondCode = ARMCC::LE; break;
1676 case ISD::SETNE:
1677 case ISD::SETUNE: CondCode = ARMCC::NE; break;
1678 }
1679}
1680
1681//===----------------------------------------------------------------------===//
1682// Calling Convention Implementation
1683//===----------------------------------------------------------------------===//
1684
1685/// getEffectiveCallingConv - Get the effective calling convention, taking into
1686/// account presence of floating point hardware and calling convention
1687/// limitations, such as support for variadic functions.
1689ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
1690 bool isVarArg) const {
1691 switch (CC) {
1692 default:
1693 report_fatal_error("Unsupported calling convention");
1696 case CallingConv::GHC:
1698 return CC;
1704 case CallingConv::Swift:
1707 case CallingConv::C:
1708 case CallingConv::Tail:
1709 if (!getTM().isAAPCS_ABI())
1710 return CallingConv::ARM_APCS;
1711 else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1712 Subtarget->isTargetHardFloat() && !isVarArg)
1714 else
1716 case CallingConv::Fast:
1718 if (!getTM().isAAPCS_ABI()) {
1719 if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() && !isVarArg)
1720 return CallingConv::Fast;
1721 return CallingConv::ARM_APCS;
1722 } else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1723 !isVarArg)
1725 else
1727 }
1728}
1729
1731 bool isVarArg) const {
1732 return CCAssignFnForNode(CC, false, isVarArg);
1733}
1734
1736 bool isVarArg) const {
1737 return CCAssignFnForNode(CC, true, isVarArg);
1738}
1739
1740/// CCAssignFnForNode - Selects the correct CCAssignFn for the given
1741/// CallingConvention.
1742CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
1743 bool Return,
1744 bool isVarArg) const {
1745 switch (getEffectiveCallingConv(CC, isVarArg)) {
1746 default:
1747 report_fatal_error("Unsupported calling convention");
1749 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1751 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1753 return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1754 case CallingConv::Fast:
1755 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1756 case CallingConv::GHC:
1757 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1759 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1761 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1763 return (Return ? RetCC_ARM_AAPCS : CC_ARM_Win32_CFGuard_Check);
1764 }
1765}
1766
1767SDValue ARMTargetLowering::MoveToHPR(const SDLoc &dl, SelectionDAG &DAG,
1768 MVT LocVT, MVT ValVT, SDValue Val) const {
1769 Val = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocVT.getSizeInBits()),
1770 Val);
1771 if (Subtarget->hasFullFP16()) {
1772 Val = DAG.getNode(ARMISD::VMOVhr, dl, ValVT, Val);
1773 } else {
1774 Val = DAG.getNode(ISD::TRUNCATE, dl,
1775 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1776 Val = DAG.getNode(ISD::BITCAST, dl, ValVT, Val);
1777 }
1778 return Val;
1779}
1780
1781SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
1782 MVT LocVT, MVT ValVT,
1783 SDValue Val) const {
1784 if (Subtarget->hasFullFP16()) {
1785 Val = DAG.getNode(ARMISD::VMOVrh, dl,
1786 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1787 } else {
1788 Val = DAG.getNode(ISD::BITCAST, dl,
1789 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1790 Val = DAG.getNode(ISD::ZERO_EXTEND, dl,
1791 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1792 }
1793 return DAG.getNode(ISD::BITCAST, dl, LocVT, Val);
1794}
1795
1796/// LowerCallResult - Lower the result values of a call into the
1797/// appropriate copies out of appropriate physical registers.
1798SDValue ARMTargetLowering::LowerCallResult(
1799 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
1800 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1801 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
1802 SDValue ThisVal, bool isCmseNSCall) const {
1803 // Assign locations to each value returned by this call.
1805 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1806 *DAG.getContext());
1807 CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, isVarArg));
1808
1809 // Copy all of the result registers out of their specified physreg.
1810 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1811 CCValAssign VA = RVLocs[i];
1812
1813 // Pass 'this' value directly from the argument to return value, to avoid
1814 // reg unit interference
1815 if (i == 0 && isThisReturn) {
1816 assert(!VA.needsCustom() && VA.getLocVT() == MVT::i32 &&
1817 "unexpected return calling convention register assignment");
1818 InVals.push_back(ThisVal);
1819 continue;
1820 }
1821
1822 SDValue Val;
1823 if (VA.needsCustom() &&
1824 (VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2f64)) {
1825 // Handle f64 or half of a v2f64.
1826 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1827 InGlue);
1828 Chain = Lo.getValue(1);
1829 InGlue = Lo.getValue(2);
1830 VA = RVLocs[++i]; // skip ahead to next loc
1831 SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1832 InGlue);
1833 Chain = Hi.getValue(1);
1834 InGlue = Hi.getValue(2);
1835 if (!Subtarget->isLittle())
1836 std::swap (Lo, Hi);
1837 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1838
1839 if (VA.getLocVT() == MVT::v2f64) {
1840 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
1841 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1842 DAG.getConstant(0, dl, MVT::i32));
1843
1844 VA = RVLocs[++i]; // skip ahead to next loc
1845 Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1846 Chain = Lo.getValue(1);
1847 InGlue = Lo.getValue(2);
1848 VA = RVLocs[++i]; // skip ahead to next loc
1849 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1850 Chain = Hi.getValue(1);
1851 InGlue = Hi.getValue(2);
1852 if (!Subtarget->isLittle())
1853 std::swap (Lo, Hi);
1854 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1855 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1856 DAG.getConstant(1, dl, MVT::i32));
1857 }
1858 } else {
1859 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(),
1860 InGlue);
1861 Chain = Val.getValue(1);
1862 InGlue = Val.getValue(2);
1863 }
1864
1865 switch (VA.getLocInfo()) {
1866 default: llvm_unreachable("Unknown loc info!");
1867 case CCValAssign::Full: break;
1868 case CCValAssign::BCvt:
1869 Val = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), Val);
1870 break;
1871 }
1872
1873 // f16 arguments have their size extended to 4 bytes and passed as if they
1874 // had been copied to the LSBs of a 32-bit register.
1875 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
1876 if (VA.needsCustom() &&
1877 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
1878 Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
1879
1880 // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
1881 // is less than 32 bits must be sign- or zero-extended after the call for
1882 // security reasons. Although the ABI mandates an extension done by the
1883 // callee, the latter cannot be trusted to follow the rules of the ABI.
1884 const ISD::InputArg &Arg = Ins[VA.getValNo()];
1885 if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
1886 VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
1887 Val = handleCMSEValue(Val, Arg, DAG, dl);
1888
1889 InVals.push_back(Val);
1890 }
1891
1892 return Chain;
1893}
1894
1895std::pair<SDValue, MachinePointerInfo> ARMTargetLowering::computeAddrForCallArg(
1896 const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA, SDValue StackPtr,
1897 bool IsTailCall, int SPDiff) const {
1898 SDValue DstAddr;
1899 MachinePointerInfo DstInfo;
1900 int32_t Offset = VA.getLocMemOffset();
1901 MachineFunction &MF = DAG.getMachineFunction();
1902
1903 if (IsTailCall) {
1904 Offset += SPDiff;
1905 auto PtrVT = getPointerTy(DAG.getDataLayout());
1906 int Size = VA.getLocVT().getFixedSizeInBits() / 8;
1907 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
1908 DstAddr = DAG.getFrameIndex(FI, PtrVT);
1909 DstInfo =
1911 } else {
1912 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1913 DstAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
1914 StackPtr, PtrOff);
1915 DstInfo =
1917 }
1918
1919 return std::make_pair(DstAddr, DstInfo);
1920}
1921
1922// Returns the type of copying which is required to set up a byval argument to
1923// a tail-called function. This isn't needed for non-tail calls, because they
1924// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
1925// avoid clobbering another argument (CopyViaTemp), and sometimes can be
1926// optimised to zero copies when forwarding an argument from the caller's
1927// caller (NoCopy).
1928ARMTargetLowering::ByValCopyKind ARMTargetLowering::ByValNeedsCopyForTailCall(
1929 SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
1930 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1931 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
1932
1933 // Globals are always safe to copy from.
1935 return CopyOnce;
1936
1937 // Can only analyse frame index nodes, conservatively assume we need a
1938 // temporary.
1939 auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
1940 auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
1941 if (!SrcFrameIdxNode || !DstFrameIdxNode)
1942 return CopyViaTemp;
1943
1944 int SrcFI = SrcFrameIdxNode->getIndex();
1945 int DstFI = DstFrameIdxNode->getIndex();
1946 assert(MFI.isFixedObjectIndex(DstFI) &&
1947 "byval passed in non-fixed stack slot");
1948
1949 int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
1950 int64_t DstOffset = MFI.getObjectOffset(DstFI);
1951
1952 // If the source is in the local frame, then the copy to the argument memory
1953 // is always valid.
1954 bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
1955 if (!FixedSrc ||
1956 (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
1957 return CopyOnce;
1958
1959 // In the case of byval arguments split between registers and the stack,
1960 // computeAddrForCallArg returns a FrameIndex which corresponds only to the
1961 // stack portion, but the Src SDValue will refer to the full value, including
1962 // the local stack memory that the register portion gets stored into. We only
1963 // need to compare them for equality, so normalise on the full value version.
1964 uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
1965 DstOffset -= RegSize;
1966
1967 // If the value is already in the correct location, then no copying is
1968 // needed. If not, then we need to copy via a temporary.
1969 if (SrcOffset == DstOffset)
1970 return NoCopy;
1971 else
1972 return CopyViaTemp;
1973}
1974
1975void ARMTargetLowering::PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG,
1976 SDValue Chain, SDValue &Arg,
1977 RegsToPassVector &RegsToPass,
1978 CCValAssign &VA, CCValAssign &NextVA,
1979 SDValue &StackPtr,
1980 SmallVectorImpl<SDValue> &MemOpChains,
1981 bool IsTailCall,
1982 int SPDiff) const {
1983 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
1984 DAG.getVTList(MVT::i32, MVT::i32), Arg);
1985 unsigned id = Subtarget->isLittle() ? 0 : 1;
1986 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
1987
1988 if (NextVA.isRegLoc())
1989 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
1990 else {
1991 assert(NextVA.isMemLoc());
1992 if (!StackPtr.getNode())
1993 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP,
1995
1996 SDValue DstAddr;
1997 MachinePointerInfo DstInfo;
1998 std::tie(DstAddr, DstInfo) =
1999 computeAddrForCallArg(dl, DAG, NextVA, StackPtr, IsTailCall, SPDiff);
2000 MemOpChains.push_back(
2001 DAG.getStore(Chain, dl, fmrrd.getValue(1 - id), DstAddr, DstInfo));
2002 }
2003}
2004
2005static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
2006 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
2008}
2009
2010/// LowerCall - Lowering a call into a callseq_start <-
2011/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
2012/// nodes.
2013SDValue
2014ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2015 SmallVectorImpl<SDValue> &InVals) const {
2016 SelectionDAG &DAG = CLI.DAG;
2017 SDLoc &dl = CLI.DL;
2018 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2019 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2020 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2021 SDValue Chain = CLI.Chain;
2022 SDValue Callee = CLI.Callee;
2023 bool &isTailCall = CLI.IsTailCall;
2024 CallingConv::ID CallConv = CLI.CallConv;
2025 bool doesNotRet = CLI.DoesNotReturn;
2026 bool isVarArg = CLI.IsVarArg;
2027 const CallBase *CB = CLI.CB;
2028
2029 MachineFunction &MF = DAG.getMachineFunction();
2030 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2031 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2032 MachineFunction::CallSiteInfo CSInfo;
2033 bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
2034 bool isThisReturn = false;
2035 bool isCmseNSCall = false;
2036 bool isSibCall = false;
2037 bool PreferIndirect = false;
2038 bool GuardWithBTI = false;
2039
2040 // Analyze operands of the call, assigning locations to each operand.
2042 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
2043 *DAG.getContext());
2044 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, isVarArg));
2045
2046 // Lower 'returns_twice' calls to a pseudo-instruction.
2047 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) &&
2048 !Subtarget->noBTIAtReturnTwice())
2049 GuardWithBTI = AFI->branchTargetEnforcement();
2050
2051 // Set type id for call site info.
2052 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
2053
2054 // Determine whether this is a non-secure function call.
2055 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
2056 isCmseNSCall = true;
2057
2058 // Disable tail calls if they're not supported.
2059 if (!Subtarget->supportsTailCall())
2060 isTailCall = false;
2061
2062 // For both the non-secure calls and the returns from a CMSE entry function,
2063 // the function needs to do some extra work after the call, or before the
2064 // return, respectively, thus it cannot end with a tail call
2065 if (isCmseNSCall || AFI->isCmseNSEntryFunction())
2066 isTailCall = false;
2067
2068 if (isa<GlobalAddressSDNode>(Callee)) {
2069 // If we're optimizing for minimum size and the function is called three or
2070 // more times in this block, we can improve codesize by calling indirectly
2071 // as BLXr has a 16-bit encoding.
2072 auto *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
2073 if (CLI.CB) {
2074 auto *BB = CLI.CB->getParent();
2075 PreferIndirect = Subtarget->isThumb() && Subtarget->hasMinSize() &&
2076 count_if(GV->users(), [&BB](const User *U) {
2077 return isa<Instruction>(U) &&
2078 cast<Instruction>(U)->getParent() == BB;
2079 }) > 2;
2080 }
2081 }
2082 if (isTailCall) {
2083 // Check if it's really possible to do a tail call.
2084 isTailCall =
2085 IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
2086
2087 if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
2088 CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
2089 isSibCall = true;
2090
2091 // We don't support GuaranteedTailCallOpt for ARM, only automatically
2092 // detected sibcalls.
2093 if (isTailCall)
2094 ++NumTailCalls;
2095 }
2096
2097 if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
2098 report_fatal_error("failed to perform tail call elimination on a call "
2099 "site marked musttail");
2100
2101 // Get a count of how many bytes are to be pushed on the stack.
2102 unsigned NumBytes = CCInfo.getStackSize();
2103
2104 // SPDiff is the byte offset of the call's argument area from the callee's.
2105 // Stores to callee stack arguments will be placed in FixedStackSlots offset
2106 // by this amount for a tail call. In a sibling call it must be 0 because the
2107 // caller will deallocate the entire stack and the callee still expects its
2108 // arguments to begin at SP+0. Completely unused for non-tail calls.
2109 int SPDiff = 0;
2110
2111 if (isTailCall && !isSibCall) {
2112 auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
2113 unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
2114
2115 // Since callee will pop argument stack as a tail call, we must keep the
2116 // popped size 16-byte aligned.
2117 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
2118 assert(StackAlign && "data layout string is missing stack alignment");
2119 NumBytes = alignTo(NumBytes, *StackAlign);
2120
2121 // SPDiff will be negative if this tail call requires more space than we
2122 // would automatically have in our incoming argument space. Positive if we
2123 // can actually shrink the stack.
2124 SPDiff = NumReusableBytes - NumBytes;
2125
2126 // If this call requires more stack than we have available from
2127 // LowerFormalArguments, tell FrameLowering to reserve space for it.
2128 if (SPDiff < 0 && AFI->getArgRegsSaveSize() < (unsigned)-SPDiff)
2129 AFI->setArgRegsSaveSize(-SPDiff);
2130 }
2131
2132 if (isSibCall) {
2133 // For sibling tail calls, memory operands are available in our caller's stack.
2134 NumBytes = 0;
2135 } else {
2136 // Adjust the stack pointer for the new arguments...
2137 // These operations are automatically eliminated by the prolog/epilog pass
2138 Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
2139 }
2140
2142 DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy(DAG.getDataLayout()));
2143
2144 RegsToPassVector RegsToPass;
2145 SmallVector<SDValue, 8> MemOpChains;
2146
2147 // If we are doing a tail-call, any byval arguments will be written to stack
2148 // space which was used for incoming arguments. If any the values being used
2149 // are incoming byval arguments to this function, then they might be
2150 // overwritten by the stores of the outgoing arguments. To avoid this, we
2151 // need to make a temporary copy of them in local stack space, then copy back
2152 // to the argument area.
2153 DenseMap<unsigned, SDValue> ByValTemporaries;
2154 SDValue ByValTempChain;
2155 if (isTailCall) {
2156 SmallVector<SDValue, 8> ByValCopyChains;
2157 for (const CCValAssign &VA : ArgLocs) {
2158 unsigned ArgIdx = VA.getValNo();
2159 SDValue Src = OutVals[ArgIdx];
2160 ISD::ArgFlagsTy Flags = Outs[ArgIdx].Flags;
2161
2162 if (!Flags.isByVal())
2163 continue;
2164
2165 SDValue Dst;
2166 MachinePointerInfo DstInfo;
2167 std::tie(Dst, DstInfo) =
2168 computeAddrForCallArg(dl, DAG, VA, SDValue(), true, SPDiff);
2169 ByValCopyKind Copy = ByValNeedsCopyForTailCall(DAG, Src, Dst, Flags);
2170
2171 if (Copy == NoCopy) {
2172 // If the argument is already at the correct offset on the stack
2173 // (because we are forwarding a byval argument from our caller), we
2174 // don't need any copying.
2175 continue;
2176 } else if (Copy == CopyOnce) {
2177 // If the argument is in our local stack frame, no other argument
2178 // preparation can clobber it, so we can copy it to the final location
2179 // later.
2180 ByValTemporaries[ArgIdx] = Src;
2181 } else {
2182 assert(Copy == CopyViaTemp && "unexpected enum value");
2183 // If we might be copying this argument from the outgoing argument
2184 // stack area, we need to copy via a temporary in the local stack
2185 // frame.
2186 int TempFrameIdx = MFI.CreateStackObject(
2187 Flags.getByValSize(), Flags.getNonZeroByValAlign(), false);
2188 SDValue Temp =
2189 DAG.getFrameIndex(TempFrameIdx, getPointerTy(DAG.getDataLayout()));
2190
2191 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
2192 SDValue AlignNode =
2193 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2194
2195 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2196 SDValue Ops[] = {Chain, Temp, Src, SizeNode, AlignNode};
2197 ByValCopyChains.push_back(
2198 DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs, Ops));
2199 ByValTemporaries[ArgIdx] = Temp;
2200 }
2201 }
2202 if (!ByValCopyChains.empty())
2203 ByValTempChain =
2204 DAG.getNode(ISD::TokenFactor, dl, MVT::Other, ByValCopyChains);
2205 }
2206
2207 // During a tail call, stores to the argument area must happen after all of
2208 // the function's incoming arguments have been loaded because they may alias.
2209 // This is done by folding in a TokenFactor from LowerFormalArguments, but
2210 // there's no point in doing so repeatedly so this tracks whether that's
2211 // happened yet.
2212 bool AfterFormalArgLoads = false;
2213
2214 // Walk the register/memloc assignments, inserting copies/loads. In the case
2215 // of tail call optimization, arguments are handled later.
2216 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size();
2217 i != e;
2218 ++i, ++realArgIdx) {
2219 CCValAssign &VA = ArgLocs[i];
2220 SDValue Arg = OutVals[realArgIdx];
2221 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
2222 bool isByVal = Flags.isByVal();
2223
2224 // Promote the value if needed.
2225 switch (VA.getLocInfo()) {
2226 default: llvm_unreachable("Unknown loc info!");
2227 case CCValAssign::Full: break;
2228 case CCValAssign::SExt:
2229 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
2230 break;
2231 case CCValAssign::ZExt:
2232 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
2233 break;
2234 case CCValAssign::AExt:
2235 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
2236 break;
2237 case CCValAssign::BCvt:
2238 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2239 break;
2240 }
2241
2242 if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
2243 Chain = DAG.getStackArgumentTokenFactor(Chain);
2244 if (ByValTempChain) {
2245 // In case of large byval copies, re-using the stackframe for tail-calls
2246 // can lead to overwriting incoming arguments on the stack. Force
2247 // loading these stack arguments before the copy to avoid that.
2248 SmallVector<SDValue, 8> IncomingLoad;
2249 for (unsigned I = 0; I < OutVals.size(); ++I) {
2250 if (Outs[I].Flags.isByVal())
2251 continue;
2252
2253 SDValue OutVal = OutVals[I];
2254 LoadSDNode *OutLN = dyn_cast_or_null<LoadSDNode>(OutVal);
2255 if (!OutLN)
2256 continue;
2257
2258 FrameIndexSDNode *FIN =
2260 if (!FIN)
2261 continue;
2262
2263 if (!MFI.isFixedObjectIndex(FIN->getIndex()))
2264 continue;
2265
2266 for (const CCValAssign &VA : ArgLocs) {
2267 if (VA.isMemLoc())
2268 IncomingLoad.push_back(OutVal.getValue(1));
2269 }
2270 }
2271
2272 // Update the chain to force loads for potentially clobbered argument
2273 // loads to happen before the byval copy.
2274 if (!IncomingLoad.empty()) {
2275 IncomingLoad.push_back(Chain);
2276 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, IncomingLoad);
2277 }
2278
2279 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chain,
2280 ByValTempChain);
2281 }
2282 AfterFormalArgLoads = true;
2283 }
2284
2285 // f16 arguments have their size extended to 4 bytes and passed as if they
2286 // had been copied to the LSBs of a 32-bit register.
2287 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
2288 if (VA.needsCustom() &&
2289 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16)) {
2290 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2291 } else {
2292 // f16 arguments could have been extended prior to argument lowering.
2293 // Mask them arguments if this is a CMSE nonsecure call.
2294 auto ArgVT = Outs[realArgIdx].ArgVT;
2295 if (isCmseNSCall && (ArgVT == MVT::f16)) {
2296 auto LocBits = VA.getLocVT().getSizeInBits();
2297 auto MaskValue = APInt::getLowBitsSet(LocBits, ArgVT.getSizeInBits());
2298 SDValue Mask =
2299 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2300 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2301 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2302 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2303 }
2304 }
2305
2306 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
2307 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
2308 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2309 DAG.getConstant(0, dl, MVT::i32));
2310 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2311 DAG.getConstant(1, dl, MVT::i32));
2312
2313 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
2314 StackPtr, MemOpChains, isTailCall, SPDiff);
2315
2316 VA = ArgLocs[++i]; // skip ahead to next loc
2317 if (VA.isRegLoc()) {
2318 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
2319 StackPtr, MemOpChains, isTailCall, SPDiff);
2320 } else {
2321 assert(VA.isMemLoc());
2322 SDValue DstAddr;
2323 MachinePointerInfo DstInfo;
2324 std::tie(DstAddr, DstInfo) =
2325 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2326 MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
2327 }
2328 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
2329 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
2330 StackPtr, MemOpChains, isTailCall, SPDiff);
2331 } else if (VA.isRegLoc()) {
2332 if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
2333 Outs[0].VT == MVT::i32) {
2334 assert(VA.getLocVT() == MVT::i32 &&
2335 "unexpected calling convention register assignment");
2336 assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
2337 "unexpected use of 'returned'");
2338 isThisReturn = true;
2339 }
2340 const TargetOptions &Options = DAG.getTarget().Options;
2341 if (Options.EmitCallSiteInfo)
2342 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
2343 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2344 } else if (isByVal) {
2345 assert(VA.isMemLoc());
2346 unsigned offset = 0;
2347
2348 // True if this byval aggregate will be split between registers
2349 // and memory.
2350 unsigned ByValArgsCount = CCInfo.getInRegsParamsCount();
2351 unsigned CurByValIdx = CCInfo.getInRegsParamsProcessed();
2352
2353 SDValue ByValSrc;
2354 bool NeedsStackCopy;
2355 if (auto It = ByValTemporaries.find(realArgIdx);
2356 It != ByValTemporaries.end()) {
2357 ByValSrc = It->second;
2358 NeedsStackCopy = true;
2359 } else {
2360 ByValSrc = Arg;
2361 NeedsStackCopy = !isTailCall;
2362 }
2363
2364 // If part of the argument is in registers, load them.
2365 if (CurByValIdx < ByValArgsCount) {
2366 unsigned RegBegin, RegEnd;
2367 CCInfo.getInRegsParamInfo(CurByValIdx, RegBegin, RegEnd);
2368
2369 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2370 unsigned int i, j;
2371 for (i = 0, j = RegBegin; j < RegEnd; i++, j++) {
2372 SDValue Const = DAG.getConstant(4*i, dl, MVT::i32);
2373 SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, Const);
2374 SDValue Load =
2375 DAG.getLoad(PtrVT, dl, Chain, AddArg, MachinePointerInfo(),
2376 DAG.InferPtrAlign(AddArg));
2377 MemOpChains.push_back(Load.getValue(1));
2378 RegsToPass.push_back(std::make_pair(j, Load));
2379 }
2380
2381 // If parameter size outsides register area, "offset" value
2382 // helps us to calculate stack slot for remained part properly.
2383 offset = RegEnd - RegBegin;
2384
2385 CCInfo.nextInRegsParam();
2386 }
2387
2388 // If the memory part of the argument isn't already in the correct place
2389 // (which can happen with tail calls), copy it into the argument area.
2390 if (NeedsStackCopy && Flags.getByValSize() > 4 * offset) {
2391 auto PtrVT = getPointerTy(DAG.getDataLayout());
2392 SDValue Dst;
2393 MachinePointerInfo DstInfo;
2394 std::tie(Dst, DstInfo) =
2395 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2396 SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
2397 SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
2398 SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
2399 MVT::i32);
2400 SDValue AlignNode =
2401 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2402
2403 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2404 SDValue Ops[] = { Chain, Dst, Src, SizeNode, AlignNode};
2405 MemOpChains.push_back(DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs,
2406 Ops));
2407 }
2408 } else {
2409 assert(VA.isMemLoc());
2410 SDValue DstAddr;
2411 MachinePointerInfo DstInfo;
2412 std::tie(DstAddr, DstInfo) =
2413 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2414
2415 SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
2416 MemOpChains.push_back(Store);
2417 }
2418 }
2419
2420 if (!MemOpChains.empty())
2421 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
2422
2423 // Build a sequence of copy-to-reg nodes chained together with token chain
2424 // and flag operands which copy the outgoing args into the appropriate regs.
2425 SDValue InGlue;
2426 for (const auto &[Reg, N] : RegsToPass) {
2427 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
2428 InGlue = Chain.getValue(1);
2429 }
2430
2431 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2432 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2433 // node so that legalize doesn't hack it.
2434 bool isDirect = false;
2435
2436 const TargetMachine &TM = getTargetMachine();
2437 const Triple &TT = TM.getTargetTriple();
2438 const GlobalValue *GVal = nullptr;
2439 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
2440 GVal = G->getGlobal();
2441 bool isStub = !TM.shouldAssumeDSOLocal(GVal) && TT.isOSBinFormatMachO();
2442
2443 bool isARMFunc = !Subtarget->isThumb() || (isStub && !Subtarget->isMClass());
2444 bool isLocalARMFunc = false;
2445 auto PtrVt = getPointerTy(DAG.getDataLayout());
2446
2447 if (Subtarget->genLongCalls()) {
2448 bool isPIC = isPositionIndependent() && !TT.isOSWindows();
2449 if (isPIC && Subtarget->genExecuteOnly())
2450 reportFatalUsageError("long-calls with execute-only and "
2451 "position-independent code is not supported");
2452 if (Subtarget->isROPI())
2453 reportFatalUsageError("long-calls with ROPI is not currently supported");
2454
2455 // Handle a global address or an external symbol. If it's not one of
2456 // those, the target's already in a register, so we don't need to do
2457 // anything extra.
2458 if (isa<GlobalAddressSDNode>(Callee)) {
2459 if (Subtarget->genExecuteOnly()) {
2460 // Execute-only forbids constant pools in .text, so use movw/movt.
2461 // fPIC is not supported with execute-only.
2462 if (Subtarget->useMovt())
2463 ++NumMovwMovt;
2464 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2465 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2466 } else if (isPIC) {
2467 // PIC without execute-only: use GOT-based addressing.
2468 // DSO-local symbols use a plain PC-relative WrapperPIC;
2469 // non-DSO-local symbols additionally load the address from the GOT.
2471 GVal, dl, PtrVt, 0, GVal->isDSOLocal() ? 0 : ARMII::MO_GOT);
2472 Callee = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVt, G);
2473 if (!GVal->isDSOLocal())
2474 Callee =
2475 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2477 } else {
2478 // Neither execute-only nor PIC: load the address from a constant pool.
2479 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2480 ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(
2481 GVal, ARMPCLabelIndex, ARMCP::CPValue, 0);
2482
2483 // Get the address of the callee into a register
2484 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2485 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2486 Callee = DAG.getLoad(
2487 PtrVt, dl, DAG.getEntryNode(), Addr,
2489 }
2490 } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
2491 const char *Sym = S->getSymbol();
2492
2493 if (Subtarget->genExecuteOnly()) {
2494 // Execute-only forbids constant pools in .text, so use movw/movt.
2495 // fPIC is not supported with execute-only.
2496 if (Subtarget->useMovt())
2497 ++NumMovwMovt;
2498 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2499 DAG.getTargetExternalSymbol(Sym, PtrVt, 0));
2500 } else if (isPIC) {
2501 // PIC without execute-only: load the symbol's address from the GOT via
2502 // a GOT_PREL constant pool entry consumed by a PICLDR.
2503 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
2504 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2505 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2506 *DAG.getContext(), Sym, ARMPCLabelIndex, PCAdj, ARMCP::GOT_PREL,
2507 /*AddCurrentAddress=*/true);
2508 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2509 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2510 SDValue GOTOffset = DAG.getLoad(
2511 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2513 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2514 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, GOTOffset, PICLabel);
2515 Callee =
2516 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2518 } else {
2519 // Neither execute-only nor PIC: load the address from a constant pool.
2520 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2521 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2522 *DAG.getContext(), Sym, ARMPCLabelIndex, 0);
2523
2524 // Get the address of the callee into a register
2525 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2526 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2527 Callee = DAG.getLoad(
2528 PtrVt, dl, DAG.getEntryNode(), Addr,
2530 }
2531 }
2532 } else if (isa<GlobalAddressSDNode>(Callee)) {
2533 if (!PreferIndirect) {
2534 isDirect = true;
2535 bool isDef = GVal->isStrongDefinitionForLinker();
2536
2537 // ARM call to a local ARM function is predicable.
2538 isLocalARMFunc = !Subtarget->isThumb() && (isDef || !ARMInterworking);
2539 // tBX takes a register source operand.
2540 if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2541 assert(TT.isOSBinFormatMachO() && "WrapperPIC use on non-MachO?");
2542 Callee = DAG.getNode(
2543 ARMISD::WrapperPIC, dl, PtrVt,
2544 DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, ARMII::MO_NONLAZY));
2545 Callee = DAG.getLoad(
2546 PtrVt, dl, DAG.getEntryNode(), Callee,
2550 } else if (Subtarget->isTargetCOFF()) {
2551 assert(Subtarget->isTargetWindows() &&
2552 "Windows is the only supported COFF target");
2553 unsigned TargetFlags = ARMII::MO_NO_FLAG;
2554 if (GVal->hasDLLImportStorageClass())
2555 TargetFlags = ARMII::MO_DLLIMPORT;
2556 else if (!TM.shouldAssumeDSOLocal(GVal))
2557 TargetFlags = ARMII::MO_COFFSTUB;
2558 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, /*offset=*/0,
2559 TargetFlags);
2560 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
2561 Callee =
2562 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
2563 DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
2565 } else {
2566 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, 0);
2567 }
2568 }
2569 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2570 isDirect = true;
2571 // tBX takes a register source operand.
2572 const char *Sym = S->getSymbol();
2573 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2574 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2575 ARMConstantPoolValue *CPV =
2577 ARMPCLabelIndex, 4);
2578 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2579 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2580 Callee = DAG.getLoad(
2581 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2583 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2584 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, Callee, PICLabel);
2585 } else {
2586 Callee = DAG.getTargetExternalSymbol(Sym, PtrVt, 0);
2587 }
2588 }
2589
2590 if (isCmseNSCall) {
2591 assert(!isARMFunc && !isDirect &&
2592 "Cannot handle call to ARM function or direct call");
2593 if (NumBytes > 0) {
2594 DAG.getContext()->diagnose(
2595 DiagnosticInfoUnsupported(DAG.getMachineFunction().getFunction(),
2596 "call to non-secure function would require "
2597 "passing arguments on stack",
2598 dl.getDebugLoc()));
2599 }
2600 if (isStructRet) {
2601 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2603 "call to non-secure function would return value through pointer",
2604 dl.getDebugLoc()));
2605 }
2606 }
2607
2608 // FIXME: handle tail calls differently.
2609 unsigned CallOpc;
2610 if (Subtarget->isThumb()) {
2611 if (GuardWithBTI)
2612 CallOpc = ARMISD::t2CALL_BTI;
2613 else if (isCmseNSCall)
2614 CallOpc = ARMISD::tSECALL;
2615 else if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
2616 CallOpc = ARMISD::CALL_NOLINK;
2617 else
2618 CallOpc = ARMISD::CALL;
2619 } else {
2620 if (!isDirect && !Subtarget->hasV5TOps())
2621 CallOpc = ARMISD::CALL_NOLINK;
2622 else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
2623 // Emit regular call when code size is the priority
2624 !Subtarget->hasMinSize())
2625 // "mov lr, pc; b _foo" to avoid confusing the RSP
2626 CallOpc = ARMISD::CALL_NOLINK;
2627 else
2628 CallOpc = isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL;
2629 }
2630
2631 // We don't usually want to end the call-sequence here because we would tidy
2632 // the frame up *after* the call, however in the ABI-changing tail-call case
2633 // we've carefully laid out the parameters so that when sp is reset they'll be
2634 // in the correct location.
2635 if (isTailCall && !isSibCall) {
2636 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
2637 InGlue = Chain.getValue(1);
2638 }
2639
2640 std::vector<SDValue> Ops;
2641 Ops.push_back(Chain);
2642 Ops.push_back(Callee);
2643
2644 if (isTailCall) {
2645 Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
2646 }
2647
2648 // Add argument registers to the end of the list so that they are known live
2649 // into the call.
2650 for (const auto &[Reg, N] : RegsToPass)
2651 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2652
2653 // Add a register mask operand representing the call-preserved registers.
2654 const uint32_t *Mask;
2655 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
2656 if (isThisReturn) {
2657 // For 'this' returns, use the R0-preserving mask if applicable
2658 Mask = ARI->getThisReturnPreservedMask(MF, CallConv);
2659 if (!Mask) {
2660 // Set isThisReturn to false if the calling convention is not one that
2661 // allows 'returned' to be modeled in this way, so LowerCallResult does
2662 // not try to pass 'this' straight through
2663 isThisReturn = false;
2664 Mask = ARI->getCallPreservedMask(MF, CallConv);
2665 }
2666 } else
2667 Mask = ARI->getCallPreservedMask(MF, CallConv);
2668
2669 assert(Mask && "Missing call preserved mask for calling convention");
2670 Ops.push_back(DAG.getRegisterMask(Mask));
2671
2672 if (InGlue.getNode())
2673 Ops.push_back(InGlue);
2674
2675 if (isTailCall) {
2677 SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
2678 if (CLI.CFIType)
2679 Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2680 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2681 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2682 return Ret;
2683 }
2684
2685 // Returns a chain and a flag for retval copy to use.
2686 Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
2687 if (CLI.CFIType)
2688 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2689 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2690 InGlue = Chain.getValue(1);
2691 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
2692
2693 // If we're guaranteeing tail-calls will be honoured, the callee must
2694 // pop its own argument stack on return. But this call is *not* a tail call so
2695 // we need to undo that after it returns to restore the status-quo.
2696 bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
2697 uint64_t CalleePopBytes =
2698 canGuaranteeTCO(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : -1U;
2699
2700 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, CalleePopBytes, InGlue, dl);
2701 if (!Ins.empty())
2702 InGlue = Chain.getValue(1);
2703
2704 // Handle result values, copying them out of physregs into vregs that we
2705 // return.
2706 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2707 InVals, isThisReturn,
2708 isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
2709}
2710
2711/// HandleByVal - Every parameter *after* a byval parameter is passed
2712/// on the stack. Remember the next parameter register to allocate,
2713/// and then confiscate the rest of the parameter registers to insure
2714/// this.
2715void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size,
2716 Align Alignment) const {
2717 // Byval (as with any stack) slots are always at least 4 byte aligned.
2718 Alignment = std::max(Alignment, Align(4));
2719
2720 MCRegister Reg = State->AllocateReg(GPRArgRegs);
2721 if (!Reg)
2722 return;
2723
2724 unsigned AlignInRegs = Alignment.value() / 4;
2725 unsigned Waste = (ARM::R4 - Reg) % AlignInRegs;
2726 for (unsigned i = 0; i < Waste; ++i)
2727 Reg = State->AllocateReg(GPRArgRegs);
2728
2729 if (!Reg)
2730 return;
2731
2732 unsigned Excess = 4 * (ARM::R4 - Reg);
2733
2734 // Special case when NSAA != SP and parameter size greater than size of
2735 // all remained GPR regs. In that case we can't split parameter, we must
2736 // send it to stack. We also must set NCRN to R4, so waste all
2737 // remained registers.
2738 const unsigned NSAAOffset = State->getStackSize();
2739 if (NSAAOffset != 0 && Size > Excess) {
2740 while (State->AllocateReg(GPRArgRegs))
2741 ;
2742 return;
2743 }
2744
2745 // First register for byval parameter is the first register that wasn't
2746 // allocated before this method call, so it would be "reg".
2747 // If parameter is small enough to be saved in range [reg, r4), then
2748 // the end (first after last) register would be reg + param-size-in-regs,
2749 // else parameter would be splitted between registers and stack,
2750 // end register would be r4 in this case.
2751 unsigned ByValRegBegin = Reg;
2752 unsigned ByValRegEnd = std::min<unsigned>(Reg + Size / 4, ARM::R4);
2753 State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd);
2754 // Note, first register is allocated in the beginning of function already,
2755 // allocate remained amount of registers we need.
2756 for (unsigned i = Reg + 1; i != ByValRegEnd; ++i)
2757 State->AllocateReg(GPRArgRegs);
2758 // A byval parameter that is split between registers and memory needs its
2759 // size truncated here.
2760 // In the case where the entire structure fits in registers, we set the
2761 // size in memory to zero.
2762 Size = std::max<int>(Size - Excess, 0);
2763}
2764
2765/// IsEligibleForTailCallOptimization - Check whether the call is eligible
2766/// for tail call optimization. Targets which want to do tail call
2767/// optimization should implement this function. Note that this function also
2768/// processes musttail calls, so when this function returns false on a valid
2769/// musttail call, a fatal backend error occurs.
2770bool ARMTargetLowering::IsEligibleForTailCallOptimization(
2772 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
2773 CallingConv::ID CalleeCC = CLI.CallConv;
2774 SDValue Callee = CLI.Callee;
2775 bool isVarArg = CLI.IsVarArg;
2776 const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2777 const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2778 const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2779 const SelectionDAG &DAG = CLI.DAG;
2780 MachineFunction &MF = DAG.getMachineFunction();
2781 const Function &CallerF = MF.getFunction();
2782 CallingConv::ID CallerCC = CallerF.getCallingConv();
2783
2784 assert(Subtarget->supportsTailCall());
2785
2786 // Indirect tail-calls require a register to hold the target address. That
2787 // register must be:
2788 // * Allocatable (i.e. r0-r7 if the target is Thumb1).
2789 // * Not callee-saved, so must be one of r0-r3 or r12.
2790 // * Not used to hold an argument to the tail-called function, which might be
2791 // in r0-r3.
2792 // * Not used to hold the return address authentication code, which is in r12
2793 // if enabled.
2794 // Sometimes, no register matches all of these conditions, so we can't do a
2795 // tail-call.
2796 if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) {
2797 SmallSet<MCPhysReg, 5> AddressRegisters = {ARM::R0, ARM::R1, ARM::R2,
2798 ARM::R3};
2799 if (!(Subtarget->isThumb1Only() ||
2800 MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)))
2801 AddressRegisters.insert(ARM::R12);
2802 for (const CCValAssign &AL : ArgLocs)
2803 if (AL.isRegLoc())
2804 AddressRegisters.erase(AL.getLocReg());
2805 if (AddressRegisters.empty()) {
2806 LLVM_DEBUG(dbgs() << "false (no reg to hold function pointer)\n");
2807 return false;
2808 }
2809 }
2810
2811 // Look for obvious safe cases to perform tail call optimization that do not
2812 // require ABI changes. This is what gcc calls sibcall.
2813
2814 // Exception-handling functions need a special set of instructions to indicate
2815 // a return to the hardware. Tail-calling another function would probably
2816 // break this.
2817 if (CallerF.hasFnAttribute("interrupt")) {
2818 LLVM_DEBUG(dbgs() << "false (interrupt attribute)\n");
2819 return false;
2820 }
2821
2822 if (canGuaranteeTCO(CalleeCC,
2823 getTargetMachine().Options.GuaranteedTailCallOpt)) {
2824 LLVM_DEBUG(dbgs() << (CalleeCC == CallerCC ? "true" : "false")
2825 << " (guaranteed tail-call CC)\n");
2826 return CalleeCC == CallerCC;
2827 }
2828
2829 // Also avoid sibcall optimization if either caller or callee uses struct
2830 // return semantics.
2831 bool isCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
2832 bool isCallerStructRet = MF.getFunction().hasStructRetAttr();
2833 if (isCalleeStructRet != isCallerStructRet) {
2834 LLVM_DEBUG(dbgs() << "false (struct-ret)\n");
2835 return false;
2836 }
2837
2838 // Externally-defined functions with weak linkage should not be
2839 // tail-called on ARM when the OS does not support dynamic
2840 // pre-emption of symbols, as the AAELF spec requires normal calls
2841 // to undefined weak functions to be replaced with a NOP or jump to the
2842 // next instruction. The behaviour of branch instructions in this
2843 // situation (as used for tail calls) is implementation-defined, so we
2844 // cannot rely on the linker replacing the tail call with a return.
2845 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2846 const GlobalValue *GV = G->getGlobal();
2847 const Triple &TT = getTargetMachine().getTargetTriple();
2848 if (GV->hasExternalWeakLinkage() &&
2849 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
2850 TT.isOSBinFormatMachO())) {
2851 LLVM_DEBUG(dbgs() << "false (external weak linkage)\n");
2852 return false;
2853 }
2854 }
2855
2856 // Check that the call results are passed in the same way.
2857 LLVMContext &C = *DAG.getContext();
2859 getEffectiveCallingConv(CalleeCC, isVarArg),
2860 getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
2861 CCAssignFnForReturn(CalleeCC, isVarArg),
2862 CCAssignFnForReturn(CallerCC, CallerF.isVarArg()))) {
2863 LLVM_DEBUG(dbgs() << "false (incompatible results)\n");
2864 return false;
2865 }
2866 // The callee has to preserve all registers the caller needs to preserve.
2867 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
2868 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
2869 if (CalleeCC != CallerCC) {
2870 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
2871 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) {
2872 LLVM_DEBUG(dbgs() << "false (not all registers preserved)\n");
2873 return false;
2874 }
2875 }
2876
2877 // If Caller's vararg argument has been split between registers and stack, do
2878 // not perform tail call, since part of the argument is in caller's local
2879 // frame.
2880 const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
2881 if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
2882 LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
2883 return false;
2884 }
2885
2886 // If the callee takes no arguments then go on to check the results of the
2887 // call.
2888 const MachineRegisterInfo &MRI = MF.getRegInfo();
2889 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals)) {
2890 LLVM_DEBUG(dbgs() << "false (parameters in CSRs do not match)\n");
2891 return false;
2892 }
2893
2894 // If the stack arguments for this call do not fit into our own save area then
2895 // the call cannot be made tail.
2896 if (CCInfo.getStackSize() > AFI_Caller->getArgumentStackSize())
2897 return false;
2898
2899 LLVM_DEBUG(dbgs() << "true\n");
2900 return true;
2901}
2902
2903bool
2904ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2905 MachineFunction &MF, bool isVarArg,
2907 LLVMContext &Context, const Type *RetTy) const {
2909 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
2910 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2911}
2912
2914 const SDLoc &DL, SelectionDAG &DAG) {
2915 const MachineFunction &MF = DAG.getMachineFunction();
2916 const Function &F = MF.getFunction();
2917
2918 StringRef IntKind = F.getFnAttribute("interrupt").getValueAsString();
2919
2920 // See ARM ARM v7 B1.8.3. On exception entry LR is set to a possibly offset
2921 // version of the "preferred return address". These offsets affect the return
2922 // instruction if this is a return from PL1 without hypervisor extensions.
2923 // IRQ/FIQ: +4 "subs pc, lr, #4"
2924 // SWI: 0 "subs pc, lr, #0"
2925 // ABORT: +4 "subs pc, lr, #4"
2926 // UNDEF: +4/+2 "subs pc, lr, #0"
2927 // UNDEF varies depending on where the exception came from ARM or Thumb
2928 // mode. Alongside GCC, we throw our hands up in disgust and pretend it's 0.
2929
2930 int64_t LROffset;
2931 if (IntKind == "" || IntKind == "IRQ" || IntKind == "FIQ" ||
2932 IntKind == "ABORT")
2933 LROffset = 4;
2934 else if (IntKind == "SWI" || IntKind == "UNDEF")
2935 LROffset = 0;
2936 else
2937 report_fatal_error("Unsupported interrupt attribute. If present, value "
2938 "must be one of: IRQ, FIQ, SWI, ABORT or UNDEF");
2939
2940 RetOps.insert(RetOps.begin() + 1,
2941 DAG.getConstant(LROffset, DL, MVT::i32, false));
2942
2943 return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
2944}
2945
2946SDValue
2947ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2948 bool isVarArg,
2950 const SmallVectorImpl<SDValue> &OutVals,
2951 const SDLoc &dl, SelectionDAG &DAG) const {
2952 // CCValAssign - represent the assignment of the return value to a location.
2954
2955 // CCState - Info about the registers and stack slots.
2956 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
2957 *DAG.getContext());
2958
2959 // Analyze outgoing return values.
2960 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2961
2962 SDValue Glue;
2964 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
2965 bool isLittleEndian = Subtarget->isLittle();
2966
2967 MachineFunction &MF = DAG.getMachineFunction();
2968 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2969 AFI->setReturnRegsCount(RVLocs.size());
2970
2971 // Report error if cmse entry function returns structure through first ptr arg.
2972 if (AFI->isCmseNSEntryFunction() && MF.getFunction().hasStructRetAttr()) {
2973 // Note: using an empty SDLoc(), as the first line of the function is a
2974 // better place to report than the last line.
2975 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2977 "secure entry function would return value through pointer",
2978 SDLoc().getDebugLoc()));
2979 }
2980
2981 // Copy the result values into the output registers.
2982 for (unsigned i = 0, realRVLocIdx = 0;
2983 i != RVLocs.size();
2984 ++i, ++realRVLocIdx) {
2985 CCValAssign &VA = RVLocs[i];
2986 assert(VA.isRegLoc() && "Can only return in registers!");
2987
2988 SDValue Arg = OutVals[realRVLocIdx];
2989 bool ReturnF16 = false;
2990
2991 if (Subtarget->hasFullFP16() && Subtarget->isTargetHardFloat()) {
2992 // Half-precision return values can be returned like this:
2993 //
2994 // t11 f16 = fadd ...
2995 // t12: i16 = bitcast t11
2996 // t13: i32 = zero_extend t12
2997 // t14: f32 = bitcast t13 <~~~~~~~ Arg
2998 //
2999 // to avoid code generation for bitcasts, we simply set Arg to the node
3000 // that produces the f16 value, t11 in this case.
3001 //
3002 if (Arg.getValueType() == MVT::f32 && Arg.getOpcode() == ISD::BITCAST) {
3003 SDValue ZE = Arg.getOperand(0);
3004 if (ZE.getOpcode() == ISD::ZERO_EXTEND && ZE.getValueType() == MVT::i32) {
3005 SDValue BC = ZE.getOperand(0);
3006 if (BC.getOpcode() == ISD::BITCAST && BC.getValueType() == MVT::i16) {
3007 Arg = BC.getOperand(0);
3008 ReturnF16 = true;
3009 }
3010 }
3011 }
3012 }
3013
3014 switch (VA.getLocInfo()) {
3015 default: llvm_unreachable("Unknown loc info!");
3016 case CCValAssign::Full: break;
3017 case CCValAssign::BCvt:
3018 if (!ReturnF16)
3019 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3020 break;
3021 }
3022
3023 // Mask f16 arguments if this is a CMSE nonsecure entry.
3024 auto RetVT = Outs[realRVLocIdx].ArgVT;
3025 if (AFI->isCmseNSEntryFunction() && (RetVT == MVT::f16)) {
3026 if (VA.needsCustom() && VA.getValVT() == MVT::f16) {
3027 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
3028 } else {
3029 auto LocBits = VA.getLocVT().getSizeInBits();
3030 auto MaskValue = APInt::getLowBitsSet(LocBits, RetVT.getSizeInBits());
3031 SDValue Mask =
3032 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
3033 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
3034 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
3035 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3036 }
3037 }
3038
3039 if (VA.needsCustom() &&
3040 (VA.getLocVT() == MVT::v2f64 || VA.getLocVT() == MVT::f64)) {
3041 if (VA.getLocVT() == MVT::v2f64) {
3042 // Extract the first half and return it in two registers.
3043 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3044 DAG.getConstant(0, dl, MVT::i32));
3045 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
3046 DAG.getVTList(MVT::i32, MVT::i32), Half);
3047
3048 Chain =
3049 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3050 HalfGPRs.getValue(isLittleEndian ? 0 : 1), Glue);
3051 Glue = Chain.getValue(1);
3052 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3053 VA = RVLocs[++i]; // skip ahead to next loc
3054 Chain =
3055 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3056 HalfGPRs.getValue(isLittleEndian ? 1 : 0), Glue);
3057 Glue = Chain.getValue(1);
3058 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3059 VA = RVLocs[++i]; // skip ahead to next loc
3060
3061 // Extract the 2nd half and fall through to handle it as an f64 value.
3062 Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3063 DAG.getConstant(1, dl, MVT::i32));
3064 }
3065 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
3066 // available.
3067 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
3068 DAG.getVTList(MVT::i32, MVT::i32), Arg);
3069 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3070 fmrrd.getValue(isLittleEndian ? 0 : 1), Glue);
3071 Glue = Chain.getValue(1);
3072 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3073 VA = RVLocs[++i]; // skip ahead to next loc
3074 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3075 fmrrd.getValue(isLittleEndian ? 1 : 0), Glue);
3076 } else
3077 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
3078
3079 // Guarantee that all emitted copies are
3080 // stuck together, avoiding something bad.
3081 Glue = Chain.getValue(1);
3082 RetOps.push_back(DAG.getRegister(
3083 VA.getLocReg(), ReturnF16 ? Arg.getValueType() : VA.getLocVT()));
3084 }
3085 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
3086 const MCPhysReg *I =
3087 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3088 if (I) {
3089 for (; *I; ++I) {
3090 if (ARM::GPRRegClass.contains(*I))
3091 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3092 else if (ARM::DPRRegClass.contains(*I))
3094 else
3095 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3096 }
3097 }
3098
3099 // Update chain and glue.
3100 RetOps[0] = Chain;
3101 if (Glue.getNode())
3102 RetOps.push_back(Glue);
3103
3104 // CPUs which aren't M-class use a special sequence to return from
3105 // exceptions (roughly, any instruction setting pc and cpsr simultaneously,
3106 // though we use "subs pc, lr, #N").
3107 //
3108 // M-class CPUs actually use a normal return sequence with a special
3109 // (hardware-provided) value in LR, so the normal code path works.
3110 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt") &&
3111 !Subtarget->isMClass()) {
3112 if (Subtarget->isThumb1Only())
3113 report_fatal_error("interrupt attribute is not supported in Thumb1");
3114 return LowerInterruptReturn(RetOps, dl, DAG);
3115 }
3116
3117 unsigned RetNode =
3118 AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
3119 return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
3120}
3121
3122bool ARMTargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
3123 if (N->getNumValues() != 1)
3124 return false;
3125 if (!N->hasNUsesOfValue(1, 0))
3126 return false;
3127
3128 SDValue TCChain = Chain;
3129 SDNode *Copy = *N->user_begin();
3130 if (Copy->getOpcode() == ISD::CopyToReg) {
3131 // If the copy has a glue operand, we conservatively assume it isn't safe to
3132 // perform a tail call.
3133 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3134 return false;
3135 TCChain = Copy->getOperand(0);
3136 } else if (Copy->getOpcode() == ARMISD::VMOVRRD) {
3137 SDNode *VMov = Copy;
3138 // f64 returned in a pair of GPRs.
3139 SmallPtrSet<SDNode*, 2> Copies;
3140 for (SDNode *U : VMov->users()) {
3141 if (U->getOpcode() != ISD::CopyToReg)
3142 return false;
3143 Copies.insert(U);
3144 }
3145 if (Copies.size() > 2)
3146 return false;
3147
3148 for (SDNode *U : VMov->users()) {
3149 SDValue UseChain = U->getOperand(0);
3150 if (Copies.count(UseChain.getNode()))
3151 // Second CopyToReg
3152 Copy = U;
3153 else {
3154 // We are at the top of this chain.
3155 // If the copy has a glue operand, we conservatively assume it
3156 // isn't safe to perform a tail call.
3157 if (U->getOperand(U->getNumOperands() - 1).getValueType() == MVT::Glue)
3158 return false;
3159 // First CopyToReg
3160 TCChain = UseChain;
3161 }
3162 }
3163 } else if (Copy->getOpcode() == ISD::BITCAST) {
3164 // f32 returned in a single GPR.
3165 if (!Copy->hasOneUse())
3166 return false;
3167 Copy = *Copy->user_begin();
3168 if (Copy->getOpcode() != ISD::CopyToReg || !Copy->hasNUsesOfValue(1, 0))
3169 return false;
3170 // If the copy has a glue operand, we conservatively assume it isn't safe to
3171 // perform a tail call.
3172 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3173 return false;
3174 TCChain = Copy->getOperand(0);
3175 } else {
3176 return false;
3177 }
3178
3179 bool HasRet = false;
3180 for (const SDNode *U : Copy->users()) {
3181 if (U->getOpcode() != ARMISD::RET_GLUE &&
3182 U->getOpcode() != ARMISD::INTRET_GLUE)
3183 return false;
3184 HasRet = true;
3185 }
3186
3187 if (!HasRet)
3188 return false;
3189
3190 Chain = TCChain;
3191 return true;
3192}
3193
3194bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
3195 if (!Subtarget->supportsTailCall())
3196 return false;
3197
3198 if (!CI->isTailCall())
3199 return false;
3200
3201 return true;
3202}
3203
3204// Trying to write a 64 bit value so need to split into two 32 bit values first,
3205// and pass the lower and high parts through.
3207 SDLoc DL(Op);
3208 SDValue WriteValue = Op->getOperand(2);
3209
3210 // This function is only supposed to be called for i64 type argument.
3211 assert(WriteValue.getValueType() == MVT::i64
3212 && "LowerWRITE_REGISTER called for non-i64 type argument.");
3213
3214 SDValue Lo, Hi;
3215 std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32);
3216 SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi };
3217 return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops);
3218}
3219
3220// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3221// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
3222// one of the above mentioned nodes. It has to be wrapped because otherwise
3223// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3224// be used to form addressing mode. These wrapped nodes will be selected
3225// into MOVi.
3226SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
3227 SelectionDAG &DAG) const {
3228 EVT PtrVT = Op.getValueType();
3229 // FIXME there is no actual debug info here
3230 SDLoc dl(Op);
3231 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3232 SDValue Res;
3233
3234 // When generating execute-only code Constant Pools must be promoted to the
3235 // global data section. It's a bit ugly that we can't share them across basic
3236 // blocks, but this way we guarantee that execute-only behaves correct with
3237 // position-independent addressing modes.
3238 if (Subtarget->genExecuteOnly()) {
3239 auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
3240 auto *T = CP->getType();
3241 auto C = const_cast<Constant*>(CP->getConstVal());
3242 auto M = DAG.getMachineFunction().getFunction().getParent();
3243 auto GV = new GlobalVariable(
3244 *M, T, /*isConstant=*/true, GlobalVariable::InternalLinkage, C,
3245 Twine(DAG.getDataLayout().getInternalSymbolPrefix()) + "CP" +
3246 Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
3247 Twine(AFI->createPICLabelUId()));
3248 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3249 return LowerGlobalAddress(GA, DAG);
3250 }
3251
3252 // The 16-bit ADR instruction can only encode offsets that are multiples of 4,
3253 // so we need to align to at least 4 bytes when we don't have 32-bit ADR.
3254 Align CPAlign = CP->getAlign();
3255 if (Subtarget->isThumb1Only())
3256 CPAlign = std::max(CPAlign, Align(4));
3258 Res =
3259 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CPAlign);
3260 else
3261 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CPAlign);
3262 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
3263}
3264
3266 // If we don't have a 32-bit pc-relative branch instruction then the jump
3267 // table consists of block addresses. Usually this is inline, but for
3268 // execute-only it must be placed out-of-line.
3269 if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
3272}
3273
3274SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
3275 SelectionDAG &DAG) const {
3278 unsigned ARMPCLabelIndex = 0;
3279 SDLoc DL(Op);
3280 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3281 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
3282 SDValue CPAddr;
3283 bool IsPositionIndependent = isPositionIndependent() || Subtarget->isROPI();
3284 if (!IsPositionIndependent) {
3285 CPAddr = DAG.getTargetConstantPool(BA, PtrVT, Align(4));
3286 } else {
3287 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3288 ARMPCLabelIndex = AFI->createPICLabelUId();
3290 ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex,
3291 ARMCP::CPBlockAddress, PCAdj);
3292 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3293 }
3294 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
3295 SDValue Result = DAG.getLoad(
3296 PtrVT, DL, DAG.getEntryNode(), CPAddr,
3298 if (!IsPositionIndependent)
3299 return Result;
3300 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, DL, MVT::i32);
3301 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
3302}
3303
3304/// Convert a TLS address reference into the correct sequence of loads
3305/// and calls to compute the variable's address for Darwin, and return an
3306/// SDValue containing the final node.
3307
3308/// Darwin only has one TLS scheme which must be capable of dealing with the
3309/// fully general situation, in the worst case. This means:
3310/// + "extern __thread" declaration.
3311/// + Defined in a possibly unknown dynamic library.
3312///
3313/// The general system is that each __thread variable has a [3 x i32] descriptor
3314/// which contains information used by the runtime to calculate the address. The
3315/// only part of this the compiler needs to know about is the first word, which
3316/// contains a function pointer that must be called with the address of the
3317/// entire descriptor in "r0".
3318///
3319/// Since this descriptor may be in a different unit, in general access must
3320/// proceed along the usual ARM rules. A common sequence to produce is:
3321///
3322/// movw rT1, :lower16:_var$non_lazy_ptr
3323/// movt rT1, :upper16:_var$non_lazy_ptr
3324/// ldr r0, [rT1]
3325/// ldr rT2, [r0]
3326/// blx rT2
3327/// [...address now in r0...]
3328SDValue
3329ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
3330 SelectionDAG &DAG) const {
3331 assert(getTargetMachine().getTargetTriple().isOSDarwin() &&
3332 "This function expects a Darwin target");
3333 SDLoc DL(Op);
3334
3335 // First step is to get the address of the actua global symbol. This is where
3336 // the TLS descriptor lives.
3337 SDValue DescAddr = LowerGlobalAddressDarwin(Op, DAG);
3338
3339 // The first entry in the descriptor is a function pointer that we must call
3340 // to obtain the address of the variable.
3341 SDValue Chain = DAG.getEntryNode();
3342 SDValue FuncTLVGet = DAG.getLoad(
3343 MVT::i32, DL, Chain, DescAddr,
3347 Chain = FuncTLVGet.getValue(1);
3348
3349 MachineFunction &F = DAG.getMachineFunction();
3350 MachineFrameInfo &MFI = F.getFrameInfo();
3351 MFI.setAdjustsStack(true);
3352
3353 // TLS calls preserve all registers except those that absolutely must be
3354 // trashed: R0 (it takes an argument), LR (it's a call) and CPSR (let's not be
3355 // silly).
3356 auto TRI =
3358 auto ARI = static_cast<const ARMRegisterInfo *>(TRI);
3359 const uint32_t *Mask = ARI->getTLSCallPreservedMask(DAG.getMachineFunction());
3360
3361 // Finally, we can make the call. This is just a degenerate version of a
3362 // normal AArch64 call node: r0 takes the address of the descriptor, and
3363 // returns the address of the variable in this thread.
3364 Chain = DAG.getCopyToReg(Chain, DL, ARM::R0, DescAddr, SDValue());
3365 Chain =
3366 DAG.getNode(ARMISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
3367 Chain, FuncTLVGet, DAG.getRegister(ARM::R0, MVT::i32),
3368 DAG.getRegisterMask(Mask), Chain.getValue(1));
3369 return DAG.getCopyFromReg(Chain, DL, ARM::R0, MVT::i32, Chain.getValue(1));
3370}
3371
3372SDValue
3373ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
3374 SelectionDAG &DAG) const {
3375 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3376 "Windows specific TLS lowering");
3377
3378 SDValue Chain = DAG.getEntryNode();
3379 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3380 SDLoc DL(Op);
3381
3382 // Load the current TEB (thread environment block)
3383 SDValue Ops[] = {Chain,
3384 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
3385 DAG.getTargetConstant(15, DL, MVT::i32),
3386 DAG.getTargetConstant(0, DL, MVT::i32),
3387 DAG.getTargetConstant(13, DL, MVT::i32),
3388 DAG.getTargetConstant(0, DL, MVT::i32),
3389 DAG.getTargetConstant(2, DL, MVT::i32)};
3390 SDValue CurrentTEB = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
3391 DAG.getVTList(MVT::i32, MVT::Other), Ops);
3392
3393 SDValue TEB = CurrentTEB.getValue(0);
3394 Chain = CurrentTEB.getValue(1);
3395
3396 // Load the ThreadLocalStoragePointer from the TEB
3397 // A pointer to the TLS array is located at offset 0x2c from the TEB.
3398 SDValue TLSArray =
3399 DAG.getNode(ISD::ADD, DL, PtrVT, TEB, DAG.getIntPtrConstant(0x2c, DL));
3400 TLSArray = DAG.getLoad(PtrVT, DL, Chain, TLSArray, MachinePointerInfo());
3401
3402 // The pointer to the thread's TLS data area is at the TLS Index scaled by 4
3403 // offset into the TLSArray.
3404
3405 // Load the TLS index from the C runtime
3406 SDValue TLSIndex =
3407 DAG.getTargetExternalSymbol("_tls_index", PtrVT, ARMII::MO_NO_FLAG);
3408 TLSIndex = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, TLSIndex);
3409 TLSIndex = DAG.getLoad(PtrVT, DL, Chain, TLSIndex, MachinePointerInfo());
3410
3411 SDValue Slot = DAG.getNode(ISD::SHL, DL, PtrVT, TLSIndex,
3412 DAG.getConstant(2, DL, MVT::i32));
3413 SDValue TLS = DAG.getLoad(PtrVT, DL, Chain,
3414 DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
3415 MachinePointerInfo());
3416
3417 // Get the offset of the start of the .tls section (section base)
3418 const auto *GA = cast<GlobalAddressSDNode>(Op);
3419 auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
3420 SDValue Offset = DAG.getLoad(
3421 PtrVT, DL, Chain,
3422 DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
3423 DAG.getTargetConstantPool(CPV, PtrVT, Align(4))),
3425
3426 return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
3427}
3428
3429// Lower ISD::GlobalTLSAddress using the "general dynamic" model
3430SDValue
3431ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
3432 SelectionDAG &DAG) const {
3433 SDLoc dl(GA);
3434 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3435 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3436 MachineFunction &MF = DAG.getMachineFunction();
3437 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3438 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3439 ARMConstantPoolValue *CPV =
3440 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3441 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
3442 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3443 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
3444 Argument = DAG.getLoad(
3445 PtrVT, dl, DAG.getEntryNode(), Argument,
3447 SDValue Chain = Argument.getValue(1);
3448
3449 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3450 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
3451
3452 // call __tls_get_addr.
3454 Args.emplace_back(Argument, Type::getInt32Ty(*DAG.getContext()));
3455
3456 // FIXME: is there useful debug info available here?
3457 TargetLowering::CallLoweringInfo CLI(DAG);
3458 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3460 DAG.getExternalSymbol("__tls_get_addr", PtrVT), std::move(Args));
3461
3462 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3463 return CallResult.first;
3464}
3465
3466// Lower ISD::GlobalTLSAddress using the "initial exec" or
3467// "local exec" model.
3468SDValue
3469ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
3470 SelectionDAG &DAG,
3471 TLSModel::Model model) const {
3472 const GlobalValue *GV = GA->getGlobal();
3473 SDLoc dl(GA);
3475 SDValue Chain = DAG.getEntryNode();
3476 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3477 // Get the Thread Pointer
3478 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3479
3480 if (model == TLSModel::InitialExec) {
3481 MachineFunction &MF = DAG.getMachineFunction();
3482 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3483 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3484 // Initial exec model.
3485 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3486 ARMConstantPoolValue *CPV =
3487 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3489 true);
3490 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3491 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3492 Offset = DAG.getLoad(
3493 PtrVT, dl, Chain, Offset,
3495 Chain = Offset.getValue(1);
3496
3497 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3498 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
3499
3500 Offset = DAG.getLoad(
3501 PtrVT, dl, Chain, Offset,
3503 } else {
3504 // local exec model
3505 assert(model == TLSModel::LocalExec);
3506 ARMConstantPoolValue *CPV =
3508 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3509 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3510 Offset = DAG.getLoad(
3511 PtrVT, dl, Chain, Offset,
3513 }
3514
3515 // The address of the thread local variable is the add of the thread
3516 // pointer with the offset of the variable.
3517 return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
3518}
3519
3520SDValue
3521ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
3522 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
3523 if (DAG.getTarget().useEmulatedTLS())
3524 return LowerToTLSEmulatedModel(GA, DAG);
3525
3526 const Triple &TT = getTargetMachine().getTargetTriple();
3527 if (TT.isOSDarwin())
3528 return LowerGlobalTLSAddressDarwin(Op, DAG);
3529
3530 if (TT.isOSWindows())
3531 return LowerGlobalTLSAddressWindows(Op, DAG);
3532
3533 // TODO: implement the "local dynamic" model
3534 assert(TT.isOSBinFormatELF() && "Only ELF implemented here");
3536
3537 switch (model) {
3540 return LowerToTLSGeneralDynamicModel(GA, DAG);
3543 return LowerToTLSExecModels(GA, DAG, model);
3544 }
3545 llvm_unreachable("bogus TLS model");
3546}
3547
3548/// Return true if all users of V are within function F, looking through
3549/// ConstantExprs.
3550static bool allUsersAreInFunction(const Value *V, const Function *F) {
3551 SmallVector<const User*,4> Worklist(V->users());
3552 while (!Worklist.empty()) {
3553 auto *U = Worklist.pop_back_val();
3554 if (isa<ConstantExpr>(U)) {
3555 append_range(Worklist, U->users());
3556 continue;
3557 }
3558
3559 auto *I = dyn_cast<Instruction>(U);
3560 if (!I || I->getParent()->getParent() != F)
3561 return false;
3562 }
3563 return true;
3564}
3565
3567 const GlobalValue *GV, SelectionDAG &DAG,
3568 EVT PtrVT, const SDLoc &dl) {
3569 // If we're creating a pool entry for a constant global with unnamed address,
3570 // and the global is small enough, we can emit it inline into the constant pool
3571 // to save ourselves an indirection.
3572 //
3573 // This is a win if the constant is only used in one function (so it doesn't
3574 // need to be duplicated) or duplicating the constant wouldn't increase code
3575 // size (implying the constant is no larger than 4 bytes).
3576 const Function &F = DAG.getMachineFunction().getFunction();
3577
3578 // We rely on this decision to inline being idempotent and unrelated to the
3579 // use-site. We know that if we inline a variable at one use site, we'll
3580 // inline it elsewhere too (and reuse the constant pool entry). Fast-isel
3581 // doesn't know about this optimization, so bail out if it's enabled else
3582 // we could decide to inline here (and thus never emit the GV) but require
3583 // the GV from fast-isel generated code.
3586 return SDValue();
3587
3588 auto *GVar = dyn_cast<GlobalVariable>(GV);
3589 if (!GVar || !GVar->hasInitializer() ||
3590 !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
3591 !GVar->hasLocalLinkage())
3592 return SDValue();
3593
3594 // If we inline a value that contains relocations, we move the relocations
3595 // from .data to .text. This is not allowed in position-independent code.
3596 auto *Init = GVar->getInitializer();
3597 if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3598 Init->needsDynamicRelocation())
3599 return SDValue();
3600
3601 // The constant islands pass can only really deal with alignment requests
3602 // <= 4 bytes and cannot pad constants itself. Therefore we cannot promote
3603 // any type wanting greater alignment requirements than 4 bytes. We also
3604 // can only promote constants that are multiples of 4 bytes in size or
3605 // are paddable to a multiple of 4. Currently we only try and pad constants
3606 // that are strings for simplicity.
3607 auto *CDAInit = dyn_cast<ConstantDataArray>(Init);
3608 unsigned Size = DAG.getDataLayout().getTypeAllocSize(Init->getType());
3609 Align PrefAlign = DAG.getDataLayout().getPreferredAlign(GVar);
3610 unsigned RequiredPadding = 4 - (Size % 4);
3611 bool PaddingPossible =
3612 RequiredPadding == 4 || (CDAInit && CDAInit->isString());
3613 if (!PaddingPossible || PrefAlign > 4 || Size > ConstpoolPromotionMaxSize ||
3614 Size == 0)
3615 return SDValue();
3616
3617 unsigned PaddedSize = Size + ((RequiredPadding == 4) ? 0 : RequiredPadding);
3619 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3620
3621 // We can't bloat the constant pool too much, else the ConstantIslands pass
3622 // may fail to converge. If we haven't promoted this global yet (it may have
3623 // multiple uses), and promoting it would increase the constant pool size (Sz
3624 // > 4), ensure we have space to do so up to MaxTotal.
3625 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar) && Size > 4)
3626 if (AFI->getPromotedConstpoolIncrease() + PaddedSize - 4 >=
3628 return SDValue();
3629
3630 // This is only valid if all users are in a single function; we can't clone
3631 // the constant in general. The LLVM IR unnamed_addr allows merging
3632 // constants, but not cloning them.
3633 //
3634 // We could potentially allow cloning if we could prove all uses of the
3635 // constant in the current function don't care about the address, like
3636 // printf format strings. But that isn't implemented for now.
3637 if (!allUsersAreInFunction(GVar, &F))
3638 return SDValue();
3639
3640 // We're going to inline this global. Pad it out if needed.
3641 if (RequiredPadding != 4) {
3642 StringRef S = CDAInit->getAsString();
3643
3645 std::copy(S.bytes_begin(), S.bytes_end(), V.begin());
3646 while (RequiredPadding--)
3647 V.push_back(0);
3649 }
3650
3651 auto CPVal = ARMConstantPoolConstant::Create(GVar, Init);
3652 SDValue CPAddr = DAG.getTargetConstantPool(CPVal, PtrVT, Align(4));
3653 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar)) {
3656 PaddedSize - 4);
3657 }
3658 ++NumConstpoolPromoted;
3659 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3660}
3661
3663 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
3664 if (!(GV = GA->getAliaseeObject()))
3665 return false;
3666 if (const auto *V = dyn_cast<GlobalVariable>(GV))
3667 return V->isConstant();
3668 return isa<Function>(GV);
3669}
3670
3671SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3672 SelectionDAG &DAG) const {
3673 switch (Subtarget->getTargetTriple().getObjectFormat()) {
3674 default: llvm_unreachable("unknown object format");
3675 case Triple::COFF:
3676 return LowerGlobalAddressWindows(Op, DAG);
3677 case Triple::ELF:
3678 return LowerGlobalAddressELF(Op, DAG);
3679 case Triple::MachO:
3680 return LowerGlobalAddressDarwin(Op, DAG);
3681 }
3682}
3683
3684SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
3685 SelectionDAG &DAG) const {
3686 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3687 SDLoc dl(Op);
3688 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3689 bool IsRO = isReadOnly(GV);
3690
3691 // promoteToConstantPool only if not generating XO text section
3692 if (GV->isDSOLocal() && !Subtarget->genExecuteOnly())
3693 if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
3694 return V;
3695
3696 if (isPositionIndependent()) {
3698 GV, dl, PtrVT, 0, GV->isDSOLocal() ? 0 : ARMII::MO_GOT);
3699 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3700 if (!GV->isDSOLocal())
3701 Result =
3702 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3704 return Result;
3705 } else if (Subtarget->isROPI() && IsRO) {
3706 // PC-relative.
3707 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3708 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3709 return Result;
3710 } else if (Subtarget->isRWPI() && !IsRO) {
3711 // SB-relative.
3712 SDValue RelAddr;
3713 if (Subtarget->useMovt()) {
3714 ++NumMovwMovt;
3715 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_SBREL);
3716 RelAddr = DAG.getNode(ARMISD::Wrapper, dl, PtrVT, G);
3717 } else { // use literal pool for address constant
3718 ARMConstantPoolValue *CPV =
3720 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3721 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3722 RelAddr = DAG.getLoad(
3723 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3725 }
3726 SDValue SB = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::R9, PtrVT);
3727 SDValue Result = DAG.getNode(ISD::ADD, dl, PtrVT, SB, RelAddr);
3728 return Result;
3729 }
3730
3731 // If we have T2 ops, we can materialize the address directly via movt/movw
3732 // pair. This is always cheaper. If need to generate Execute Only code, and we
3733 // only have Thumb1 available, we can't use a constant pool and are forced to
3734 // use immediate relocations.
3735 if (Subtarget->useMovt() || Subtarget->genExecuteOnly()) {
3736 if (Subtarget->useMovt())
3737 ++NumMovwMovt;
3738 // FIXME: Once remat is capable of dealing with instructions with register
3739 // operands, expand this into two nodes.
3740 return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
3741 DAG.getTargetGlobalAddress(GV, dl, PtrVT));
3742 } else {
3743 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
3744 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3745 return DAG.getLoad(
3746 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3748 }
3749}
3750
3751SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3752 SelectionDAG &DAG) const {
3753 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3754 "ROPI/RWPI not currently supported for Darwin");
3755 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3756 SDLoc dl(Op);
3757 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3758
3759 if (Subtarget->useMovt())
3760 ++NumMovwMovt;
3761
3762 // FIXME: Once remat is capable of dealing with instructions with register
3763 // operands, expand this into multiple nodes
3764 unsigned Wrapper =
3765 isPositionIndependent() ? ARMISD::WrapperPIC : ARMISD::Wrapper;
3766
3767 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
3768 SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
3769
3770 if (Subtarget->isGVIndirectSymbol(GV))
3771 Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3773 return Result;
3774}
3775
3776SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op,
3777 SelectionDAG &DAG) const {
3778 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3779 "non-Windows COFF is not supported");
3780 assert(Subtarget->useMovt() &&
3781 "Windows on ARM expects to use movw/movt");
3782 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3783 "ROPI/RWPI not currently supported for Windows");
3784
3785 const TargetMachine &TM = getTargetMachine();
3786 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3787 ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG;
3788 if (GV->hasDLLImportStorageClass())
3789 TargetFlags = ARMII::MO_DLLIMPORT;
3790 else if (!TM.shouldAssumeDSOLocal(GV))
3791 TargetFlags = ARMII::MO_COFFSTUB;
3792 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3794 SDLoc DL(Op);
3795
3796 ++NumMovwMovt;
3797
3798 // FIXME: Once remat is capable of dealing with instructions with register
3799 // operands, expand this into two nodes.
3800 Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT,
3801 DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*offset=*/0,
3802 TargetFlags));
3803 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
3804 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
3806 return Result;
3807}
3808
3809SDValue
3810ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const {
3811 SDLoc dl(Op);
3812 SDValue Val = DAG.getConstant(0, dl, MVT::i32);
3813 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl,
3814 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
3815 Op.getOperand(1), Val);
3816}
3817
3818SDValue
3819ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
3820 SDLoc dl(Op);
3821 return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
3822 Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
3823}
3824
3825SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
3826 SelectionDAG &DAG) const {
3827 SDLoc dl(Op);
3828 return DAG.getNode(ARMISD::EH_SJLJ_SETUP_DISPATCH, dl, MVT::Other,
3829 Op.getOperand(0));
3830}
3831
3832SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3833 SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3834 unsigned IntNo =
3835 Op.getConstantOperandVal(Op.getOperand(0).getValueType() == MVT::Other);
3836 switch (IntNo) {
3837 default:
3838 return SDValue(); // Don't custom lower most intrinsics.
3839 case Intrinsic::arm_gnu_eabi_mcount: {
3840 MachineFunction &MF = DAG.getMachineFunction();
3841 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3842 SDLoc dl(Op);
3843 SDValue Chain = Op.getOperand(0);
3844 // call "\01__gnu_mcount_nc"
3845 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3846 const uint32_t *Mask =
3848 assert(Mask && "Missing call preserved mask for calling convention");
3849 // Mark LR an implicit live-in.
3850 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3851 SDValue ReturnAddress =
3852 DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3853 constexpr EVT ResultTys[] = {MVT::Other, MVT::Glue};
3854 SDValue Callee =
3855 DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3857 if (Subtarget->isThumb())
3858 return SDValue(
3859 DAG.getMachineNode(
3860 ARM::tBL_PUSHLR, dl, ResultTys,
3861 {ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3862 DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3863 0);
3864 return SDValue(
3865 DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3866 {ReturnAddress, Callee, RegisterMask, Chain}),
3867 0);
3868 }
3869 }
3870}
3871
3872SDValue
3873ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
3874 const ARMSubtarget *Subtarget) const {
3875 unsigned IntNo = Op.getConstantOperandVal(0);
3876 SDLoc dl(Op);
3877 switch (IntNo) {
3878 default: return SDValue(); // Don't custom lower most intrinsics.
3879 case Intrinsic::localaddress: {
3880 const MachineFunction &MF = DAG.getMachineFunction();
3881 const auto *RegInfo = Subtarget->getRegisterInfo();
3882 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
3883 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
3884 Op.getSimpleValueType());
3885 }
3886 case Intrinsic::eh_recoverfp: {
3887 SDValue FnOp = Op.getOperand(1);
3888 GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
3889 auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
3890 if (!Fn)
3892 "llvm.eh.recoverfp must take a function as the first argument");
3893 const auto *RegInfo = Subtarget->getRegisterInfo();
3894 Register BaseReg = RegInfo->getBaseRegister();
3895 MachineFunction &MF = DAG.getMachineFunction();
3896 MachineBasicBlock &MBB = *MF.begin();
3897 if (!MBB.isLiveIn(BaseReg))
3898 MBB.addLiveIn(BaseReg);
3899 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3900 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, BaseReg, PtrVT);
3901 }
3902 case Intrinsic::thread_pointer: {
3903 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3904 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3905 }
3906 case Intrinsic::arm_cls: {
3907 // Note: arm_cls and arm_cls64 intrinsics are expanded directly here
3908 // in LowerINTRINSIC_WO_CHAIN since there's no native scalar CLS
3909 // instruction.
3910 const SDValue &Operand = Op.getOperand(1);
3911 const EVT VTy = Op.getValueType();
3912 return DAG.getNode(ISD::CTLS, dl, VTy, Operand);
3913 }
3914 case Intrinsic::arm_cls64: {
3915 // arm_cls64 returns i32 but takes i64 input.
3916 // Use ISD::CTLS for i64 and truncate the result.
3917 SDValue CTLS64 = DAG.getNode(ISD::CTLS, dl, MVT::i64, Op.getOperand(1));
3918 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, CTLS64);
3919 }
3920 case Intrinsic::arm_neon_vcls:
3921 case Intrinsic::arm_mve_vcls: {
3922 // Lower vector CLS intrinsics to ISD::CTLS.
3923 // Vector CTLS is Legal when NEON/MVE is available (set elsewhere).
3924 const EVT VTy = Op.getValueType();
3925 return DAG.getNode(ISD::CTLS, dl, VTy, Op.getOperand(1));
3926 }
3927 case Intrinsic::eh_sjlj_lsda: {
3928 MachineFunction &MF = DAG.getMachineFunction();
3929 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3930 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3931 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3932 SDValue CPAddr;
3933 bool IsPositionIndependent = isPositionIndependent();
3934 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
3935 ARMConstantPoolValue *CPV =
3936 ARMConstantPoolConstant::Create(&MF.getFunction(), ARMPCLabelIndex,
3937 ARMCP::CPLSDA, PCAdj);
3938 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3939 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3940 SDValue Result = DAG.getLoad(
3941 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3943
3944 if (IsPositionIndependent) {
3945 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3946 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
3947 }
3948 return Result;
3949 }
3950 case Intrinsic::arm_neon_vabs:
3951 return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(),
3952 Op.getOperand(1));
3953 case Intrinsic::arm_neon_vabds:
3954 if (Op.getValueType().isInteger())
3955 return DAG.getNode(ISD::ABDS, SDLoc(Op), Op.getValueType(),
3956 Op.getOperand(1), Op.getOperand(2));
3957 return SDValue();
3958 case Intrinsic::arm_neon_vabdu:
3959 return DAG.getNode(ISD::ABDU, SDLoc(Op), Op.getValueType(),
3960 Op.getOperand(1), Op.getOperand(2));
3961 case Intrinsic::arm_neon_vmulls:
3962 case Intrinsic::arm_neon_vmullu: {
3963 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
3964 ? ARMISD::VMULLs : ARMISD::VMULLu;
3965 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3966 Op.getOperand(1), Op.getOperand(2));
3967 }
3968 case Intrinsic::arm_neon_vminnm:
3969 case Intrinsic::arm_neon_vmaxnm: {
3970 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminnm)
3971 ? ISD::FMINNUM : ISD::FMAXNUM;
3972 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3973 Op.getOperand(1), Op.getOperand(2));
3974 }
3975 case Intrinsic::arm_neon_vminu:
3976 case Intrinsic::arm_neon_vmaxu: {
3977 if (Op.getValueType().isFloatingPoint())
3978 return SDValue();
3979 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminu)
3980 ? ISD::UMIN : ISD::UMAX;
3981 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3982 Op.getOperand(1), Op.getOperand(2));
3983 }
3984 case Intrinsic::arm_neon_vmins:
3985 case Intrinsic::arm_neon_vmaxs: {
3986 // v{min,max}s is overloaded between signed integers and floats.
3987 if (!Op.getValueType().isFloatingPoint()) {
3988 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3989 ? ISD::SMIN : ISD::SMAX;
3990 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3991 Op.getOperand(1), Op.getOperand(2));
3992 }
3993 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3994 ? ISD::FMINIMUM : ISD::FMAXIMUM;
3995 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3996 Op.getOperand(1), Op.getOperand(2));
3997 }
3998 case Intrinsic::arm_neon_vtbl1:
3999 return DAG.getNode(ARMISD::VTBL1, SDLoc(Op), Op.getValueType(),
4000 Op.getOperand(1), Op.getOperand(2));
4001 case Intrinsic::arm_neon_vtbl2:
4002 return DAG.getNode(ARMISD::VTBL2, SDLoc(Op), Op.getValueType(),
4003 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4004 case Intrinsic::arm_mve_pred_i2v:
4005 case Intrinsic::arm_mve_pred_v2i:
4006 return DAG.getNode(ARMISD::PREDICATE_CAST, SDLoc(Op), Op.getValueType(),
4007 Op.getOperand(1));
4008 case Intrinsic::arm_mve_vreinterpretq:
4009 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(Op), Op.getValueType(),
4010 Op.getOperand(1));
4011 case Intrinsic::arm_mve_lsll:
4012 return DAG.getNode(ARMISD::LSLL, SDLoc(Op), Op->getVTList(),
4013 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4014 case Intrinsic::arm_mve_asrl:
4015 return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
4016 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4017 case Intrinsic::arm_mve_vsli:
4018 return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
4019 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4020 case Intrinsic::arm_mve_vsri:
4021 return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
4022 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4023 }
4024}
4025
4027 const ARMSubtarget *Subtarget) {
4028 SDLoc dl(Op);
4029 auto SSID = static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
4030 if (SSID == SyncScope::SingleThread)
4031 return Op;
4032
4033 if (!Subtarget->hasDataBarrier()) {
4034 // Some ARMv6 cpus can support data barriers with an mcr instruction.
4035 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
4036 // here.
4037 assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() &&
4038 "Unexpected ISD::ATOMIC_FENCE encountered. Should be libcall!");
4039 return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0),
4040 DAG.getConstant(0, dl, MVT::i32));
4041 }
4042
4043 AtomicOrdering Ord =
4044 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
4046 if (Subtarget->isMClass()) {
4047 // Only a full system barrier exists in the M-class architectures.
4049 } else if (Subtarget->preferISHSTBarriers() &&
4050 Ord == AtomicOrdering::Release) {
4051 // Swift happens to implement ISHST barriers in a way that's compatible with
4052 // Release semantics but weaker than ISH so we'd be fools not to use
4053 // it. Beware: other processors probably don't!
4055 }
4056
4057 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
4058 DAG.getConstant(Intrinsic::arm_dmb, dl, MVT::i32),
4059 DAG.getConstant(Domain, dl, MVT::i32));
4060}
4061
4063 const ARMSubtarget *Subtarget) {
4064 // ARM pre v5TE and Thumb1 does not have preload instructions.
4065 if (!(Subtarget->isThumb2() ||
4066 (!Subtarget->isThumb1Only() && Subtarget->hasV5TEOps())))
4067 // Just preserve the chain.
4068 return Op.getOperand(0);
4069
4070 SDLoc dl(Op);
4071 unsigned isRead = ~Op.getConstantOperandVal(2) & 1;
4072 if (!isRead &&
4073 (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
4074 // ARMv7 with MP extension has PLDW.
4075 return Op.getOperand(0);
4076
4077 unsigned isData = Op.getConstantOperandVal(4);
4078 if (Subtarget->isThumb()) {
4079 // Invert the bits.
4080 isRead = ~isRead & 1;
4081 isData = ~isData & 1;
4082 }
4083
4084 return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
4085 Op.getOperand(1), DAG.getConstant(isRead, dl, MVT::i32),
4086 DAG.getConstant(isData, dl, MVT::i32));
4087}
4088
4091 ARMFunctionInfo *FuncInfo = MF.getInfo<ARMFunctionInfo>();
4092
4093 // vastart just stores the address of the VarArgsFrameIndex slot into the
4094 // memory location argument.
4095 SDLoc dl(Op);
4097 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4098 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4099 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
4100 MachinePointerInfo(SV));
4101}
4102
4103SDValue ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA,
4104 CCValAssign &NextVA,
4105 SDValue &Root,
4106 SelectionDAG &DAG,
4107 const SDLoc &dl) const {
4108 MachineFunction &MF = DAG.getMachineFunction();
4109 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4110
4111 const TargetRegisterClass *RC;
4112 if (AFI->isThumb1OnlyFunction())
4113 RC = &ARM::tGPRRegClass;
4114 else
4115 RC = &ARM::GPRRegClass;
4116
4117 // Transform the arguments stored in physical registers into virtual ones.
4118 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4119 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4120
4121 SDValue ArgValue2;
4122 if (NextVA.isMemLoc()) {
4123 MachineFrameInfo &MFI = MF.getFrameInfo();
4124 int FI = MFI.CreateFixedObject(4, NextVA.getLocMemOffset(), true);
4125
4126 // Create load node to retrieve arguments from the stack.
4127 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4128 ArgValue2 = DAG.getLoad(
4129 MVT::i32, dl, Root, FIN,
4131 } else {
4132 Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
4133 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4134 }
4135 if (!Subtarget->isLittle())
4136 std::swap (ArgValue, ArgValue2);
4137 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
4138}
4139
4140// The remaining GPRs hold either the beginning of variable-argument
4141// data, or the beginning of an aggregate passed by value (usually
4142// byval). Either way, we allocate stack slots adjacent to the data
4143// provided by our caller, and store the unallocated registers there.
4144// If this is a variadic function, the va_list pointer will begin with
4145// these values; otherwise, this reassembles a (byval) structure that
4146// was split between registers and memory.
4147// Return: The frame index registers were stored into.
4148int ARMTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG,
4149 const SDLoc &dl, SDValue &Chain,
4150 const Value *OrigArg,
4151 unsigned InRegsParamRecordIdx,
4152 int ArgOffset, unsigned ArgSize) const {
4153 // Currently, two use-cases possible:
4154 // Case #1. Non-var-args function, and we meet first byval parameter.
4155 // Setup first unallocated register as first byval register;
4156 // eat all remained registers
4157 // (these two actions are performed by HandleByVal method).
4158 // Then, here, we initialize stack frame with
4159 // "store-reg" instructions.
4160 // Case #2. Var-args function, that doesn't contain byval parameters.
4161 // The same: eat all remained unallocated registers,
4162 // initialize stack frame.
4163
4164 MachineFunction &MF = DAG.getMachineFunction();
4165 MachineFrameInfo &MFI = MF.getFrameInfo();
4166 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4167 unsigned RBegin, REnd;
4168 if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) {
4169 CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, RBegin, REnd);
4170 } else {
4171 unsigned RBeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4172 RBegin = RBeginIdx == 4 ? (unsigned)ARM::R4 : GPRArgRegs[RBeginIdx];
4173 REnd = ARM::R4;
4174 }
4175
4176 if (REnd != RBegin)
4177 ArgOffset = -4 * (ARM::R4 - RBegin);
4178
4179 auto PtrVT = getPointerTy(DAG.getDataLayout());
4180 int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, false);
4181 SDValue FIN = DAG.getFrameIndex(FrameIndex, PtrVT);
4182
4184 const TargetRegisterClass *RC =
4185 AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
4186
4187 for (unsigned Reg = RBegin, i = 0; Reg < REnd; ++Reg, ++i) {
4188 Register VReg = MF.addLiveIn(Reg, RC);
4189 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
4190 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
4191 MachinePointerInfo(OrigArg, 4 * i));
4192 MemOps.push_back(Store);
4193 FIN = DAG.getNode(ISD::ADD, dl, PtrVT, FIN, DAG.getConstant(4, dl, PtrVT));
4194 }
4195
4196 if (!MemOps.empty())
4197 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
4198 return FrameIndex;
4199}
4200
4201// Setup stack frame, the va_list pointer will start from.
4202void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
4203 const SDLoc &dl, SDValue &Chain,
4204 unsigned ArgOffset,
4205 unsigned TotalArgRegsSaveSize,
4206 bool ForceMutable) const {
4207 MachineFunction &MF = DAG.getMachineFunction();
4208 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4209
4210 // Try to store any remaining integer argument regs
4211 // to their spots on the stack so that they may be loaded by dereferencing
4212 // the result of va_next.
4213 // If there is no regs to be stored, just point address after last
4214 // argument passed via stack.
4215 int FrameIndex = StoreByValRegs(
4216 CCInfo, DAG, dl, Chain, nullptr, CCInfo.getInRegsParamsCount(),
4217 CCInfo.getStackSize(), std::max(4U, TotalArgRegsSaveSize));
4218 AFI->setVarArgsFrameIndex(FrameIndex);
4219}
4220
4221bool ARMTargetLowering::splitValueIntoRegisterParts(
4222 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
4223 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
4224 EVT ValueVT = Val.getValueType();
4225 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4226 unsigned ValueBits = ValueVT.getSizeInBits();
4227 unsigned PartBits = PartVT.getSizeInBits();
4228 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(ValueBits), Val);
4229 Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::getIntegerVT(PartBits), Val);
4230 Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
4231 Parts[0] = Val;
4232 return true;
4233 }
4234 return false;
4235}
4236
4237SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
4238 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
4239 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
4240 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4241 unsigned ValueBits = ValueVT.getSizeInBits();
4242 unsigned PartBits = PartVT.getSizeInBits();
4243 SDValue Val = Parts[0];
4244
4245 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(PartBits), Val);
4246 Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::getIntegerVT(ValueBits), Val);
4247 Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
4248 return Val;
4249 }
4250 return SDValue();
4251}
4252
4253SDValue ARMTargetLowering::LowerFormalArguments(
4254 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
4255 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
4256 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
4257 MachineFunction &MF = DAG.getMachineFunction();
4258 MachineFrameInfo &MFI = MF.getFrameInfo();
4259
4260 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4261
4262 // Assign locations to all of the incoming arguments.
4264 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
4265 *DAG.getContext());
4266 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4267
4269 unsigned CurArgIdx = 0;
4270
4271 // Initially ArgRegsSaveSize is zero.
4272 // Then we increase this value each time we meet byval parameter.
4273 // We also increase this value in case of varargs function.
4274 AFI->setArgRegsSaveSize(0);
4275
4276 // Calculate the amount of stack space that we need to allocate to store
4277 // byval and variadic arguments that are passed in registers.
4278 // We need to know this before we allocate the first byval or variadic
4279 // argument, as they will be allocated a stack slot below the CFA (Canonical
4280 // Frame Address, the stack pointer at entry to the function).
4281 unsigned ArgRegBegin = ARM::R4;
4282 for (const CCValAssign &VA : ArgLocs) {
4283 if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
4284 break;
4285
4286 unsigned Index = VA.getValNo();
4287 ISD::ArgFlagsTy Flags = Ins[Index].Flags;
4288 if (!Flags.isByVal())
4289 continue;
4290
4291 assert(VA.isMemLoc() && "unexpected byval pointer in reg");
4292 unsigned RBegin, REnd;
4293 CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
4294 ArgRegBegin = std::min(ArgRegBegin, RBegin);
4295
4296 CCInfo.nextInRegsParam();
4297 }
4298 CCInfo.rewindByValRegsInfo();
4299
4300 int lastInsIndex = -1;
4301 if (isVarArg && MFI.hasVAStart()) {
4302 unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4303 if (RegIdx != std::size(GPRArgRegs))
4304 ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
4305 }
4306
4307 unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
4308 AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
4309 auto PtrVT = getPointerTy(DAG.getDataLayout());
4310
4311 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4312 CCValAssign &VA = ArgLocs[i];
4313 if (Ins[VA.getValNo()].isOrigArg()) {
4314 std::advance(CurOrigArg,
4315 Ins[VA.getValNo()].getOrigArgIndex() - CurArgIdx);
4316 CurArgIdx = Ins[VA.getValNo()].getOrigArgIndex();
4317 }
4318 // Arguments stored in registers.
4319 if (VA.isRegLoc()) {
4320 EVT RegVT = VA.getLocVT();
4321 SDValue ArgValue;
4322
4323 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4324 // f64 and vector types are split up into multiple registers or
4325 // combinations of registers and stack slots.
4326 SDValue ArgValue1 =
4327 GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4328 VA = ArgLocs[++i]; // skip ahead to next loc
4329 SDValue ArgValue2;
4330 if (VA.isMemLoc()) {
4331 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), true);
4332 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4333 ArgValue2 = DAG.getLoad(
4334 MVT::f64, dl, Chain, FIN,
4336 } else {
4337 ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4338 }
4339 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
4340 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4341 ArgValue1, DAG.getIntPtrConstant(0, dl));
4342 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4343 ArgValue2, DAG.getIntPtrConstant(1, dl));
4344 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
4345 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4346 } else {
4347 const TargetRegisterClass *RC;
4348
4349 if (RegVT == MVT::f16 || RegVT == MVT::bf16)
4350 RC = &ARM::HPRRegClass;
4351 else if (RegVT == MVT::f32)
4352 RC = &ARM::SPRRegClass;
4353 else if (RegVT == MVT::f64 || RegVT == MVT::v4f16 ||
4354 RegVT == MVT::v4bf16)
4355 RC = &ARM::DPRRegClass;
4356 else if (RegVT == MVT::v2f64 || RegVT == MVT::v8f16 ||
4357 RegVT == MVT::v8bf16)
4358 RC = &ARM::QPRRegClass;
4359 else if (RegVT == MVT::i32)
4360 RC = AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass
4361 : &ARM::GPRRegClass;
4362 else
4363 llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
4364
4365 // Transform the arguments in physical registers into virtual ones.
4366 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4367 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
4368
4369 // If this value is passed in r0 and has the returned attribute (e.g.
4370 // C++ 'structors), record this fact for later use.
4371 if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
4372 AFI->setPreservesR0();
4373 }
4374 }
4375
4376 // If this is an 8 or 16-bit value, it is really passed promoted
4377 // to 32 bits. Insert an assert[sz]ext to capture this, then
4378 // truncate to the right size.
4379 switch (VA.getLocInfo()) {
4380 default: llvm_unreachable("Unknown loc info!");
4381 case CCValAssign::Full: break;
4382 case CCValAssign::BCvt:
4383 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4384 break;
4385 }
4386
4387 // f16 arguments have their size extended to 4 bytes and passed as if they
4388 // had been copied to the LSBs of a 32-bit register.
4389 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
4390 if (VA.needsCustom() &&
4391 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4392 ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4393
4394 // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4395 // less than 32 bits must be sign- or zero-extended in the callee for
4396 // security reasons. Although the ABI mandates an extension done by the
4397 // caller, the latter cannot be trusted to follow the rules of the ABI.
4398 const ISD::InputArg &Arg = Ins[VA.getValNo()];
4399 if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4400 RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4401 ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4402
4403 InVals.push_back(ArgValue);
4404 } else { // VA.isRegLoc()
4405 // Only arguments passed on the stack should make it here.
4406 assert(VA.isMemLoc());
4407 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
4408
4409 int index = VA.getValNo();
4410
4411 // Some Ins[] entries become multiple ArgLoc[] entries.
4412 // Process them only once.
4413 if (index != lastInsIndex)
4414 {
4415 ISD::ArgFlagsTy Flags = Ins[index].Flags;
4416 // FIXME: For now, all byval parameter objects are marked mutable.
4417 // This can be changed with more analysis.
4418 // In case of tail call optimization mark all arguments mutable.
4419 // Since they could be overwritten by lowering of arguments in case of
4420 // a tail call.
4421 if (Flags.isByVal()) {
4422 assert(Ins[index].isOrigArg() &&
4423 "Byval arguments cannot be implicit");
4424 unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed();
4425
4426 int FrameIndex = StoreByValRegs(
4427 CCInfo, DAG, dl, Chain, &*CurOrigArg, CurByValIndex,
4428 VA.getLocMemOffset(), Flags.getByValSize());
4429 InVals.push_back(DAG.getFrameIndex(FrameIndex, PtrVT));
4430 CCInfo.nextInRegsParam();
4431 } else if (VA.needsCustom() && (VA.getValVT() == MVT::f16 ||
4432 VA.getValVT() == MVT::bf16)) {
4433 // f16 and bf16 values are passed in the least-significant half of
4434 // a 4 byte stack slot. This is done as-if the extension was done
4435 // in a 32-bit register, so the actual bytes used for the value
4436 // differ between little and big endian.
4437 assert(VA.getLocVT().getSizeInBits() == 32);
4438 unsigned FIOffset = VA.getLocMemOffset();
4439 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits() / 8,
4440 FIOffset, true);
4441
4442 SDValue Addr = DAG.getFrameIndex(FI, PtrVT);
4443 if (DAG.getDataLayout().isBigEndian())
4444 Addr = DAG.getObjectPtrOffset(dl, Addr, TypeSize::getFixed(2));
4445
4446 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, Addr,
4448 DAG.getMachineFunction(), FI)));
4449
4450 } else {
4451 unsigned FIOffset = VA.getLocMemOffset();
4452 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
4453 FIOffset, true);
4454
4455 // Create load nodes to retrieve arguments from the stack.
4456 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4457 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
4459 DAG.getMachineFunction(), FI)));
4460 }
4461 lastInsIndex = index;
4462 }
4463 }
4464 }
4465
4466 // varargs
4467 if (isVarArg && MFI.hasVAStart()) {
4468 VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getStackSize(),
4469 TotalArgRegsSaveSize);
4470 if (AFI->isCmseNSEntryFunction()) {
4471 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4473 "secure entry function must not be variadic", dl.getDebugLoc()));
4474 }
4475 }
4476
4477 unsigned StackArgSize = CCInfo.getStackSize();
4478 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4479 if (canGuaranteeTCO(CallConv, TailCallOpt)) {
4480 // The only way to guarantee a tail call is if the callee restores its
4481 // argument area, but it must also keep the stack aligned when doing so.
4482 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
4483 assert(StackAlign && "data layout string is missing stack alignment");
4484 StackArgSize = alignTo(StackArgSize, *StackAlign);
4485
4486 AFI->setArgumentStackToRestore(StackArgSize);
4487 }
4488 AFI->setArgumentStackSize(StackArgSize);
4489
4490 if (CCInfo.getStackSize() > 0 && AFI->isCmseNSEntryFunction()) {
4491 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4493 "secure entry function requires arguments on stack", dl.getDebugLoc()));
4494 }
4495
4496 return Chain;
4497}
4498
4499/// isFloatingPointZero - Return true if this is +0.0.
4502 return CFP->getValueAPF().isPosZero();
4503 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
4504 // Maybe this has already been legalized into the constant pool?
4505 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
4506 SDValue WrapperOp = Op.getOperand(1).getOperand(0);
4508 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
4509 return CFP->getValueAPF().isPosZero();
4510 }
4511 } else if (Op->getOpcode() == ISD::BITCAST &&
4512 Op->getValueType(0) == MVT::f64) {
4513 // Handle (ISD::BITCAST (ARMISD::VMOVIMM (ISD::TargetConstant 0)) MVT::f64)
4514 // created by LowerConstantFP().
4515 SDValue BitcastOp = Op->getOperand(0);
4516 if (BitcastOp->getOpcode() == ARMISD::VMOVIMM &&
4517 isNullConstant(BitcastOp->getOperand(0)))
4518 return true;
4519 }
4520 return false;
4521}
4522
4524 // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
4525 if (Op->getFlags().hasNoSignedWrap())
4526 return true;
4527
4528 // We can still figure out if the second operand is safe to use
4529 // in a CMN instruction by checking if it is known to be not the minimum
4530 // signed value. If it is not, then we can safely use CMN.
4531 // Note: We can eventually remove this check and simply rely on
4532 // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
4533 // consistently sets them appropriately when making said nodes.
4534
4535 KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
4536 return !KnownSrc.getSignedMinValue().isMinSignedValue();
4537}
4538
4540 return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
4541 (isIntEqualitySetCC(CC) ||
4542 (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
4543 (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
4544}
4545
4546/// Returns how profitable it is to fold a comparison's operand's shift and/or
4547/// extension operations into the comparison instruction's second operand
4548/// (so_reg_imm / so_reg_reg for ARM, t2_so_reg for Thumb-2).
4550 // Thumb-1 CMP does not support shifted second operands.
4551 if (ST.isThumb1Only() || !Op.hasOneUse())
4552 return 0;
4553
4554 unsigned Opc = Op.getOpcode();
4555 if (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) {
4556 if (auto *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
4557 return ShiftAmt->getZExtValue() <= 31 ? 1 : 0;
4558 // Register-controlled shift: only ARM-mode CMP/CMN (so_reg_reg) supports
4559 // this; Thumb-2 t2_so_reg requires an immediate shift amount.
4560 return ST.isThumb() ? 0 : 1;
4561 }
4562
4563 if (Opc == ISD::ROTR) {
4564 // Rotr constants will be normalized via mod 32, or & 31,
4565 // so we do not have to bounds check.
4566 if (isa<ConstantSDNode>(Op.getOperand(1)))
4567 return 1;
4568 return ST.isThumb() ? 0 : 1;
4569 }
4570
4571 return 0;
4572}
4573
4574/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4575/// the given operands.
4576SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4577 SDValue &ARMcc, SelectionDAG &DAG,
4578 const SDLoc &dl) const {
4579 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4580 unsigned C = RHSC->getZExtValue();
4581 if (!isLegalICmpImmediate((int32_t)C)) {
4582 // Constant does not fit, try adjusting it by one.
4583 switch (CC) {
4584 default: break;
4585 case ISD::SETLT:
4586 case ISD::SETGE:
4587 if (C != 0x80000000 && isLegalICmpImmediate(C-1)) {
4588 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4589 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4590 }
4591 break;
4592 case ISD::SETULT:
4593 case ISD::SETUGE:
4594 if (C != 0 && isLegalICmpImmediate(C-1)) {
4595 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4596 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4597 }
4598 break;
4599 case ISD::SETLE:
4600 case ISD::SETGT:
4601 if (C != 0x7fffffff && isLegalICmpImmediate(C+1)) {
4602 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4603 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4604 }
4605 break;
4606 case ISD::SETULE:
4607 case ISD::SETUGT:
4608 if (C != 0xffffffff && isLegalICmpImmediate(C+1)) {
4609 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4610 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4611 }
4612 break;
4613 }
4614 }
4615 }
4616
4617 // Thumb1 has very limited immediate modes, so turning an "and" into a
4618 // shift can save multiple instructions.
4619 //
4620 // If we have (x & C1), and C1 is an appropriate mask, we can transform it
4621 // into "((x << n) >> n)". But that isn't necessarily profitable on its
4622 // own. If it's the operand to an unsigned comparison with an immediate,
4623 // we can eliminate one of the shifts: we transform
4624 // "((x << n) >> n) == C2" to "(x << n) == (C2 << n)".
4625 //
4626 // We avoid transforming cases which aren't profitable due to encoding
4627 // details:
4628 //
4629 // 1. C2 fits into the immediate field of a cmp, and the transformed version
4630 // would not; in that case, we're essentially trading one immediate load for
4631 // another.
4632 // 2. C1 is 255 or 65535, so we can use uxtb or uxth.
4633 // 3. C2 is zero; we have other code for this special case.
4634 //
4635 // FIXME: Figure out profitability for Thumb2; we usually can't save an
4636 // instruction, since the AND is always one instruction anyway, but we could
4637 // use narrow instructions in some cases.
4638 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::AND &&
4639 LHS->hasOneUse() && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4640 LHS.getValueType() == MVT::i32 && isa<ConstantSDNode>(RHS) &&
4641 !isSignedIntSetCC(CC)) {
4642 unsigned Mask = LHS.getConstantOperandVal(1);
4643 auto *RHSC = cast<ConstantSDNode>(RHS.getNode());
4644 uint64_t RHSV = RHSC->getZExtValue();
4645 if (isMask_32(Mask) && (RHSV & ~Mask) == 0 && Mask != 255 && Mask != 65535) {
4646 unsigned ShiftBits = llvm::countl_zero(Mask);
4647 if (RHSV && (RHSV > 255 || (RHSV << ShiftBits) <= 255)) {
4648 SDValue ShiftAmt = DAG.getConstant(ShiftBits, dl, MVT::i32);
4649 LHS = DAG.getNode(ISD::SHL, dl, MVT::i32, LHS.getOperand(0), ShiftAmt);
4650 RHS = DAG.getConstant(RHSV << ShiftBits, dl, MVT::i32);
4651 }
4652 }
4653 }
4654
4655 // The specific comparison "(x<<c) > 0x80000000U" can be optimized to a
4656 // single "lsls x, c+1". The shift sets the "C" and "Z" flags the same
4657 // way a cmp would.
4658 // FIXME: Add support for ARM/Thumb2; this would need isel patterns, and
4659 // some tweaks to the heuristics for the previous and->shift transform.
4660 // FIXME: Optimize cases where the LHS isn't a shift.
4661 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::SHL &&
4662 isa<ConstantSDNode>(RHS) && RHS->getAsZExtVal() == 0x80000000U &&
4663 CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4664 LHS.getConstantOperandVal(1) < 31) {
4665 unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
4666 SDValue Shift =
4667 DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
4668 LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
4669 ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
4670 return Shift.getValue(1);
4671 }
4672
4674
4675 unsigned CompareType;
4676 switch (CondCode) {
4677 default:
4678 CompareType = ARMISD::CMP;
4679 break;
4680 case ARMCC::EQ:
4681 case ARMCC::NE:
4682 // Uses only Z Flag
4683 CompareType = ARMISD::CMPZ;
4684 break;
4685 }
4686
4687 // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
4688 // the codebase.
4689
4690 // TODO: When we have a solution to the vselect predicate not allowing pl/mi
4691 // all the time, allow those cases to be cmn too no matter what.
4692 if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
4693 CompareType = ARMISD::CMN;
4694 RHS = RHS.getOperand(1);
4695 } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
4696 CompareType = ARMISD::CMN;
4697 LHS = LHS.getOperand(1);
4699 }
4700
4701 // Prefer folding shifts / CMN into the cmp/cmn second operand (so_reg /
4702 // t2_so_reg). When both sides compete, pick the higher
4703 // getCmpOperandFoldingProfit. Only when RHS is not a legal icmp
4704 // immediate: otherwise keep the canonical (reg, imm) form.
4705 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getNode());
4706 if (!C || !isLegalICmpImmediate(C->getSExtValue())) {
4707 if (getCmpOperandFoldingProfit(LHS, *Subtarget) >
4708 getCmpOperandFoldingProfit(RHS, *Subtarget)) {
4709 std::swap(LHS, RHS);
4710 if (CompareType == ARMISD::CMP)
4712 }
4713 }
4714
4715 // If the RHS is a constant zero then the V (overflow) flag will never be
4716 // set. This can allow us to simplify GE to PL or LT to MI, which can be
4717 // simpler for other passes (like the peephole optimiser) to deal with.
4718 if (isNullConstant(RHS)) {
4719 switch (CondCode) {
4720 default:
4721 break;
4722 case ARMCC::GE:
4724 break;
4725 case ARMCC::LT:
4727 break;
4728 }
4729 }
4730
4731 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
4732 return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
4733}
4734
4735/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
4736SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4737 SelectionDAG &DAG, const SDLoc &dl,
4738 bool Signaling) const {
4739 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
4740 SDValue Flags;
4742 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP, dl, FlagsVT,
4743 LHS, RHS);
4744 else
4745 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
4746 FlagsVT, LHS);
4747 return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
4748}
4749
4750// This function returns three things: the arithmetic computation itself
4751// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4752// comparison and the condition code define the case in which the arithmetic
4753// computation *does not* overflow.
4754std::pair<SDValue, SDValue>
4755ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4756 SDValue &ARMcc) const {
4757 assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4758
4759 SDValue Value, OverflowCmp;
4760 SDValue LHS = Op.getOperand(0);
4761 SDValue RHS = Op.getOperand(1);
4762 SDLoc dl(Op);
4763
4764 // FIXME: We are currently always generating CMPs because we don't support
4765 // generating CMN through the backend. This is not as good as the natural
4766 // CMP case because it causes a register dependency and cannot be folded
4767 // later.
4768
4769 switch (Op.getOpcode()) {
4770 default:
4771 llvm_unreachable("Unknown overflow instruction!");
4772 case ISD::SADDO:
4773 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4774 Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4775 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4776 break;
4777 case ISD::UADDO:
4778 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4779 // We use ADDC here to correspond to its use in LowerALUO.
4780 // We do not use it in the USUBO case as Value may not be used.
4781 Value = DAG.getNode(ARMISD::ADDC, dl,
4782 DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4783 .getValue(0);
4784 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4785 break;
4786 case ISD::SSUBO:
4787 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4788 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4789 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4790 break;
4791 case ISD::USUBO:
4792 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4793 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4794 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4795 break;
4796 case ISD::UMULO:
4797 // We generate a UMUL_LOHI and then check if the high word is 0.
4798 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4799 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4800 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4801 LHS, RHS);
4802 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4803 DAG.getConstant(0, dl, MVT::i32));
4804 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4805 break;
4806 case ISD::SMULO:
4807 // We generate a SMUL_LOHI and then check if all the bits of the high word
4808 // are the same as the sign bit of the low word.
4809 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4810 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4811 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4812 LHS, RHS);
4813 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4814 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4815 Value.getValue(0),
4816 DAG.getConstant(31, dl, MVT::i32)));
4817 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4818 break;
4819 } // switch (...)
4820
4821 return std::make_pair(Value, OverflowCmp);
4822}
4823
4825 SDLoc DL(Value);
4826 EVT VT = Value.getValueType();
4827
4828 if (Invert)
4829 Value = DAG.getNode(ISD::SUB, DL, MVT::i32,
4830 DAG.getConstant(1, DL, MVT::i32), Value);
4831
4832 SDValue Cmp = DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(VT, MVT::i32),
4833 Value, DAG.getConstant(1, DL, VT));
4834 return Cmp.getValue(1);
4835}
4836
4838 bool Invert) {
4839 SDLoc DL(Flags);
4840
4841 if (Invert) {
4842 // Convert flags to boolean with ADDE 0,0,Carry then compute 1 - bool.
4843 SDValue BoolCarry = DAG.getNode(
4844 ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4845 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT), Flags);
4846 return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, VT), BoolCarry);
4847 }
4848
4849 // Now convert the carry flag into a boolean carry. We do this
4850 // using ARMISD::ADDE 0, 0, Carry
4851 return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4852 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT),
4853 Flags);
4854}
4855
4856// Value is 1 if 'V' bit is 1, else 0
4858 SDLoc DL(Flags);
4859 SDValue Zero = DAG.getConstant(0, DL, VT);
4860 SDValue One = DAG.getConstant(1, DL, VT);
4861 SDValue ARMcc = DAG.getConstant(ARMCC::VS, DL, MVT::i32);
4862 return DAG.getNode(ARMISD::CMOV, DL, VT, Zero, One, ARMcc, Flags);
4863}
4864
4865SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
4866 // Let legalize expand this if it isn't a legal type yet.
4867 if (!isTypeLegal(Op.getValueType()))
4868 return SDValue();
4869
4870 SDValue LHS = Op.getOperand(0);
4871 SDValue RHS = Op.getOperand(1);
4872 SDLoc dl(Op);
4873
4874 EVT VT = Op.getValueType();
4875 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4876 SDValue Value;
4877 SDValue Overflow;
4878 switch (Op.getOpcode()) {
4879 case ISD::UADDO:
4880 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4881 // Convert the carry flag into a boolean value.
4882 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, false);
4883 break;
4884 case ISD::USUBO:
4885 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4886 // Convert the carry flag into a boolean value.
4887 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, true);
4888 break;
4889 default: {
4890 // Handle other operations with getARMXALUOOp
4891 SDValue OverflowCmp, ARMcc;
4892 std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4893 // We use 0 and 1 as false and true values.
4894 // ARMcc represents the "no overflow" condition (e.g., VC for signed ops).
4895 // CMOV operand order is (FalseVal, TrueVal), so we put 1 in FalseVal
4896 // position to get Overflow=1 when the "no overflow" condition is false.
4897 Overflow =
4898 DAG.getNode(ARMISD::CMOV, dl, MVT::i32,
4899 DAG.getConstant(1, dl, MVT::i32), // FalseVal: overflow
4900 DAG.getConstant(0, dl, MVT::i32), // TrueVal: no overflow
4901 ARMcc, OverflowCmp);
4902 break;
4903 }
4904 }
4905
4906 return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4907}
4908
4910 const ARMSubtarget *Subtarget) {
4911 EVT VT = Op.getValueType();
4912 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || Subtarget->isThumb1Only())
4913 return SDValue();
4914 if (!VT.isSimple())
4915 return SDValue();
4916
4917 unsigned NewOpcode;
4918 switch (VT.getSimpleVT().SimpleTy) {
4919 default:
4920 return SDValue();
4921 case MVT::i8:
4922 switch (Op->getOpcode()) {
4923 case ISD::UADDSAT:
4924 NewOpcode = ARMISD::UQADD8b;
4925 break;
4926 case ISD::SADDSAT:
4927 NewOpcode = ARMISD::QADD8b;
4928 break;
4929 case ISD::USUBSAT:
4930 NewOpcode = ARMISD::UQSUB8b;
4931 break;
4932 case ISD::SSUBSAT:
4933 NewOpcode = ARMISD::QSUB8b;
4934 break;
4935 }
4936 break;
4937 case MVT::i16:
4938 switch (Op->getOpcode()) {
4939 case ISD::UADDSAT:
4940 NewOpcode = ARMISD::UQADD16b;
4941 break;
4942 case ISD::SADDSAT:
4943 NewOpcode = ARMISD::QADD16b;
4944 break;
4945 case ISD::USUBSAT:
4946 NewOpcode = ARMISD::UQSUB16b;
4947 break;
4948 case ISD::SSUBSAT:
4949 NewOpcode = ARMISD::QSUB16b;
4950 break;
4951 }
4952 break;
4953 }
4954
4955 SDLoc dl(Op);
4956 SDValue Add =
4957 DAG.getNode(NewOpcode, dl, MVT::i32,
4958 DAG.getSExtOrTrunc(Op->getOperand(0), dl, MVT::i32),
4959 DAG.getSExtOrTrunc(Op->getOperand(1), dl, MVT::i32));
4960 return DAG.getNode(ISD::TRUNCATE, dl, VT, Add);
4961}
4962
4963SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
4964 SDValue Cond = Op.getOperand(0);
4965 SDValue SelectTrue = Op.getOperand(1);
4966 SDValue SelectFalse = Op.getOperand(2);
4967 SDLoc dl(Op);
4968 unsigned Opc = Cond.getOpcode();
4969
4970 if (Cond.getResNo() == 1 &&
4971 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
4972 Opc == ISD::USUBO)) {
4973 if (!isTypeLegal(Cond->getValueType(0)))
4974 return SDValue();
4975
4976 SDValue Value, OverflowCmp;
4977 SDValue ARMcc;
4978 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
4979 EVT VT = Op.getValueType();
4980
4981 return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
4982 }
4983
4984 // Convert:
4985 //
4986 // (select (cmov 1, 0, cond), t, f) -> (cmov t, f, cond)
4987 // (select (cmov 0, 1, cond), t, f) -> (cmov f, t, cond)
4988 //
4989 if (Cond.getOpcode() == ARMISD::CMOV && Cond.hasOneUse()) {
4990 const ConstantSDNode *CMOVTrue =
4991 dyn_cast<ConstantSDNode>(Cond.getOperand(0));
4992 const ConstantSDNode *CMOVFalse =
4993 dyn_cast<ConstantSDNode>(Cond.getOperand(1));
4994
4995 if (CMOVTrue && CMOVFalse) {
4996 unsigned CMOVTrueVal = CMOVTrue->getZExtValue();
4997 unsigned CMOVFalseVal = CMOVFalse->getZExtValue();
4998
4999 SDValue True;
5000 SDValue False;
5001 if (CMOVTrueVal == 1 && CMOVFalseVal == 0) {
5002 True = SelectTrue;
5003 False = SelectFalse;
5004 } else if (CMOVTrueVal == 0 && CMOVFalseVal == 1) {
5005 True = SelectFalse;
5006 False = SelectTrue;
5007 }
5008
5009 if (True.getNode() && False.getNode())
5010 return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
5011 Cond.getOperand(3), DAG);
5012 }
5013 }
5014
5015 return DAG.getSelectCC(dl, Cond,
5016 DAG.getConstant(0, dl, Cond.getValueType()),
5017 SelectTrue, SelectFalse, ISD::SETNE);
5018}
5019
5021 bool &swpCmpOps, bool &swpVselOps) {
5022 // Start by selecting the GE condition code for opcodes that return true for
5023 // 'equality'
5024 if (CC == ISD::SETUGE || CC == ISD::SETOGE || CC == ISD::SETOLE ||
5025 CC == ISD::SETULE || CC == ISD::SETGE || CC == ISD::SETLE)
5026 CondCode = ARMCC::GE;
5027
5028 // and GT for opcodes that return false for 'equality'.
5029 else if (CC == ISD::SETUGT || CC == ISD::SETOGT || CC == ISD::SETOLT ||
5030 CC == ISD::SETULT || CC == ISD::SETGT || CC == ISD::SETLT)
5031 CondCode = ARMCC::GT;
5032
5033 // Since we are constrained to GE/GT, if the opcode contains 'less', we need
5034 // to swap the compare operands.
5035 if (CC == ISD::SETOLE || CC == ISD::SETULE || CC == ISD::SETOLT ||
5036 CC == ISD::SETULT || CC == ISD::SETLE || CC == ISD::SETLT)
5037 swpCmpOps = true;
5038
5039 // Both GT and GE are ordered comparisons, and return false for 'unordered'.
5040 // If we have an unordered opcode, we need to swap the operands to the VSEL
5041 // instruction (effectively negating the condition).
5042 //
5043 // This also has the effect of swapping which one of 'less' or 'greater'
5044 // returns true, so we also swap the compare operands. It also switches
5045 // whether we return true for 'equality', so we compensate by picking the
5046 // opposite condition code to our original choice.
5047 if (CC == ISD::SETULE || CC == ISD::SETULT || CC == ISD::SETUGE ||
5048 CC == ISD::SETUGT) {
5049 swpCmpOps = !swpCmpOps;
5050 swpVselOps = !swpVselOps;
5051 CondCode = CondCode == ARMCC::GT ? ARMCC::GE : ARMCC::GT;
5052 }
5053
5054 // 'ordered' is 'anything but unordered', so use the VS condition code and
5055 // swap the VSEL operands.
5056 if (CC == ISD::SETO) {
5057 CondCode = ARMCC::VS;
5058 swpVselOps = true;
5059 }
5060
5061 // 'unordered or not equal' is 'anything but equal', so use the EQ condition
5062 // code and swap the VSEL operands. Also do this if we don't care about the
5063 // unordered case.
5064 if (CC == ISD::SETUNE || CC == ISD::SETNE) {
5065 CondCode = ARMCC::EQ;
5066 swpVselOps = true;
5067 }
5068}
5069
5070SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
5071 SDValue TrueVal, SDValue ARMcc,
5072 SDValue Flags, SelectionDAG &DAG) const {
5073 if (!Subtarget->hasFP64() && VT == MVT::f64) {
5074 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5075 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
5076 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5077 DAG.getVTList(MVT::i32, MVT::i32), TrueVal);
5078
5079 SDValue TrueLow = TrueVal.getValue(0);
5080 SDValue TrueHigh = TrueVal.getValue(1);
5081 SDValue FalseLow = FalseVal.getValue(0);
5082 SDValue FalseHigh = FalseVal.getValue(1);
5083
5084 SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
5085 ARMcc, Flags);
5086 SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
5087 ARMcc, Flags);
5088
5089 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
5090 }
5091 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
5092}
5093
5094static bool isGTorGE(ISD::CondCode CC) {
5095 return CC == ISD::SETGT || CC == ISD::SETGE;
5096}
5097
5098static bool isLTorLE(ISD::CondCode CC) {
5099 return CC == ISD::SETLT || CC == ISD::SETLE;
5100}
5101
5102// See if a conditional (LHS CC RHS ? TrueVal : FalseVal) is lower-saturating.
5103// All of these conditions (and their <= and >= counterparts) will do:
5104// x < k ? k : x
5105// x > k ? x : k
5106// k < x ? x : k
5107// k > x ? k : x
5108static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
5109 const SDValue TrueVal, const SDValue FalseVal,
5110 const ISD::CondCode CC, const SDValue K) {
5111 return (isGTorGE(CC) &&
5112 ((K == LHS && K == TrueVal) || (K == RHS && K == FalseVal))) ||
5113 (isLTorLE(CC) &&
5114 ((K == RHS && K == TrueVal) || (K == LHS && K == FalseVal)));
5115}
5116
5117// Check if two chained conditionals could be converted into SSAT or USAT.
5118//
5119// SSAT can replace a set of two conditional selectors that bound a number to an
5120// interval of type [k, ~k] when k + 1 is a power of 2. Here are some examples:
5121//
5122// x < -k ? -k : (x > k ? k : x)
5123// x < -k ? -k : (x < k ? x : k)
5124// x > -k ? (x > k ? k : x) : -k
5125// x < k ? (x < -k ? -k : x) : k
5126// etc.
5127//
5128// LLVM canonicalizes these to either a min(max()) or a max(min())
5129// pattern. This function tries to match one of these and will return a SSAT
5130// node if successful.
5131//
5132// USAT works similarly to SSAT but bounds on the interval [0, k] where k + 1
5133// is a power of 2.
5135 EVT VT = Op.getValueType();
5136 SDValue V1 = Op.getOperand(0);
5137 SDValue K1 = Op.getOperand(1);
5138 SDValue TrueVal1 = Op.getOperand(2);
5139 SDValue FalseVal1 = Op.getOperand(3);
5140 ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5141
5142 const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
5143 if (Op2.getOpcode() != ISD::SELECT_CC)
5144 return SDValue();
5145
5146 SDValue V2 = Op2.getOperand(0);
5147 SDValue K2 = Op2.getOperand(1);
5148 SDValue TrueVal2 = Op2.getOperand(2);
5149 SDValue FalseVal2 = Op2.getOperand(3);
5150 ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
5151
5152 SDValue V1Tmp = V1;
5153 SDValue V2Tmp = V2;
5154
5155 // Check that the registers and the constants match a max(min()) or min(max())
5156 // pattern
5157 if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
5158 K2 != FalseVal2 ||
5159 !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
5160 return SDValue();
5161
5162 // Check that the constant in the lower-bound check is
5163 // the opposite of the constant in the upper-bound check
5164 // in 1's complement.
5166 return SDValue();
5167
5168 int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
5169 int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
5170 int64_t PosVal = std::max(Val1, Val2);
5171 int64_t NegVal = std::min(Val1, Val2);
5172
5173 if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
5174 !isPowerOf2_64(PosVal + 1))
5175 return SDValue();
5176
5177 // Handle the difference between USAT (unsigned) and SSAT (signed)
5178 // saturation
5179 // At this point, PosVal is guaranteed to be positive
5180 uint64_t K = PosVal;
5181 SDLoc dl(Op);
5182 if (Val1 == ~Val2)
5183 return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
5184 DAG.getConstant(llvm::countr_one(K), dl, VT));
5185 if (NegVal == 0)
5186 return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
5187 DAG.getConstant(llvm::countr_one(K), dl, VT));
5188
5189 return SDValue();
5190}
5191
5192// Check if a condition of the type x < k ? k : x can be converted into a
5193// bit operation instead of conditional moves.
5194// Currently this is allowed given:
5195// - The conditions and values match up
5196// - k is 0 or -1 (all ones)
5197// This function will not check the last condition, thats up to the caller
5198// It returns true if the transformation can be made, and in such case
5199// returns x in V, and k in SatK.
5201 SDValue &SatK)
5202{
5203 SDValue LHS = Op.getOperand(0);
5204 SDValue RHS = Op.getOperand(1);
5205 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5206 SDValue TrueVal = Op.getOperand(2);
5207 SDValue FalseVal = Op.getOperand(3);
5208
5210 ? &RHS
5211 : nullptr;
5212
5213 // No constant operation in comparison, early out
5214 if (!K)
5215 return false;
5216
5217 SDValue KTmp = isa<ConstantSDNode>(TrueVal) ? TrueVal : FalseVal;
5218 V = (KTmp == TrueVal) ? FalseVal : TrueVal;
5219 SDValue VTmp = (K && *K == LHS) ? RHS : LHS;
5220
5221 // If the constant on left and right side, or variable on left and right,
5222 // does not match, early out
5223 if (*K != KTmp || V != VTmp)
5224 return false;
5225
5226 if (isLowerSaturate(LHS, RHS, TrueVal, FalseVal, CC, *K)) {
5227 SatK = *K;
5228 return true;
5229 }
5230
5231 return false;
5232}
5233
5234bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
5235 if (VT == MVT::f32)
5236 return !Subtarget->hasVFP2Base();
5237 if (VT == MVT::f64)
5238 return !Subtarget->hasFP64();
5239 if (VT == MVT::f16)
5240 return !Subtarget->hasFullFP16();
5241 return false;
5242}
5243
5244static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
5245 SDValue FalseVal, const ARMSubtarget *Subtarget) {
5246 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5247 ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
5248 if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
5249 return SDValue();
5250
5251 unsigned TVal = CTVal->getZExtValue();
5252 unsigned FVal = CFVal->getZExtValue();
5253
5254 Opcode = 0;
5255 InvertCond = false;
5256 if (TVal == ~FVal) {
5257 Opcode = ARMISD::CSINV;
5258 } else if (TVal == ~FVal + 1) {
5259 Opcode = ARMISD::CSNEG;
5260 } else if (TVal + 1 == FVal) {
5261 Opcode = ARMISD::CSINC;
5262 } else if (TVal == FVal + 1) {
5263 Opcode = ARMISD::CSINC;
5264 std::swap(TrueVal, FalseVal);
5265 std::swap(TVal, FVal);
5266 InvertCond = !InvertCond;
5267 } else {
5268 return SDValue();
5269 }
5270
5271 // If one of the constants is cheaper than another, materialise the
5272 // cheaper one and let the csel generate the other.
5273 if (Opcode != ARMISD::CSINC &&
5274 HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
5275 std::swap(TrueVal, FalseVal);
5276 std::swap(TVal, FVal);
5277 InvertCond = !InvertCond;
5278 }
5279
5280 // Attempt to use ZR checking TVal is 0, possibly inverting the condition
5281 // to get there. CSINC not is invertable like the other two (~(~a) == a,
5282 // -(-a) == a, but (a+1)+1 != a).
5283 if (FVal == 0 && Opcode != ARMISD::CSINC) {
5284 std::swap(TrueVal, FalseVal);
5285 std::swap(TVal, FVal);
5286 InvertCond = !InvertCond;
5287 }
5288
5289 return TrueVal;
5290}
5291
5292SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
5293 EVT VT = Op.getValueType();
5294 SDLoc dl(Op);
5295
5296 // Try to convert two saturating conditional selects into a single SSAT
5297 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
5298 if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
5299 return SatValue;
5300
5301 // Try to convert expressions of the form x < k ? k : x (and similar forms)
5302 // into more efficient bit operations, which is possible when k is 0 or -1
5303 // On ARM and Thumb-2 which have flexible operand 2 this will result in
5304 // single instructions. On Thumb the shift and the bit operation will be two
5305 // instructions.
5306 // Only allow this transformation on full-width (32-bit) operations
5307 SDValue LowerSatConstant;
5308 SDValue SatValue;
5309 if (VT == MVT::i32 &&
5310 isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
5311 SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
5312 DAG.getConstant(31, dl, VT));
5313 if (isNullConstant(LowerSatConstant)) {
5314 SDValue NotShiftV = DAG.getNode(ISD::XOR, dl, VT, ShiftV,
5315 DAG.getAllOnesConstant(dl, VT));
5316 return DAG.getNode(ISD::AND, dl, VT, SatValue, NotShiftV);
5317 } else if (isAllOnesConstant(LowerSatConstant))
5318 return DAG.getNode(ISD::OR, dl, VT, SatValue, ShiftV);
5319 }
5320
5321 SDValue LHS = Op.getOperand(0);
5322 SDValue RHS = Op.getOperand(1);
5323 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5324 SDValue TrueVal = Op.getOperand(2);
5325 SDValue FalseVal = Op.getOperand(3);
5326 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5327 ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
5328 if (Op.getValueType().isInteger()) {
5329
5330 // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
5331 // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
5332 // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
5333 // Both require less instructions than compare and conditional select.
5334 if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
5335 RHSC->isZero() && CFVal && CFVal->isZero() &&
5336 LHS.getValueType() == RHS.getValueType()) {
5337 EVT VT = LHS.getValueType();
5338 SDValue Shift =
5339 DAG.getNode(ISD::SRA, dl, VT, LHS,
5340 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5341
5342 if (CC == ISD::SETGT)
5343 Shift = DAG.getNOT(dl, Shift, VT);
5344
5345 return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
5346 }
5347
5348 // (SELECT_CC setlt, x, 0, 1, 0) -> SRL(x, bw-1)
5349 if (CC == ISD::SETLT && isNullConstant(RHS) && isOneConstant(TrueVal) &&
5350 isNullConstant(FalseVal) && LHS.getValueType() == VT)
5351 return DAG.getNode(ISD::SRL, dl, VT, LHS,
5352 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5353 }
5354
5355 if (LHS.getValueType() == MVT::i32) {
5356 unsigned Opcode;
5357 bool InvertCond;
5358 if (SDValue Op =
5359 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
5360 if (InvertCond)
5361 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5362
5363 SDValue ARMcc;
5364 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5365 EVT VT = Op.getValueType();
5366 return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
5367 }
5368 }
5369
5370 if (isUnsupportedFloatingType(LHS.getValueType())) {
5371 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5372
5373 // If softenSetCCOperands only returned one value, we should compare it to
5374 // zero.
5375 if (!RHS.getNode()) {
5376 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5377 CC = ISD::SETNE;
5378 }
5379 }
5380
5381 if (LHS.getValueType() == MVT::i32) {
5382 // Try to generate VSEL on ARMv8.
5383 // The VSEL instruction can't use all the usual ARM condition
5384 // codes: it only has two bits to select the condition code, so it's
5385 // constrained to use only GE, GT, VS and EQ.
5386 //
5387 // To implement all the various ISD::SETXXX opcodes, we sometimes need to
5388 // swap the operands of the previous compare instruction (effectively
5389 // inverting the compare condition, swapping 'less' and 'greater') and
5390 // sometimes need to swap the operands to the VSEL (which inverts the
5391 // condition in the sense of firing whenever the previous condition didn't)
5392 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
5393 TrueVal.getValueType() == MVT::f32 ||
5394 TrueVal.getValueType() == MVT::f64)) {
5396 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
5397 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
5398 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5399 std::swap(TrueVal, FalseVal);
5400 }
5401 }
5402
5403 SDValue ARMcc;
5404 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5405 // Choose GE over PL, which vsel does now support
5406 if (ARMcc->getAsZExtVal() == ARMCC::PL)
5407 ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
5408 return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5409 }
5410
5411 ARMCC::CondCodes CondCode, CondCode2;
5412 FPCCToARMCC(CC, CondCode, CondCode2);
5413
5414 // Normalize the fp compare. If RHS is zero we prefer to keep it there so we
5415 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
5416 // must use VSEL (limited condition codes), due to not having conditional f16
5417 // moves.
5418 if (Subtarget->hasFPARMv8Base() &&
5419 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
5420 (TrueVal.getValueType() == MVT::f16 ||
5421 TrueVal.getValueType() == MVT::f32 ||
5422 TrueVal.getValueType() == MVT::f64)) {
5423 bool swpCmpOps = false;
5424 bool swpVselOps = false;
5425 checkVSELConstraints(CC, CondCode, swpCmpOps, swpVselOps);
5426
5427 if (CondCode == ARMCC::GT || CondCode == ARMCC::GE ||
5428 CondCode == ARMCC::VS || CondCode == ARMCC::EQ) {
5429 if (swpCmpOps)
5430 std::swap(LHS, RHS);
5431 if (swpVselOps)
5432 std::swap(TrueVal, FalseVal);
5433 }
5434 }
5435
5436 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5437 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5438 SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5439 if (CondCode2 != ARMCC::AL) {
5440 SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
5441 Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
5442 }
5443 return Result;
5444}
5445
5446/// canChangeToInt - Given the fp compare operand, return true if it is suitable
5447/// to morph to an integer compare sequence.
5448static bool canChangeToInt(SDValue Op, bool &SeenZero,
5449 const ARMSubtarget *Subtarget) {
5450 SDNode *N = Op.getNode();
5451 if (!N->hasOneUse())
5452 // Otherwise it requires moving the value from fp to integer registers.
5453 return false;
5454 if (!N->getNumValues())
5455 return false;
5456 EVT VT = Op.getValueType();
5457 if (VT != MVT::f32 && !Subtarget->isFPBrccSlow())
5458 // f32 case is generally profitable. f64 case only makes sense when vcmpe +
5459 // vmrs are very slow, e.g. cortex-a8.
5460 return false;
5461
5462 if (isFloatingPointZero(Op)) {
5463 SeenZero = true;
5464 return true;
5465 }
5466 return ISD::isNormalLoad(N);
5467}
5468
5471 return DAG.getConstant(0, SDLoc(Op), MVT::i32);
5472
5474 return DAG.getLoad(MVT::i32, SDLoc(Op), Ld->getChain(), Ld->getBasePtr(),
5475 Ld->getPointerInfo(), Ld->getAlign(),
5476 Ld->getMemOperand()->getFlags());
5477
5478 llvm_unreachable("Unknown VFP cmp argument!");
5479}
5480
5482 SDValue &RetVal1, SDValue &RetVal2) {
5483 SDLoc dl(Op);
5484
5485 if (isFloatingPointZero(Op)) {
5486 RetVal1 = DAG.getConstant(0, dl, MVT::i32);
5487 RetVal2 = DAG.getConstant(0, dl, MVT::i32);
5488 return;
5489 }
5490
5491 if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Op)) {
5492 SDValue Ptr = Ld->getBasePtr();
5493 RetVal1 =
5494 DAG.getLoad(MVT::i32, dl, Ld->getChain(), Ptr, Ld->getPointerInfo(),
5495 Ld->getAlign(), Ld->getMemOperand()->getFlags());
5496
5497 EVT PtrType = Ptr.getValueType();
5498 SDValue NewPtr = DAG.getNode(ISD::ADD, dl,
5499 PtrType, Ptr, DAG.getConstant(4, dl, PtrType));
5500 RetVal2 = DAG.getLoad(MVT::i32, dl, Ld->getChain(), NewPtr,
5501 Ld->getPointerInfo().getWithOffset(4),
5502 commonAlignment(Ld->getAlign(), 4),
5503 Ld->getMemOperand()->getFlags());
5504 return;
5505 }
5506
5507 llvm_unreachable("Unknown VFP cmp argument!");
5508}
5509
5510/// OptimizeVFPBrcond - With nnan and without daz, it's legal to optimize some
5511/// f32 and even f64 comparisons to integer ones.
5512SDValue
5513ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
5514 SDValue Chain = Op.getOperand(0);
5515 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5516 SDValue LHS = Op.getOperand(2);
5517 SDValue RHS = Op.getOperand(3);
5518 SDValue Dest = Op.getOperand(4);
5519 SDLoc dl(Op);
5520
5521 bool LHSSeenZero = false;
5522 bool LHSOk = canChangeToInt(LHS, LHSSeenZero, Subtarget);
5523 bool RHSSeenZero = false;
5524 bool RHSOk = canChangeToInt(RHS, RHSSeenZero, Subtarget);
5525 if (LHSOk && RHSOk && (LHSSeenZero || RHSSeenZero)) {
5526 // If unsafe fp math optimization is enabled and there are no other uses of
5527 // the CMP operands, and the condition code is EQ or NE, we can optimize it
5528 // to an integer comparison.
5529 if (CC == ISD::SETOEQ)
5530 CC = ISD::SETEQ;
5531 else if (CC == ISD::SETUNE)
5532 CC = ISD::SETNE;
5533
5534 SDValue Mask = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5535 SDValue ARMcc;
5536 if (LHS.getValueType() == MVT::f32) {
5537 LHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5538 bitcastf32Toi32(LHS, DAG), Mask);
5539 RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5540 bitcastf32Toi32(RHS, DAG), Mask);
5541 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5542 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5543 Cmp);
5544 }
5545
5546 SDValue LHS1, LHS2;
5547 SDValue RHS1, RHS2;
5548 expandf64Toi32(LHS, DAG, LHS1, LHS2);
5549 expandf64Toi32(RHS, DAG, RHS1, RHS2);
5550 LHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, LHS2, Mask);
5551 RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
5553 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5554 SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
5555 return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
5556 }
5557
5558 return SDValue();
5559}
5560
5561// Generate CMP + CMOV for integer abs.
5562SDValue ARMTargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
5563 SDLoc DL(Op);
5564
5565 SDValue Neg = DAG.getNegative(Op.getOperand(0), DL, MVT::i32);
5566
5567 // Generate CMP & CMOV.
5568 SDValue Cmp = DAG.getNode(ARMISD::CMP, DL, FlagsVT, Op.getOperand(0),
5569 DAG.getConstant(0, DL, MVT::i32));
5570 return DAG.getNode(ARMISD::CMOV, DL, MVT::i32, Op.getOperand(0), Neg,
5571 DAG.getConstant(ARMCC::MI, DL, MVT::i32), Cmp);
5572}
5573
5575 ARMCC::CondCodes CondCode =
5576 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();
5577 CondCode = ARMCC::getOppositeCondition(CondCode);
5578 return DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5579}
5580
5581SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5582 SDValue Chain = Op.getOperand(0);
5583 SDValue Cond = Op.getOperand(1);
5584 SDValue Dest = Op.getOperand(2);
5585 SDLoc dl(Op);
5586
5587 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5588 // instruction.
5589 unsigned Opc = Cond.getOpcode();
5590 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5591 !Subtarget->isThumb1Only();
5592 if (Cond.getResNo() == 1 &&
5593 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5594 Opc == ISD::USUBO || OptimizeMul)) {
5595 // Only lower legal XALUO ops.
5596 if (!isTypeLegal(Cond->getValueType(0)))
5597 return SDValue();
5598
5599 // The actual operation with overflow check.
5600 SDValue Value, OverflowCmp;
5601 SDValue ARMcc;
5602 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5603
5604 // Reverse the condition code.
5605 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5606
5607 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5608 OverflowCmp);
5609 }
5610
5611 return SDValue();
5612}
5613
5614SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5615 SDValue Chain = Op.getOperand(0);
5616 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5617 SDValue LHS = Op.getOperand(2);
5618 SDValue RHS = Op.getOperand(3);
5619 SDValue Dest = Op.getOperand(4);
5620 SDLoc dl(Op);
5621
5622 if (isUnsupportedFloatingType(LHS.getValueType())) {
5623 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5624
5625 // If softenSetCCOperands only returned one value, we should compare it to
5626 // zero.
5627 if (!RHS.getNode()) {
5628 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5629 CC = ISD::SETNE;
5630 }
5631 }
5632
5633 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5634 // instruction.
5635 unsigned Opc = LHS.getOpcode();
5636 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5637 !Subtarget->isThumb1Only();
5638 if (LHS.getResNo() == 1 && (isOneConstant(RHS) || isNullConstant(RHS)) &&
5639 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5640 Opc == ISD::USUBO || OptimizeMul) &&
5641 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5642 // Only lower legal XALUO ops.
5643 if (!isTypeLegal(LHS->getValueType(0)))
5644 return SDValue();
5645
5646 // The actual operation with overflow check.
5647 SDValue Value, OverflowCmp;
5648 SDValue ARMcc;
5649 std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5650
5651 if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5652 // Reverse the condition code.
5653 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5654 }
5655
5656 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5657 OverflowCmp);
5658 }
5659
5660 if (LHS.getValueType() == MVT::i32) {
5661 SDValue ARMcc;
5662 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5663 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
5664 }
5665
5666 SDNodeFlags Flags = Op->getFlags();
5667 if (Flags.hasNoNaNs() &&
5668 DAG.getDenormalMode(MVT::f32) == DenormalMode::getIEEE() &&
5669 DAG.getDenormalMode(MVT::f64) == DenormalMode::getIEEE() &&
5670 (CC == ISD::SETEQ || CC == ISD::SETOEQ || CC == ISD::SETNE ||
5671 CC == ISD::SETUNE)) {
5672 if (SDValue Result = OptimizeVFPBrcond(Op, DAG))
5673 return Result;
5674 }
5675
5676 ARMCC::CondCodes CondCode, CondCode2;
5677 FPCCToARMCC(CC, CondCode, CondCode2);
5678
5679 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5680 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5681 SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
5682 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5683 if (CondCode2 != ARMCC::AL) {
5684 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
5685 SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
5686 Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5687 }
5688 return Res;
5689}
5690
5691SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
5692 SDValue Chain = Op.getOperand(0);
5693 SDValue Table = Op.getOperand(1);
5694 SDValue Index = Op.getOperand(2);
5695 SDLoc dl(Op);
5696
5697 EVT PTy = getPointerTy(DAG.getDataLayout());
5698 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
5699 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
5700 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
5701 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
5702 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
5703 if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
5704 // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
5705 // which does another jump to the destination. This also makes it easier
5706 // to translate it to TBB / TBH later (Thumb2 only).
5707 // FIXME: This might not work if the function is extremely large.
5708 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,
5709 Addr, Op.getOperand(2), JTI);
5710 }
5711 if (isPositionIndependent() || Subtarget->isROPI()) {
5712 Addr =
5713 DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
5715 Chain = Addr.getValue(1);
5716 Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
5717 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5718 } else {
5719 Addr =
5720 DAG.getLoad(PTy, dl, Chain, Addr,
5722 Chain = Addr.getValue(1);
5723 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5724 }
5725}
5726
5728 EVT VT = Op.getValueType();
5729 SDLoc dl(Op);
5730
5731 if (Op.getValueType().getVectorElementType() == MVT::i32) {
5732 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::f32)
5733 return Op;
5734 return DAG.UnrollVectorOp(Op.getNode());
5735 }
5736
5737 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5738
5739 EVT NewTy;
5740 const EVT OpTy = Op.getOperand(0).getValueType();
5741 if (OpTy == MVT::v4f32)
5742 NewTy = MVT::v4i32;
5743 else if (OpTy == MVT::v4f16 && HasFullFP16)
5744 NewTy = MVT::v4i16;
5745 else if (OpTy == MVT::v8f16 && HasFullFP16)
5746 NewTy = MVT::v8i16;
5747 else
5748 llvm_unreachable("Invalid type for custom lowering!");
5749
5750 if (VT != MVT::v4i16 && VT != MVT::v8i16)
5751 return DAG.UnrollVectorOp(Op.getNode());
5752
5753 Op = DAG.getNode(Op.getOpcode(), dl, NewTy, Op.getOperand(0));
5754 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
5755}
5756
5757SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
5758 EVT VT = Op.getValueType();
5759 if (VT.isVector())
5760 return LowerVectorFP_TO_INT(Op, DAG);
5761
5762 bool IsStrict = Op->isStrictFPOpcode();
5763 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5764
5765 if (isUnsupportedFloatingType(SrcVal.getValueType())) {
5766 RTLIB::Libcall LC;
5767 if (Op.getOpcode() == ISD::FP_TO_SINT ||
5768 Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
5769 LC = RTLIB::getFPTOSINT(SrcVal.getValueType(),
5770 Op.getValueType());
5771 else
5772 LC = RTLIB::getFPTOUINT(SrcVal.getValueType(),
5773 Op.getValueType());
5774 SDLoc Loc(Op);
5775 MakeLibCallOptions CallOptions;
5776 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5778 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5779 CallOptions, Loc, Chain);
5780 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5781 }
5782
5783 return Op;
5784}
5785
5787 const ARMSubtarget *Subtarget) {
5788 EVT VT = Op.getValueType();
5789 EVT ToVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
5790 EVT FromVT = Op.getOperand(0).getValueType();
5791
5792 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f32)
5793 return Op;
5794 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f64 &&
5795 Subtarget->hasFP64())
5796 return Op;
5797 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f16 &&
5798 Subtarget->hasFullFP16())
5799 return Op;
5800 if (VT == MVT::v4i32 && ToVT == MVT::i32 && FromVT == MVT::v4f32 &&
5801 Subtarget->hasMVEFloatOps())
5802 return Op;
5803 if (VT == MVT::v8i16 && ToVT == MVT::i16 && FromVT == MVT::v8f16 &&
5804 Subtarget->hasMVEFloatOps())
5805 return Op;
5806
5807 if (FromVT != MVT::v4f32 && FromVT != MVT::v8f16)
5808 return SDValue();
5809
5810 SDLoc DL(Op);
5811 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
5812 unsigned BW = ToVT.getScalarSizeInBits() - IsSigned;
5813 SDValue CVT = DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
5814 DAG.getValueType(VT.getScalarType()));
5815 SDValue Max = DAG.getNode(IsSigned ? ISD::SMIN : ISD::UMIN, DL, VT, CVT,
5816 DAG.getConstant((1 << BW) - 1, DL, VT));
5817 if (IsSigned)
5818 Max = DAG.getNode(ISD::SMAX, DL, VT, Max,
5819 DAG.getSignedConstant(-(1 << BW), DL, VT));
5820 return Max;
5821}
5822
5824 EVT VT = Op.getValueType();
5825 SDLoc dl(Op);
5826
5827 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::i32) {
5828 if (VT.getVectorElementType() == MVT::f32)
5829 return Op;
5830 return DAG.UnrollVectorOp(Op.getNode());
5831 }
5832
5833 assert((Op.getOperand(0).getValueType() == MVT::v4i16 ||
5834 Op.getOperand(0).getValueType() == MVT::v8i16) &&
5835 "Invalid type for custom lowering!");
5836
5837 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5838
5839 EVT DestVecType;
5840 if (VT == MVT::v4f32)
5841 DestVecType = MVT::v4i32;
5842 else if (VT == MVT::v4f16 && HasFullFP16)
5843 DestVecType = MVT::v4i16;
5844 else if (VT == MVT::v8f16 && HasFullFP16)
5845 DestVecType = MVT::v8i16;
5846 else
5847 return DAG.UnrollVectorOp(Op.getNode());
5848
5849 unsigned CastOpc;
5850 unsigned Opc;
5851 switch (Op.getOpcode()) {
5852 default: llvm_unreachable("Invalid opcode!");
5853 case ISD::SINT_TO_FP:
5854 CastOpc = ISD::SIGN_EXTEND;
5856 break;
5857 case ISD::UINT_TO_FP:
5858 CastOpc = ISD::ZERO_EXTEND;
5860 break;
5861 }
5862
5863 Op = DAG.getNode(CastOpc, dl, DestVecType, Op.getOperand(0));
5864 return DAG.getNode(Opc, dl, VT, Op);
5865}
5866
5867SDValue ARMTargetLowering::LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const {
5868 EVT VT = Op.getValueType();
5869 if (VT.isVector())
5870 return LowerVectorINT_TO_FP(Op, DAG);
5871
5872 bool IsStrict = Op->isStrictFPOpcode();
5873 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5874
5875 if (isUnsupportedFloatingType(VT)) {
5876 RTLIB::Libcall LC;
5877 if (Op.getOpcode() == ISD::SINT_TO_FP ||
5878 Op.getOpcode() == ISD::STRICT_SINT_TO_FP)
5879 LC = RTLIB::getSINTTOFP(SrcVal.getValueType(), Op.getValueType());
5880 else
5881 LC = RTLIB::getUINTTOFP(SrcVal.getValueType(), Op.getValueType());
5882 SDLoc Loc(Op);
5883 MakeLibCallOptions CallOptions;
5884 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5886 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5887 CallOptions, Loc, Chain);
5888 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5889 }
5890
5891 return Op;
5892}
5893
5894SDValue ARMTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
5895 // Implement fcopysign with a fabs and a conditional fneg.
5896 SDValue Tmp0 = Op.getOperand(0);
5897 SDValue Tmp1 = Op.getOperand(1);
5898 SDLoc dl(Op);
5899 EVT VT = Op.getValueType();
5900 EVT SrcVT = Tmp1.getValueType();
5901 bool InGPR = Tmp0.getOpcode() == ISD::BITCAST ||
5902 Tmp0.getOpcode() == ARMISD::VMOVDRR;
5903 bool UseNEON = !InGPR && Subtarget->hasNEON();
5904
5905 if (UseNEON) {
5906 // Use VBSL to copy the sign bit.
5907 unsigned EncodedVal = ARM_AM::createVMOVModImm(0x6, 0x80);
5908 SDValue Mask = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v2i32,
5909 DAG.getTargetConstant(EncodedVal, dl, MVT::i32));
5910 EVT OpVT = (VT == MVT::f32) ? MVT::v2i32 : MVT::v1i64;
5911 if (VT == MVT::f64)
5912 Mask = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5913 DAG.getNode(ISD::BITCAST, dl, OpVT, Mask),
5914 DAG.getConstant(32, dl, MVT::i32));
5915 else /*if (VT == MVT::f32)*/
5916 Tmp0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp0);
5917 if (SrcVT == MVT::f32) {
5918 Tmp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp1);
5919 if (VT == MVT::f64)
5920 Tmp1 = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5921 DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1),
5922 DAG.getConstant(32, dl, MVT::i32));
5923 } else if (VT == MVT::f32)
5924 Tmp1 = DAG.getNode(ARMISD::VSHRuIMM, dl, MVT::v1i64,
5925 DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, Tmp1),
5926 DAG.getConstant(32, dl, MVT::i32));
5927 Tmp0 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp0);
5928 Tmp1 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1);
5929
5931 dl, MVT::i32);
5932 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v8i8, AllOnes);
5933 SDValue MaskNot = DAG.getNode(ISD::XOR, dl, OpVT, Mask,
5934 DAG.getNode(ISD::BITCAST, dl, OpVT, AllOnes));
5935
5936 SDValue Res = DAG.getNode(ISD::OR, dl, OpVT,
5937 DAG.getNode(ISD::AND, dl, OpVT, Tmp1, Mask),
5938 DAG.getNode(ISD::AND, dl, OpVT, Tmp0, MaskNot));
5939 if (VT == MVT::f32) {
5940 Res = DAG.getNode(ISD::BITCAST, dl, MVT::v2f32, Res);
5941 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
5942 DAG.getConstant(0, dl, MVT::i32));
5943 } else {
5944 Res = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Res);
5945 }
5946
5947 return Res;
5948 }
5949
5950 // Bitcast operand 1 to i32.
5951 if (SrcVT == MVT::f64)
5952 Tmp1 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5953 Tmp1).getValue(1);
5954 Tmp1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp1);
5955
5956 // Or in the signbit with integer operations.
5957 SDValue Mask1 = DAG.getConstant(0x80000000, dl, MVT::i32);
5958 SDValue Mask2 = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5959 Tmp1 = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp1, Mask1);
5960 if (VT == MVT::f32) {
5961 Tmp0 = DAG.getNode(ISD::AND, dl, MVT::i32,
5962 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp0), Mask2);
5963 return DAG.getNode(ISD::BITCAST, dl, MVT::f32,
5964 DAG.getNode(ISD::OR, dl, MVT::i32, Tmp0, Tmp1));
5965 }
5966
5967 // f64: Or the high part with signbit and then combine two parts.
5968 Tmp0 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5969 Tmp0);
5970 SDValue Lo = Tmp0.getValue(0);
5971 SDValue Hi = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp0.getValue(1), Mask2);
5972 Hi = DAG.getNode(ISD::OR, dl, MVT::i32, Hi, Tmp1);
5973 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
5974}
5975
5976SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
5977 MachineFunction &MF = DAG.getMachineFunction();
5978 MachineFrameInfo &MFI = MF.getFrameInfo();
5979 MFI.setReturnAddressIsTaken(true);
5980
5981 EVT VT = Op.getValueType();
5982 SDLoc dl(Op);
5983 unsigned Depth = Op.getConstantOperandVal(0);
5984 if (Depth) {
5985 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
5986 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
5987 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
5988 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
5989 MachinePointerInfo());
5990 }
5991
5992 // Return LR, which contains the return address. Mark it an implicit live-in.
5993 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
5994 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
5995}
5996
5997SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
5998 const ARMBaseRegisterInfo &ARI =
5999 *static_cast<const ARMBaseRegisterInfo*>(RegInfo);
6000 MachineFunction &MF = DAG.getMachineFunction();
6001 MachineFrameInfo &MFI = MF.getFrameInfo();
6002 MFI.setFrameAddressIsTaken(true);
6003
6004 EVT VT = Op.getValueType();
6005 SDLoc dl(Op); // FIXME probably not meaningful
6006 unsigned Depth = Op.getConstantOperandVal(0);
6007 Register FrameReg = ARI.getFrameRegister(MF);
6008 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
6009 while (Depth--)
6010 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
6011 MachinePointerInfo());
6012 return FrameAddr;
6013}
6014
6015// FIXME? Maybe this could be a TableGen attribute on some registers and
6016// this table could be generated automatically from RegInfo.
6017Register ARMTargetLowering::getRegisterByName(const char* RegName, LLT VT,
6018 const MachineFunction &MF) const {
6019 return StringSwitch<Register>(RegName)
6020 .Case("sp", ARM::SP)
6021 .Default(Register());
6022}
6023
6024// Result is 64 bit value so split into two 32 bit values and return as a
6025// pair of values.
6027 SelectionDAG &DAG) {
6028 SDLoc DL(N);
6029
6030 // This function is only supposed to be called for i64 type destination.
6031 assert(N->getValueType(0) == MVT::i64
6032 && "ExpandREAD_REGISTER called for non-i64 type result.");
6033
6035 DAG.getVTList(MVT::i32, MVT::i32, MVT::Other),
6036 N->getOperand(0),
6037 N->getOperand(1));
6038
6039 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0),
6040 Read.getValue(1)));
6041 Results.push_back(Read.getValue(2)); // Chain
6042}
6043
6044/// \p BC is a bitcast that is about to be turned into a VMOVDRR.
6045/// When \p DstVT, the destination type of \p BC, is on the vector
6046/// register bank and the source of bitcast, \p Op, operates on the same bank,
6047/// it might be possible to combine them, such that everything stays on the
6048/// vector register bank.
6049/// \p return The node that would replace \p BT, if the combine
6050/// is possible.
6052 SelectionDAG &DAG) {
6053 SDValue Op = BC->getOperand(0);
6054 EVT DstVT = BC->getValueType(0);
6055
6056 // The only vector instruction that can produce a scalar (remember,
6057 // since the bitcast was about to be turned into VMOVDRR, the source
6058 // type is i64) from a vector is EXTRACT_VECTOR_ELT.
6059 // Moreover, we can do this combine only if there is one use.
6060 // Finally, if the destination type is not a vector, there is not
6061 // much point on forcing everything on the vector bank.
6062 if (!DstVT.isVector() || Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
6063 !Op.hasOneUse())
6064 return SDValue();
6065
6066 // If the index is not constant, we will introduce an additional
6067 // multiply that will stick.
6068 // Give up in that case.
6069 ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Op.getOperand(1));
6070 if (!Index)
6071 return SDValue();
6072 unsigned DstNumElt = DstVT.getVectorNumElements();
6073
6074 // Compute the new index.
6075 const APInt &APIntIndex = Index->getAPIntValue();
6076 APInt NewIndex(APIntIndex.getBitWidth(), DstNumElt);
6077 NewIndex *= APIntIndex;
6078 // Check if the new constant index fits into i32.
6079 if (NewIndex.getBitWidth() > 32)
6080 return SDValue();
6081
6082 // vMTy bitcast(i64 extractelt vNi64 src, i32 index) ->
6083 // vMTy extractsubvector vNxMTy (bitcast vNi64 src), i32 index*M)
6084 SDLoc dl(Op);
6085 SDValue ExtractSrc = Op.getOperand(0);
6086 EVT VecVT = EVT::getVectorVT(
6087 *DAG.getContext(), DstVT.getScalarType(),
6088 ExtractSrc.getValueType().getVectorNumElements() * DstNumElt);
6089 SDValue BitCast = DAG.getNode(ISD::BITCAST, dl, VecVT, ExtractSrc);
6090 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, BitCast,
6091 DAG.getConstant(NewIndex.getZExtValue(), dl, MVT::i32));
6092}
6093
6094/// ExpandBITCAST - If the target supports VFP, this function is called to
6095/// expand a bit convert where either the source or destination type is i64 to
6096/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
6097/// operand type is illegal (e.g., v2f32 for a target that doesn't support
6098/// vectors), since the legalizer won't know what to do with that.
6099SDValue ARMTargetLowering::ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
6100 const ARMSubtarget *Subtarget) const {
6101 SDLoc dl(N);
6102 SDValue Op = N->getOperand(0);
6103
6104 // This function is only supposed to be called for i16 and i64 types, either
6105 // as the source or destination of the bit convert.
6106 EVT SrcVT = Op.getValueType();
6107 EVT DstVT = N->getValueType(0);
6108
6109 if ((SrcVT == MVT::i16 || SrcVT == MVT::i32) &&
6110 (DstVT == MVT::f16 || DstVT == MVT::bf16))
6111 return MoveToHPR(SDLoc(N), DAG, MVT::i32, DstVT.getSimpleVT(),
6112 DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i32, Op));
6113
6114 if ((DstVT == MVT::i16 || DstVT == MVT::i32) &&
6115 (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
6116 if (Subtarget->hasFullFP16() && !Subtarget->hasBF16())
6117 Op = DAG.getBitcast(MVT::f16, Op);
6118 return DAG.getNode(
6119 ISD::TRUNCATE, SDLoc(N), DstVT,
6120 MoveFromHPR(SDLoc(N), DAG, MVT::i32, SrcVT.getSimpleVT(), Op));
6121 }
6122
6123 if (!(SrcVT == MVT::i64 || DstVT == MVT::i64))
6124 return SDValue();
6125
6126 // Turn i64->f64 into VMOVDRR.
6127 if (SrcVT == MVT::i64 && isTypeLegal(DstVT)) {
6128 // Do not force values to GPRs (this is what VMOVDRR does for the inputs)
6129 // if we can combine the bitcast with its source.
6131 return Val;
6132 SDValue Lo, Hi;
6133 std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32);
6134 return DAG.getNode(ISD::BITCAST, dl, DstVT,
6135 DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi));
6136 }
6137
6138 // Turn f64->i64 into VMOVRRD.
6139 if (DstVT == MVT::i64 && isTypeLegal(SrcVT)) {
6140 SDValue Cvt;
6141 if (DAG.getDataLayout().isBigEndian() && SrcVT.isVector() &&
6142 SrcVT.getVectorNumElements() > 1)
6143 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6144 DAG.getVTList(MVT::i32, MVT::i32),
6145 DAG.getNode(ARMISD::VREV64, dl, SrcVT, Op));
6146 else
6147 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6148 DAG.getVTList(MVT::i32, MVT::i32), Op);
6149 // Merge the pieces into a single i64 value.
6150 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1));
6151 }
6152
6153 return SDValue();
6154}
6155
6156/// getZeroVector - Returns a vector of specified type with all zero elements.
6157/// Zero vectors are used to represent vector negation and in those cases
6158/// will be implemented with the NEON VNEG instruction. However, VNEG does
6159/// not support i64 elements, so sometimes the zero vectors will need to be
6160/// explicitly constructed. Regardless, use a canonical VMOV to create the
6161/// zero vector.
6162static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
6163 assert(VT.isVector() && "Expected a vector type");
6164 // The canonical modified immediate encoding of a zero vector is....0!
6165 SDValue EncodedVal = DAG.getTargetConstant(0, dl, MVT::i32);
6166 EVT VmovVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
6167 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, EncodedVal);
6168 return DAG.getNode(ISD::BITCAST, dl, VT, Vmov);
6169}
6170
6171/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
6172/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6173SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
6174 SelectionDAG &DAG) const {
6175 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6176 EVT VT = Op.getValueType();
6177 unsigned VTBits = VT.getSizeInBits();
6178 SDLoc dl(Op);
6179 SDValue ShOpLo = Op.getOperand(0);
6180 SDValue ShOpHi = Op.getOperand(1);
6181 SDValue ShAmt = Op.getOperand(2);
6182 SDValue ARMcc;
6183 unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
6184
6185 assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
6186
6187 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6188 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6189 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt);
6190 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6191 DAG.getConstant(VTBits, dl, MVT::i32));
6192 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt);
6193 SDValue LoSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6194 SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
6195 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6196 ISD::SETGE, ARMcc, DAG, dl);
6197 SDValue Lo =
6198 DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
6199
6200 SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
6201 SDValue HiBigShift = Opc == ISD::SRA
6202 ? DAG.getNode(Opc, dl, VT, ShOpHi,
6203 DAG.getConstant(VTBits - 1, dl, VT))
6204 : DAG.getConstant(0, dl, VT);
6205 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6206 ISD::SETGE, ARMcc, DAG, dl);
6207 SDValue Hi =
6208 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6209
6210 SDValue Ops[2] = { Lo, Hi };
6211 return DAG.getMergeValues(Ops, dl);
6212}
6213
6214/// LowerShiftLeftParts - Lower SHL_PARTS, which returns two
6215/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6216SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op,
6217 SelectionDAG &DAG) const {
6218 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6219 EVT VT = Op.getValueType();
6220 unsigned VTBits = VT.getSizeInBits();
6221 SDLoc dl(Op);
6222 SDValue ShOpLo = Op.getOperand(0);
6223 SDValue ShOpHi = Op.getOperand(1);
6224 SDValue ShAmt = Op.getOperand(2);
6225 SDValue ARMcc;
6226
6227 assert(Op.getOpcode() == ISD::SHL_PARTS);
6228 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6229 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6230 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
6231 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
6232 SDValue HiSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6233
6234 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6235 DAG.getConstant(VTBits, dl, MVT::i32));
6236 SDValue HiBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
6237 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6238 ISD::SETGE, ARMcc, DAG, dl);
6239 SDValue Hi =
6240 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6241
6242 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6243 ISD::SETGE, ARMcc, DAG, dl);
6244 SDValue LoSmallShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
6245 SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift,
6246 DAG.getConstant(0, dl, VT), ARMcc, CmpLo);
6247
6248 SDValue Ops[2] = { Lo, Hi };
6249 return DAG.getMergeValues(Ops, dl);
6250}
6251
6252SDValue ARMTargetLowering::LowerGET_ROUNDING(SDValue Op,
6253 SelectionDAG &DAG) const {
6254 // The rounding mode is in bits 23:22 of the FPSCR.
6255 // The ARM rounding mode value to FLT_ROUNDS mapping is 0->1, 1->2, 2->3, 3->0
6256 // The formula we use to implement this is (((FPSCR + 1 << 22) >> 22) & 3)
6257 // so that the shift + and get folded into a bitfield extract.
6258 SDLoc dl(Op);
6259 SDValue Chain = Op.getOperand(0);
6260 SDValue Ops[] = {Chain,
6261 DAG.getConstant(Intrinsic::arm_get_fpscr, dl, MVT::i32)};
6262
6263 SDValue FPSCR =
6264 DAG.getNode(ISD::INTRINSIC_W_CHAIN, dl, {MVT::i32, MVT::Other}, Ops);
6265 Chain = FPSCR.getValue(1);
6266 SDValue FltRounds = DAG.getNode(ISD::ADD, dl, MVT::i32, FPSCR,
6267 DAG.getConstant(1U << 22, dl, MVT::i32));
6268 SDValue RMODE = DAG.getNode(ISD::SRL, dl, MVT::i32, FltRounds,
6269 DAG.getConstant(22, dl, MVT::i32));
6270 SDValue And = DAG.getNode(ISD::AND, dl, MVT::i32, RMODE,
6271 DAG.getConstant(3, dl, MVT::i32));
6272 return DAG.getMergeValues({And, Chain}, dl);
6273}
6274
6275SDValue ARMTargetLowering::LowerSET_ROUNDING(SDValue Op,
6276 SelectionDAG &DAG) const {
6277 SDLoc DL(Op);
6278 SDValue Chain = Op->getOperand(0);
6279 SDValue RMValue = Op->getOperand(1);
6280
6281 // The rounding mode is in bits 23:22 of the FPSCR.
6282 // The llvm.set.rounding argument value to ARM rounding mode value mapping
6283 // is 0->3, 1->0, 2->1, 3->2. The formula we use to implement this is
6284 // ((arg - 1) & 3) << 22).
6285 //
6286 // It is expected that the argument of llvm.set.rounding is within the
6287 // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
6288 // responsibility of the code generated llvm.set.rounding to ensure this
6289 // condition.
6290
6291 // Calculate new value of FPSCR[23:22].
6292 RMValue = DAG.getNode(ISD::SUB, DL, MVT::i32, RMValue,
6293 DAG.getConstant(1, DL, MVT::i32));
6294 RMValue = DAG.getNode(ISD::AND, DL, MVT::i32, RMValue,
6295 DAG.getConstant(0x3, DL, MVT::i32));
6296 RMValue = DAG.getNode(ISD::SHL, DL, MVT::i32, RMValue,
6297 DAG.getConstant(ARM::RoundingBitsPos, DL, MVT::i32));
6298
6299 // Get current value of FPSCR.
6300 SDValue Ops[] = {Chain,
6301 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6302 SDValue FPSCR =
6303 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6304 Chain = FPSCR.getValue(1);
6305 FPSCR = FPSCR.getValue(0);
6306
6307 // Put new rounding mode into FPSCR[23:22].
6308 const unsigned RMMask = ~(ARM::Rounding::rmMask << ARM::RoundingBitsPos);
6309 FPSCR = DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6310 DAG.getConstant(RMMask, DL, MVT::i32));
6311 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCR, RMValue);
6312 SDValue Ops2[] = {
6313 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6314 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6315}
6316
6317SDValue ARMTargetLowering::LowerSET_FPMODE(SDValue Op,
6318 SelectionDAG &DAG) const {
6319 SDLoc DL(Op);
6320 SDValue Chain = Op->getOperand(0);
6321 SDValue Mode = Op->getOperand(1);
6322
6323 // Generate nodes to build:
6324 // FPSCR = (FPSCR & FPStatusBits) | (Mode & ~FPStatusBits)
6325 SDValue Ops[] = {Chain,
6326 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6327 SDValue FPSCR =
6328 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6329 Chain = FPSCR.getValue(1);
6330 FPSCR = FPSCR.getValue(0);
6331
6332 SDValue FPSCRMasked =
6333 DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6334 DAG.getConstant(ARM::FPStatusBits, DL, MVT::i32));
6335 SDValue InputMasked =
6336 DAG.getNode(ISD::AND, DL, MVT::i32, Mode,
6337 DAG.getConstant(~ARM::FPStatusBits, DL, MVT::i32));
6338 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCRMasked, InputMasked);
6339
6340 SDValue Ops2[] = {
6341 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6342 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6343}
6344
6345SDValue ARMTargetLowering::LowerRESET_FPMODE(SDValue Op,
6346 SelectionDAG &DAG) const {
6347 SDLoc DL(Op);
6348 SDValue Chain = Op->getOperand(0);
6349
6350 // To get the default FP mode all control bits are cleared:
6351 // FPSCR = FPSCR & (FPStatusBits | FPReservedBits)
6352 SDValue Ops[] = {Chain,
6353 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6354 SDValue FPSCR =
6355 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6356 Chain = FPSCR.getValue(1);
6357 FPSCR = FPSCR.getValue(0);
6358
6359 SDValue FPSCRMasked = DAG.getNode(
6360 ISD::AND, DL, MVT::i32, FPSCR,
6362 SDValue Ops2[] = {Chain,
6363 DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32),
6364 FPSCRMasked};
6365 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6366}
6367
6369 const ARMSubtarget *ST) {
6370 SDLoc dl(N);
6371 EVT VT = N->getValueType(0);
6372 if (VT.isVector() && ST->hasNEON()) {
6373
6374 // Compute the least significant set bit: LSB = X & -X
6375 SDValue X = N->getOperand(0);
6376 SDValue NX = DAG.getNode(ISD::SUB, dl, VT, getZeroVector(VT, DAG, dl), X);
6377 SDValue LSB = DAG.getNode(ISD::AND, dl, VT, X, NX);
6378
6379 EVT ElemTy = VT.getVectorElementType();
6380
6381 if (ElemTy == MVT::i8) {
6382 // Compute with: cttz(x) = ctpop(lsb - 1)
6383 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6384 DAG.getTargetConstant(1, dl, ElemTy));
6385 SDValue Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6386 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6387 }
6388
6389 if ((ElemTy == MVT::i16 || ElemTy == MVT::i32) &&
6390 (N->getOpcode() == ISD::CTTZ_ZERO_POISON)) {
6391 // Compute with: cttz(x) = (width - 1) - ctlz(lsb), if x != 0
6392 unsigned NumBits = ElemTy.getSizeInBits();
6393 SDValue WidthMinus1 =
6394 DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6395 DAG.getTargetConstant(NumBits - 1, dl, ElemTy));
6396 SDValue CTLZ = DAG.getNode(ISD::CTLZ, dl, VT, LSB);
6397 return DAG.getNode(ISD::SUB, dl, VT, WidthMinus1, CTLZ);
6398 }
6399
6400 // Compute with: cttz(x) = ctpop(lsb - 1)
6401
6402 // Compute LSB - 1.
6403 SDValue Bits;
6404 if (ElemTy == MVT::i64) {
6405 // Load constant 0xffff'ffff'ffff'ffff to register.
6406 SDValue FF = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6407 DAG.getTargetConstant(0x1eff, dl, MVT::i32));
6408 Bits = DAG.getNode(ISD::ADD, dl, VT, LSB, FF);
6409 } else {
6410 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6411 DAG.getTargetConstant(1, dl, ElemTy));
6412 Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6413 }
6414 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6415 }
6416
6417 if (!ST->hasV6T2Ops())
6418 return SDValue();
6419
6420 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, VT, N->getOperand(0));
6421 return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
6422}
6423
6425 const ARMSubtarget *ST) {
6426 EVT VT = N->getValueType(0);
6427 SDLoc DL(N);
6428
6429 assert(ST->hasNEON() && "Custom ctpop lowering requires NEON.");
6430 assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
6431 VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
6432 "Unexpected type for custom ctpop lowering");
6433
6434 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6435 EVT VT8Bit = VT.is64BitVector() ? MVT::v8i8 : MVT::v16i8;
6436 SDValue Res = DAG.getBitcast(VT8Bit, N->getOperand(0));
6437 Res = DAG.getNode(ISD::CTPOP, DL, VT8Bit, Res);
6438
6439 // Widen v8i8/v16i8 CTPOP result to VT by repeatedly widening pairwise adds.
6440 unsigned EltSize = 8;
6441 unsigned NumElts = VT.is64BitVector() ? 8 : 16;
6442 while (EltSize != VT.getScalarSizeInBits()) {
6444 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddlu, DL,
6445 TLI.getPointerTy(DAG.getDataLayout())));
6446 Ops.push_back(Res);
6447
6448 EltSize *= 2;
6449 NumElts /= 2;
6450 MVT WidenVT = MVT::getVectorVT(MVT::getIntegerVT(EltSize), NumElts);
6451 Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, WidenVT, Ops);
6452 }
6453
6454 return Res;
6455}
6456
6457/// Getvshiftimm - Check if this is a valid build_vector for the immediate
6458/// operand of a vector shift operation, where all the elements of the
6459/// build_vector must have the same constant integer value.
6460static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) {
6461 // Ignore bit_converts.
6462 while (Op.getOpcode() == ISD::BITCAST)
6463 Op = Op.getOperand(0);
6465 APInt SplatBits, SplatUndef;
6466 unsigned SplatBitSize;
6467 bool HasAnyUndefs;
6468 if (!BVN ||
6469 !BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6470 ElementBits) ||
6471 SplatBitSize > ElementBits)
6472 return false;
6473 Cnt = SplatBits.getSExtValue();
6474 return true;
6475}
6476
6477/// isVShiftLImm - Check if this is a valid build_vector for the immediate
6478/// operand of a vector shift left operation. That value must be in the range:
6479/// 0 <= Value < ElementBits for a left shift; or
6480/// 0 <= Value <= ElementBits for a long left shift.
6481static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) {
6482 assert(VT.isVector() && "vector shift count is not a vector type");
6483 int64_t ElementBits = VT.getScalarSizeInBits();
6484 if (!getVShiftImm(Op, ElementBits, Cnt))
6485 return false;
6486 return (Cnt >= 0 && (isLong ? Cnt - 1 : Cnt) < ElementBits);
6487}
6488
6489/// isVShiftRImm - Check if this is a valid build_vector for the immediate
6490/// operand of a vector shift right operation. For a shift opcode, the value
6491/// is positive, but for an intrinsic the value count must be negative. The
6492/// absolute value must be in the range:
6493/// 1 <= |Value| <= ElementBits for a right shift; or
6494/// 1 <= |Value| <= ElementBits/2 for a narrow right shift.
6495static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic,
6496 int64_t &Cnt) {
6497 assert(VT.isVector() && "vector shift count is not a vector type");
6498 int64_t ElementBits = VT.getScalarSizeInBits();
6499 if (!getVShiftImm(Op, ElementBits, Cnt))
6500 return false;
6501 if (!isIntrinsic)
6502 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits / 2 : ElementBits));
6503 if (Cnt >= -(isNarrow ? ElementBits / 2 : ElementBits) && Cnt <= -1) {
6504 Cnt = -Cnt;
6505 return true;
6506 }
6507 return false;
6508}
6509
6511 const ARMSubtarget *ST) {
6512 EVT VT = N->getValueType(0);
6513 SDLoc dl(N);
6514 int64_t Cnt;
6515
6516 if (!VT.isVector())
6517 return SDValue();
6518
6519 // We essentially have two forms here. Shift by an immediate and shift by a
6520 // vector register (there are also shift by a gpr, but that is just handled
6521 // with a tablegen pattern). We cannot easily match shift by an immediate in
6522 // tablegen so we do that here and generate a VSHLIMM/VSHRsIMM/VSHRuIMM.
6523 // For shifting by a vector, we don't have VSHR, only VSHL (which can be
6524 // signed or unsigned, and a negative shift indicates a shift right).
6525 if (N->getOpcode() == ISD::SHL) {
6526 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt))
6527 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
6528 DAG.getConstant(Cnt, dl, MVT::i32));
6529 return DAG.getNode(ARMISD::VSHLu, dl, VT, N->getOperand(0),
6530 N->getOperand(1));
6531 }
6532
6533 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
6534 "unexpected vector shift opcode");
6535
6536 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
6537 unsigned VShiftOpc =
6538 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
6539 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
6540 DAG.getConstant(Cnt, dl, MVT::i32));
6541 }
6542
6543 // Other right shifts we don't have operations for (we use a shift left by a
6544 // negative number).
6545 EVT ShiftVT = N->getOperand(1).getValueType();
6546 SDValue NegatedCount = DAG.getNode(
6547 ISD::SUB, dl, ShiftVT, getZeroVector(ShiftVT, DAG, dl), N->getOperand(1));
6548 unsigned VShiftOpc =
6549 (N->getOpcode() == ISD::SRA ? ARMISD::VSHLs : ARMISD::VSHLu);
6550 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0), NegatedCount);
6551}
6552
6554 const ARMSubtarget *ST) {
6555 EVT VT = N->getValueType(0);
6556 SDLoc dl(N);
6557
6558 // We can get here for a node like i32 = ISD::SHL i32, i64
6559 if (VT != MVT::i64)
6560 return SDValue();
6561
6562 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA ||
6563 N->getOpcode() == ISD::SHL) &&
6564 "Unknown shift to lower!");
6565
6566 unsigned ShOpc = N->getOpcode();
6567 if (ST->hasMVEIntegerOps()) {
6568 SDValue ShAmt = N->getOperand(1);
6569 unsigned ShPartsOpc = ARMISD::LSLL;
6571
6572 // If the shift amount is greater than 32 or has a greater bitwidth than 64
6573 // then do the default optimisation
6574 if ((!Con && ShAmt->getValueType(0).getSizeInBits() > 64) ||
6575 (Con && (Con->getAPIntValue() == 0 || Con->getAPIntValue().uge(32))))
6576 return SDValue();
6577
6578 // Extract the lower 32 bits of the shift amount if it's not an i32
6579 if (ShAmt->getValueType(0) != MVT::i32)
6580 ShAmt = DAG.getZExtOrTrunc(ShAmt, dl, MVT::i32);
6581
6582 if (ShOpc == ISD::SRL) {
6583 if (!Con)
6584 // There is no t2LSRLr instruction so negate and perform an lsll if the
6585 // shift amount is in a register, emulating a right shift.
6586 ShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6587 DAG.getConstant(0, dl, MVT::i32), ShAmt);
6588 else
6589 // Else generate an lsrl on the immediate shift amount
6590 ShPartsOpc = ARMISD::LSRL;
6591 } else if (ShOpc == ISD::SRA)
6592 ShPartsOpc = ARMISD::ASRL;
6593
6594 // Split Lower/Upper 32 bits of the destination/source
6595 SDValue Lo, Hi;
6596 std::tie(Lo, Hi) =
6597 DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6598 // Generate the shift operation as computed above
6599 Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi,
6600 ShAmt);
6601 // The upper 32 bits come from the second return value of lsll
6602 Hi = SDValue(Lo.getNode(), 1);
6603 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6604 }
6605
6606 // We only lower SRA, SRL of 1 here, all others use generic lowering.
6607 if (!isOneConstant(N->getOperand(1)) || N->getOpcode() == ISD::SHL)
6608 return SDValue();
6609
6610 // If we are in thumb mode, we don't have RRX.
6611 if (ST->isThumb1Only())
6612 return SDValue();
6613
6614 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr.
6615 SDValue Lo, Hi;
6616 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6617
6618 // First, build a LSRS1/ASRS1 op, which shifts the top part by one and
6619 // captures the shifted out bit into a carry flag.
6620 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::LSRS1 : ARMISD::ASRS1;
6621 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, FlagsVT), Hi);
6622
6623 // The low part is an ARMISD::RRX operand, which shifts the carry in.
6624 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1));
6625
6626 // Merge the pieces into a single i64 value.
6627 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6628}
6629
6631 const ARMSubtarget *ST) {
6632 bool Invert = false;
6633 bool Swap = false;
6634 unsigned Opc = ARMCC::AL;
6635
6636 SDValue Op0 = Op.getOperand(0);
6637 SDValue Op1 = Op.getOperand(1);
6638 SDValue CC = Op.getOperand(2);
6639 EVT VT = Op.getValueType();
6640 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
6641 SDLoc dl(Op);
6642
6643 EVT CmpVT;
6644 if (ST->hasNEON())
6646 else {
6647 assert(ST->hasMVEIntegerOps() &&
6648 "No hardware support for integer vector comparison!");
6649
6650 if (Op.getValueType().getVectorElementType() != MVT::i1)
6651 return SDValue();
6652
6653 // Make sure we expand floating point setcc to scalar if we do not have
6654 // mve.fp, so that we can handle them from there.
6655 if (Op0.getValueType().isFloatingPoint() && !ST->hasMVEFloatOps())
6656 return SDValue();
6657
6658 CmpVT = VT;
6659 }
6660
6661 if (Op0.getValueType().getVectorElementType() == MVT::i64 &&
6662 (SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE)) {
6663 // Special-case integer 64-bit equality comparisons. They aren't legal,
6664 // but they can be lowered with a few vector instructions.
6665 unsigned CmpElements = CmpVT.getVectorNumElements() * 2;
6666 EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, CmpElements);
6667 SDValue CastOp0 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op0);
6668 SDValue CastOp1 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op1);
6669 SDValue Cmp = DAG.getNode(ISD::SETCC, dl, SplitVT, CastOp0, CastOp1,
6670 DAG.getCondCode(ISD::SETEQ));
6671 SDValue Reversed = DAG.getNode(ARMISD::VREV64, dl, SplitVT, Cmp);
6672 SDValue Merged = DAG.getNode(ISD::AND, dl, SplitVT, Cmp, Reversed);
6673 Merged = DAG.getNode(ISD::BITCAST, dl, CmpVT, Merged);
6674 if (SetCCOpcode == ISD::SETNE)
6675 Merged = DAG.getNOT(dl, Merged, CmpVT);
6676 Merged = DAG.getSExtOrTrunc(Merged, dl, VT);
6677 return Merged;
6678 }
6679
6680 if (CmpVT.getVectorElementType() == MVT::i64)
6681 // 64-bit comparisons are not legal in general.
6682 return SDValue();
6683
6684 if (Op1.getValueType().isFloatingPoint()) {
6685 switch (SetCCOpcode) {
6686 default: llvm_unreachable("Illegal FP comparison");
6687 case ISD::SETUNE:
6688 case ISD::SETNE:
6689 if (ST->hasMVEFloatOps()) {
6690 Opc = ARMCC::NE; break;
6691 } else {
6692 Invert = true; [[fallthrough]];
6693 }
6694 case ISD::SETOEQ:
6695 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6696 case ISD::SETOLT:
6697 case ISD::SETLT: Swap = true; [[fallthrough]];
6698 case ISD::SETOGT:
6699 case ISD::SETGT: Opc = ARMCC::GT; break;
6700 case ISD::SETOLE:
6701 case ISD::SETLE: Swap = true; [[fallthrough]];
6702 case ISD::SETOGE:
6703 case ISD::SETGE: Opc = ARMCC::GE; break;
6704 case ISD::SETUGE: Swap = true; [[fallthrough]];
6705 case ISD::SETULE: Invert = true; Opc = ARMCC::GT; break;
6706 case ISD::SETUGT: Swap = true; [[fallthrough]];
6707 case ISD::SETULT: Invert = true; Opc = ARMCC::GE; break;
6708 case ISD::SETUEQ: Invert = true; [[fallthrough]];
6709 case ISD::SETONE: {
6710 // Expand this to (OLT | OGT).
6711 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6712 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6713 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6714 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6715 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6716 if (Invert)
6717 Result = DAG.getNOT(dl, Result, VT);
6718 return Result;
6719 }
6720 case ISD::SETUO: Invert = true; [[fallthrough]];
6721 case ISD::SETO: {
6722 // Expand this to (OLT | OGE).
6723 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6724 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6725 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6726 DAG.getConstant(ARMCC::GE, dl, MVT::i32));
6727 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6728 if (Invert)
6729 Result = DAG.getNOT(dl, Result, VT);
6730 return Result;
6731 }
6732 }
6733 } else {
6734 // Integer comparisons.
6735 switch (SetCCOpcode) {
6736 default: llvm_unreachable("Illegal integer comparison");
6737 case ISD::SETNE:
6738 if (ST->hasMVEIntegerOps()) {
6739 Opc = ARMCC::NE; break;
6740 } else {
6741 Invert = true; [[fallthrough]];
6742 }
6743 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6744 case ISD::SETLT: Swap = true; [[fallthrough]];
6745 case ISD::SETGT: Opc = ARMCC::GT; break;
6746 case ISD::SETLE: Swap = true; [[fallthrough]];
6747 case ISD::SETGE: Opc = ARMCC::GE; break;
6748 case ISD::SETULT: Swap = true; [[fallthrough]];
6749 case ISD::SETUGT: Opc = ARMCC::HI; break;
6750 case ISD::SETULE: Swap = true; [[fallthrough]];
6751 case ISD::SETUGE: Opc = ARMCC::HS; break;
6752 }
6753
6754 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero).
6755 if (ST->hasNEON() && Opc == ARMCC::EQ) {
6756 SDValue AndOp;
6758 AndOp = Op0;
6759 else if (ISD::isBuildVectorAllZeros(Op0.getNode()))
6760 AndOp = Op1;
6761
6762 // Ignore bitconvert.
6763 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BITCAST)
6764 AndOp = AndOp.getOperand(0);
6765
6766 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
6767 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
6768 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
6769 SDValue Result = DAG.getNode(ARMISD::VTST, dl, CmpVT, Op0, Op1);
6770 if (!Invert)
6771 Result = DAG.getNOT(dl, Result, VT);
6772 return Result;
6773 }
6774 }
6775 }
6776
6777 if (Swap)
6778 std::swap(Op0, Op1);
6779
6780 // If one of the operands is a constant vector zero, attempt to fold the
6781 // comparison to a specialized compare-against-zero form.
6783 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::EQ ||
6784 Opc == ARMCC::NE)) {
6785 if (Opc == ARMCC::GE)
6786 Opc = ARMCC::LE;
6787 else if (Opc == ARMCC::GT)
6788 Opc = ARMCC::LT;
6789 std::swap(Op0, Op1);
6790 }
6791
6792 SDValue Result;
6794 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::LE ||
6795 Opc == ARMCC::LT || Opc == ARMCC::NE || Opc == ARMCC::EQ))
6796 Result = DAG.getNode(ARMISD::VCMPZ, dl, CmpVT, Op0,
6797 DAG.getConstant(Opc, dl, MVT::i32));
6798 else
6799 Result = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6800 DAG.getConstant(Opc, dl, MVT::i32));
6801
6802 Result = DAG.getSExtOrTrunc(Result, dl, VT);
6803
6804 if (Invert)
6805 Result = DAG.getNOT(dl, Result, VT);
6806
6807 return Result;
6808}
6809
6811 SDValue LHS = Op.getOperand(0);
6812 SDValue RHS = Op.getOperand(1);
6813
6814 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
6815
6816 SDValue Carry = Op.getOperand(2);
6817 SDValue Cond = Op.getOperand(3);
6818 SDLoc DL(Op);
6819
6820 // ARMISD::SUBE expects a carry not a borrow like ISD::USUBO_CARRY so we
6821 // have to invert the carry first.
6822 SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
6823
6824 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
6825 SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, InvCarry);
6826
6827 SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
6828 SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
6829 SDValue ARMcc = DAG.getConstant(
6830 IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
6831 return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
6832 Cmp.getValue(1));
6833}
6834
6835/// isVMOVModifiedImm - Check if the specified splat value corresponds to a
6836/// valid vector constant for a NEON or MVE instruction with a "modified
6837/// immediate" operand (e.g., VMOV). If so, return the encoded value.
6838static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
6839 unsigned SplatBitSize, SelectionDAG &DAG,
6840 const SDLoc &dl, EVT &VT, EVT VectorVT,
6841 VMOVModImmType type) {
6842 unsigned OpCmode, Imm;
6843 bool is128Bits = VectorVT.is128BitVector();
6844
6845 // SplatBitSize is set to the smallest size that splats the vector, so a
6846 // zero vector will always have SplatBitSize == 8. However, NEON modified
6847 // immediate instructions others than VMOV do not support the 8-bit encoding
6848 // of a zero vector, and the default encoding of zero is supposed to be the
6849 // 32-bit version.
6850 if (SplatBits == 0)
6851 SplatBitSize = 32;
6852
6853 switch (SplatBitSize) {
6854 case 8:
6855 if (type != VMOVModImm)
6856 return SDValue();
6857 // Any 1-byte value is OK. Op=0, Cmode=1110.
6858 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
6859 OpCmode = 0xe;
6860 Imm = SplatBits;
6861 VT = is128Bits ? MVT::v16i8 : MVT::v8i8;
6862 break;
6863
6864 case 16:
6865 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero.
6866 VT = is128Bits ? MVT::v8i16 : MVT::v4i16;
6867 if ((SplatBits & ~0xff) == 0) {
6868 // Value = 0x00nn: Op=x, Cmode=100x.
6869 OpCmode = 0x8;
6870 Imm = SplatBits;
6871 break;
6872 }
6873 if ((SplatBits & ~0xff00) == 0) {
6874 // Value = 0xnn00: Op=x, Cmode=101x.
6875 OpCmode = 0xa;
6876 Imm = SplatBits >> 8;
6877 break;
6878 }
6879 return SDValue();
6880
6881 case 32:
6882 // NEON's 32-bit VMOV supports splat values where:
6883 // * only one byte is nonzero, or
6884 // * the least significant byte is 0xff and the second byte is nonzero, or
6885 // * the least significant 2 bytes are 0xff and the third is nonzero.
6886 VT = is128Bits ? MVT::v4i32 : MVT::v2i32;
6887 if ((SplatBits & ~0xff) == 0) {
6888 // Value = 0x000000nn: Op=x, Cmode=000x.
6889 OpCmode = 0;
6890 Imm = SplatBits;
6891 break;
6892 }
6893 if ((SplatBits & ~0xff00) == 0) {
6894 // Value = 0x0000nn00: Op=x, Cmode=001x.
6895 OpCmode = 0x2;
6896 Imm = SplatBits >> 8;
6897 break;
6898 }
6899 if ((SplatBits & ~0xff0000) == 0) {
6900 // Value = 0x00nn0000: Op=x, Cmode=010x.
6901 OpCmode = 0x4;
6902 Imm = SplatBits >> 16;
6903 break;
6904 }
6905 if ((SplatBits & ~0xff000000) == 0) {
6906 // Value = 0xnn000000: Op=x, Cmode=011x.
6907 OpCmode = 0x6;
6908 Imm = SplatBits >> 24;
6909 break;
6910 }
6911
6912 // cmode == 0b1100 and cmode == 0b1101 are not supported for VORR or VBIC
6913 if (type == OtherModImm) return SDValue();
6914
6915 if ((SplatBits & ~0xffff) == 0 &&
6916 ((SplatBits | SplatUndef) & 0xff) == 0xff) {
6917 // Value = 0x0000nnff: Op=x, Cmode=1100.
6918 OpCmode = 0xc;
6919 Imm = SplatBits >> 8;
6920 break;
6921 }
6922
6923 // cmode == 0b1101 is not supported for MVE VMVN
6924 if (type == MVEVMVNModImm)
6925 return SDValue();
6926
6927 if ((SplatBits & ~0xffffff) == 0 &&
6928 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
6929 // Value = 0x00nnffff: Op=x, Cmode=1101.
6930 OpCmode = 0xd;
6931 Imm = SplatBits >> 16;
6932 break;
6933 }
6934
6935 // Note: there are a few 32-bit splat values (specifically: 00ffff00,
6936 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not
6937 // VMOV.I32. A (very) minor optimization would be to replicate the value
6938 // and fall through here to test for a valid 64-bit splat. But, then the
6939 // caller would also need to check and handle the change in size.
6940 return SDValue();
6941
6942 case 64: {
6943 if (type != VMOVModImm)
6944 return SDValue();
6945 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
6946 uint64_t BitMask = 0xff;
6947 unsigned ImmMask = 1;
6948 Imm = 0;
6949 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) {
6950 if (((SplatBits | SplatUndef) & BitMask) == BitMask) {
6951 Imm |= ImmMask;
6952 } else if ((SplatBits & BitMask) != 0) {
6953 return SDValue();
6954 }
6955 BitMask <<= 8;
6956 ImmMask <<= 1;
6957 }
6958
6959 // Op=1, Cmode=1110.
6960 OpCmode = 0x1e;
6961 VT = is128Bits ? MVT::v2i64 : MVT::v1i64;
6962 break;
6963 }
6964
6965 default:
6966 llvm_unreachable("unexpected size for isVMOVModifiedImm");
6967 }
6968
6969 unsigned EncodedVal = ARM_AM::createVMOVModImm(OpCmode, Imm);
6970 return DAG.getTargetConstant(EncodedVal, dl, MVT::i32);
6971}
6972
6973SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
6974 const ARMSubtarget *ST) const {
6975 EVT VT = Op.getValueType();
6976 bool IsDouble = (VT == MVT::f64);
6977 ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
6978 const APFloat &FPVal = CFP->getValueAPF();
6979
6980 // Prevent floating-point constants from using literal loads
6981 // when execute-only is enabled.
6982 if (ST->genExecuteOnly()) {
6983 // We shouldn't trigger this for v6m execute-only
6984 assert((!ST->isThumb1Only() || ST->hasV8MBaselineOps()) &&
6985 "Unexpected architecture");
6986
6987 // If we can represent the constant as an immediate, don't lower it
6988 if (isFPImmLegal(FPVal, VT))
6989 return Op;
6990 // Otherwise, construct as integer, and move to float register
6991 APInt INTVal = FPVal.bitcastToAPInt();
6992 SDLoc DL(CFP);
6993 switch (VT.getSimpleVT().SimpleTy) {
6994 default:
6995 llvm_unreachable("Unknown floating point type!");
6996 break;
6997 case MVT::f64: {
6998 SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);
6999 SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);
7000 return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);
7001 }
7002 case MVT::f32:
7003 return DAG.getNode(ARMISD::VMOVSR, DL, VT,
7004 DAG.getConstant(INTVal, DL, MVT::i32));
7005 }
7006 }
7007
7008 if (!ST->hasVFP3Base())
7009 return SDValue();
7010
7011 // Use the default (constant pool) lowering for double constants when we have
7012 // an SP-only FPU
7013 if (IsDouble && !Subtarget->hasFP64())
7014 return SDValue();
7015
7016 // Try splatting with a VMOV.f32...
7017 int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);
7018
7019 if (ImmVal != -1) {
7020 if (IsDouble || !ST->useNEONForSinglePrecisionFP()) {
7021 // We have code in place to select a valid ConstantFP already, no need to
7022 // do any mangling.
7023 return Op;
7024 }
7025
7026 // It's a float and we are trying to use NEON operations where
7027 // possible. Lower it to a splat followed by an extract.
7028 SDLoc DL(Op);
7029 SDValue NewVal = DAG.getTargetConstant(ImmVal, DL, MVT::i32);
7030 SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
7031 NewVal);
7032 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
7033 DAG.getConstant(0, DL, MVT::i32));
7034 }
7035
7036 // The rest of our options are NEON only, make sure that's allowed before
7037 // proceeding..
7038 if (!ST->hasNEON() || (!IsDouble && !ST->useNEONForSinglePrecisionFP()))
7039 return SDValue();
7040
7041 EVT VMovVT;
7042 uint64_t iVal = FPVal.bitcastToAPInt().getZExtValue();
7043
7044 // It wouldn't really be worth bothering for doubles except for one very
7045 // important value, which does happen to match: 0.0. So make sure we don't do
7046 // anything stupid.
7047 if (IsDouble && (iVal & 0xffffffff) != (iVal >> 32))
7048 return SDValue();
7049
7050 // Try a VMOV.i32 (FIXME: i8, i16, or i64 could work too).
7051 SDValue NewVal = isVMOVModifiedImm(iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op),
7052 VMovVT, VT, VMOVModImm);
7053 if (NewVal != SDValue()) {
7054 SDLoc DL(Op);
7055 SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
7056 NewVal);
7057 if (IsDouble)
7058 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7059
7060 // It's a float: cast and extract a vector element.
7061 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7062 VecConstant);
7063 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7064 DAG.getConstant(0, DL, MVT::i32));
7065 }
7066
7067 // Finally, try a VMVN.i32
7068 NewVal = isVMOVModifiedImm(~iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op), VMovVT,
7069 VT, VMVNModImm);
7070 if (NewVal != SDValue()) {
7071 SDLoc DL(Op);
7072 SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
7073
7074 if (IsDouble)
7075 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7076
7077 // It's a float: cast and extract a vector element.
7078 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7079 VecConstant);
7080 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7081 DAG.getConstant(0, DL, MVT::i32));
7082 }
7083
7084 return SDValue();
7085}
7086
7087// check if an VEXT instruction can handle the shuffle mask when the
7088// vector sources of the shuffle are the same.
7089static bool isSingletonVEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
7090 unsigned NumElts = VT.getVectorNumElements();
7091
7092 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7093 if (M[0] < 0)
7094 return false;
7095
7096 Imm = M[0];
7097
7098 // If this is a VEXT shuffle, the immediate value is the index of the first
7099 // element. The other shuffle indices must be the successive elements after
7100 // the first one.
7101 unsigned ExpectedElt = Imm;
7102 for (unsigned i = 1; i < NumElts; ++i) {
7103 // Increment the expected index. If it wraps around, just follow it
7104 // back to index zero and keep going.
7105 ++ExpectedElt;
7106 if (ExpectedElt == NumElts)
7107 ExpectedElt = 0;
7108
7109 if (M[i] < 0) continue; // ignore UNDEF indices
7110 if (ExpectedElt != static_cast<unsigned>(M[i]))
7111 return false;
7112 }
7113
7114 return true;
7115}
7116
7117static bool isVEXTMask(ArrayRef<int> M, EVT VT,
7118 bool &ReverseVEXT, unsigned &Imm) {
7119 unsigned NumElts = VT.getVectorNumElements();
7120 ReverseVEXT = false;
7121
7122 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7123 if (M[0] < 0)
7124 return false;
7125
7126 Imm = M[0];
7127
7128 // If this is a VEXT shuffle, the immediate value is the index of the first
7129 // element. The other shuffle indices must be the successive elements after
7130 // the first one.
7131 unsigned ExpectedElt = Imm;
7132 for (unsigned i = 1; i < NumElts; ++i) {
7133 // Increment the expected index. If it wraps around, it may still be
7134 // a VEXT but the source vectors must be swapped.
7135 ExpectedElt += 1;
7136 if (ExpectedElt == NumElts * 2) {
7137 ExpectedElt = 0;
7138 ReverseVEXT = true;
7139 }
7140
7141 if (M[i] < 0) continue; // ignore UNDEF indices
7142 if (ExpectedElt != static_cast<unsigned>(M[i]))
7143 return false;
7144 }
7145
7146 // Adjust the index value if the source operands will be swapped.
7147 if (ReverseVEXT)
7148 Imm -= NumElts;
7149
7150 return true;
7151}
7152
7153static bool isVTBLMask(ArrayRef<int> M, EVT VT) {
7154 // We can handle <8 x i8> vector shuffles. If the index in the mask is out of
7155 // range, then 0 is placed into the resulting vector. So pretty much any mask
7156 // of 8 elements can work here.
7157 return VT == MVT::v8i8 && M.size() == 8;
7158}
7159
7160static unsigned SelectPairHalf(unsigned Elements, ArrayRef<int> Mask,
7161 unsigned Index) {
7162 if (Mask.size() == Elements * 2)
7163 return Index / Elements;
7164 return Mask[Index] == 0 ? 0 : 1;
7165}
7166
7167// Checks whether the shuffle mask represents a vector transpose (VTRN) by
7168// checking that pairs of elements in the shuffle mask represent the same index
7169// in each vector, incrementing the expected index by 2 at each step.
7170// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 2, 6]
7171// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,c,g}
7172// v2={e,f,g,h}
7173// WhichResult gives the offset for each element in the mask based on which
7174// of the two results it belongs to.
7175//
7176// The transpose can be represented either as:
7177// result1 = shufflevector v1, v2, result1_shuffle_mask
7178// result2 = shufflevector v1, v2, result2_shuffle_mask
7179// where v1/v2 and the shuffle masks have the same number of elements
7180// (here WhichResult (see below) indicates which result is being checked)
7181//
7182// or as:
7183// results = shufflevector v1, v2, shuffle_mask
7184// where both results are returned in one vector and the shuffle mask has twice
7185// as many elements as v1/v2 (here WhichResult will always be 0 if true) here we
7186// want to check the low half and high half of the shuffle mask as if it were
7187// the other case
7188static bool isVTRNMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7189 unsigned EltSz = VT.getScalarSizeInBits();
7190 if (EltSz == 64)
7191 return false;
7192
7193 unsigned NumElts = VT.getVectorNumElements();
7194 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7195 return false;
7196
7197 // If the mask is twice as long as the input vector then we need to check the
7198 // upper and lower parts of the mask with a matching value for WhichResult
7199 // FIXME: A mask with only even values will be rejected in case the first
7200 // element is undefined, e.g. [-1, 4, 2, 6] will be rejected, because only
7201 // M[0] is used to determine WhichResult
7202 for (unsigned i = 0; i < M.size(); i += NumElts) {
7203 WhichResult = SelectPairHalf(NumElts, M, i);
7204 for (unsigned j = 0; j < NumElts; j += 2) {
7205 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7206 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + NumElts + WhichResult))
7207 return false;
7208 }
7209 }
7210
7211 if (M.size() == NumElts*2)
7212 WhichResult = 0;
7213
7214 return true;
7215}
7216
7217/// isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of
7218/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7219/// Mask is e.g., <0, 0, 2, 2> instead of <0, 4, 2, 6>.
7220static bool isVTRN_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7221 unsigned EltSz = VT.getScalarSizeInBits();
7222 if (EltSz == 64)
7223 return false;
7224
7225 unsigned NumElts = VT.getVectorNumElements();
7226 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7227 return false;
7228
7229 for (unsigned i = 0; i < M.size(); i += NumElts) {
7230 WhichResult = SelectPairHalf(NumElts, M, i);
7231 for (unsigned j = 0; j < NumElts; j += 2) {
7232 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7233 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + WhichResult))
7234 return false;
7235 }
7236 }
7237
7238 if (M.size() == NumElts*2)
7239 WhichResult = 0;
7240
7241 return true;
7242}
7243
7244// Checks whether the shuffle mask represents a vector unzip (VUZP) by checking
7245// that the mask elements are either all even and in steps of size 2 or all odd
7246// and in steps of size 2.
7247// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 2, 4, 6]
7248// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,c,e,g}
7249// v2={e,f,g,h}
7250// Requires similar checks to that of isVTRNMask with
7251// respect the how results are returned.
7252static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7253 unsigned EltSz = VT.getScalarSizeInBits();
7254 if (EltSz == 64)
7255 return false;
7256
7257 unsigned NumElts = VT.getVectorNumElements();
7258 if (M.size() != NumElts && M.size() != NumElts*2)
7259 return false;
7260
7261 for (unsigned i = 0; i < M.size(); i += NumElts) {
7262 WhichResult = SelectPairHalf(NumElts, M, i);
7263 for (unsigned j = 0; j < NumElts; ++j) {
7264 if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
7265 return false;
7266 }
7267 }
7268
7269 if (M.size() == NumElts*2)
7270 WhichResult = 0;
7271
7272 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7273 if (VT.is64BitVector() && EltSz == 32)
7274 return false;
7275
7276 return true;
7277}
7278
7279/// isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of
7280/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7281/// Mask is e.g., <0, 2, 0, 2> instead of <0, 2, 4, 6>,
7282static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7283 unsigned EltSz = VT.getScalarSizeInBits();
7284 if (EltSz == 64)
7285 return false;
7286
7287 unsigned NumElts = VT.getVectorNumElements();
7288 if (M.size() != NumElts && M.size() != NumElts*2)
7289 return false;
7290
7291 unsigned Half = NumElts / 2;
7292 for (unsigned i = 0; i < M.size(); i += NumElts) {
7293 WhichResult = SelectPairHalf(NumElts, M, i);
7294 for (unsigned j = 0; j < NumElts; j += Half) {
7295 unsigned Idx = WhichResult;
7296 for (unsigned k = 0; k < Half; ++k) {
7297 int MIdx = M[i + j + k];
7298 if (MIdx >= 0 && (unsigned) MIdx != Idx)
7299 return false;
7300 Idx += 2;
7301 }
7302 }
7303 }
7304
7305 if (M.size() == NumElts*2)
7306 WhichResult = 0;
7307
7308 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7309 if (VT.is64BitVector() && EltSz == 32)
7310 return false;
7311
7312 return true;
7313}
7314
7315// Checks whether the shuffle mask represents a vector zip (VZIP) by checking
7316// that pairs of elements of the shufflemask represent the same index in each
7317// vector incrementing sequentially through the vectors.
7318// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 1, 5]
7319// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,b,f}
7320// v2={e,f,g,h}
7321// Requires similar checks to that of isVTRNMask with respect the how results
7322// are returned.
7323static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7324 unsigned EltSz = VT.getScalarSizeInBits();
7325 if (EltSz == 64)
7326 return false;
7327
7328 unsigned NumElts = VT.getVectorNumElements();
7329 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7330 return false;
7331
7332 for (unsigned i = 0; i < M.size(); i += NumElts) {
7333 WhichResult = SelectPairHalf(NumElts, M, i);
7334 unsigned Idx = WhichResult * NumElts / 2;
7335 for (unsigned j = 0; j < NumElts; j += 2) {
7336 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7337 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx + NumElts))
7338 return false;
7339 Idx += 1;
7340 }
7341 }
7342
7343 if (M.size() == NumElts*2)
7344 WhichResult = 0;
7345
7346 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7347 if (VT.is64BitVector() && EltSz == 32)
7348 return false;
7349
7350 return true;
7351}
7352
7353/// isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of
7354/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7355/// Mask is e.g., <0, 0, 1, 1> instead of <0, 4, 1, 5>.
7356static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7357 unsigned EltSz = VT.getScalarSizeInBits();
7358 if (EltSz == 64)
7359 return false;
7360
7361 unsigned NumElts = VT.getVectorNumElements();
7362 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7363 return false;
7364
7365 for (unsigned i = 0; i < M.size(); i += NumElts) {
7366 WhichResult = SelectPairHalf(NumElts, M, i);
7367 unsigned Idx = WhichResult * NumElts / 2;
7368 for (unsigned j = 0; j < NumElts; j += 2) {
7369 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7370 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx))
7371 return false;
7372 Idx += 1;
7373 }
7374 }
7375
7376 if (M.size() == NumElts*2)
7377 WhichResult = 0;
7378
7379 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7380 if (VT.is64BitVector() && EltSz == 32)
7381 return false;
7382
7383 return true;
7384}
7385
7386/// Check if \p ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN),
7387/// and return the corresponding ARMISD opcode if it is, or 0 if it isn't.
7388static unsigned isNEONTwoResultShuffleMask(ArrayRef<int> ShuffleMask, EVT VT,
7389 unsigned &WhichResult,
7390 bool &isV_UNDEF) {
7391 isV_UNDEF = false;
7392 if (isVTRNMask(ShuffleMask, VT, WhichResult))
7393 return ARMISD::VTRN;
7394 if (isVUZPMask(ShuffleMask, VT, WhichResult))
7395 return ARMISD::VUZP;
7396 if (isVZIPMask(ShuffleMask, VT, WhichResult))
7397 return ARMISD::VZIP;
7398
7399 isV_UNDEF = true;
7400 if (isVTRN_v_undef_Mask(ShuffleMask, VT, WhichResult))
7401 return ARMISD::VTRN;
7402 if (isVUZP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7403 return ARMISD::VUZP;
7404 if (isVZIP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7405 return ARMISD::VZIP;
7406
7407 return 0;
7408}
7409
7410/// \return true if this is a reverse operation on an vector.
7411static bool isReverseMask(ArrayRef<int> M, EVT VT) {
7412 unsigned NumElts = VT.getVectorNumElements();
7413 // Make sure the mask has the right size.
7414 if (NumElts != M.size())
7415 return false;
7416
7417 // Look for <15, ..., 3, -1, 1, 0>.
7418 for (unsigned i = 0; i != NumElts; ++i)
7419 if (M[i] >= 0 && M[i] != (int) (NumElts - 1 - i))
7420 return false;
7421
7422 return true;
7423}
7424
7425static bool isTruncMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7426 unsigned NumElts = VT.getVectorNumElements();
7427 // Make sure the mask has the right size.
7428 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7429 return false;
7430
7431 // Half-width truncation patterns (e.g. v4i32 -> v8i16):
7432 // !Top && SingleSource: <0, 2, 4, 6, 0, 2, 4, 6>
7433 // !Top && !SingleSource: <0, 2, 4, 6, 8, 10, 12, 14>
7434 // Top && SingleSource: <1, 3, 5, 7, 1, 3, 5, 7>
7435 // Top && !SingleSource: <1, 3, 5, 7, 9, 11, 13, 15>
7436 int Ofs = Top ? 1 : 0;
7437 int Upper = SingleSource ? 0 : NumElts;
7438 for (int i = 0, e = NumElts / 2; i != e; ++i) {
7439 if (M[i] >= 0 && M[i] != (i * 2) + Ofs)
7440 return false;
7441 if (M[i + e] >= 0 && M[i + e] != (i * 2) + Ofs + Upper)
7442 return false;
7443 }
7444 return true;
7445}
7446
7447static bool isVMOVNMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7448 unsigned NumElts = VT.getVectorNumElements();
7449 // Make sure the mask has the right size.
7450 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7451 return false;
7452
7453 // If Top
7454 // Look for <0, N, 2, N+2, 4, N+4, ..>.
7455 // This inserts Input2 into Input1
7456 // else if not Top
7457 // Look for <0, N+1, 2, N+3, 4, N+5, ..>
7458 // This inserts Input1 into Input2
7459 unsigned Offset = Top ? 0 : 1;
7460 unsigned N = SingleSource ? 0 : NumElts;
7461 for (unsigned i = 0; i < NumElts; i += 2) {
7462 if (M[i] >= 0 && M[i] != (int)i)
7463 return false;
7464 if (M[i + 1] >= 0 && M[i + 1] != (int)(N + i + Offset))
7465 return false;
7466 }
7467
7468 return true;
7469}
7470
7471static bool isVMOVNTruncMask(ArrayRef<int> M, EVT ToVT, bool rev) {
7472 unsigned NumElts = ToVT.getVectorNumElements();
7473 if (NumElts != M.size())
7474 return false;
7475
7476 // Test if the Trunc can be convertible to a VMOVN with this shuffle. We are
7477 // looking for patterns of:
7478 // !rev: 0 N/2 1 N/2+1 2 N/2+2 ...
7479 // rev: N/2 0 N/2+1 1 N/2+2 2 ...
7480
7481 unsigned Off0 = rev ? NumElts / 2 : 0;
7482 unsigned Off1 = rev ? 0 : NumElts / 2;
7483 for (unsigned i = 0; i < NumElts; i += 2) {
7484 if (M[i] >= 0 && M[i] != (int)(Off0 + i / 2))
7485 return false;
7486 if (M[i + 1] >= 0 && M[i + 1] != (int)(Off1 + i / 2))
7487 return false;
7488 }
7489
7490 return true;
7491}
7492
7493// Reconstruct an MVE VCVT from a BuildVector of scalar fptrunc, all extracted
7494// from a pair of inputs. For example:
7495// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7496// FP_ROUND(EXTRACT_ELT(Y, 0),
7497// FP_ROUND(EXTRACT_ELT(X, 1),
7498// FP_ROUND(EXTRACT_ELT(Y, 1), ...)
7500 const ARMSubtarget *ST) {
7501 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7502 if (!ST->hasMVEFloatOps())
7503 return SDValue();
7504
7505 SDLoc dl(BV);
7506 EVT VT = BV.getValueType();
7507 if (VT != MVT::v8f16)
7508 return SDValue();
7509
7510 // We are looking for a buildvector of fptrunc elements, where all the
7511 // elements are interleavingly extracted from two sources. Check the first two
7512 // items are valid enough and extract some info from them (they are checked
7513 // properly in the loop below).
7514 if (BV.getOperand(0).getOpcode() != ISD::FP_ROUND ||
7517 return SDValue();
7518 if (BV.getOperand(1).getOpcode() != ISD::FP_ROUND ||
7521 return SDValue();
7522 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7523 SDValue Op1 = BV.getOperand(1).getOperand(0).getOperand(0);
7524 if (Op0.getValueType() != MVT::v4f32 || Op1.getValueType() != MVT::v4f32)
7525 return SDValue();
7526
7527 // Check all the values in the BuildVector line up with our expectations.
7528 for (unsigned i = 1; i < 4; i++) {
7529 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7530 return Trunc.getOpcode() == ISD::FP_ROUND &&
7532 Trunc.getOperand(0).getOperand(0) == Op &&
7533 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7534 };
7535 if (!Check(BV.getOperand(i * 2 + 0), Op0, i))
7536 return SDValue();
7537 if (!Check(BV.getOperand(i * 2 + 1), Op1, i))
7538 return SDValue();
7539 }
7540
7541 SDValue N1 = DAG.getNode(ARMISD::VCVTN, dl, VT, DAG.getUNDEF(VT), Op0,
7542 DAG.getConstant(0, dl, MVT::i32));
7543 return DAG.getNode(ARMISD::VCVTN, dl, VT, N1, Op1,
7544 DAG.getConstant(1, dl, MVT::i32));
7545}
7546
7547// Reconstruct an MVE VCVT from a BuildVector of scalar fpext, all extracted
7548// from a single input on alternating lanes. For example:
7549// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7550// FP_ROUND(EXTRACT_ELT(X, 2),
7551// FP_ROUND(EXTRACT_ELT(X, 4), ...)
7553 const ARMSubtarget *ST) {
7554 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7555 if (!ST->hasMVEFloatOps())
7556 return SDValue();
7557
7558 SDLoc dl(BV);
7559 EVT VT = BV.getValueType();
7560 if (VT != MVT::v4f32)
7561 return SDValue();
7562
7563 // We are looking for a buildvector of fptext elements, where all the
7564 // elements are alternating lanes from a single source. For example <0,2,4,6>
7565 // or <1,3,5,7>. Check the first two items are valid enough and extract some
7566 // info from them (they are checked properly in the loop below).
7567 if (BV.getOperand(0).getOpcode() != ISD::FP_EXTEND ||
7569 return SDValue();
7570 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7572 if (Op0.getValueType() != MVT::v8f16 || (Offset != 0 && Offset != 1))
7573 return SDValue();
7574
7575 // Check all the values in the BuildVector line up with our expectations.
7576 for (unsigned i = 1; i < 4; i++) {
7577 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7578 return Trunc.getOpcode() == ISD::FP_EXTEND &&
7580 Trunc.getOperand(0).getOperand(0) == Op &&
7581 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7582 };
7583 if (!Check(BV.getOperand(i), Op0, 2 * i + Offset))
7584 return SDValue();
7585 }
7586
7587 return DAG.getNode(ARMISD::VCVTL, dl, VT, Op0,
7588 DAG.getConstant(Offset, dl, MVT::i32));
7589}
7590
7591// If N is an integer constant that can be moved into a register in one
7592// instruction, return an SDValue of such a constant (will become a MOV
7593// instruction). Otherwise return null.
7595 const ARMSubtarget *ST, const SDLoc &dl) {
7596 uint64_t Val;
7597 if (!isa<ConstantSDNode>(N))
7598 return SDValue();
7599 Val = N->getAsZExtVal();
7600
7601 if (ST->isThumb1Only()) {
7602 if (Val <= 255 || ~Val <= 255)
7603 return DAG.getConstant(Val, dl, MVT::i32);
7604 } else {
7605 if (ARM_AM::getSOImmVal(Val) != -1 || ARM_AM::getSOImmVal(~Val) != -1)
7606 return DAG.getConstant(Val, dl, MVT::i32);
7607 }
7608 return SDValue();
7609}
7610
7612 const ARMSubtarget *ST) {
7613 SDLoc dl(Op);
7614 EVT VT = Op.getValueType();
7615
7616 assert(ST->hasMVEIntegerOps() && "LowerBUILD_VECTOR_i1 called without MVE!");
7617
7618 unsigned NumElts = VT.getVectorNumElements();
7619 unsigned BoolMask;
7620 unsigned BitsPerBool;
7621 if (NumElts == 2) {
7622 BitsPerBool = 8;
7623 BoolMask = 0xff;
7624 } else if (NumElts == 4) {
7625 BitsPerBool = 4;
7626 BoolMask = 0xf;
7627 } else if (NumElts == 8) {
7628 BitsPerBool = 2;
7629 BoolMask = 0x3;
7630 } else if (NumElts == 16) {
7631 BitsPerBool = 1;
7632 BoolMask = 0x1;
7633 } else
7634 return SDValue();
7635
7636 // If this is a single value copied into all lanes (a splat), we can just sign
7637 // extend that single value
7638 SDValue FirstOp = Op.getOperand(0);
7639 if (!isa<ConstantSDNode>(FirstOp) &&
7640 llvm::all_of(llvm::drop_begin(Op->ops()), [&FirstOp](const SDUse &U) {
7641 return U.get().isUndef() || U.get() == FirstOp;
7642 })) {
7643 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
7644 DAG.getValueType(MVT::i1));
7645 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
7646 }
7647
7648 // First create base with bits set where known
7649 unsigned Bits32 = 0;
7650 for (unsigned i = 0; i < NumElts; ++i) {
7651 SDValue V = Op.getOperand(i);
7652 if (!isa<ConstantSDNode>(V) && !V.isUndef())
7653 continue;
7654 bool BitSet = V.isUndef() ? false : V->getAsZExtVal();
7655 if (BitSet)
7656 Bits32 |= BoolMask << (i * BitsPerBool);
7657 }
7658
7659 // Add in unknown nodes
7660 SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
7661 DAG.getConstant(Bits32, dl, MVT::i32));
7662 for (unsigned i = 0; i < NumElts; ++i) {
7663 SDValue V = Op.getOperand(i);
7664 if (isa<ConstantSDNode>(V) || V.isUndef())
7665 continue;
7666 Base = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Base, V,
7667 DAG.getConstant(i, dl, MVT::i32));
7668 }
7669
7670 return Base;
7671}
7672
7674 const ARMSubtarget *ST) {
7675 if (!ST->hasMVEIntegerOps())
7676 return SDValue();
7677
7678 // We are looking for a buildvector where each element is Op[0] + i*N
7679 EVT VT = Op.getValueType();
7680 SDValue Op0 = Op.getOperand(0);
7681 unsigned NumElts = VT.getVectorNumElements();
7682
7683 // Get the increment value from operand 1
7684 SDValue Op1 = Op.getOperand(1);
7685 if (Op1.getOpcode() != ISD::ADD || Op1.getOperand(0) != Op0 ||
7687 return SDValue();
7688 unsigned N = Op1.getConstantOperandVal(1);
7689 if (N != 1 && N != 2 && N != 4 && N != 8)
7690 return SDValue();
7691
7692 // Check that each other operand matches
7693 for (unsigned I = 2; I < NumElts; I++) {
7694 SDValue OpI = Op.getOperand(I);
7695 if (OpI.getOpcode() != ISD::ADD || OpI.getOperand(0) != Op0 ||
7697 OpI.getConstantOperandVal(1) != I * N)
7698 return SDValue();
7699 }
7700
7701 SDLoc DL(Op);
7702 return DAG.getNode(ARMISD::VIDUP, DL, DAG.getVTList(VT, MVT::i32), Op0,
7703 DAG.getConstant(N, DL, MVT::i32));
7704}
7705
7706// Returns true if the operation N can be treated as qr instruction variant at
7707// operand Op.
7708static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op) {
7709 switch (N->getOpcode()) {
7710 case ISD::ADD:
7711 case ISD::MUL:
7712 case ISD::SADDSAT:
7713 case ISD::UADDSAT:
7714 case ISD::AVGFLOORS:
7715 case ISD::AVGFLOORU:
7716 return true;
7717 case ISD::SUB:
7718 case ISD::SSUBSAT:
7719 case ISD::USUBSAT:
7720 return N->getOperand(1).getNode() == Op;
7722 switch (N->getConstantOperandVal(0)) {
7723 case Intrinsic::arm_mve_add_predicated:
7724 case Intrinsic::arm_mve_mul_predicated:
7725 case Intrinsic::arm_mve_qadd_predicated:
7726 case Intrinsic::arm_mve_vhadd:
7727 case Intrinsic::arm_mve_hadd_predicated:
7728 case Intrinsic::arm_mve_vqdmulh:
7729 case Intrinsic::arm_mve_qdmulh_predicated:
7730 case Intrinsic::arm_mve_vqrdmulh:
7731 case Intrinsic::arm_mve_qrdmulh_predicated:
7732 case Intrinsic::arm_mve_vqdmull:
7733 case Intrinsic::arm_mve_vqdmull_predicated:
7734 return true;
7735 case Intrinsic::arm_mve_sub_predicated:
7736 case Intrinsic::arm_mve_qsub_predicated:
7737 case Intrinsic::arm_mve_vhsub:
7738 case Intrinsic::arm_mve_hsub_predicated:
7739 return N->getOperand(2).getNode() == Op;
7740 default:
7741 return false;
7742 }
7743 default:
7744 return false;
7745 }
7746}
7747
7748// If this is a case we can't handle, return null and let the default
7749// expansion code take care of it.
7750SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
7751 const ARMSubtarget *ST) const {
7752 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode());
7753 SDLoc dl(Op);
7754 EVT VT = Op.getValueType();
7755
7756 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
7757 return LowerBUILD_VECTOR_i1(Op, DAG, ST);
7758
7759 if (SDValue R = LowerBUILD_VECTORToVIDUP(Op, DAG, ST))
7760 return R;
7761
7762 APInt SplatBits, SplatUndef;
7763 unsigned SplatBitSize;
7764 bool HasAnyUndefs;
7765 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
7766 if (SplatUndef.isAllOnes())
7767 return DAG.getUNDEF(VT);
7768
7769 // If all the users of this constant splat are qr instruction variants,
7770 // generate a vdup of the constant.
7771 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == SplatBitSize &&
7772 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32) &&
7773 all_of(BVN->users(),
7774 [BVN](const SDNode *U) { return IsQRMVEInstruction(U, BVN); })) {
7775 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7776 : SplatBitSize == 16 ? MVT::v8i16
7777 : MVT::v16i8;
7778 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7779 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7780 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7781 }
7782
7783 if ((ST->hasNEON() && SplatBitSize <= 64) ||
7784 (ST->hasMVEIntegerOps() && SplatBitSize <= 64)) {
7785 // Check if an immediate VMOV works.
7786 EVT VmovVT;
7787 SDValue Val =
7788 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
7789 SplatBitSize, DAG, dl, VmovVT, VT, VMOVModImm);
7790
7791 if (Val.getNode()) {
7792 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, Val);
7793 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7794 }
7795
7796 // Try an immediate VMVN.
7797 uint64_t NegatedImm = (~SplatBits).getZExtValue();
7798 Val = isVMOVModifiedImm(
7799 NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, dl, VmovVT,
7800 VT, ST->hasMVEIntegerOps() ? MVEVMVNModImm : VMVNModImm);
7801 if (Val.getNode()) {
7802 SDValue Vmov = DAG.getNode(ARMISD::VMVNIMM, dl, VmovVT, Val);
7803 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7804 }
7805
7806 // Use vmov.f32 to materialize other v2f32 and v4f32 splats.
7807 if ((VT == MVT::v2f32 || VT == MVT::v4f32) && SplatBitSize == 32) {
7808 int ImmVal = ARM_AM::getFP32Imm(SplatBits);
7809 if (ImmVal != -1) {
7810 SDValue Val = DAG.getTargetConstant(ImmVal, dl, MVT::i32);
7811 return DAG.getNode(ARMISD::VMOVFPIMM, dl, VT, Val);
7812 }
7813 }
7814
7815 // If we are under MVE, generate a VDUP(constant), bitcast to the original
7816 // type.
7817 if (ST->hasMVEIntegerOps() &&
7818 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32)) {
7819 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7820 : SplatBitSize == 16 ? MVT::v8i16
7821 : MVT::v16i8;
7822 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7823 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7824 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7825 }
7826 }
7827 }
7828
7829 // Scan through the operands to see if only one value is used.
7830 //
7831 // As an optimisation, even if more than one value is used it may be more
7832 // profitable to splat with one value then change some lanes.
7833 //
7834 // Heuristically we decide to do this if the vector has a "dominant" value,
7835 // defined as splatted to more than half of the lanes.
7836 unsigned NumElts = VT.getVectorNumElements();
7837 bool isOnlyLowElement = true;
7838 bool usesOnlyOneValue = true;
7839 bool hasDominantValue = false;
7840 bool isConstant = true;
7841
7842 // Map of the number of times a particular SDValue appears in the
7843 // element list.
7844 DenseMap<SDValue, unsigned> ValueCounts;
7845 SDValue Value;
7846 for (unsigned i = 0; i < NumElts; ++i) {
7847 SDValue V = Op.getOperand(i);
7848 if (V.isUndef())
7849 continue;
7850 if (i > 0)
7851 isOnlyLowElement = false;
7853 isConstant = false;
7854
7855 unsigned &Count = ValueCounts[V];
7856
7857 // Is this value dominant? (takes up more than half of the lanes)
7858 if (++Count > (NumElts / 2)) {
7859 hasDominantValue = true;
7860 Value = V;
7861 }
7862 }
7863 if (ValueCounts.size() != 1)
7864 usesOnlyOneValue = false;
7865 if (!Value.getNode() && !ValueCounts.empty())
7866 Value = ValueCounts.begin()->first;
7867
7868 if (ValueCounts.empty())
7869 return DAG.getUNDEF(VT);
7870
7871 // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
7872 // Keep going if we are hitting this case.
7873 if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()) &&
7874 (VT != MVT::v8f16 || ST->hasFullFP16()))
7875 return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
7876
7877 unsigned EltSize = VT.getScalarSizeInBits();
7878
7879 // Use VDUP for non-constant splats. For f32 constant splats, reduce to
7880 // i32 and try again.
7881 if (hasDominantValue && EltSize <= 32) {
7882 if (!isConstant) {
7883 SDValue N;
7884
7885 // If we are VDUPing a value that comes directly from a vector, that will
7886 // cause an unnecessary move to and from a GPR, where instead we could
7887 // just use VDUPLANE. We can only do this if the lane being extracted
7888 // is at a constant index, as the VDUP from lane instructions only have
7889 // constant-index forms.
7890 ConstantSDNode *constIndex;
7891 if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7892 (constIndex = dyn_cast<ConstantSDNode>(Value->getOperand(1)))) {
7893 // We need to create a new undef vector to use for the VDUPLANE if the
7894 // size of the vector from which we get the value is different than the
7895 // size of the vector that we need to create. We will insert the element
7896 // such that the register coalescer will remove unnecessary copies.
7897 if (VT != Value->getOperand(0).getValueType()) {
7898 unsigned index = constIndex->getAPIntValue().getLimitedValue() %
7900 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7901 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DAG.getUNDEF(VT),
7902 Value, DAG.getConstant(index, dl, MVT::i32)),
7903 DAG.getConstant(index, dl, MVT::i32));
7904 } else
7905 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7906 Value->getOperand(0), Value->getOperand(1));
7907 } else
7908 N = DAG.getNode(ARMISD::VDUP, dl, VT, Value);
7909
7910 if (!usesOnlyOneValue) {
7911 // The dominant value was splatted as 'N', but we now have to insert
7912 // all differing elements.
7913 for (unsigned I = 0; I < NumElts; ++I) {
7914 if (Op.getOperand(I) == Value)
7915 continue;
7917 Ops.push_back(N);
7918 Ops.push_back(Op.getOperand(I));
7919 Ops.push_back(DAG.getConstant(I, dl, MVT::i32));
7920 N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ops);
7921 }
7922 }
7923 return N;
7924 }
7927 MVT FVT = VT.getVectorElementType().getSimpleVT();
7928 assert(FVT == MVT::f32 || FVT == MVT::f16);
7929 MVT IVT = (FVT == MVT::f32) ? MVT::i32 : MVT::i16;
7930 for (unsigned i = 0; i < NumElts; ++i)
7931 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, IVT,
7932 Op.getOperand(i)));
7933 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), IVT, NumElts);
7934 SDValue Val = DAG.getBuildVector(VecVT, dl, Ops);
7935 Val = LowerBUILD_VECTOR(Val, DAG, ST);
7936 if (Val.getNode())
7937 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7938 }
7939 if (usesOnlyOneValue) {
7940 SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl);
7941 if (isConstant && Val.getNode())
7942 return DAG.getNode(ARMISD::VDUP, dl, VT, Val);
7943 }
7944 }
7945
7946 // If all elements are constants and the case above didn't get hit, fall back
7947 // to the default expansion, which will generate a load from the constant
7948 // pool.
7949 if (isConstant)
7950 return SDValue();
7951
7952 // Reconstruct the BUILDVECTOR to one of the legal shuffles (such as vext and
7953 // vmovn). Empirical tests suggest this is rarely worth it for vectors of
7954 // length <= 2.
7955 if (NumElts >= 4)
7956 if (SDValue shuffle = ReconstructShuffle(Op, DAG))
7957 return shuffle;
7958
7959 // Attempt to turn a buildvector of scalar fptrunc's or fpext's back into
7960 // VCVT's
7961 if (SDValue VCVT = LowerBuildVectorOfFPTrunc(Op, DAG, Subtarget))
7962 return VCVT;
7963 if (SDValue VCVT = LowerBuildVectorOfFPExt(Op, DAG, Subtarget))
7964 return VCVT;
7965
7966 if (ST->hasNEON() && VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
7967 // If we haven't found an efficient lowering, try splitting a 128-bit vector
7968 // into two 64-bit vectors; we might discover a better way to lower it.
7969 SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
7970 EVT ExtVT = VT.getVectorElementType();
7971 EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
7972 SDValue Lower = DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[0], NumElts / 2));
7973 if (Lower.getOpcode() == ISD::BUILD_VECTOR)
7974 Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
7975 SDValue Upper =
7976 DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[NumElts / 2], NumElts / 2));
7977 if (Upper.getOpcode() == ISD::BUILD_VECTOR)
7978 Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
7979 if (Lower && Upper)
7980 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
7981 }
7982
7983 // Vectors with 32- or 64-bit elements can be built by directly assigning
7984 // the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
7985 // will be legalized.
7986 if (EltSize >= 32) {
7987 // Do the expansion with floating-point types, since that is what the VFP
7988 // registers are defined to use, and since i64 is not legal.
7989 EVT EltVT = EVT::getFloatingPointVT(EltSize);
7990 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
7992 for (unsigned i = 0; i < NumElts; ++i)
7993 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, EltVT, Op.getOperand(i)));
7994 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
7995 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7996 }
7997
7998 // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
7999 // know the default expansion would otherwise fall back on something even
8000 // worse. For a vector with one or two non-undef values, that's
8001 // scalar_to_vector for the elements followed by a shuffle (provided the
8002 // shuffle is valid for the target) and materialization element by element
8003 // on the stack followed by a load for everything else.
8004 if ((!isConstant && !usesOnlyOneValue) ||
8005 (VT == MVT::v8f16 && !ST->hasFullFP16())) {
8006 SDValue Vec = DAG.getUNDEF(VT);
8007 for (unsigned i = 0 ; i < NumElts; ++i) {
8008 SDValue V = Op.getOperand(i);
8009 if (V.isUndef())
8010 continue;
8011 SDValue LaneIdx = DAG.getConstant(i, dl, MVT::i32);
8012 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
8013 }
8014 return Vec;
8015 }
8016
8017 return SDValue();
8018}
8019
8020// Gather data to see if the operation can be modelled as a
8021// shuffle in combination with VEXTs.
8022SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
8023 SelectionDAG &DAG) const {
8024 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
8025 SDLoc dl(Op);
8026 EVT VT = Op.getValueType();
8027 unsigned NumElts = VT.getVectorNumElements();
8028
8029 struct ShuffleSourceInfo {
8030 SDValue Vec;
8031 unsigned MinElt = std::numeric_limits<unsigned>::max();
8032 unsigned MaxElt = 0;
8033
8034 // We may insert some combination of BITCASTs and VEXT nodes to force Vec to
8035 // be compatible with the shuffle we intend to construct. As a result
8036 // ShuffleVec will be some sliding window into the original Vec.
8037 SDValue ShuffleVec;
8038
8039 // Code should guarantee that element i in Vec starts at element "WindowBase
8040 // + i * WindowScale in ShuffleVec".
8041 int WindowBase = 0;
8042 int WindowScale = 1;
8043
8044 ShuffleSourceInfo(SDValue Vec) : Vec(Vec), ShuffleVec(Vec) {}
8045
8046 bool operator ==(SDValue OtherVec) { return Vec == OtherVec; }
8047 };
8048
8049 // First gather all vectors used as an immediate source for this BUILD_VECTOR
8050 // node.
8052 for (unsigned i = 0; i < NumElts; ++i) {
8053 SDValue V = Op.getOperand(i);
8054 if (V.isUndef())
8055 continue;
8056 else if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
8057 // A shuffle can only come from building a vector from various
8058 // elements of other vectors.
8059 return SDValue();
8060 } else if (!isa<ConstantSDNode>(V.getOperand(1))) {
8061 // Furthermore, shuffles require a constant mask, whereas extractelts
8062 // accept variable indices.
8063 return SDValue();
8064 }
8065
8066 // Add this element source to the list if it's not already there.
8067 SDValue SourceVec = V.getOperand(0);
8068 auto Source = llvm::find(Sources, SourceVec);
8069 if (Source == Sources.end())
8070 Source = Sources.insert(Sources.end(), ShuffleSourceInfo(SourceVec));
8071
8072 // Update the minimum and maximum lane number seen.
8073 unsigned EltNo = V.getConstantOperandVal(1);
8074 Source->MinElt = std::min(Source->MinElt, EltNo);
8075 Source->MaxElt = std::max(Source->MaxElt, EltNo);
8076 }
8077
8078 // Currently only do something sane when at most two source vectors
8079 // are involved.
8080 if (Sources.size() > 2)
8081 return SDValue();
8082
8083 // Find out the smallest element size among result and two sources, and use
8084 // it as element size to build the shuffle_vector.
8085 EVT SmallestEltTy = VT.getVectorElementType();
8086 for (auto &Source : Sources) {
8087 EVT SrcEltTy = Source.Vec.getValueType().getVectorElementType();
8088 if (SrcEltTy.bitsLT(SmallestEltTy))
8089 SmallestEltTy = SrcEltTy;
8090 }
8091 unsigned ResMultiplier =
8092 VT.getScalarSizeInBits() / SmallestEltTy.getSizeInBits();
8093 NumElts = VT.getSizeInBits() / SmallestEltTy.getSizeInBits();
8094 EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
8095
8096 // If the source vector is too wide or too narrow, we may nevertheless be able
8097 // to construct a compatible shuffle either by concatenating it with UNDEF or
8098 // extracting a suitable range of elements.
8099 for (auto &Src : Sources) {
8100 EVT SrcVT = Src.ShuffleVec.getValueType();
8101
8102 uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
8103 uint64_t VTSize = VT.getFixedSizeInBits();
8104 if (SrcVTSize == VTSize)
8105 continue;
8106
8107 // This stage of the search produces a source with the same element type as
8108 // the original, but with a total width matching the BUILD_VECTOR output.
8109 EVT EltVT = SrcVT.getVectorElementType();
8110 unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
8111 EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
8112
8113 if (SrcVTSize < VTSize) {
8114 if (2 * SrcVTSize != VTSize)
8115 return SDValue();
8116 // We can pad out the smaller vector for free, so if it's part of a
8117 // shuffle...
8118 Src.ShuffleVec =
8119 DAG.getNode(ISD::CONCAT_VECTORS, dl, DestVT, Src.ShuffleVec,
8120 DAG.getUNDEF(Src.ShuffleVec.getValueType()));
8121 continue;
8122 }
8123
8124 if (SrcVTSize != 2 * VTSize)
8125 return SDValue();
8126
8127 if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
8128 // Span too large for a VEXT to cope
8129 return SDValue();
8130 }
8131
8132 if (Src.MinElt >= NumSrcElts) {
8133 // The extraction can just take the second half
8134 Src.ShuffleVec =
8135 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8136 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8137 Src.WindowBase = -NumSrcElts;
8138 } else if (Src.MaxElt < NumSrcElts) {
8139 // The extraction can just take the first half
8140 Src.ShuffleVec =
8141 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8142 DAG.getConstant(0, dl, MVT::i32));
8143 } else {
8144 // An actual VEXT is needed
8145 SDValue VEXTSrc1 =
8146 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8147 DAG.getConstant(0, dl, MVT::i32));
8148 SDValue VEXTSrc2 =
8149 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8150 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8151
8152 Src.ShuffleVec = DAG.getNode(ARMISD::VEXT, dl, DestVT, VEXTSrc1,
8153 VEXTSrc2,
8154 DAG.getConstant(Src.MinElt, dl, MVT::i32));
8155 Src.WindowBase = -Src.MinElt;
8156 }
8157 }
8158
8159 // Another possible incompatibility occurs from the vector element types. We
8160 // can fix this by bitcasting the source vectors to the same type we intend
8161 // for the shuffle.
8162 for (auto &Src : Sources) {
8163 EVT SrcEltTy = Src.ShuffleVec.getValueType().getVectorElementType();
8164 if (SrcEltTy == SmallestEltTy)
8165 continue;
8166 assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
8167 Src.ShuffleVec = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, ShuffleVT, Src.ShuffleVec);
8168 Src.WindowScale = SrcEltTy.getSizeInBits() / SmallestEltTy.getSizeInBits();
8169 Src.WindowBase *= Src.WindowScale;
8170 }
8171
8172 // Final check before we try to actually produce a shuffle.
8173 LLVM_DEBUG({
8174 for (auto Src : Sources)
8175 assert(Src.ShuffleVec.getValueType() == ShuffleVT);
8176 });
8177
8178 // The stars all align, our next step is to produce the mask for the shuffle.
8179 SmallVector<int, 8> Mask(ShuffleVT.getVectorNumElements(), -1);
8180 int BitsPerShuffleLane = ShuffleVT.getScalarSizeInBits();
8181 for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
8182 SDValue Entry = Op.getOperand(i);
8183 if (Entry.isUndef())
8184 continue;
8185
8186 auto Src = llvm::find(Sources, Entry.getOperand(0));
8187 int EltNo = cast<ConstantSDNode>(Entry.getOperand(1))->getSExtValue();
8188
8189 // EXTRACT_VECTOR_ELT performs an implicit any_ext; BUILD_VECTOR an implicit
8190 // trunc. So only std::min(SrcBits, DestBits) actually get defined in this
8191 // segment.
8192 EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
8193 int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
8194 VT.getScalarSizeInBits());
8195 int LanesDefined = BitsDefined / BitsPerShuffleLane;
8196
8197 // This source is expected to fill ResMultiplier lanes of the final shuffle,
8198 // starting at the appropriate offset.
8199 int *LaneMask = &Mask[i * ResMultiplier];
8200
8201 int ExtractBase = EltNo * Src->WindowScale + Src->WindowBase;
8202 ExtractBase += NumElts * (Src - Sources.begin());
8203 for (int j = 0; j < LanesDefined; ++j)
8204 LaneMask[j] = ExtractBase + j;
8205 }
8206
8207
8208 // We can't handle more than two sources. This should have already
8209 // been checked before this point.
8210 assert(Sources.size() <= 2 && "Too many sources!");
8211
8212 SDValue ShuffleOps[] = { DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT) };
8213 for (unsigned i = 0; i < Sources.size(); ++i)
8214 ShuffleOps[i] = Sources[i].ShuffleVec;
8215
8216 SDValue Shuffle = buildLegalVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
8217 ShuffleOps[1], Mask, DAG);
8218 if (!Shuffle)
8219 return SDValue();
8220 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuffle);
8221}
8222
8224 OP_COPY = 0, // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
8233 OP_VUZPL, // VUZP, left result
8234 OP_VUZPR, // VUZP, right result
8235 OP_VZIPL, // VZIP, left result
8236 OP_VZIPR, // VZIP, right result
8237 OP_VTRNL, // VTRN, left result
8238 OP_VTRNR // VTRN, right result
8239};
8240
8241static bool isLegalMVEShuffleOp(unsigned PFEntry) {
8242 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8243 switch (OpNum) {
8244 case OP_COPY:
8245 case OP_VREV:
8246 case OP_VDUP0:
8247 case OP_VDUP1:
8248 case OP_VDUP2:
8249 case OP_VDUP3:
8250 return true;
8251 }
8252 return false;
8253}
8254
8255/// isShuffleMaskLegal - Targets can use this to indicate that they only
8256/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
8257/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
8258/// are assumed to be legal.
8260 if (VT.getVectorNumElements() == 4 &&
8261 (VT.is128BitVector() || VT.is64BitVector())) {
8262 unsigned PFIndexes[4];
8263 for (unsigned i = 0; i != 4; ++i) {
8264 if (M[i] < 0)
8265 PFIndexes[i] = 8;
8266 else
8267 PFIndexes[i] = M[i];
8268 }
8269
8270 // Compute the index in the perfect shuffle table.
8271 unsigned PFTableIndex =
8272 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8273 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8274 unsigned Cost = (PFEntry >> 30);
8275
8276 if (Cost <= 4 && (Subtarget->hasNEON() || isLegalMVEShuffleOp(PFEntry)))
8277 return true;
8278 }
8279
8280 bool ReverseVEXT, isV_UNDEF;
8281 unsigned Imm, WhichResult;
8282
8283 unsigned EltSize = VT.getScalarSizeInBits();
8284 if (EltSize >= 32 ||
8286 ShuffleVectorInst::isIdentityMask(M, M.size()) ||
8287 isVREVMask(M, VT, 64) ||
8288 isVREVMask(M, VT, 32) ||
8289 isVREVMask(M, VT, 16))
8290 return true;
8291 else if (Subtarget->hasNEON() &&
8292 (isVEXTMask(M, VT, ReverseVEXT, Imm) ||
8293 isVTBLMask(M, VT) ||
8294 isNEONTwoResultShuffleMask(M, VT, WhichResult, isV_UNDEF)))
8295 return true;
8296 else if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8297 isReverseMask(M, VT))
8298 return true;
8299 else if (Subtarget->hasMVEIntegerOps() &&
8300 (isVMOVNMask(M, VT, true, false) ||
8301 isVMOVNMask(M, VT, false, false) || isVMOVNMask(M, VT, true, true)))
8302 return true;
8303 else if (Subtarget->hasMVEIntegerOps() &&
8304 (isTruncMask(M, VT, false, false) ||
8305 isTruncMask(M, VT, false, true) ||
8306 isTruncMask(M, VT, true, false) || isTruncMask(M, VT, true, true)))
8307 return true;
8308 else
8309 return false;
8310}
8311
8312/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
8313/// the specified operations to build the shuffle.
8315 SDValue RHS, SelectionDAG &DAG,
8316 const SDLoc &dl) {
8317 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8318 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8319 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8320
8321 if (OpNum == OP_COPY) {
8322 if (LHSID == (1*9+2)*9+3) return LHS;
8323 assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
8324 return RHS;
8325 }
8326
8327 SDValue OpLHS, OpRHS;
8328 OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
8329 OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);
8330 EVT VT = OpLHS.getValueType();
8331
8332 switch (OpNum) {
8333 default: llvm_unreachable("Unknown shuffle opcode!");
8334 case OP_VREV:
8335 // VREV divides the vector in half and swaps within the half.
8336 if (VT.getScalarSizeInBits() == 32)
8337 return DAG.getNode(ARMISD::VREV64, dl, VT, OpLHS);
8338 // vrev <4 x i16> -> VREV32
8339 if (VT.getScalarSizeInBits() == 16)
8340 return DAG.getNode(ARMISD::VREV32, dl, VT, OpLHS);
8341 // vrev <4 x i8> -> VREV16
8342 assert(VT.getScalarSizeInBits() == 8);
8343 return DAG.getNode(ARMISD::VREV16, dl, VT, OpLHS);
8344 case OP_VDUP0:
8345 case OP_VDUP1:
8346 case OP_VDUP2:
8347 case OP_VDUP3:
8348 return DAG.getNode(ARMISD::VDUPLANE, dl, VT,
8349 OpLHS, DAG.getConstant(OpNum-OP_VDUP0, dl, MVT::i32));
8350 case OP_VEXT1:
8351 case OP_VEXT2:
8352 case OP_VEXT3:
8353 return DAG.getNode(ARMISD::VEXT, dl, VT,
8354 OpLHS, OpRHS,
8355 DAG.getConstant(OpNum - OP_VEXT1 + 1, dl, MVT::i32));
8356 case OP_VUZPL:
8357 case OP_VUZPR:
8358 return DAG.getNode(ARMISD::VUZP, dl, DAG.getVTList(VT, VT),
8359 OpLHS, OpRHS).getValue(OpNum-OP_VUZPL);
8360 case OP_VZIPL:
8361 case OP_VZIPR:
8362 return DAG.getNode(ARMISD::VZIP, dl, DAG.getVTList(VT, VT),
8363 OpLHS, OpRHS).getValue(OpNum-OP_VZIPL);
8364 case OP_VTRNL:
8365 case OP_VTRNR:
8366 return DAG.getNode(ARMISD::VTRN, dl, DAG.getVTList(VT, VT),
8367 OpLHS, OpRHS).getValue(OpNum-OP_VTRNL);
8368 }
8369}
8370
8372 ArrayRef<int> ShuffleMask,
8373 SelectionDAG &DAG) {
8374 // Check to see if we can use the VTBL instruction.
8375 SDValue V1 = Op.getOperand(0);
8376 SDValue V2 = Op.getOperand(1);
8377 SDLoc DL(Op);
8378
8379 SmallVector<SDValue, 8> VTBLMask;
8380 for (int I : ShuffleMask)
8381 VTBLMask.push_back(DAG.getSignedConstant(I, DL, MVT::i32));
8382
8383 if (V2.getNode()->isUndef())
8384 return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1,
8385 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8386
8387 return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2,
8388 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8389}
8390
8392 SDLoc DL(Op);
8393 EVT VT = Op.getValueType();
8394
8395 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8396 "Expect an v8i16/v16i8 type");
8397 SDValue OpLHS = DAG.getNode(ARMISD::VREV64, DL, VT, Op.getOperand(0));
8398 // For a v16i8 type: After the VREV, we have got <7, ..., 0, 15, ..., 8>. Now,
8399 // extract the first 8 bytes into the top double word and the last 8 bytes
8400 // into the bottom double word, through a new vector shuffle that will be
8401 // turned into a VEXT on Neon, or a couple of VMOVDs on MVE.
8402 std::vector<int> NewMask;
8403 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8404 NewMask.push_back(VT.getVectorNumElements() / 2 + i);
8405 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8406 NewMask.push_back(i);
8407 return DAG.getVectorShuffle(VT, DL, OpLHS, OpLHS, NewMask);
8408}
8409
8411 switch (VT.getSimpleVT().SimpleTy) {
8412 case MVT::v2i1:
8413 return MVT::v2f64;
8414 case MVT::v4i1:
8415 return MVT::v4i32;
8416 case MVT::v8i1:
8417 return MVT::v8i16;
8418 case MVT::v16i1:
8419 return MVT::v16i8;
8420 default:
8421 llvm_unreachable("Unexpected vector predicate type");
8422 }
8423}
8424
8426 SelectionDAG &DAG) {
8427 // Converting from boolean predicates to integers involves creating a vector
8428 // of all ones or all zeroes and selecting the lanes based upon the real
8429 // predicate.
8431 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff), dl, MVT::i32);
8432 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllOnes);
8433
8434 SDValue AllZeroes =
8435 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0x0), dl, MVT::i32);
8436 AllZeroes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllZeroes);
8437
8438 // Get full vector type from predicate type
8440
8441 SDValue RecastV1;
8442 // If the real predicate is an v8i1 or v4i1 (not v16i1) then we need to recast
8443 // this to a v16i1. This cannot be done with an ordinary bitcast because the
8444 // sizes are not the same. We have to use a MVE specific PREDICATE_CAST node,
8445 // since we know in hardware the sizes are really the same.
8446 if (VT != MVT::v16i1)
8447 RecastV1 = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Pred);
8448 else
8449 RecastV1 = Pred;
8450
8451 // Select either all ones or zeroes depending upon the real predicate bits.
8452 SDValue PredAsVector =
8453 DAG.getNode(ISD::VSELECT, dl, MVT::v16i8, RecastV1, AllOnes, AllZeroes);
8454
8455 // Recast our new predicate-as-integer v16i8 vector into something
8456 // appropriate for the shuffle, i.e. v4i32 for a real v4i1 predicate.
8457 return DAG.getNode(ISD::BITCAST, dl, NewVT, PredAsVector);
8458}
8459
8461 const ARMSubtarget *ST) {
8462 EVT VT = Op.getValueType();
8464 ArrayRef<int> ShuffleMask = SVN->getMask();
8465
8466 assert(ST->hasMVEIntegerOps() &&
8467 "No support for vector shuffle of boolean predicates");
8468
8469 SDValue V1 = Op.getOperand(0);
8470 SDValue V2 = Op.getOperand(1);
8471 SDLoc dl(Op);
8472 if (isReverseMask(ShuffleMask, VT)) {
8473 SDValue cast = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, V1);
8474 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, cast);
8475 SDValue srl = DAG.getNode(ISD::SRL, dl, MVT::i32, rbit,
8476 DAG.getConstant(16, dl, MVT::i32));
8477 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, srl);
8478 }
8479
8480 // Until we can come up with optimised cases for every single vector
8481 // shuffle in existence we have chosen the least painful strategy. This is
8482 // to essentially promote the boolean predicate to a 8-bit integer, where
8483 // each predicate represents a byte. Then we fall back on a normal integer
8484 // vector shuffle and convert the result back into a predicate vector. In
8485 // many cases the generated code might be even better than scalar code
8486 // operating on bits. Just imagine trying to shuffle 8 arbitrary 2-bit
8487 // fields in a register into 8 other arbitrary 2-bit fields!
8488 SDValue PredAsVector1 = PromoteMVEPredVector(dl, V1, VT, DAG);
8489 EVT NewVT = PredAsVector1.getValueType();
8490 SDValue PredAsVector2 = V2.isUndef() ? DAG.getUNDEF(NewVT)
8491 : PromoteMVEPredVector(dl, V2, VT, DAG);
8492 assert(PredAsVector2.getValueType() == NewVT &&
8493 "Expected identical vector type in expanded i1 shuffle!");
8494
8495 // Do the shuffle!
8496 SDValue Shuffled = DAG.getVectorShuffle(NewVT, dl, PredAsVector1,
8497 PredAsVector2, ShuffleMask);
8498
8499 // Now return the result of comparing the shuffled vector with zero,
8500 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1. For a v2i1
8501 // we convert to a v4i1 compare to fill in the two halves of the i64 as i32s.
8502 if (VT == MVT::v2i1) {
8503 SDValue BC = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Shuffled);
8504 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, BC,
8505 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8506 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8507 }
8508 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Shuffled,
8509 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8510}
8511
8513 ArrayRef<int> ShuffleMask,
8514 SelectionDAG &DAG) {
8515 // Attempt to lower the vector shuffle using as many whole register movs as
8516 // possible. This is useful for types smaller than 32bits, which would
8517 // often otherwise become a series for grp movs.
8518 SDLoc dl(Op);
8519 EVT VT = Op.getValueType();
8520 if (VT.getScalarSizeInBits() >= 32)
8521 return SDValue();
8522
8523 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8524 "Unexpected vector type");
8525 int NumElts = VT.getVectorNumElements();
8526 int QuarterSize = NumElts / 4;
8527 // The four final parts of the vector, as i32's
8528 SDValue Parts[4];
8529
8530 // Look for full lane vmovs like <0,1,2,3> or <u,5,6,7> etc, (but not
8531 // <u,u,u,u>), returning the vmov lane index
8532 auto getMovIdx = [](ArrayRef<int> ShuffleMask, int Start, int Length) {
8533 // Detect which mov lane this would be from the first non-undef element.
8534 int MovIdx = -1;
8535 for (int i = 0; i < Length; i++) {
8536 if (ShuffleMask[Start + i] >= 0) {
8537 if (ShuffleMask[Start + i] % Length != i)
8538 return -1;
8539 MovIdx = ShuffleMask[Start + i] / Length;
8540 break;
8541 }
8542 }
8543 // If all items are undef, leave this for other combines
8544 if (MovIdx == -1)
8545 return -1;
8546 // Check the remaining values are the correct part of the same mov
8547 for (int i = 1; i < Length; i++) {
8548 if (ShuffleMask[Start + i] >= 0 &&
8549 (ShuffleMask[Start + i] / Length != MovIdx ||
8550 ShuffleMask[Start + i] % Length != i))
8551 return -1;
8552 }
8553 return MovIdx;
8554 };
8555
8556 for (int Part = 0; Part < 4; ++Part) {
8557 // Does this part look like a mov
8558 int Elt = getMovIdx(ShuffleMask, Part * QuarterSize, QuarterSize);
8559 if (Elt != -1) {
8560 SDValue Input = Op->getOperand(0);
8561 if (Elt >= 4) {
8562 Input = Op->getOperand(1);
8563 Elt -= 4;
8564 }
8565 SDValue BitCast = DAG.getBitcast(MVT::v4f32, Input);
8566 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, BitCast,
8567 DAG.getConstant(Elt, dl, MVT::i32));
8568 }
8569 }
8570
8571 // Nothing interesting found, just return
8572 if (!Parts[0] && !Parts[1] && !Parts[2] && !Parts[3])
8573 return SDValue();
8574
8575 // The other parts need to be built with the old shuffle vector, cast to a
8576 // v4i32 and extract_vector_elts
8577 if (!Parts[0] || !Parts[1] || !Parts[2] || !Parts[3]) {
8578 SmallVector<int, 16> NewShuffleMask;
8579 for (int Part = 0; Part < 4; ++Part)
8580 for (int i = 0; i < QuarterSize; i++)
8581 NewShuffleMask.push_back(
8582 Parts[Part] ? -1 : ShuffleMask[Part * QuarterSize + i]);
8583 SDValue NewShuffle = DAG.getVectorShuffle(
8584 VT, dl, Op->getOperand(0), Op->getOperand(1), NewShuffleMask);
8585 SDValue BitCast = DAG.getBitcast(MVT::v4f32, NewShuffle);
8586
8587 for (int Part = 0; Part < 4; ++Part)
8588 if (!Parts[Part])
8589 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32,
8590 BitCast, DAG.getConstant(Part, dl, MVT::i32));
8591 }
8592 // Build a vector out of the various parts and bitcast it back to the original
8593 // type.
8594 SDValue NewVec = DAG.getNode(ARMISD::BUILD_VECTOR, dl, MVT::v4f32, Parts);
8595 return DAG.getBitcast(VT, NewVec);
8596}
8597
8599 ArrayRef<int> ShuffleMask,
8600 SelectionDAG &DAG) {
8601 SDValue V1 = Op.getOperand(0);
8602 SDValue V2 = Op.getOperand(1);
8603 EVT VT = Op.getValueType();
8604 unsigned NumElts = VT.getVectorNumElements();
8605
8606 // An One-Off Identity mask is one that is mostly an identity mask from as
8607 // single source but contains a single element out-of-place, either from a
8608 // different vector or from another position in the same vector. As opposed to
8609 // lowering this via a ARMISD::BUILD_VECTOR we can generate an extract/insert
8610 // pair directly.
8611 auto isOneOffIdentityMask = [](ArrayRef<int> Mask, EVT VT, int BaseOffset,
8612 int &OffElement) {
8613 OffElement = -1;
8614 int NonUndef = 0;
8615 for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
8616 if (Mask[i] == -1)
8617 continue;
8618 NonUndef++;
8619 if (Mask[i] != i + BaseOffset) {
8620 if (OffElement == -1)
8621 OffElement = i;
8622 else
8623 return false;
8624 }
8625 }
8626 return NonUndef > 2 && OffElement != -1;
8627 };
8628 int OffElement;
8629 SDValue VInput;
8630 if (isOneOffIdentityMask(ShuffleMask, VT, 0, OffElement))
8631 VInput = V1;
8632 else if (isOneOffIdentityMask(ShuffleMask, VT, NumElts, OffElement))
8633 VInput = V2;
8634 else
8635 return SDValue();
8636
8637 SDLoc dl(Op);
8638 EVT SVT = VT.getScalarType() == MVT::i8 || VT.getScalarType() == MVT::i16
8639 ? MVT::i32
8640 : VT.getScalarType();
8641 SDValue Elt = DAG.getNode(
8642 ISD::EXTRACT_VECTOR_ELT, dl, SVT,
8643 ShuffleMask[OffElement] < (int)NumElts ? V1 : V2,
8644 DAG.getVectorIdxConstant(ShuffleMask[OffElement] % NumElts, dl));
8645 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, VInput, Elt,
8646 DAG.getVectorIdxConstant(OffElement % NumElts, dl));
8647}
8648
8650 const ARMSubtarget *ST) {
8651 SDValue V1 = Op.getOperand(0);
8652 SDValue V2 = Op.getOperand(1);
8653 SDLoc dl(Op);
8654 EVT VT = Op.getValueType();
8656 unsigned EltSize = VT.getScalarSizeInBits();
8657
8658 if (ST->hasMVEIntegerOps() && EltSize == 1)
8659 return LowerVECTOR_SHUFFLE_i1(Op, DAG, ST);
8660
8661 // Convert shuffles that are directly supported on NEON to target-specific
8662 // DAG nodes, instead of keeping them as shuffles and matching them again
8663 // during code selection. This is more efficient and avoids the possibility
8664 // of inconsistencies between legalization and selection.
8665 // FIXME: floating-point vectors should be canonicalized to integer vectors
8666 // of the same time so that they get CSEd properly.
8667 ArrayRef<int> ShuffleMask = SVN->getMask();
8668
8669 if (EltSize <= 32) {
8670 if (SVN->isSplat()) {
8671 int Lane = SVN->getSplatIndex();
8672 // If this is undef splat, generate it via "just" vdup, if possible.
8673 if (Lane == -1) Lane = 0;
8674
8675 // Test if V1 is a SCALAR_TO_VECTOR.
8676 if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR) {
8677 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8678 }
8679 // Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
8680 // (and probably will turn into a SCALAR_TO_VECTOR once legalization
8681 // reaches it).
8682 if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
8683 !isa<ConstantSDNode>(V1.getOperand(0))) {
8684 bool IsScalarToVector = true;
8685 for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
8686 if (!V1.getOperand(i).isUndef()) {
8687 IsScalarToVector = false;
8688 break;
8689 }
8690 if (IsScalarToVector)
8691 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8692 }
8693 return DAG.getNode(ARMISD::VDUPLANE, dl, VT, V1,
8694 DAG.getConstant(Lane, dl, MVT::i32));
8695 }
8696
8697 bool ReverseVEXT = false;
8698 unsigned Imm = 0;
8699 if (ST->hasNEON() && isVEXTMask(ShuffleMask, VT, ReverseVEXT, Imm)) {
8700 if (ReverseVEXT)
8701 std::swap(V1, V2);
8702 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V2,
8703 DAG.getConstant(Imm, dl, MVT::i32));
8704 }
8705
8706 if (isVREVMask(ShuffleMask, VT, 64))
8707 return DAG.getNode(ARMISD::VREV64, dl, VT, V1);
8708 if (isVREVMask(ShuffleMask, VT, 32))
8709 return DAG.getNode(ARMISD::VREV32, dl, VT, V1);
8710 if (isVREVMask(ShuffleMask, VT, 16))
8711 return DAG.getNode(ARMISD::VREV16, dl, VT, V1);
8712
8713 if (ST->hasNEON() && V2->isUndef() && isSingletonVEXTMask(ShuffleMask, VT, Imm)) {
8714 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V1,
8715 DAG.getConstant(Imm, dl, MVT::i32));
8716 }
8717
8718 // Check for Neon shuffles that modify both input vectors in place.
8719 // If both results are used, i.e., if there are two shuffles with the same
8720 // source operands and with masks corresponding to both results of one of
8721 // these operations, DAG memoization will ensure that a single node is
8722 // used for both shuffles.
8723 unsigned WhichResult = 0;
8724 bool isV_UNDEF = false;
8725 if (ST->hasNEON()) {
8726 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8727 ShuffleMask, VT, WhichResult, isV_UNDEF)) {
8728 if (isV_UNDEF)
8729 V2 = V1;
8730 return DAG.getNode(ShuffleOpc, dl, DAG.getVTList(VT, VT), V1, V2)
8731 .getValue(WhichResult);
8732 }
8733 }
8734 if (ST->hasMVEIntegerOps()) {
8735 if (isVMOVNMask(ShuffleMask, VT, false, false))
8736 return DAG.getNode(ARMISD::VMOVN, dl, VT, V2, V1,
8737 DAG.getConstant(0, dl, MVT::i32));
8738 if (isVMOVNMask(ShuffleMask, VT, true, false))
8739 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V2,
8740 DAG.getConstant(1, dl, MVT::i32));
8741 if (isVMOVNMask(ShuffleMask, VT, true, true))
8742 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V1,
8743 DAG.getConstant(1, dl, MVT::i32));
8744 }
8745
8746 // Also check for these shuffles through CONCAT_VECTORS: we canonicalize
8747 // shuffles that produce a result larger than their operands with:
8748 // shuffle(concat(v1, undef), concat(v2, undef))
8749 // ->
8750 // shuffle(concat(v1, v2), undef)
8751 // because we can access quad vectors (see PerformVECTOR_SHUFFLECombine).
8752 //
8753 // This is useful in the general case, but there are special cases where
8754 // native shuffles produce larger results: the two-result ops.
8755 //
8756 // Look through the concat when lowering them:
8757 // shuffle(concat(v1, v2), undef)
8758 // ->
8759 // concat(VZIP(v1, v2):0, :1)
8760 //
8761 if (ST->hasNEON() && V1->getOpcode() == ISD::CONCAT_VECTORS && V2->isUndef()) {
8762 SDValue SubV1 = V1->getOperand(0);
8763 SDValue SubV2 = V1->getOperand(1);
8764 EVT SubVT = SubV1.getValueType();
8765
8766 // We expect these to have been canonicalized to -1.
8767 assert(llvm::all_of(ShuffleMask, [&](int i) {
8768 return i < (int)VT.getVectorNumElements();
8769 }) && "Unexpected shuffle index into UNDEF operand!");
8770
8771 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8772 ShuffleMask, SubVT, WhichResult, isV_UNDEF)) {
8773 if (isV_UNDEF)
8774 SubV2 = SubV1;
8775 assert((WhichResult == 0) &&
8776 "In-place shuffle of concat can only have one result!");
8777 SDValue Res = DAG.getNode(ShuffleOpc, dl, DAG.getVTList(SubVT, SubVT),
8778 SubV1, SubV2);
8779 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Res.getValue(0),
8780 Res.getValue(1));
8781 }
8782 }
8783 }
8784
8785 if (ST->hasMVEIntegerOps() && EltSize <= 32 &&
8786 (ST->hasFullFP16() || VT != MVT::v8f16)) {
8787 if (SDValue V = LowerVECTOR_SHUFFLEUsingOneOff(Op, ShuffleMask, DAG))
8788 return V;
8789
8790 for (bool Top : {false, true}) {
8791 for (bool SingleSource : {false, true}) {
8792 if (isTruncMask(ShuffleMask, VT, Top, SingleSource)) {
8793 MVT FromSVT = MVT::getIntegerVT(EltSize * 2);
8794 MVT FromVT = MVT::getVectorVT(FromSVT, ShuffleMask.size() / 2);
8795 SDValue Lo = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT, V1);
8796 SDValue Hi = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT,
8797 SingleSource ? V1 : V2);
8798 if (Top) {
8799 SDValue Amt = DAG.getConstant(EltSize, dl, FromVT);
8800 Lo = DAG.getNode(ISD::SRL, dl, FromVT, Lo, Amt);
8801 Hi = DAG.getNode(ISD::SRL, dl, FromVT, Hi, Amt);
8802 }
8803 return DAG.getNode(ARMISD::MVETRUNC, dl, VT, Lo, Hi);
8804 }
8805 }
8806 }
8807 }
8808
8809 // If the shuffle is not directly supported and it has 4 elements, use
8810 // the PerfectShuffle-generated table to synthesize it from other shuffles.
8811 unsigned NumElts = VT.getVectorNumElements();
8812 if (NumElts == 4) {
8813 unsigned PFIndexes[4];
8814 for (unsigned i = 0; i != 4; ++i) {
8815 if (ShuffleMask[i] < 0)
8816 PFIndexes[i] = 8;
8817 else
8818 PFIndexes[i] = ShuffleMask[i];
8819 }
8820
8821 // Compute the index in the perfect shuffle table.
8822 unsigned PFTableIndex =
8823 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8824 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8825 unsigned Cost = (PFEntry >> 30);
8826
8827 if (Cost <= 4) {
8828 if (ST->hasNEON())
8829 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8830 else if (isLegalMVEShuffleOp(PFEntry)) {
8831 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8832 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8833 unsigned PFEntryLHS = PerfectShuffleTable[LHSID];
8834 unsigned PFEntryRHS = PerfectShuffleTable[RHSID];
8835 if (isLegalMVEShuffleOp(PFEntryLHS) && isLegalMVEShuffleOp(PFEntryRHS))
8836 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8837 }
8838 }
8839 }
8840
8841 // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
8842 if (EltSize >= 32) {
8843 // Do the expansion with floating-point types, since that is what the VFP
8844 // registers are defined to use, and since i64 is not legal.
8845 EVT EltVT = EVT::getFloatingPointVT(EltSize);
8846 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
8847 V1 = DAG.getNode(ISD::BITCAST, dl, VecVT, V1);
8848 V2 = DAG.getNode(ISD::BITCAST, dl, VecVT, V2);
8850 for (unsigned i = 0; i < NumElts; ++i) {
8851 if (ShuffleMask[i] < 0)
8852 Ops.push_back(DAG.getUNDEF(EltVT));
8853 else
8854 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
8855 ShuffleMask[i] < (int)NumElts ? V1 : V2,
8856 DAG.getConstant(ShuffleMask[i] & (NumElts-1),
8857 dl, MVT::i32)));
8858 }
8859 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
8860 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
8861 }
8862
8863 if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8864 isReverseMask(ShuffleMask, VT))
8865 return LowerReverse_VECTOR_SHUFFLE(Op, DAG);
8866
8867 if (ST->hasNEON() && VT == MVT::v8i8)
8868 if (SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG))
8869 return NewOp;
8870
8871 if (ST->hasMVEIntegerOps())
8872 if (SDValue NewOp = LowerVECTOR_SHUFFLEUsingMovs(Op, ShuffleMask, DAG))
8873 return NewOp;
8874
8875 // Lower v8f16 via v8i16 to avoid invalid f16 nodes.
8876 if (VT == MVT::v8f16 && !ST->hasFullFP16()) {
8877 SDValue BC0 =
8878 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(0));
8879 SDValue BC1 =
8880 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(1));
8881 SDValue Shuf = DAG.getVectorShuffle(MVT::v8i16, dl, BC0, BC1, ShuffleMask);
8882 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuf);
8883 }
8884
8885 return SDValue();
8886}
8887
8889 const ARMSubtarget *ST) {
8890 EVT VecVT = Op.getOperand(0).getValueType();
8891 SDLoc dl(Op);
8892
8893 assert(ST->hasMVEIntegerOps() &&
8894 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8895
8896 SDValue Conv =
8897 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8898 unsigned Lane = Op.getConstantOperandVal(2);
8899 unsigned LaneWidth =
8901 unsigned Mask = ((1 << LaneWidth) - 1) << Lane * LaneWidth;
8902 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32,
8903 Op.getOperand(1), DAG.getValueType(MVT::i1));
8904 SDValue BFI = DAG.getNode(ARMISD::BFI, dl, MVT::i32, Conv, Ext,
8905 DAG.getConstant(~Mask, dl, MVT::i32));
8906 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), BFI);
8907}
8908
8909SDValue ARMTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
8910 SelectionDAG &DAG) const {
8911 // INSERT_VECTOR_ELT is legal only for immediate indexes.
8912 SDValue Lane = Op.getOperand(2);
8913 if (!isa<ConstantSDNode>(Lane))
8914 return SDValue();
8915
8916 SDValue Elt = Op.getOperand(1);
8917 EVT EltVT = Elt.getValueType();
8918
8919 if (Subtarget->hasMVEIntegerOps() &&
8920 Op.getValueType().getScalarSizeInBits() == 1)
8921 return LowerINSERT_VECTOR_ELT_i1(Op, DAG, Subtarget);
8922
8923 if (getTypeAction(*DAG.getContext(), EltVT) ==
8925 // INSERT_VECTOR_ELT doesn't want f16 operands promoting to f32,
8926 // but the type system will try to do that if we don't intervene.
8927 // Reinterpret any such vector-element insertion as one with the
8928 // corresponding integer types.
8929
8930 SDLoc dl(Op);
8931
8932 EVT IEltVT = MVT::getIntegerVT(EltVT.getScalarSizeInBits());
8933 assert(getTypeAction(*DAG.getContext(), IEltVT) !=
8935
8936 SDValue VecIn = Op.getOperand(0);
8937 EVT VecVT = VecIn.getValueType();
8938 EVT IVecVT = EVT::getVectorVT(*DAG.getContext(), IEltVT,
8939 VecVT.getVectorNumElements());
8940
8941 SDValue IElt = DAG.getNode(ISD::BITCAST, dl, IEltVT, Elt);
8942 SDValue IVecIn = DAG.getNode(ISD::BITCAST, dl, IVecVT, VecIn);
8943 SDValue IVecOut = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, IVecVT,
8944 IVecIn, IElt, Lane);
8945 return DAG.getNode(ISD::BITCAST, dl, VecVT, IVecOut);
8946 }
8947
8948 return Op;
8949}
8950
8952 const ARMSubtarget *ST) {
8953 EVT VecVT = Op.getOperand(0).getValueType();
8954 SDLoc dl(Op);
8955
8956 assert(ST->hasMVEIntegerOps() &&
8957 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8958
8959 SDValue Conv =
8960 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8961 unsigned Lane = Op.getConstantOperandVal(1);
8962 unsigned LaneWidth =
8964 SDValue Shift = DAG.getNode(ISD::SRL, dl, MVT::i32, Conv,
8965 DAG.getConstant(Lane * LaneWidth, dl, MVT::i32));
8966 return Shift;
8967}
8968
8970 const ARMSubtarget *ST) {
8971 // EXTRACT_VECTOR_ELT is legal only for immediate indexes.
8972 SDValue Lane = Op.getOperand(1);
8973 if (!isa<ConstantSDNode>(Lane))
8974 return SDValue();
8975
8976 SDValue Vec = Op.getOperand(0);
8977 EVT VT = Vec.getValueType();
8978
8979 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8980 return LowerEXTRACT_VECTOR_ELT_i1(Op, DAG, ST);
8981
8982 if (Op.getValueType() == MVT::i32 && Vec.getScalarValueSizeInBits() < 32) {
8983 SDLoc dl(Op);
8984 return DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane);
8985 }
8986
8987 return Op;
8988}
8989
8991 const ARMSubtarget *ST) {
8992 SDLoc dl(Op);
8993 assert(Op.getValueType().getScalarSizeInBits() == 1 &&
8994 "Unexpected custom CONCAT_VECTORS lowering");
8995 assert(isPowerOf2_32(Op.getNumOperands()) &&
8996 "Unexpected custom CONCAT_VECTORS lowering");
8997 assert(ST->hasMVEIntegerOps() &&
8998 "CONCAT_VECTORS lowering only supported for MVE");
8999
9000 auto ConcatPair = [&](SDValue V1, SDValue V2) {
9001 EVT Op1VT = V1.getValueType();
9002 EVT Op2VT = V2.getValueType();
9003 assert(Op1VT == Op2VT && "Operand types don't match!");
9004 assert((Op1VT == MVT::v2i1 || Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) &&
9005 "Unexpected i1 concat operations!");
9006 EVT VT = Op1VT.getDoubleNumVectorElementsVT(*DAG.getContext());
9007
9008 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9009 SDValue NewV2 = PromoteMVEPredVector(dl, V2, Op2VT, DAG);
9010
9011 // We now have Op1 + Op2 promoted to vectors of integers, where v8i1 gets
9012 // promoted to v8i16, etc.
9013 MVT ElType =
9015 unsigned NumElts = 2 * Op1VT.getVectorNumElements();
9016
9017 EVT ConcatVT = MVT::getVectorVT(ElType, NumElts);
9018 if (Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) {
9019 // Use MVETRUNC to truncate the combined NewV1::NewV2 into the smaller
9020 // ConcatVT.
9021 SDValue ConVec =
9022 DAG.getNode(ARMISD::MVETRUNC, dl, ConcatVT, NewV1, NewV2);
9023 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9024 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9025 }
9026
9027 // Extract the vector elements from Op1 and Op2 one by one and truncate them
9028 // to be the right size for the destination. For example, if Op1 is v4i1
9029 // then the promoted vector is v4i32. The result of concatenation gives a
9030 // v8i1, which when promoted is v8i16. That means each i32 element from Op1
9031 // needs truncating to i16 and inserting in the result.
9032 auto ExtractInto = [&DAG, &dl](SDValue NewV, SDValue ConVec, unsigned &j) {
9033 EVT NewVT = NewV.getValueType();
9034 EVT ConcatVT = ConVec.getValueType();
9035 unsigned ExtScale = 1;
9036 if (NewVT == MVT::v2f64) {
9037 NewV = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, NewV);
9038 ExtScale = 2;
9039 }
9040 for (unsigned i = 0, e = NewVT.getVectorNumElements(); i < e; i++, j++) {
9041 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV,
9042 DAG.getIntPtrConstant(i * ExtScale, dl));
9043 ConVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ConcatVT, ConVec, Elt,
9044 DAG.getConstant(j, dl, MVT::i32));
9045 }
9046 return ConVec;
9047 };
9048 unsigned j = 0;
9049 SDValue ConVec = DAG.getNode(ISD::UNDEF, dl, ConcatVT);
9050 ConVec = ExtractInto(NewV1, ConVec, j);
9051 ConVec = ExtractInto(NewV2, ConVec, j);
9052
9053 // Now return the result of comparing the subvector with zero, which will
9054 // generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9055 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9056 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9057 };
9058
9059 // Concat each pair of subvectors and pack into the lower half of the array.
9060 SmallVector<SDValue> ConcatOps(Op->ops());
9061 while (ConcatOps.size() > 1) {
9062 for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) {
9063 SDValue V1 = ConcatOps[I];
9064 SDValue V2 = ConcatOps[I + 1];
9065 ConcatOps[I / 2] = ConcatPair(V1, V2);
9066 }
9067 ConcatOps.resize(ConcatOps.size() / 2);
9068 }
9069 return ConcatOps[0];
9070}
9071
9073 const ARMSubtarget *ST) {
9074 EVT VT = Op->getValueType(0);
9075 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
9076 return LowerCONCAT_VECTORS_i1(Op, DAG, ST);
9077
9078 // The only time a CONCAT_VECTORS operation can have legal types is when
9079 // two 64-bit vectors are concatenated to a 128-bit vector.
9080 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
9081 "unexpected CONCAT_VECTORS");
9082 SDLoc dl(Op);
9083 SDValue Val = DAG.getUNDEF(MVT::v2f64);
9084 SDValue Op0 = Op.getOperand(0);
9085 SDValue Op1 = Op.getOperand(1);
9086 if (!Op0.isUndef())
9087 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9088 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op0),
9089 DAG.getIntPtrConstant(0, dl));
9090 if (!Op1.isUndef())
9091 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9092 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op1),
9093 DAG.getIntPtrConstant(1, dl));
9094 return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Val);
9095}
9096
9098 const ARMSubtarget *ST) {
9099 SDValue V1 = Op.getOperand(0);
9100 SDValue V2 = Op.getOperand(1);
9101 SDLoc dl(Op);
9102 EVT VT = Op.getValueType();
9103 EVT Op1VT = V1.getValueType();
9104 unsigned NumElts = VT.getVectorNumElements();
9105 unsigned Index = V2->getAsZExtVal();
9106
9107 assert(VT.getScalarSizeInBits() == 1 &&
9108 "Unexpected custom EXTRACT_SUBVECTOR lowering");
9109 assert(ST->hasMVEIntegerOps() &&
9110 "EXTRACT_SUBVECTOR lowering only supported for MVE");
9111
9112 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9113
9114 // We now have Op1 promoted to a vector of integers, where v8i1 gets
9115 // promoted to v8i16, etc.
9116
9118
9119 if (NumElts == 2) {
9120 EVT SubVT = MVT::v4i32;
9121 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9122 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j += 2) {
9123 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9124 DAG.getIntPtrConstant(i, dl));
9125 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9126 DAG.getConstant(j, dl, MVT::i32));
9127 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9128 DAG.getConstant(j + 1, dl, MVT::i32));
9129 }
9130 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, SubVec,
9131 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9132 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
9133 }
9134
9135 EVT SubVT = MVT::getVectorVT(ElType, NumElts);
9136 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9137 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j++) {
9138 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9139 DAG.getIntPtrConstant(i, dl));
9140 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9141 DAG.getConstant(j, dl, MVT::i32));
9142 }
9143
9144 // Now return the result of comparing the subvector with zero,
9145 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9146 return DAG.getNode(ARMISD::VCMPZ, dl, VT, SubVec,
9147 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9148}
9149
9150// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
9152 const ARMSubtarget *ST) {
9153 assert(ST->hasMVEIntegerOps() && "Expected MVE!");
9154 EVT VT = N->getValueType(0);
9155 assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
9156 "Expected a vector i1 type!");
9157 SDValue Op = N->getOperand(0);
9158 EVT FromVT = Op.getValueType();
9159 SDLoc DL(N);
9160
9161 SDValue And =
9162 DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
9163 return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
9164 DAG.getCondCode(ISD::SETNE));
9165}
9166
9168 const ARMSubtarget *Subtarget) {
9169 if (!Subtarget->hasMVEIntegerOps())
9170 return SDValue();
9171
9172 EVT ToVT = N->getValueType(0);
9173 if (ToVT.getScalarType() == MVT::i1)
9174 return LowerTruncatei1(N, DAG, Subtarget);
9175
9176 // MVE does not have a single instruction to perform the truncation of a v4i32
9177 // into the lower half of a v8i16, in the same way that a NEON vmovn would.
9178 // Most of the instructions in MVE follow the 'Beats' system, where moving
9179 // values from different lanes is usually something that the instructions
9180 // avoid.
9181 //
9182 // Instead it has top/bottom instructions such as VMOVLT/B and VMOVNT/B,
9183 // which take a the top/bottom half of a larger lane and extend it (or do the
9184 // opposite, truncating into the top/bottom lane from a larger lane). Note
9185 // that because of the way we widen lanes, a v4i16 is really a v4i32 using the
9186 // bottom 16bits from each vector lane. This works really well with T/B
9187 // instructions, but that doesn't extend to v8i32->v8i16 where the lanes need
9188 // to move order.
9189 //
9190 // But truncates and sext/zext are always going to be fairly common from llvm.
9191 // We have several options for how to deal with them:
9192 // - Wherever possible combine them into an instruction that makes them
9193 // "free". This includes loads/stores, which can perform the trunc as part
9194 // of the memory operation. Or certain shuffles that can be turned into
9195 // VMOVN/VMOVL.
9196 // - Lane Interleaving to transform blocks surrounded by ext/trunc. So
9197 // trunc(mul(sext(a), sext(b))) may become
9198 // VMOVNT(VMUL(VMOVLB(a), VMOVLB(b)), VMUL(VMOVLT(a), VMOVLT(b))). (Which in
9199 // this case can use VMULL). This is performed in the
9200 // MVELaneInterleavingPass.
9201 // - Otherwise we have an option. By default we would expand the
9202 // zext/sext/trunc into a series of lane extract/inserts going via GPR
9203 // registers. One for each vector lane in the vector. This can obviously be
9204 // very expensive.
9205 // - The other option is to use the fact that loads/store can extend/truncate
9206 // to turn a trunc into two truncating stack stores and a stack reload. This
9207 // becomes 3 back-to-back memory operations, but at least that is less than
9208 // all the insert/extracts.
9209 //
9210 // In order to do the last, we convert certain trunc's into MVETRUNC, which
9211 // are either optimized where they can be, or eventually lowered into stack
9212 // stores/loads. This prevents us from splitting a v8i16 trunc into two stores
9213 // two early, where other instructions would be better, and stops us from
9214 // having to reconstruct multiple buildvector shuffles into loads/stores.
9215 if (ToVT != MVT::v8i16 && ToVT != MVT::v16i8)
9216 return SDValue();
9217 EVT FromVT = N->getOperand(0).getValueType();
9218 if (FromVT != MVT::v8i32 && FromVT != MVT::v16i16)
9219 return SDValue();
9220
9221 SDValue Lo, Hi;
9222 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
9223 SDLoc DL(N);
9224 return DAG.getNode(ARMISD::MVETRUNC, DL, ToVT, Lo, Hi);
9225}
9226
9228 const ARMSubtarget *Subtarget) {
9229 if (!Subtarget->hasMVEIntegerOps())
9230 return SDValue();
9231
9232 // See LowerTruncate above for an explanation of MVEEXT/MVETRUNC.
9233
9234 EVT ToVT = N->getValueType(0);
9235 if (ToVT != MVT::v16i32 && ToVT != MVT::v8i32 && ToVT != MVT::v16i16)
9236 return SDValue();
9237 SDValue Op = N->getOperand(0);
9238 EVT FromVT = Op.getValueType();
9239 if (FromVT != MVT::v8i16 && FromVT != MVT::v16i8)
9240 return SDValue();
9241
9242 SDLoc DL(N);
9243 EVT ExtVT = ToVT.getHalfNumVectorElementsVT(*DAG.getContext());
9244 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8)
9245 ExtVT = MVT::v8i16;
9246
9247 unsigned Opcode =
9249 SDValue Ext = DAG.getNode(Opcode, DL, DAG.getVTList(ExtVT, ExtVT), Op);
9250 SDValue Ext1 = Ext.getValue(1);
9251
9252 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8) {
9253 Ext = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext);
9254 Ext1 = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext1);
9255 }
9256
9257 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Ext, Ext1);
9258}
9259
9260/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
9261/// element has been zero/sign-extended, depending on the isSigned parameter,
9262/// from an integer type half its size.
9264 bool isSigned) {
9265 // A v2i64 BUILD_VECTOR will have been legalized to a BITCAST from v4i32.
9266 EVT VT = N->getValueType(0);
9267 if (VT == MVT::v2i64 && N->getOpcode() == ISD::BITCAST) {
9268 SDNode *BVN = N->getOperand(0).getNode();
9269 if (BVN->getValueType(0) != MVT::v4i32 ||
9270 BVN->getOpcode() != ISD::BUILD_VECTOR)
9271 return false;
9272 unsigned LoElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9273 unsigned HiElt = 1 - LoElt;
9278 if (!Lo0 || !Hi0 || !Lo1 || !Hi1)
9279 return false;
9280 if (isSigned) {
9281 if (Hi0->getSExtValue() == Lo0->getSExtValue() >> 32 &&
9282 Hi1->getSExtValue() == Lo1->getSExtValue() >> 32)
9283 return true;
9284 } else {
9285 if (Hi0->isZero() && Hi1->isZero())
9286 return true;
9287 }
9288 return false;
9289 }
9290
9291 if (N->getOpcode() != ISD::BUILD_VECTOR)
9292 return false;
9293
9294 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
9295 SDNode *Elt = N->getOperand(i).getNode();
9297 unsigned EltSize = VT.getScalarSizeInBits();
9298 unsigned HalfSize = EltSize / 2;
9299 if (isSigned) {
9300 if (!isIntN(HalfSize, C->getSExtValue()))
9301 return false;
9302 } else {
9303 if (!isUIntN(HalfSize, C->getZExtValue()))
9304 return false;
9305 }
9306 continue;
9307 }
9308 return false;
9309 }
9310
9311 return true;
9312}
9313
9314/// isSignExtended - Check if a node is a vector value that is sign-extended
9315/// or a constant BUILD_VECTOR with sign-extended elements.
9317 if (N->getOpcode() == ISD::SIGN_EXTEND || ISD::isSEXTLoad(N))
9318 return true;
9319 if (isExtendedBUILD_VECTOR(N, DAG, true))
9320 return true;
9321 return false;
9322}
9323
9324/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
9325/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
9327 if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
9329 return true;
9330 if (isExtendedBUILD_VECTOR(N, DAG, false))
9331 return true;
9332 return false;
9333}
9334
9335static EVT getExtensionTo64Bits(const EVT &OrigVT) {
9336 if (OrigVT.getSizeInBits() >= 64)
9337 return OrigVT;
9338
9339 assert(OrigVT.isSimple() && "Expecting a simple value type");
9340
9341 MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
9342 switch (OrigSimpleTy) {
9343 default: llvm_unreachable("Unexpected Vector Type");
9344 case MVT::v2i8:
9345 case MVT::v2i16:
9346 return MVT::v2i32;
9347 case MVT::v4i8:
9348 return MVT::v4i16;
9349 }
9350}
9351
9352/// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
9353/// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
9354/// We insert the required extension here to get the vector to fill a D register.
9356 const EVT &OrigTy,
9357 const EVT &ExtTy,
9358 unsigned ExtOpcode) {
9359 // The vector originally had a size of OrigTy. It was then extended to ExtTy.
9360 // We expect the ExtTy to be 128-bits total. If the OrigTy is less than
9361 // 64-bits we need to insert a new extension so that it will be 64-bits.
9362 assert(ExtTy.is128BitVector() && "Unexpected extension size");
9363 if (OrigTy.getSizeInBits() >= 64)
9364 return N;
9365
9366 // Must extend size to at least 64 bits to be used as an operand for VMULL.
9367 EVT NewVT = getExtensionTo64Bits(OrigTy);
9368
9369 return DAG.getNode(ExtOpcode, SDLoc(N), NewVT, N);
9370}
9371
9372/// SkipLoadExtensionForVMULL - return a load of the original vector size that
9373/// does not do any sign/zero extension. If the original vector is less
9374/// than 64 bits, an appropriate extension will be added after the load to
9375/// reach a total size of 64 bits. We have to add the extension separately
9376/// because ARM does not have a sign/zero extending load for vectors.
9378 EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
9379
9380 // The load already has the right type.
9381 if (ExtendedTy == LD->getMemoryVT())
9382 return DAG.getLoad(LD->getMemoryVT(), SDLoc(LD), LD->getChain(),
9383 LD->getBasePtr(), LD->getPointerInfo(), LD->getAlign(),
9384 LD->getMemOperand()->getFlags());
9385
9386 // We need to create a zextload/sextload. We cannot just create a load
9387 // followed by a zext/zext node because LowerMUL is also run during normal
9388 // operation legalization where we can't create illegal types.
9389 return DAG.getExtLoad(LD->getExtensionType(), SDLoc(LD), ExtendedTy,
9390 LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
9391 LD->getMemoryVT(), LD->getAlign(),
9392 LD->getMemOperand()->getFlags());
9393}
9394
9395/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
9396/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
9397/// the unextended value. The unextended vector should be 64 bits so that it can
9398/// be used as an operand to a VMULL instruction. If the original vector size
9399/// before extension is less than 64 bits we add a an extension to resize
9400/// the vector to 64 bits.
9402 if (N->getOpcode() == ISD::SIGN_EXTEND ||
9403 N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
9404 return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
9405 N->getOperand(0)->getValueType(0),
9406 N->getValueType(0),
9407 N->getOpcode());
9408
9409 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
9410 assert((ISD::isSEXTLoad(LD) || ISD::isZEXTLoad(LD)) &&
9411 "Expected extending load");
9412
9413 SDValue newLoad = SkipLoadExtensionForVMULL(LD, DAG);
9414 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), newLoad.getValue(1));
9415 unsigned Opcode = ISD::isSEXTLoad(LD) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
9416 SDValue extLoad =
9417 DAG.getNode(Opcode, SDLoc(newLoad), LD->getValueType(0), newLoad);
9418 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 0), extLoad);
9419
9420 return newLoad;
9421 }
9422
9423 // Otherwise, the value must be a BUILD_VECTOR. For v2i64, it will
9424 // have been legalized as a BITCAST from v4i32.
9425 if (N->getOpcode() == ISD::BITCAST) {
9426 SDNode *BVN = N->getOperand(0).getNode();
9428 BVN->getValueType(0) == MVT::v4i32 && "expected v4i32 BUILD_VECTOR");
9429 unsigned LowElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9430 return DAG.getBuildVector(
9431 MVT::v2i32, SDLoc(N),
9432 {BVN->getOperand(LowElt), BVN->getOperand(LowElt + 2)});
9433 }
9434 // Construct a new BUILD_VECTOR with elements truncated to half the size.
9435 assert(N->getOpcode() == ISD::BUILD_VECTOR && "expected BUILD_VECTOR");
9436 EVT VT = N->getValueType(0);
9437 unsigned EltSize = VT.getScalarSizeInBits() / 2;
9438 unsigned NumElts = VT.getVectorNumElements();
9439 MVT TruncVT = MVT::getIntegerVT(EltSize);
9441 SDLoc dl(N);
9442 for (unsigned i = 0; i != NumElts; ++i) {
9443 const APInt &CInt = N->getConstantOperandAPInt(i);
9444 // Element types smaller than 32 bits are not legal, so use i32 elements.
9445 // The values are implicitly truncated so sext vs. zext doesn't matter.
9446 Ops.push_back(DAG.getConstant(CInt.zextOrTrunc(32), dl, MVT::i32));
9447 }
9448 return DAG.getBuildVector(MVT::getVectorVT(TruncVT, NumElts), dl, Ops);
9449}
9450
9451static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
9452 unsigned Opcode = N->getOpcode();
9453 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9454 SDNode *N0 = N->getOperand(0).getNode();
9455 SDNode *N1 = N->getOperand(1).getNode();
9456 return N0->hasOneUse() && N1->hasOneUse() &&
9457 isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
9458 }
9459 return false;
9460}
9461
9462static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
9463 unsigned Opcode = N->getOpcode();
9464 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9465 SDNode *N0 = N->getOperand(0).getNode();
9466 SDNode *N1 = N->getOperand(1).getNode();
9467 return N0->hasOneUse() && N1->hasOneUse() &&
9468 isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
9469 }
9470 return false;
9471}
9472
9474 // Multiplications are only custom-lowered for 128-bit vectors so that
9475 // VMULL can be detected. Otherwise v2i64 multiplications are not legal.
9476 EVT VT = Op.getValueType();
9477 assert(VT.is128BitVector() && VT.isInteger() &&
9478 "unexpected type for custom-lowering ISD::MUL");
9479 SDNode *N0 = Op.getOperand(0).getNode();
9480 SDNode *N1 = Op.getOperand(1).getNode();
9481 unsigned NewOpc = 0;
9482 bool isMLA = false;
9483 bool isN0SExt = isSignExtended(N0, DAG);
9484 bool isN1SExt = isSignExtended(N1, DAG);
9485 if (isN0SExt && isN1SExt)
9486 NewOpc = ARMISD::VMULLs;
9487 else {
9488 bool isN0ZExt = isZeroExtended(N0, DAG);
9489 bool isN1ZExt = isZeroExtended(N1, DAG);
9490 if (isN0ZExt && isN1ZExt)
9491 NewOpc = ARMISD::VMULLu;
9492 else if (isN1SExt || isN1ZExt) {
9493 // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
9494 // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
9495 if (isN1SExt && isAddSubSExt(N0, DAG)) {
9496 NewOpc = ARMISD::VMULLs;
9497 isMLA = true;
9498 } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
9499 NewOpc = ARMISD::VMULLu;
9500 isMLA = true;
9501 } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
9502 std::swap(N0, N1);
9503 NewOpc = ARMISD::VMULLu;
9504 isMLA = true;
9505 }
9506 }
9507
9508 if (!NewOpc) {
9509 if (VT == MVT::v2i64)
9510 // Fall through to expand this. It is not legal.
9511 return SDValue();
9512 else
9513 // Other vector multiplications are legal.
9514 return Op;
9515 }
9516 }
9517
9518 // Legalize to a VMULL instruction.
9519 SDLoc DL(Op);
9520 SDValue Op0;
9521 SDValue Op1 = SkipExtensionForVMULL(N1, DAG);
9522 if (!isMLA) {
9523 Op0 = SkipExtensionForVMULL(N0, DAG);
9525 Op1.getValueType().is64BitVector() &&
9526 "unexpected types for extended operands to VMULL");
9527 return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
9528 }
9529
9530 // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
9531 // isel lowering to take advantage of no-stall back to back vmul + vmla.
9532 // vmull q0, d4, d6
9533 // vmlal q0, d5, d6
9534 // is faster than
9535 // vaddl q0, d4, d5
9536 // vmovl q1, d6
9537 // vmul q0, q0, q1
9538 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG);
9539 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG);
9540 EVT Op1VT = Op1.getValueType();
9541 return DAG.getNode(N0->getOpcode(), DL, VT,
9542 DAG.getNode(NewOpc, DL, VT,
9543 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
9544 DAG.getNode(NewOpc, DL, VT,
9545 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
9546}
9547
9549 SelectionDAG &DAG) {
9550 // TODO: Should this propagate fast-math-flags?
9551
9552 // Convert to float
9553 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo));
9554 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo));
9555 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X);
9556 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y);
9557 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X);
9558 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y);
9559 // Get reciprocal estimate.
9560 // float4 recip = vrecpeq_f32(yf);
9561 Y = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9562 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9563 Y);
9564 // Because char has a smaller range than uchar, we can actually get away
9565 // without any newton steps. This requires that we use a weird bias
9566 // of 0xb000, however (again, this has been exhaustively tested).
9567 // float4 result = as_float4(as_int4(xf*recip) + 0xb000);
9568 X = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, X, Y);
9569 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, X);
9570 Y = DAG.getConstant(0xb000, dl, MVT::v4i32);
9571 X = DAG.getNode(ISD::ADD, dl, MVT::v4i32, X, Y);
9572 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, X);
9573 // Convert back to short.
9574 X = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, X);
9575 X = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, X);
9576 return X;
9577}
9578
9580 SelectionDAG &DAG) {
9581 // TODO: Should this propagate fast-math-flags?
9582
9583 SDValue N2;
9584 // Convert to float.
9585 // float4 yf = vcvt_f32_s32(vmovl_s16(y));
9586 // float4 xf = vcvt_f32_s32(vmovl_s16(x));
9587 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N0);
9588 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N1);
9589 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9590 N1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9591
9592 // Use reciprocal estimate and one refinement step.
9593 // float4 recip = vrecpeq_f32(yf);
9594 // recip *= vrecpsq_f32(yf, recip);
9595 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9596 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9597 N1);
9598 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9599 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9600 N1, N2);
9601 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9602 // Because short has a smaller range than ushort, we can actually get away
9603 // with only a single newton step. This requires that we use a weird bias
9604 // of 89, however (again, this has been exhaustively tested).
9605 // float4 result = as_float4(as_int4(xf*recip) + 0x89);
9606 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9607 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9608 N1 = DAG.getConstant(0x89, dl, MVT::v4i32);
9609 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9610 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9611 // Convert back to integer and return.
9612 // return vmovn_s32(vcvt_s32_f32(result));
9613 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9614 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9615 return N0;
9616}
9617
9619 const ARMSubtarget *ST) {
9620 EVT VT = Op.getValueType();
9621 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9622 "unexpected type for custom-lowering ISD::SDIV");
9623
9624 SDLoc dl(Op);
9625 SDValue N0 = Op.getOperand(0);
9626 SDValue N1 = Op.getOperand(1);
9627 SDValue N2, N3;
9628
9629 if (VT == MVT::v8i8) {
9630 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N0);
9631 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N1);
9632
9633 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9634 DAG.getIntPtrConstant(4, dl));
9635 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9636 DAG.getIntPtrConstant(4, dl));
9637 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9638 DAG.getIntPtrConstant(0, dl));
9639 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9640 DAG.getIntPtrConstant(0, dl));
9641
9642 N0 = LowerSDIV_v4i8(N0, N1, dl, DAG); // v4i16
9643 N2 = LowerSDIV_v4i8(N2, N3, dl, DAG); // v4i16
9644
9645 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9646 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9647
9648 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v8i8, N0);
9649 return N0;
9650 }
9651 return LowerSDIV_v4i16(N0, N1, dl, DAG);
9652}
9653
9655 const ARMSubtarget *ST) {
9656 // TODO: Should this propagate fast-math-flags?
9657 EVT VT = Op.getValueType();
9658 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9659 "unexpected type for custom-lowering ISD::UDIV");
9660
9661 SDLoc dl(Op);
9662 SDValue N0 = Op.getOperand(0);
9663 SDValue N1 = Op.getOperand(1);
9664 SDValue N2, N3;
9665
9666 if (VT == MVT::v8i8) {
9667 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N0);
9668 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N1);
9669
9670 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9671 DAG.getIntPtrConstant(4, dl));
9672 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9673 DAG.getIntPtrConstant(4, dl));
9674 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9675 DAG.getIntPtrConstant(0, dl));
9676 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9677 DAG.getIntPtrConstant(0, dl));
9678
9679 N0 = LowerSDIV_v4i16(N0, N1, dl, DAG); // v4i16
9680 N2 = LowerSDIV_v4i16(N2, N3, dl, DAG); // v4i16
9681
9682 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9683 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9684
9685 N0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v8i8,
9686 DAG.getConstant(Intrinsic::arm_neon_vqmovnsu, dl,
9687 MVT::i32),
9688 N0);
9689 return N0;
9690 }
9691
9692 // v4i16 sdiv ... Convert to float.
9693 // float4 yf = vcvt_f32_s32(vmovl_u16(y));
9694 // float4 xf = vcvt_f32_s32(vmovl_u16(x));
9695 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N0);
9696 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N1);
9697 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9698 SDValue BN1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9699
9700 // Use reciprocal estimate and two refinement steps.
9701 // float4 recip = vrecpeq_f32(yf);
9702 // recip *= vrecpsq_f32(yf, recip);
9703 // recip *= vrecpsq_f32(yf, recip);
9704 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9705 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9706 BN1);
9707 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9708 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9709 BN1, N2);
9710 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9711 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9712 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9713 BN1, N2);
9714 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9715 // Simply multiplying by the reciprocal estimate can leave us a few ulps
9716 // too low, so we add 2 ulps (exhaustive testing shows that this is enough,
9717 // and that it will never cause us to return an answer too large).
9718 // float4 result = as_float4(as_int4(xf*recip) + 2);
9719 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9720 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9721 N1 = DAG.getConstant(2, dl, MVT::v4i32);
9722 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9723 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9724 // Convert back to integer and return.
9725 // return vmovn_u32(vcvt_s32_f32(result));
9726 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9727 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9728 return N0;
9729}
9730
9732 unsigned Opcode, bool IsSigned) {
9733 EVT VT0 = Op.getValue(0).getValueType();
9734 EVT VT1 = Op.getValue(1).getValueType();
9735
9736 bool InvertCarry = Opcode == ARMISD::SUBE;
9737 SDValue OpLHS = Op.getOperand(0);
9738 SDValue OpRHS = Op.getOperand(1);
9739 SDValue OpCarryIn = valueToCarryFlag(Op.getOperand(2), DAG, InvertCarry);
9740
9741 SDLoc DL(Op);
9742
9743 SDValue Result = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::i32), OpLHS,
9744 OpRHS, OpCarryIn);
9745
9746 SDValue OutFlag =
9747 IsSigned ? overflowFlagToValue(Result.getValue(1), VT1, DAG)
9748 : carryFlagToValue(Result.getValue(1), VT1, DAG, InvertCarry);
9749
9750 return DAG.getMergeValues({Result, OutFlag}, DL);
9751}
9752
9753SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
9754 bool Signed,
9755 SDValue &Chain) const {
9756 EVT VT = Op.getValueType();
9757 assert((VT == MVT::i32 || VT == MVT::i64) &&
9758 "unexpected type for custom lowering DIV");
9759 SDLoc dl(Op);
9760
9761 const auto &DL = DAG.getDataLayout();
9762 RTLIB::Libcall LC;
9763 if (Signed)
9764 LC = VT == MVT::i32 ? RTLIB::SDIVREM_I32 : RTLIB::SDIVREM_I64;
9765 else
9766 LC = VT == MVT::i32 ? RTLIB::UDIVREM_I32 : RTLIB::UDIVREM_I64;
9767
9768 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
9769 SDValue ES = DAG.getExternalSymbol(LCImpl, getPointerTy(DL));
9770
9772
9773 for (auto AI : {1, 0}) {
9774 SDValue Operand = Op.getOperand(AI);
9775 Args.emplace_back(Operand,
9776 Operand.getValueType().getTypeForEVT(*DAG.getContext()));
9777 }
9778
9779 CallLoweringInfo CLI(DAG);
9780 CLI.setDebugLoc(dl).setChain(Chain).setCallee(
9782 VT.getTypeForEVT(*DAG.getContext()), ES, std::move(Args));
9783
9784 return LowerCallTo(CLI).first;
9785}
9786
9787// This is a code size optimisation: return the original SDIV node to
9788// DAGCombiner when we don't want to expand SDIV into a sequence of
9789// instructions, and an empty node otherwise which will cause the
9790// SDIV to be expanded in DAGCombine.
9791SDValue
9792ARMTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
9793 SelectionDAG &DAG,
9794 SmallVectorImpl<SDNode *> &Created) const {
9795 // TODO: Support SREM
9796 if (N->getOpcode() != ISD::SDIV)
9797 return SDValue();
9798
9799 const auto &ST = DAG.getSubtarget<ARMSubtarget>();
9800 const bool MinSize = ST.hasMinSize();
9801 const bool HasDivide = ST.isThumb() ? ST.hasDivideInThumbMode()
9802 : ST.hasDivideInARMMode();
9803
9804 // Don't touch vector types; rewriting this may lead to scalarizing
9805 // the int divs.
9806 if (N->getOperand(0).getValueType().isVector())
9807 return SDValue();
9808
9809 // Bail if MinSize is not set, and also for both ARM and Thumb mode we need
9810 // hwdiv support for this to be really profitable.
9811 if (!(MinSize && HasDivide))
9812 return SDValue();
9813
9814 // ARM mode is a bit simpler than Thumb: we can handle large power
9815 // of 2 immediates with 1 mov instruction; no further checks required,
9816 // just return the sdiv node.
9817 if (!ST.isThumb())
9818 return SDValue(N, 0);
9819
9820 // In Thumb mode, immediates larger than 128 need a wide 4-byte MOV,
9821 // and thus lose the code size benefits of a MOVS that requires only 2.
9822 // TargetTransformInfo and 'getIntImmCodeSizeCost' could be helpful here,
9823 // but as it's doing exactly this, it's not worth the trouble to get TTI.
9824 if (Divisor.sgt(128))
9825 return SDValue();
9826
9827 return SDValue(N, 0);
9828}
9829
9830SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
9831 bool Signed) const {
9832 assert(Op.getValueType() == MVT::i32 &&
9833 "unexpected type for custom lowering DIV");
9834 SDLoc dl(Op);
9835
9836 SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
9837 DAG.getEntryNode(), Op.getOperand(1));
9838
9839 return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9840}
9841
9843 SDLoc DL(N);
9844 SDValue Op = N->getOperand(1);
9845 if (N->getValueType(0) == MVT::i32)
9846 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
9847 SDValue Lo, Hi;
9848 std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32);
9849 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
9850 DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
9851}
9852
9853void ARMTargetLowering::ExpandDIV_Windows(
9854 SDValue Op, SelectionDAG &DAG, bool Signed,
9856 const auto &DL = DAG.getDataLayout();
9857
9858 assert(Op.getValueType() == MVT::i64 &&
9859 "unexpected type for custom lowering DIV");
9860 SDLoc dl(Op);
9861
9862 SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
9863
9864 SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9865
9866 SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
9867 SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
9868 DAG.getConstant(32, dl, getPointerTy(DL)));
9869 Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper);
9870
9871 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lower, Upper));
9872}
9873
9874std::pair<SDValue, SDValue>
9875ARMTargetLowering::LowerAEABIUnalignedLoad(SDValue Op,
9876 SelectionDAG &DAG) const {
9877 // If we have an unaligned load from a i32 or i64 that would normally be
9878 // split into separate ldrb's, we can use the __aeabi_uread4/__aeabi_uread8
9879 // functions instead.
9880 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9881 EVT MemVT = LD->getMemoryVT();
9882 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9883 return std::make_pair(SDValue(), SDValue());
9884
9885 const auto &MF = DAG.getMachineFunction();
9886 unsigned AS = LD->getAddressSpace();
9887 Align Alignment = LD->getAlign();
9888 const DataLayout &DL = DAG.getDataLayout();
9889 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9890 RTLIB::Libcall LC =
9891 (MemVT == MVT::i32) ? RTLIB::AEABI_UREAD4 : RTLIB::AEABI_UREAD8;
9892
9893 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9894 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9895 MakeLibCallOptions Opts;
9896 SDLoc dl(Op);
9897
9898 auto Pair = makeLibCall(DAG, LC, MemVT.getSimpleVT(), LD->getBasePtr(),
9899 Opts, dl, LD->getChain());
9900
9901 // If necessary, extend the node to 64bit
9902 if (LD->getExtensionType() != ISD::NON_EXTLOAD) {
9903 unsigned ExtType = LD->getExtensionType() == ISD::SEXTLOAD
9906 SDValue EN = DAG.getNode(ExtType, dl, LD->getValueType(0), Pair.first);
9907 Pair.first = EN;
9908 }
9909 return Pair;
9910 }
9911
9912 // Default expand to individual loads
9913 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9914 return expandUnalignedLoad(LD, DAG);
9915 return std::make_pair(SDValue(), SDValue());
9916}
9917
9918SDValue ARMTargetLowering::LowerAEABIUnalignedStore(SDValue Op,
9919 SelectionDAG &DAG) const {
9920 // If we have an unaligned store to a i32 or i64 that would normally be
9921 // split into separate ldrb's, we can use the __aeabi_uwrite4/__aeabi_uwrite8
9922 // functions instead.
9923 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9924 EVT MemVT = ST->getMemoryVT();
9925 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9926 return SDValue();
9927
9928 const auto &MF = DAG.getMachineFunction();
9929 unsigned AS = ST->getAddressSpace();
9930 Align Alignment = ST->getAlign();
9931 const DataLayout &DL = DAG.getDataLayout();
9932 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9933 RTLIB::Libcall LC =
9934 (MemVT == MVT::i32) ? RTLIB::AEABI_UWRITE4 : RTLIB::AEABI_UWRITE8;
9935
9936 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9937 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9938
9939 SDLoc dl(Op);
9940
9941 // If necessary, trunc the value to 32bit
9942 SDValue StoreVal = ST->getOperand(1);
9943 if (ST->isTruncatingStore())
9944 StoreVal = DAG.getNode(ISD::TRUNCATE, dl, MemVT, ST->getOperand(1));
9945
9946 MakeLibCallOptions Opts;
9947 auto CallResult =
9948 makeLibCall(DAG, LC, MVT::isVoid, {StoreVal, ST->getBasePtr()}, Opts,
9949 dl, ST->getChain());
9950
9951 return CallResult.second;
9952 }
9953
9954 // Default expand to individual stores
9955 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9956 return expandUnalignedStore(ST, DAG);
9957 return SDValue();
9958}
9959
9961 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9962 EVT MemVT = LD->getMemoryVT();
9963 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9964 MemVT == MVT::v16i1) &&
9965 "Expected a predicate type!");
9966 assert(MemVT == Op.getValueType());
9967 assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
9968 "Expected a non-extending load");
9969 assert(LD->isUnindexed() && "Expected a unindexed load");
9970
9971 // The basic MVE VLDR on a v2i1/v4i1/v8i1 actually loads the entire 16bit
9972 // predicate, with the "v4i1" bits spread out over the 16 bits loaded. We
9973 // need to make sure that 8/4/2 bits are actually loaded into the correct
9974 // place, which means loading the value and then shuffling the values into
9975 // the bottom bits of the predicate.
9976 // Equally, VLDR for an v16i1 will actually load 32bits (so will be incorrect
9977 // for BE).
9978 // Speaking of BE, apparently the rest of llvm will assume a reverse order to
9979 // a natural VMSR(load), so needs to be reversed.
9980
9981 SDLoc dl(Op);
9982 SDValue Load = DAG.getExtLoad(
9983 ISD::EXTLOAD, dl, MVT::i32, LD->getChain(), LD->getBasePtr(),
9985 LD->getMemOperand());
9986 SDValue Val = Load;
9987 if (DAG.getDataLayout().isBigEndian())
9988 Val = DAG.getNode(ISD::SRL, dl, MVT::i32,
9989 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Load),
9990 DAG.getConstant(32 - MemVT.getSizeInBits(), dl, MVT::i32));
9991 SDValue Pred = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Val);
9992 if (MemVT != MVT::v16i1)
9993 Pred = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MemVT, Pred,
9994 DAG.getConstant(0, dl, MVT::i32));
9995 return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
9996}
9997
9998void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9999 SelectionDAG &DAG) const {
10000 LoadSDNode *LD = cast<LoadSDNode>(N);
10001 EVT MemVT = LD->getMemoryVT();
10002
10003 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10004 !Subtarget->isThumb1Only() && LD->isVolatile() &&
10005 LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10006 assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
10007 SDLoc dl(N);
10009 ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
10010 {LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
10011 SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
10012 SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
10013 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
10014 Results.append({Pair, Result.getValue(2)});
10015 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10016 auto Pair = LowerAEABIUnalignedLoad(SDValue(N, 0), DAG);
10017 if (Pair.first) {
10018 Results.push_back(Pair.first);
10019 Results.push_back(Pair.second);
10020 }
10021 }
10022}
10023
10025 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10026 EVT MemVT = ST->getMemoryVT();
10027 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10028 MemVT == MVT::v16i1) &&
10029 "Expected a predicate type!");
10030 assert(MemVT == ST->getValue().getValueType());
10031 assert(!ST->isTruncatingStore() && "Expected a non-extending store");
10032 assert(ST->isUnindexed() && "Expected a unindexed store");
10033
10034 // Only store the v2i1 or v4i1 or v8i1 worth of bits, via a buildvector with
10035 // top bits unset and a scalar store.
10036 SDLoc dl(Op);
10037 SDValue Build = ST->getValue();
10038 if (MemVT != MVT::v16i1) {
10040 for (unsigned I = 0; I < MemVT.getVectorNumElements(); I++) {
10041 unsigned Elt = DAG.getDataLayout().isBigEndian()
10042 ? MemVT.getVectorNumElements() - I - 1
10043 : I;
10044 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Build,
10045 DAG.getConstant(Elt, dl, MVT::i32)));
10046 }
10047 for (unsigned I = MemVT.getVectorNumElements(); I < 16; I++)
10048 Ops.push_back(DAG.getUNDEF(MVT::i32));
10049 Build = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i1, Ops);
10050 }
10051 SDValue GRP = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Build);
10052 if (MemVT == MVT::v16i1 && DAG.getDataLayout().isBigEndian())
10053 GRP = DAG.getNode(ISD::SRL, dl, MVT::i32,
10054 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, GRP),
10055 DAG.getConstant(16, dl, MVT::i32));
10056 return DAG.getTruncStore(
10057 ST->getChain(), dl, GRP, ST->getBasePtr(),
10059 ST->getMemOperand());
10060}
10061
10062SDValue ARMTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG,
10063 const ARMSubtarget *Subtarget) const {
10064 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10065 EVT MemVT = ST->getMemoryVT();
10066
10067 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10068 !Subtarget->isThumb1Only() && ST->isVolatile() &&
10069 ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10070 assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
10071 SDNode *N = Op.getNode();
10072 SDLoc dl(N);
10073
10074 SDValue Lo = DAG.getNode(
10075 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10076 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
10077 MVT::i32));
10078 SDValue Hi = DAG.getNode(
10079 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10080 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
10081 MVT::i32));
10082
10083 return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
10084 {ST->getChain(), Lo, Hi, ST->getBasePtr()},
10085 MemVT, ST->getMemOperand());
10086 } else if (Subtarget->hasMVEIntegerOps() &&
10087 ((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10088 MemVT == MVT::v16i1))) {
10089 return LowerPredicateStore(Op, DAG);
10090 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10091 return LowerAEABIUnalignedStore(Op, DAG);
10092 }
10093 return SDValue();
10094}
10095
10096static bool isZeroVector(SDValue N) {
10097 return (ISD::isBuildVectorAllZeros(N.getNode()) ||
10098 (N->getOpcode() == ARMISD::VMOVIMM &&
10099 isNullConstant(N->getOperand(0))));
10100}
10101
10104 MVT VT = Op.getSimpleValueType();
10105 SDValue Mask = N->getMask();
10106 SDValue PassThru = N->getPassThru();
10107 SDLoc dl(Op);
10108
10109 if (isZeroVector(PassThru))
10110 return Op;
10111
10112 // MVE Masked loads use zero as the passthru value. Here we convert undef to
10113 // zero too, and other values are lowered to a select.
10114 SDValue ZeroVec = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
10115 DAG.getTargetConstant(0, dl, MVT::i32));
10116 SDValue NewLoad = DAG.getMaskedLoad(
10117 VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask, ZeroVec,
10118 N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
10119 N->getExtensionType(), N->isExpandingLoad());
10120 SDValue Combo = NewLoad;
10121 bool PassThruIsCastZero = (PassThru.getOpcode() == ISD::BITCAST ||
10122 PassThru.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
10123 isZeroVector(PassThru->getOperand(0));
10124 if (!PassThru.isUndef() && !PassThruIsCastZero)
10125 Combo = DAG.getNode(ISD::VSELECT, dl, VT, Mask, NewLoad, PassThru);
10126 return DAG.getMergeValues({Combo, NewLoad.getValue(1)}, dl);
10127}
10128
10130 const ARMSubtarget *ST) {
10131 if (!ST->hasMVEIntegerOps())
10132 return SDValue();
10133
10134 SDLoc dl(Op);
10135 unsigned BaseOpcode = 0;
10136 switch (Op->getOpcode()) {
10137 default: llvm_unreachable("Expected VECREDUCE opcode");
10138 case ISD::VECREDUCE_FADD: BaseOpcode = ISD::FADD; break;
10139 case ISD::VECREDUCE_FMUL: BaseOpcode = ISD::FMUL; break;
10140 case ISD::VECREDUCE_MUL: BaseOpcode = ISD::MUL; break;
10141 case ISD::VECREDUCE_AND: BaseOpcode = ISD::AND; break;
10142 case ISD::VECREDUCE_OR: BaseOpcode = ISD::OR; break;
10143 case ISD::VECREDUCE_XOR: BaseOpcode = ISD::XOR; break;
10144 case ISD::VECREDUCE_FMAX: BaseOpcode = ISD::FMAXNUM; break;
10145 case ISD::VECREDUCE_FMIN: BaseOpcode = ISD::FMINNUM; break;
10146 }
10147
10148 SDValue Op0 = Op->getOperand(0);
10149 EVT VT = Op0.getValueType();
10150 EVT EltVT = VT.getVectorElementType();
10151 unsigned NumElts = VT.getVectorNumElements();
10152 unsigned NumActiveLanes = NumElts;
10153
10154 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10155 NumActiveLanes == 2) &&
10156 "Only expected a power 2 vector size");
10157
10158 // Use Mul(X, Rev(X)) until 4 items remain. Going down to 4 vector elements
10159 // allows us to easily extract vector elements from the lanes.
10160 while (NumActiveLanes > 4) {
10161 unsigned RevOpcode = NumActiveLanes == 16 ? ARMISD::VREV16 : ARMISD::VREV32;
10162 SDValue Rev = DAG.getNode(RevOpcode, dl, VT, Op0);
10163 Op0 = DAG.getNode(BaseOpcode, dl, VT, Op0, Rev);
10164 NumActiveLanes /= 2;
10165 }
10166
10167 SDValue Res;
10168 if (NumActiveLanes == 4) {
10169 // The remaining 4 elements are summed sequentially
10170 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10171 DAG.getConstant(0 * NumElts / 4, dl, MVT::i32));
10172 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10173 DAG.getConstant(1 * NumElts / 4, dl, MVT::i32));
10174 SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10175 DAG.getConstant(2 * NumElts / 4, dl, MVT::i32));
10176 SDValue Ext3 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10177 DAG.getConstant(3 * NumElts / 4, dl, MVT::i32));
10178 SDValue Res0 = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10179 SDValue Res1 = DAG.getNode(BaseOpcode, dl, EltVT, Ext2, Ext3, Op->getFlags());
10180 Res = DAG.getNode(BaseOpcode, dl, EltVT, Res0, Res1, Op->getFlags());
10181 } else {
10182 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10183 DAG.getConstant(0, dl, MVT::i32));
10184 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10185 DAG.getConstant(1, dl, MVT::i32));
10186 Res = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10187 }
10188
10189 // Result type may be wider than element type.
10190 if (EltVT != Op->getValueType(0))
10191 Res = DAG.getNode(ISD::ANY_EXTEND, dl, Op->getValueType(0), Res);
10192 return Res;
10193}
10194
10196 const ARMSubtarget *ST) {
10197 if (!ST->hasMVEFloatOps())
10198 return SDValue();
10199 return LowerVecReduce(Op, DAG, ST);
10200}
10201
10203 const ARMSubtarget *ST) {
10204 if (!ST->hasNEON())
10205 return SDValue();
10206
10207 SDLoc dl(Op);
10208 SDValue Op0 = Op->getOperand(0);
10209 EVT VT = Op0.getValueType();
10210 EVT EltVT = VT.getVectorElementType();
10211
10212 unsigned PairwiseIntrinsic = 0;
10213 switch (Op->getOpcode()) {
10214 default:
10215 llvm_unreachable("Expected VECREDUCE opcode");
10217 PairwiseIntrinsic = Intrinsic::arm_neon_vpminu;
10218 break;
10220 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxu;
10221 break;
10223 PairwiseIntrinsic = Intrinsic::arm_neon_vpmins;
10224 break;
10226 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxs;
10227 break;
10228 }
10229 SDValue PairwiseOp = DAG.getConstant(PairwiseIntrinsic, dl, MVT::i32);
10230
10231 unsigned NumElts = VT.getVectorNumElements();
10232 unsigned NumActiveLanes = NumElts;
10233
10234 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10235 NumActiveLanes == 2) &&
10236 "Only expected a power 2 vector size");
10237
10238 // Split 128-bit vectors, since vpmin/max takes 2 64-bit vectors.
10239 if (VT.is128BitVector()) {
10240 SDValue Lo, Hi;
10241 std::tie(Lo, Hi) = DAG.SplitVector(Op0, dl);
10242 VT = Lo.getValueType();
10243 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Lo, Hi});
10244 NumActiveLanes /= 2;
10245 }
10246
10247 // Use pairwise reductions until one lane remains
10248 while (NumActiveLanes > 1) {
10249 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Op0, Op0});
10250 NumActiveLanes /= 2;
10251 }
10252
10253 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10254 DAG.getConstant(0, dl, MVT::i32));
10255
10256 // Result type may be wider than element type.
10257 if (EltVT != Op.getValueType()) {
10258 unsigned Extend = 0;
10259 switch (Op->getOpcode()) {
10260 default:
10261 llvm_unreachable("Expected VECREDUCE opcode");
10264 Extend = ISD::ZERO_EXTEND;
10265 break;
10268 Extend = ISD::SIGN_EXTEND;
10269 break;
10270 }
10271 Res = DAG.getNode(Extend, dl, Op.getValueType(), Res);
10272 }
10273 return Res;
10274}
10275
10277 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering()))
10278 // Acquire/Release load/store is not legal for targets without a dmb or
10279 // equivalent available.
10280 return SDValue();
10281
10282 // Monotonic load/store is legal for all targets.
10283 return Op;
10284}
10285
10288 SelectionDAG &DAG,
10289 const ARMSubtarget *Subtarget) {
10290 SDLoc DL(N);
10291 // Under Power Management extensions, the cycle-count is:
10292 // mrc p15, #0, <Rt>, c9, c13, #0
10293 SDValue Ops[] = { N->getOperand(0), // Chain
10294 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
10295 DAG.getTargetConstant(15, DL, MVT::i32),
10296 DAG.getTargetConstant(0, DL, MVT::i32),
10297 DAG.getTargetConstant(9, DL, MVT::i32),
10298 DAG.getTargetConstant(13, DL, MVT::i32),
10299 DAG.getTargetConstant(0, DL, MVT::i32)
10300 };
10301
10302 SDValue Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
10303 DAG.getVTList(MVT::i32, MVT::Other), Ops);
10304 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Cycles32,
10305 DAG.getConstant(0, DL, MVT::i32)));
10306 Results.push_back(Cycles32.getValue(1));
10307}
10308
10310 SDValue V1) {
10311 SDLoc dl(V0.getNode());
10312 SDValue RegClass =
10313 DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
10314 SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
10315 SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
10316 const SDValue Ops[] = {RegClass, V0, SubReg0, V1, SubReg1};
10317 return SDValue(
10318 DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
10319}
10320
10322 SDLoc dl(V.getNode());
10323 auto [VLo, VHi] = DAG.SplitScalar(V, dl, MVT::i32, MVT::i32);
10324 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10325 if (isBigEndian)
10326 std::swap(VLo, VHi);
10327 return createGPRPairNode2xi32(DAG, VLo, VHi);
10328}
10329
10332 SelectionDAG &DAG) {
10333 assert(N->getValueType(0) == MVT::i64 &&
10334 "AtomicCmpSwap on types less than 64 should be legal");
10335 SDValue Ops[] = {
10336 createGPRPairNode2xi32(DAG, N->getOperand(1),
10337 DAG.getUNDEF(MVT::i32)), // pointer, temp
10338 createGPRPairNodei64(DAG, N->getOperand(2)), // expected
10339 createGPRPairNodei64(DAG, N->getOperand(3)), // new
10340 N->getOperand(0), // chain in
10341 };
10342 SDNode *CmpSwap = DAG.getMachineNode(
10343 ARM::CMP_SWAP_64, SDLoc(N),
10344 DAG.getVTList(MVT::Untyped, MVT::Untyped, MVT::Other), Ops);
10345
10346 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
10347 DAG.setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
10348
10349 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10350
10351 SDValue Lo =
10352 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0,
10353 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10354 SDValue Hi =
10355 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1,
10356 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10357 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i64, Lo, Hi));
10358 Results.push_back(SDValue(CmpSwap, 2));
10359}
10360
10361SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
10362 SDLoc dl(Op);
10363 EVT VT = Op.getValueType();
10364 SDValue Chain = Op.getOperand(0);
10365 SDValue LHS = Op.getOperand(1);
10366 SDValue RHS = Op.getOperand(2);
10367 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
10368 bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
10369
10370 // If we don't have instructions of this float type then soften to a libcall
10371 // and use SETCC instead.
10372 if (isUnsupportedFloatingType(LHS.getValueType())) {
10373 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS,
10374 Chain, IsSignaling);
10375 if (!RHS.getNode()) {
10376 RHS = DAG.getConstant(0, dl, LHS.getValueType());
10377 CC = ISD::SETNE;
10378 }
10379 SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
10380 DAG.getCondCode(CC));
10381 return DAG.getMergeValues({Result, Chain}, dl);
10382 }
10383
10384 ARMCC::CondCodes CondCode, CondCode2;
10385 FPCCToARMCC(CC, CondCode, CondCode2);
10386
10387 SDValue True = DAG.getConstant(1, dl, VT);
10388 SDValue False = DAG.getConstant(0, dl, VT);
10389 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
10390 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
10391 SDValue Result = getCMOV(dl, VT, False, True, ARMcc, Cmp, DAG);
10392 if (CondCode2 != ARMCC::AL) {
10393 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
10394 Result = getCMOV(dl, VT, Result, True, ARMcc, Cmp, DAG);
10395 }
10396 return DAG.getMergeValues({Result, Chain}, dl);
10397}
10398
10399SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
10400 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
10401
10402 EVT VT = getPointerTy(DAG.getDataLayout());
10403 int FI = MFI.CreateFixedObject(4, 0, false);
10404 return DAG.getFrameIndex(FI, VT);
10405}
10406
10407SDValue ARMTargetLowering::LowerFP_TO_BF16(SDValue Op,
10408 SelectionDAG &DAG) const {
10409 SDLoc DL(Op);
10410 MakeLibCallOptions CallOptions;
10411 MVT SVT = Op.getOperand(0).getSimpleValueType();
10412 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, MVT::bf16);
10413 SDValue Res =
10414 makeLibCall(DAG, LC, MVT::f32, Op.getOperand(0), CallOptions, DL).first;
10415 return DAG.getBitcast(MVT::i32, Res);
10416}
10417
10418SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
10419 SDLoc dl(Op);
10420 SDValue LHS = Op.getOperand(0);
10421 SDValue RHS = Op.getOperand(1);
10422
10423 // Determine if this is signed or unsigned comparison
10424 bool IsSigned = (Op.getOpcode() == ISD::SCMP);
10425
10426 // Special case for Thumb1 UCMP only
10427 if (!IsSigned && Subtarget->isThumb1Only()) {
10428 // For Thumb unsigned comparison, use this sequence:
10429 // subs r2, r0, r1 ; r2 = LHS - RHS, sets flags
10430 // sbc r2, r2 ; r2 = r2 - r2 - !carry
10431 // cmp r1, r0 ; compare RHS with LHS
10432 // sbc r1, r1 ; r1 = r1 - r1 - !carry
10433 // subs r0, r2, r1 ; r0 = r2 - r1 (final result)
10434
10435 // First subtraction: LHS - RHS
10436 SDValue Sub1WithFlags = DAG.getNode(
10437 ARMISD::SUBC, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10438 SDValue Sub1Result = Sub1WithFlags.getValue(0);
10439 SDValue Flags1 = Sub1WithFlags.getValue(1);
10440
10441 // SUBE: Sub1Result - Sub1Result - !carry
10442 // This gives 0 if LHS >= RHS (unsigned), -1 if LHS < RHS (unsigned)
10443 SDValue Sbc1 =
10444 DAG.getNode(ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT),
10445 Sub1Result, Sub1Result, Flags1);
10446 SDValue Sbc1Result = Sbc1.getValue(0);
10447
10448 // Second comparison: RHS vs LHS (reverse comparison)
10449 SDValue CmpFlags = DAG.getNode(ARMISD::CMP, dl, FlagsVT, RHS, LHS);
10450
10451 // SUBE: RHS - RHS - !carry
10452 // This gives 0 if RHS <= LHS (unsigned), -1 if RHS > LHS (unsigned)
10453 SDValue Sbc2 = DAG.getNode(
10454 ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT), RHS, RHS, CmpFlags);
10455 SDValue Sbc2Result = Sbc2.getValue(0);
10456
10457 // Final subtraction: Sbc1Result - Sbc2Result (no flags needed)
10458 SDValue Result =
10459 DAG.getNode(ISD::SUB, dl, MVT::i32, Sbc1Result, Sbc2Result);
10460 if (Op.getValueType() != MVT::i32)
10461 Result = DAG.getSExtOrTrunc(Result, dl, Op.getValueType());
10462
10463 return Result;
10464 }
10465
10466 // For the ARM assembly pattern:
10467 // subs r0, r0, r1 ; subtract RHS from LHS and set flags
10468 // movgt r0, #1 ; if LHS > RHS, set result to 1 (GT for signed, HI for
10469 // unsigned) mvnlt r0, #0 ; if LHS < RHS, set result to -1 (LT for
10470 // signed, LO for unsigned)
10471 // ; if LHS == RHS, result remains 0 from the subs
10472
10473 // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
10474 unsigned Opcode = ARMISD::SUBC;
10475
10476 // Check if RHS is a subtraction against 0: (0 - X)
10477 if (RHS.getOpcode() == ISD::SUB) {
10478 SDValue SubLHS = RHS.getOperand(0);
10479 SDValue SubRHS = RHS.getOperand(1);
10480
10481 // Check if it's 0 - X
10482 if (isNullConstant(SubLHS)) {
10483 bool CanUseAdd = false;
10484 if (IsSigned) {
10485 // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
10486 if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
10488 .isMinSignedValue()) {
10489 CanUseAdd = true;
10490 }
10491 } else {
10492 // For UCMP: only if X is known to never be zero
10493 if (DAG.isKnownNeverZero(SubRHS)) {
10494 CanUseAdd = true;
10495 }
10496 }
10497
10498 if (CanUseAdd) {
10499 Opcode = ARMISD::ADDC;
10500 RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
10501 // LHS - (0 - X)
10502 }
10503 }
10504 }
10505
10506 // Generate the operation with flags
10507 SDValue OpWithFlags =
10508 DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10509
10510 SDValue OpResult = OpWithFlags.getValue(0);
10511 SDValue Flags = OpWithFlags.getValue(1);
10512
10513 // Constants for conditional moves
10514 SDValue One = DAG.getConstant(1, dl, MVT::i32);
10515 SDValue MinusOne = DAG.getAllOnesConstant(dl, MVT::i32);
10516
10517 // Select condition codes based on signed vs unsigned
10518 ARMCC::CondCodes GTCond = IsSigned ? ARMCC::GT : ARMCC::HI;
10519 ARMCC::CondCodes LTCond = IsSigned ? ARMCC::LT : ARMCC::LO;
10520
10521 // First conditional move: if greater than, set to 1
10522 SDValue GTCondValue = DAG.getConstant(GTCond, dl, MVT::i32);
10523 SDValue Result1 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, OpResult, One,
10524 GTCondValue, Flags);
10525
10526 // Second conditional move: if less than, set to -1
10527 SDValue LTCondValue = DAG.getConstant(LTCond, dl, MVT::i32);
10528 SDValue Result2 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, Result1, MinusOne,
10529 LTCondValue, Flags);
10530
10531 if (Op.getValueType() != MVT::i32)
10532 Result2 = DAG.getSExtOrTrunc(Result2, dl, Op.getValueType());
10533
10534 return Result2;
10535}
10536
10538 LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
10539 switch (Op.getOpcode()) {
10540 default: llvm_unreachable("Don't know how to custom lower this!");
10541 case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
10542 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
10543 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
10544 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
10545 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
10546 case ISD::SELECT: return LowerSELECT(Op, DAG);
10547 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10548 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
10549 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
10550 case ISD::BR_JT: return LowerBR_JT(Op, DAG);
10551 case ISD::VASTART: return LowerVASTART(Op, DAG);
10552 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget);
10553 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget);
10556 case ISD::SINT_TO_FP:
10557 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
10560 case ISD::FP_TO_SINT:
10561 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
10563 case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG, Subtarget);
10564 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
10565 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
10566 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
10567 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
10568 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
10569 case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
10570 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
10571 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
10572 Subtarget);
10573 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);
10574 case ISD::SHL:
10575 case ISD::SRL:
10576 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget);
10577 case ISD::SREM: return LowerREM(Op.getNode(), DAG);
10578 case ISD::UREM: return LowerREM(Op.getNode(), DAG);
10579 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
10580 case ISD::SRL_PARTS:
10581 case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
10582 case ISD::CTTZ:
10583 case ISD::CTTZ_ZERO_POISON: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
10584 case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
10585 case ISD::SETCC: return LowerVSETCC(Op, DAG, Subtarget);
10586 case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
10587 case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
10588 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
10589 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
10590 case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG, Subtarget);
10591 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
10592 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
10593 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
10594 case ISD::TRUNCATE: return LowerTruncate(Op.getNode(), DAG, Subtarget);
10595 case ISD::SIGN_EXTEND:
10596 case ISD::ZERO_EXTEND: return LowerVectorExtend(Op.getNode(), DAG, Subtarget);
10597 case ISD::GET_ROUNDING: return LowerGET_ROUNDING(Op, DAG);
10598 case ISD::SET_ROUNDING: return LowerSET_ROUNDING(Op, DAG);
10599 case ISD::SET_FPMODE:
10600 return LowerSET_FPMODE(Op, DAG);
10601 case ISD::RESET_FPMODE:
10602 return LowerRESET_FPMODE(Op, DAG);
10603 case ISD::MUL: return LowerMUL(Op, DAG);
10604 case ISD::SDIV:
10605 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10606 !Op.getValueType().isVector())
10607 return LowerDIV_Windows(Op, DAG, /* Signed */ true);
10608 return LowerSDIV(Op, DAG, Subtarget);
10609 case ISD::UDIV:
10610 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10611 !Op.getValueType().isVector())
10612 return LowerDIV_Windows(Op, DAG, /* Signed */ false);
10613 return LowerUDIV(Op, DAG, Subtarget);
10614 case ISD::UADDO_CARRY:
10615 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, false /*unsigned*/);
10616 case ISD::USUBO_CARRY:
10617 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, false /*unsigned*/);
10618 case ISD::SADDO_CARRY:
10619 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, true /*signed*/);
10620 case ISD::SSUBO_CARRY:
10621 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, true /*signed*/);
10622 case ISD::UADDO:
10623 case ISD::USUBO:
10624 case ISD::UMULO:
10625 case ISD::SADDO:
10626 case ISD::SSUBO:
10627 case ISD::SMULO:
10628 return LowerALUO(Op, DAG);
10629 case ISD::SADDSAT:
10630 case ISD::SSUBSAT:
10631 case ISD::UADDSAT:
10632 case ISD::USUBSAT:
10633 return LowerADDSUBSAT(Op, DAG, Subtarget);
10634 case ISD::LOAD: {
10635 auto *LD = cast<LoadSDNode>(Op);
10636 EVT MemVT = LD->getMemoryVT();
10637 if (Subtarget->hasMVEIntegerOps() &&
10638 (MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10639 MemVT == MVT::v16i1))
10640 return LowerPredicateLoad(Op, DAG);
10641
10642 auto Pair = LowerAEABIUnalignedLoad(Op, DAG);
10643 if (Pair.first)
10644 return DAG.getMergeValues({Pair.first, Pair.second}, SDLoc(Pair.first));
10645 return SDValue();
10646 }
10647 case ISD::STORE:
10648 return LowerSTORE(Op, DAG, Subtarget);
10649 case ISD::MLOAD:
10650 return LowerMLOAD(Op, DAG);
10651 case ISD::VECREDUCE_MUL:
10652 case ISD::VECREDUCE_AND:
10653 case ISD::VECREDUCE_OR:
10654 case ISD::VECREDUCE_XOR:
10655 return LowerVecReduce(Op, DAG, Subtarget);
10660 return LowerVecReduceF(Op, DAG, Subtarget);
10665 return LowerVecReduceMinMax(Op, DAG, Subtarget);
10666 case ISD::ATOMIC_LOAD:
10667 case ISD::ATOMIC_STORE:
10668 return LowerAtomicLoadStore(Op, DAG);
10669 case ISD::SDIVREM:
10670 case ISD::UDIVREM: return LowerDivRem(Op, DAG);
10672 if (getTargetMachine().getTargetTriple().isOSWindows())
10673 return LowerDYNAMIC_STACKALLOC(Op, DAG);
10674 llvm_unreachable("Don't know how to custom lower this!");
10676 case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
10678 case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
10679 case ISD::STRICT_FSETCC:
10680 case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
10681 case ISD::SPONENTRY:
10682 return LowerSPONENTRY(Op, DAG);
10683 case ISD::FP_TO_BF16:
10684 return LowerFP_TO_BF16(Op, DAG);
10685 case ARMISD::WIN__DBZCHK: return SDValue();
10686 case ISD::UCMP:
10687 case ISD::SCMP:
10688 return LowerCMP(Op, DAG);
10689 case ISD::ABS:
10690 return LowerABS(Op, DAG);
10691 case ISD::STRICT_LROUND:
10693 case ISD::STRICT_LRINT:
10694 case ISD::STRICT_LLRINT: {
10695 assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10696 Op.getOperand(1).getValueType() == MVT::bf16) &&
10697 "Expected custom lowering of rounding operations only for f16");
10698 SDLoc DL(Op);
10699 SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10700 {Op.getOperand(0), Op.getOperand(1)});
10701 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10702 {Ext.getValue(1), Ext.getValue(0)});
10703 }
10704 }
10705}
10706
10708 SelectionDAG &DAG) {
10709 unsigned IntNo = N->getConstantOperandVal(0);
10710 unsigned Opc = 0;
10711 if (IntNo == Intrinsic::arm_smlald)
10712 Opc = ARMISD::SMLALD;
10713 else if (IntNo == Intrinsic::arm_smlaldx)
10714 Opc = ARMISD::SMLALDX;
10715 else if (IntNo == Intrinsic::arm_smlsld)
10716 Opc = ARMISD::SMLSLD;
10717 else if (IntNo == Intrinsic::arm_smlsldx)
10718 Opc = ARMISD::SMLSLDX;
10719 else
10720 return;
10721
10722 SDLoc dl(N);
10723 SDValue Lo, Hi;
10724 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32);
10725
10726 SDValue LongMul = DAG.getNode(Opc, dl,
10727 DAG.getVTList(MVT::i32, MVT::i32),
10728 N->getOperand(1), N->getOperand(2),
10729 Lo, Hi);
10730 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
10731 LongMul.getValue(0), LongMul.getValue(1)));
10732}
10733
10734/// ReplaceNodeResults - Replace the results of node with an illegal result
10735/// type with new values built out of custom code.
10738 SelectionDAG &DAG) const {
10739 SDValue Res;
10740 switch (N->getOpcode()) {
10741 default:
10742 llvm_unreachable("Don't know how to custom expand this!");
10743 case ISD::READ_REGISTER:
10745 break;
10746 case ISD::BITCAST:
10747 Res = ExpandBITCAST(N, DAG, Subtarget);
10748 break;
10749 case ISD::SRL:
10750 case ISD::SRA:
10751 case ISD::SHL:
10752 Res = Expand64BitShift(N, DAG, Subtarget);
10753 break;
10754 case ISD::SREM:
10755 case ISD::UREM:
10756 Res = LowerREM(N, DAG);
10757 break;
10758 case ISD::SDIVREM:
10759 case ISD::UDIVREM:
10760 Res = LowerDivRem(SDValue(N, 0), DAG);
10761 assert(Res.getNumOperands() == 2 && "DivRem needs two values");
10762 Results.push_back(Res.getValue(0));
10763 Results.push_back(Res.getValue(1));
10764 return;
10765 case ISD::SADDSAT:
10766 case ISD::SSUBSAT:
10767 case ISD::UADDSAT:
10768 case ISD::USUBSAT:
10769 Res = LowerADDSUBSAT(SDValue(N, 0), DAG, Subtarget);
10770 break;
10772 ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
10773 return;
10774 case ISD::UDIV:
10775 case ISD::SDIV:
10776 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
10777 "can only expand DIV on Windows");
10778 return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
10779 Results);
10782 return;
10784 return ReplaceLongIntrinsic(N, Results, DAG);
10785 case ISD::LOAD:
10786 LowerLOAD(N, Results, DAG);
10787 break;
10788 case ISD::STORE:
10789 Res = LowerAEABIUnalignedStore(SDValue(N, 0), DAG);
10790 break;
10791 case ISD::TRUNCATE:
10792 Res = LowerTruncate(N, DAG, Subtarget);
10793 break;
10794 case ISD::SIGN_EXTEND:
10795 case ISD::ZERO_EXTEND:
10796 Res = LowerVectorExtend(N, DAG, Subtarget);
10797 break;
10800 Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
10801 break;
10802 }
10803 if (Res.getNode())
10804 Results.push_back(Res);
10805}
10806
10807//===----------------------------------------------------------------------===//
10808// ARM Scheduler Hooks
10809//===----------------------------------------------------------------------===//
10810
10811/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and
10812/// registers the function context.
10813void ARMTargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
10815 MachineBasicBlock *DispatchBB,
10816 int FI) const {
10817 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
10818 "ROPI/RWPI not currently supported with SjLj");
10819 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10820 DebugLoc dl = MI.getDebugLoc();
10821 MachineFunction *MF = MBB->getParent();
10822 MachineRegisterInfo *MRI = &MF->getRegInfo();
10825 const Function &F = MF->getFunction();
10826
10827 bool isThumb = Subtarget->isThumb();
10828 bool isThumb2 = Subtarget->isThumb2();
10829
10830 unsigned PCLabelId = AFI->createPICLabelUId();
10831 unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8;
10833 ARMConstantPoolMBB::Create(F.getContext(), DispatchBB, PCLabelId, PCAdj);
10834 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
10835
10836 const TargetRegisterClass *TRC = isThumb ? &ARM::tGPRRegClass
10837 : &ARM::GPRRegClass;
10838
10839 // Grab constant pool and fixed stack memory operands.
10840 MachineMemOperand *CPMMO =
10843
10844 MachineMemOperand *FIMMOSt =
10847
10848 // Load the address of the dispatch MBB into the jump buffer.
10849 if (isThumb2) {
10850 // Incoming value: jbuf
10851 // ldr.n r5, LCPI1_1
10852 // orr r5, r5, #1
10853 // add r5, pc
10854 // str r5, [$jbuf, #+4] ; &jbuf[1]
10855 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10856 BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1)
10858 .addMemOperand(CPMMO)
10860 // Set the low bit because of thumb mode.
10861 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10862 BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2)
10863 .addReg(NewVReg1, RegState::Kill)
10864 .addImm(0x01)
10866 .add(condCodeOp());
10867 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10868 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3)
10869 .addReg(NewVReg2, RegState::Kill)
10870 .addImm(PCLabelId);
10871 BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12))
10872 .addReg(NewVReg3, RegState::Kill)
10873 .addFrameIndex(FI)
10874 .addImm(36) // &jbuf[1] :: pc
10875 .addMemOperand(FIMMOSt)
10877 } else if (isThumb) {
10878 // Incoming value: jbuf
10879 // ldr.n r1, LCPI1_4
10880 // add r1, pc
10881 // mov r2, #1
10882 // orrs r1, r2
10883 // add r2, $jbuf, #+4 ; &jbuf[1]
10884 // str r1, [r2]
10885 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10886 BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1)
10888 .addMemOperand(CPMMO)
10890 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10891 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2)
10892 .addReg(NewVReg1, RegState::Kill)
10893 .addImm(PCLabelId);
10894 // Set the low bit because of thumb mode.
10895 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10896 BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3)
10897 .addReg(ARM::CPSR, RegState::Define)
10898 .addImm(1)
10900 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10901 BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4)
10902 .addReg(ARM::CPSR, RegState::Define)
10903 .addReg(NewVReg2, RegState::Kill)
10904 .addReg(NewVReg3, RegState::Kill)
10906 Register NewVReg5 = MRI->createVirtualRegister(TRC);
10907 BuildMI(*MBB, MI, dl, TII->get(ARM::tADDframe), NewVReg5)
10908 .addFrameIndex(FI)
10909 .addImm(36); // &jbuf[1] :: pc
10910 BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi))
10911 .addReg(NewVReg4, RegState::Kill)
10912 .addReg(NewVReg5, RegState::Kill)
10913 .addImm(0)
10914 .addMemOperand(FIMMOSt)
10916 } else {
10917 // Incoming value: jbuf
10918 // ldr r1, LCPI1_1
10919 // add r1, pc, r1
10920 // str r1, [$jbuf, #+4] ; &jbuf[1]
10921 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10922 BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1)
10924 .addImm(0)
10925 .addMemOperand(CPMMO)
10927 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10928 BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
10929 .addReg(NewVReg1, RegState::Kill)
10930 .addImm(PCLabelId)
10932 BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
10933 .addReg(NewVReg2, RegState::Kill)
10934 .addFrameIndex(FI)
10935 .addImm(36) // &jbuf[1] :: pc
10936 .addMemOperand(FIMMOSt)
10938 }
10939}
10940
10941void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
10942 MachineBasicBlock *MBB) const {
10943 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10944 DebugLoc dl = MI.getDebugLoc();
10945 MachineFunction *MF = MBB->getParent();
10946 MachineRegisterInfo *MRI = &MF->getRegInfo();
10947 MachineFrameInfo &MFI = MF->getFrameInfo();
10948 int FI = MFI.getFunctionContextIndex();
10949
10950 const TargetRegisterClass *TRC = Subtarget->isThumb() ? &ARM::tGPRRegClass
10951 : &ARM::GPRnopcRegClass;
10952
10953 // Get a mapping of the call site numbers to all of the landing pads they're
10954 // associated with.
10955 DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2>> CallSiteNumToLPad;
10956 unsigned MaxCSNum = 0;
10957 for (MachineBasicBlock &BB : *MF) {
10958 if (!BB.isEHPad())
10959 continue;
10960
10961 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
10962 // pad.
10963 for (MachineInstr &II : BB) {
10964 if (!II.isEHLabel())
10965 continue;
10966
10967 MCSymbol *Sym = II.getOperand(0).getMCSymbol();
10968 if (!MF->hasCallSiteLandingPad(Sym)) continue;
10969
10970 SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
10971 for (unsigned Idx : CallSiteIdxs) {
10972 CallSiteNumToLPad[Idx].push_back(&BB);
10973 MaxCSNum = std::max(MaxCSNum, Idx);
10974 }
10975 break;
10976 }
10977 }
10978
10979 // Get an ordered list of the machine basic blocks for the jump table.
10980 std::vector<MachineBasicBlock*> LPadList;
10981 SmallPtrSet<MachineBasicBlock*, 32> InvokeBBs;
10982 LPadList.reserve(CallSiteNumToLPad.size());
10983 for (unsigned I = 1; I <= MaxCSNum; ++I) {
10984 SmallVectorImpl<MachineBasicBlock*> &MBBList = CallSiteNumToLPad[I];
10985 for (MachineBasicBlock *MBB : MBBList) {
10986 LPadList.push_back(MBB);
10987 InvokeBBs.insert_range(MBB->predecessors());
10988 }
10989 }
10990
10991 assert(!LPadList.empty() &&
10992 "No landing pad destinations for the dispatch jump table!");
10993
10994 // Create the jump table and associated information.
10995 MachineJumpTableInfo *JTI =
10996 MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline);
10997 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
10998
10999 // Create the MBBs for the dispatch code.
11000
11001 // Shove the dispatch's address into the return slot in the function context.
11002 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
11003 DispatchBB->setIsEHPad();
11004
11005 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11006
11007 BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
11008 DispatchBB->addSuccessor(TrapBB);
11009
11010 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
11011 DispatchBB->addSuccessor(DispContBB);
11012
11013 // Insert and MBBs.
11014 MF->insert(MF->end(), DispatchBB);
11015 MF->insert(MF->end(), DispContBB);
11016 MF->insert(MF->end(), TrapBB);
11017
11018 // Insert code into the entry block that creates and registers the function
11019 // context.
11020 SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI);
11021
11022 MachineMemOperand *FIMMOLd = MF->getMachineMemOperand(
11025
11026 MachineInstrBuilder MIB;
11027 MIB = BuildMI(DispatchBB, dl, TII->get(ARM::Int_eh_sjlj_dispatchsetup));
11028
11029 const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
11030 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
11031
11032 // Add a register mask with no preserved registers. This results in all
11033 // registers being marked as clobbered. This can't work if the dispatch block
11034 // is in a Thumb1 function and is linked with ARM code which uses the FP
11035 // registers, as there is no way to preserve the FP registers in Thumb1 mode.
11037
11038 bool IsPositionIndependent = isPositionIndependent();
11039 unsigned NumLPads = LPadList.size();
11040 if (Subtarget->isThumb2()) {
11041 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11042 BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1)
11043 .addFrameIndex(FI)
11044 .addImm(4)
11045 .addMemOperand(FIMMOLd)
11047
11048 if (NumLPads < 256) {
11049 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri))
11050 .addReg(NewVReg1)
11051 .addImm(LPadList.size())
11053 } else {
11054 Register VReg1 = MRI->createVirtualRegister(TRC);
11055 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVi16), VReg1)
11056 .addImm(NumLPads & 0xFFFF)
11058
11059 unsigned VReg2 = VReg1;
11060 if ((NumLPads & 0xFFFF0000) != 0) {
11061 VReg2 = MRI->createVirtualRegister(TRC);
11062 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVTi16), VReg2)
11063 .addReg(VReg1)
11064 .addImm(NumLPads >> 16)
11066 }
11067
11068 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPrr))
11069 .addReg(NewVReg1)
11070 .addReg(VReg2)
11072 }
11073
11074 BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc))
11075 .addMBB(TrapBB)
11077 .addReg(ARM::CPSR);
11078
11079 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11080 BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT), NewVReg3)
11081 .addJumpTableIndex(MJTI)
11083
11084 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11085 BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg4)
11086 .addReg(NewVReg3, RegState::Kill)
11087 .addReg(NewVReg1)
11090 .add(condCodeOp());
11091
11092 BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT))
11093 .addReg(NewVReg4, RegState::Kill)
11094 .addReg(NewVReg1)
11095 .addJumpTableIndex(MJTI);
11096 } else if (Subtarget->isThumb()) {
11097 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11098 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1)
11099 .addFrameIndex(FI)
11100 .addImm(1)
11101 .addMemOperand(FIMMOLd)
11103
11104 if (NumLPads < 256) {
11105 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8))
11106 .addReg(NewVReg1)
11107 .addImm(NumLPads)
11109 } else {
11110 MachineConstantPool *ConstantPool = MF->getConstantPool();
11111 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11112 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11113
11114 // MachineConstantPool wants an explicit alignment.
11115 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11116 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11117
11118 Register VReg1 = MRI->createVirtualRegister(TRC);
11119 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRpci))
11120 .addReg(VReg1, RegState::Define)
11123 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPr))
11124 .addReg(NewVReg1)
11125 .addReg(VReg1)
11127 }
11128
11129 BuildMI(DispatchBB, dl, TII->get(ARM::tBcc))
11130 .addMBB(TrapBB)
11132 .addReg(ARM::CPSR);
11133
11134 Register NewVReg2 = MRI->createVirtualRegister(TRC);
11135 BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2)
11136 .addReg(ARM::CPSR, RegState::Define)
11137 .addReg(NewVReg1)
11138 .addImm(2)
11140
11141 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11142 BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3)
11143 .addJumpTableIndex(MJTI)
11145
11146 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11147 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4)
11148 .addReg(ARM::CPSR, RegState::Define)
11149 .addReg(NewVReg2, RegState::Kill)
11150 .addReg(NewVReg3)
11152
11153 MachineMemOperand *JTMMOLd =
11154 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11156
11157 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11158 BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5)
11159 .addReg(NewVReg4, RegState::Kill)
11160 .addImm(0)
11161 .addMemOperand(JTMMOLd)
11163
11164 unsigned NewVReg6 = NewVReg5;
11165 if (IsPositionIndependent) {
11166 NewVReg6 = MRI->createVirtualRegister(TRC);
11167 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6)
11168 .addReg(ARM::CPSR, RegState::Define)
11169 .addReg(NewVReg5, RegState::Kill)
11170 .addReg(NewVReg3)
11172 }
11173
11174 BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr))
11175 .addReg(NewVReg6, RegState::Kill)
11176 .addJumpTableIndex(MJTI);
11177 } else {
11178 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11179 BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1)
11180 .addFrameIndex(FI)
11181 .addImm(4)
11182 .addMemOperand(FIMMOLd)
11184
11185 if (NumLPads < 256) {
11186 BuildMI(DispatchBB, dl, TII->get(ARM::CMPri))
11187 .addReg(NewVReg1)
11188 .addImm(NumLPads)
11190 } else if (Subtarget->hasV6T2Ops() && isUInt<16>(NumLPads)) {
11191 Register VReg1 = MRI->createVirtualRegister(TRC);
11192 BuildMI(DispatchBB, dl, TII->get(ARM::MOVi16), VReg1)
11193 .addImm(NumLPads & 0xFFFF)
11195
11196 unsigned VReg2 = VReg1;
11197 if ((NumLPads & 0xFFFF0000) != 0) {
11198 VReg2 = MRI->createVirtualRegister(TRC);
11199 BuildMI(DispatchBB, dl, TII->get(ARM::MOVTi16), VReg2)
11200 .addReg(VReg1)
11201 .addImm(NumLPads >> 16)
11203 }
11204
11205 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11206 .addReg(NewVReg1)
11207 .addReg(VReg2)
11209 } else {
11210 MachineConstantPool *ConstantPool = MF->getConstantPool();
11211 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11212 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11213
11214 // MachineConstantPool wants an explicit alignment.
11215 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11216 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11217
11218 Register VReg1 = MRI->createVirtualRegister(TRC);
11219 BuildMI(DispatchBB, dl, TII->get(ARM::LDRcp))
11220 .addReg(VReg1, RegState::Define)
11222 .addImm(0)
11224 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11225 .addReg(NewVReg1)
11226 .addReg(VReg1, RegState::Kill)
11228 }
11229
11230 BuildMI(DispatchBB, dl, TII->get(ARM::Bcc))
11231 .addMBB(TrapBB)
11233 .addReg(ARM::CPSR);
11234
11235 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11236 BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg3)
11237 .addReg(NewVReg1)
11240 .add(condCodeOp());
11241 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11242 BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg4)
11243 .addJumpTableIndex(MJTI)
11245
11246 MachineMemOperand *JTMMOLd =
11247 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11249 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11250 BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg5)
11251 .addReg(NewVReg3, RegState::Kill)
11252 .addReg(NewVReg4)
11253 .addImm(0)
11254 .addMemOperand(JTMMOLd)
11256
11257 if (IsPositionIndependent) {
11258 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd))
11259 .addReg(NewVReg5, RegState::Kill)
11260 .addReg(NewVReg4)
11261 .addJumpTableIndex(MJTI);
11262 } else {
11263 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTr))
11264 .addReg(NewVReg5, RegState::Kill)
11265 .addJumpTableIndex(MJTI);
11266 }
11267 }
11268
11269 // Add the jump table entries as successors to the MBB.
11270 SmallPtrSet<MachineBasicBlock*, 8> SeenMBBs;
11271 for (MachineBasicBlock *CurMBB : LPadList) {
11272 if (SeenMBBs.insert(CurMBB).second)
11273 DispContBB->addSuccessor(CurMBB);
11274 }
11275
11276 // N.B. the order the invoke BBs are processed in doesn't matter here.
11277 const MCPhysReg *SavedRegs = RI.getCalleeSavedRegs(MF);
11279 for (MachineBasicBlock *BB : InvokeBBs) {
11280
11281 // Remove the landing pad successor from the invoke block and replace it
11282 // with the new dispatch block.
11283 SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
11284 while (!Successors.empty()) {
11285 MachineBasicBlock *SMBB = Successors.pop_back_val();
11286 if (SMBB->isEHPad()) {
11287 BB->removeSuccessor(SMBB);
11288 MBBLPads.push_back(SMBB);
11289 }
11290 }
11291
11292 BB->addSuccessor(DispatchBB, BranchProbability::getZero());
11293 BB->normalizeSuccProbs();
11294
11295 // Find the invoke call and mark all of the callee-saved registers as
11296 // 'implicit defined' so that they're spilled. This prevents code from
11297 // moving instructions to before the EH block, where they will never be
11298 // executed.
11300 II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
11301 if (!II->isCall()) continue;
11302
11303 DenseSet<unsigned> DefRegs;
11305 OI = II->operands_begin(), OE = II->operands_end();
11306 OI != OE; ++OI) {
11307 if (!OI->isReg()) continue;
11308 DefRegs.insert(OI->getReg());
11309 }
11310
11311 MachineInstrBuilder MIB(*MF, &*II);
11312
11313 for (unsigned i = 0; SavedRegs[i] != 0; ++i) {
11314 unsigned Reg = SavedRegs[i];
11315 if (Subtarget->isThumb2() &&
11316 !ARM::tGPRRegClass.contains(Reg) &&
11317 !ARM::hGPRRegClass.contains(Reg))
11318 continue;
11319 if (Subtarget->isThumb1Only() && !ARM::tGPRRegClass.contains(Reg))
11320 continue;
11321 if (!Subtarget->isThumb() && !ARM::GPRRegClass.contains(Reg))
11322 continue;
11323 if (!DefRegs.contains(Reg))
11325 }
11326
11327 break;
11328 }
11329 }
11330
11331 // Mark all former landing pads as non-landing pads. The dispatch is the only
11332 // landing pad now.
11333 for (MachineBasicBlock *MBBLPad : MBBLPads)
11334 MBBLPad->setIsEHPad(false);
11335
11336 // The instruction is gone now.
11337 MI.eraseFromParent();
11338}
11339
11340static
11342 for (MachineBasicBlock *S : MBB->successors())
11343 if (S != Succ)
11344 return S;
11345 llvm_unreachable("Expecting a BB with two successors!");
11346}
11347
11348/// Return the load opcode for a given load size. If load size >= 8,
11349/// neon opcode will be returned.
11350static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2) {
11351 if (LdSize >= 8)
11352 return LdSize == 16 ? ARM::VLD1q32wb_fixed
11353 : LdSize == 8 ? ARM::VLD1d32wb_fixed : 0;
11354 if (IsThumb1)
11355 return LdSize == 4 ? ARM::tLDRi
11356 : LdSize == 2 ? ARM::tLDRHi
11357 : LdSize == 1 ? ARM::tLDRBi : 0;
11358 if (IsThumb2)
11359 return LdSize == 4 ? ARM::t2LDR_POST
11360 : LdSize == 2 ? ARM::t2LDRH_POST
11361 : LdSize == 1 ? ARM::t2LDRB_POST : 0;
11362 return LdSize == 4 ? ARM::LDR_POST_IMM
11363 : LdSize == 2 ? ARM::LDRH_POST
11364 : LdSize == 1 ? ARM::LDRB_POST_IMM : 0;
11365}
11366
11367/// Return the store opcode for a given store size. If store size >= 8,
11368/// neon opcode will be returned.
11369static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2) {
11370 if (StSize >= 8)
11371 return StSize == 16 ? ARM::VST1q32wb_fixed
11372 : StSize == 8 ? ARM::VST1d32wb_fixed : 0;
11373 if (IsThumb1)
11374 return StSize == 4 ? ARM::tSTRi
11375 : StSize == 2 ? ARM::tSTRHi
11376 : StSize == 1 ? ARM::tSTRBi : 0;
11377 if (IsThumb2)
11378 return StSize == 4 ? ARM::t2STR_POST
11379 : StSize == 2 ? ARM::t2STRH_POST
11380 : StSize == 1 ? ARM::t2STRB_POST : 0;
11381 return StSize == 4 ? ARM::STR_POST_IMM
11382 : StSize == 2 ? ARM::STRH_POST
11383 : StSize == 1 ? ARM::STRB_POST_IMM : 0;
11384}
11385
11386/// Emit a post-increment load operation with given size. The instructions
11387/// will be added to BB at Pos.
11389 const TargetInstrInfo *TII, const DebugLoc &dl,
11390 unsigned LdSize, unsigned Data, unsigned AddrIn,
11391 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11392 unsigned LdOpc = getLdOpcode(LdSize, IsThumb1, IsThumb2);
11393 assert(LdOpc != 0 && "Should have a load opcode");
11394 if (LdSize >= 8) {
11395 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11396 .addReg(AddrOut, RegState::Define)
11397 .addReg(AddrIn)
11398 .addImm(0)
11400 } else if (IsThumb1) {
11401 // load + update AddrIn
11402 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11403 .addReg(AddrIn)
11404 .addImm(0)
11406 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11407 .add(t1CondCodeOp())
11408 .addReg(AddrIn)
11409 .addImm(LdSize)
11411 } else if (IsThumb2) {
11412 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11413 .addReg(AddrOut, RegState::Define)
11414 .addReg(AddrIn)
11415 .addImm(LdSize)
11417 } else { // arm
11418 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11419 .addReg(AddrOut, RegState::Define)
11420 .addReg(AddrIn)
11421 .addReg(0)
11422 .addImm(LdSize)
11424 }
11425}
11426
11427/// Emit a post-increment store operation with given size. The instructions
11428/// will be added to BB at Pos.
11430 const TargetInstrInfo *TII, const DebugLoc &dl,
11431 unsigned StSize, unsigned Data, unsigned AddrIn,
11432 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11433 unsigned StOpc = getStOpcode(StSize, IsThumb1, IsThumb2);
11434 assert(StOpc != 0 && "Should have a store opcode");
11435 if (StSize >= 8) {
11436 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11437 .addReg(AddrIn)
11438 .addImm(0)
11439 .addReg(Data)
11441 } else if (IsThumb1) {
11442 // store + update AddrIn
11443 BuildMI(*BB, Pos, dl, TII->get(StOpc))
11444 .addReg(Data)
11445 .addReg(AddrIn)
11446 .addImm(0)
11448 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11449 .add(t1CondCodeOp())
11450 .addReg(AddrIn)
11451 .addImm(StSize)
11453 } else if (IsThumb2) {
11454 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11455 .addReg(Data)
11456 .addReg(AddrIn)
11457 .addImm(StSize)
11459 } else { // arm
11460 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11461 .addReg(Data)
11462 .addReg(AddrIn)
11463 .addReg(0)
11464 .addImm(StSize)
11466 }
11467}
11468
11470ARMTargetLowering::EmitStructByval(MachineInstr &MI,
11471 MachineBasicBlock *BB) const {
11472 // This pseudo instruction has 3 operands: dst, src, size
11473 // We expand it to a loop if size > Subtarget->getMaxInlineSizeThreshold().
11474 // Otherwise, we will generate unrolled scalar copies.
11475 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11476 const BasicBlock *LLVM_BB = BB->getBasicBlock();
11478
11479 Register dest = MI.getOperand(0).getReg();
11480 Register src = MI.getOperand(1).getReg();
11481 unsigned SizeVal = MI.getOperand(2).getImm();
11482 unsigned Alignment = MI.getOperand(3).getImm();
11483 DebugLoc dl = MI.getDebugLoc();
11484
11485 MachineFunction *MF = BB->getParent();
11486 MachineRegisterInfo &MRI = MF->getRegInfo();
11487 unsigned UnitSize = 0;
11488 const TargetRegisterClass *TRC = nullptr;
11489 const TargetRegisterClass *VecTRC = nullptr;
11490
11491 bool IsThumb1 = Subtarget->isThumb1Only();
11492 bool IsThumb2 = Subtarget->isThumb2();
11493 bool IsThumb = Subtarget->isThumb();
11494
11495 if (Alignment & 1) {
11496 UnitSize = 1;
11497 } else if (Alignment & 2) {
11498 UnitSize = 2;
11499 } else {
11500 // Check whether we can use NEON instructions.
11501 if (!MF->getFunction().hasFnAttribute(Attribute::NoImplicitFloat) &&
11502 Subtarget->hasNEON()) {
11503 if ((Alignment % 16 == 0) && SizeVal >= 16)
11504 UnitSize = 16;
11505 else if ((Alignment % 8 == 0) && SizeVal >= 8)
11506 UnitSize = 8;
11507 }
11508 // Can't use NEON instructions.
11509 if (UnitSize == 0)
11510 UnitSize = 4;
11511 }
11512
11513 // Select the correct opcode and register class for unit size load/store
11514 bool IsNeon = UnitSize >= 8;
11515 TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
11516 if (IsNeon)
11517 VecTRC = UnitSize == 16 ? &ARM::DPairRegClass
11518 : UnitSize == 8 ? &ARM::DPRRegClass
11519 : nullptr;
11520
11521 unsigned BytesLeft = SizeVal % UnitSize;
11522 unsigned LoopSize = SizeVal - BytesLeft;
11523
11524 if (SizeVal <= Subtarget->getMaxInlineSizeThreshold()) {
11525 // Use LDR and STR to copy.
11526 // [scratch, srcOut] = LDR_POST(srcIn, UnitSize)
11527 // [destOut] = STR_POST(scratch, destIn, UnitSize)
11528 unsigned srcIn = src;
11529 unsigned destIn = dest;
11530 for (unsigned i = 0; i < LoopSize; i+=UnitSize) {
11531 Register srcOut = MRI.createVirtualRegister(TRC);
11532 Register destOut = MRI.createVirtualRegister(TRC);
11533 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11534 emitPostLd(BB, MI, TII, dl, UnitSize, scratch, srcIn, srcOut,
11535 IsThumb1, IsThumb2);
11536 emitPostSt(BB, MI, TII, dl, UnitSize, scratch, destIn, destOut,
11537 IsThumb1, IsThumb2);
11538 srcIn = srcOut;
11539 destIn = destOut;
11540 }
11541
11542 // Handle the leftover bytes with LDRB and STRB.
11543 // [scratch, srcOut] = LDRB_POST(srcIn, 1)
11544 // [destOut] = STRB_POST(scratch, destIn, 1)
11545 for (unsigned i = 0; i < BytesLeft; i++) {
11546 Register srcOut = MRI.createVirtualRegister(TRC);
11547 Register destOut = MRI.createVirtualRegister(TRC);
11548 Register scratch = MRI.createVirtualRegister(TRC);
11549 emitPostLd(BB, MI, TII, dl, 1, scratch, srcIn, srcOut,
11550 IsThumb1, IsThumb2);
11551 emitPostSt(BB, MI, TII, dl, 1, scratch, destIn, destOut,
11552 IsThumb1, IsThumb2);
11553 srcIn = srcOut;
11554 destIn = destOut;
11555 }
11556 MI.eraseFromParent(); // The instruction is gone now.
11557 return BB;
11558 }
11559
11560 // Expand the pseudo op to a loop.
11561 // thisMBB:
11562 // ...
11563 // movw varEnd, # --> with thumb2
11564 // movt varEnd, #
11565 // ldrcp varEnd, idx --> without thumb2
11566 // fallthrough --> loopMBB
11567 // loopMBB:
11568 // PHI varPhi, varEnd, varLoop
11569 // PHI srcPhi, src, srcLoop
11570 // PHI destPhi, dst, destLoop
11571 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11572 // [destLoop] = STR_POST(scratch, destPhi, UnitSize)
11573 // subs varLoop, varPhi, #UnitSize
11574 // bne loopMBB
11575 // fallthrough --> exitMBB
11576 // exitMBB:
11577 // epilogue to handle left-over bytes
11578 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11579 // [destOut] = STRB_POST(scratch, destLoop, 1)
11580 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11581 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11582 MF->insert(It, loopMBB);
11583 MF->insert(It, exitMBB);
11584
11585 // Set the call frame size on entry to the new basic blocks.
11586 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11587 loopMBB->setCallFrameSize(CallFrameSize);
11588 exitMBB->setCallFrameSize(CallFrameSize);
11589
11590 // Transfer the remainder of BB and its successor edges to exitMBB.
11591 exitMBB->splice(exitMBB->begin(), BB,
11592 std::next(MachineBasicBlock::iterator(MI)), BB->end());
11594
11595 // Load an immediate to varEnd.
11596 Register varEnd = MRI.createVirtualRegister(TRC);
11597 if (Subtarget->useMovt()) {
11598 BuildMI(BB, dl, TII->get(IsThumb ? ARM::t2MOVi32imm : ARM::MOVi32imm),
11599 varEnd)
11600 .addImm(LoopSize);
11601 } else if (Subtarget->genExecuteOnly()) {
11602 assert(IsThumb && "Non-thumb expected to have used movt");
11603 BuildMI(BB, dl, TII->get(ARM::tMOVi32imm), varEnd).addImm(LoopSize);
11604 } else {
11605 MachineConstantPool *ConstantPool = MF->getConstantPool();
11606 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11607 const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
11608
11609 // MachineConstantPool wants an explicit alignment.
11610 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11611 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11612 MachineMemOperand *CPMMO =
11615
11616 if (IsThumb)
11617 BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci))
11618 .addReg(varEnd, RegState::Define)
11621 .addMemOperand(CPMMO);
11622 else
11623 BuildMI(*BB, MI, dl, TII->get(ARM::LDRcp))
11624 .addReg(varEnd, RegState::Define)
11626 .addImm(0)
11628 .addMemOperand(CPMMO);
11629 }
11630 BB->addSuccessor(loopMBB);
11631
11632 // Generate the loop body:
11633 // varPhi = PHI(varLoop, varEnd)
11634 // srcPhi = PHI(srcLoop, src)
11635 // destPhi = PHI(destLoop, dst)
11636 MachineBasicBlock *entryBB = BB;
11637 BB = loopMBB;
11638 Register varLoop = MRI.createVirtualRegister(TRC);
11639 Register varPhi = MRI.createVirtualRegister(TRC);
11640 Register srcLoop = MRI.createVirtualRegister(TRC);
11641 Register srcPhi = MRI.createVirtualRegister(TRC);
11642 Register destLoop = MRI.createVirtualRegister(TRC);
11643 Register destPhi = MRI.createVirtualRegister(TRC);
11644
11645 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), varPhi)
11646 .addReg(varLoop).addMBB(loopMBB)
11647 .addReg(varEnd).addMBB(entryBB);
11648 BuildMI(BB, dl, TII->get(ARM::PHI), srcPhi)
11649 .addReg(srcLoop).addMBB(loopMBB)
11650 .addReg(src).addMBB(entryBB);
11651 BuildMI(BB, dl, TII->get(ARM::PHI), destPhi)
11652 .addReg(destLoop).addMBB(loopMBB)
11653 .addReg(dest).addMBB(entryBB);
11654
11655 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11656 // [destLoop] = STR_POST(scratch, destPhi, UnitSiz)
11657 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11658 emitPostLd(BB, BB->end(), TII, dl, UnitSize, scratch, srcPhi, srcLoop,
11659 IsThumb1, IsThumb2);
11660 emitPostSt(BB, BB->end(), TII, dl, UnitSize, scratch, destPhi, destLoop,
11661 IsThumb1, IsThumb2);
11662
11663 // Decrement loop variable by UnitSize.
11664 if (IsThumb1) {
11665 BuildMI(*BB, BB->end(), dl, TII->get(ARM::tSUBi8), varLoop)
11666 .add(t1CondCodeOp())
11667 .addReg(varPhi)
11668 .addImm(UnitSize)
11670 } else {
11671 MachineInstrBuilder MIB =
11672 BuildMI(*BB, BB->end(), dl,
11673 TII->get(IsThumb2 ? ARM::t2SUBri : ARM::SUBri), varLoop);
11674 MIB.addReg(varPhi)
11675 .addImm(UnitSize)
11677 .add(condCodeOp());
11678 MIB->getOperand(5).setReg(ARM::CPSR);
11679 MIB->getOperand(5).setIsDef(true);
11680 }
11681 BuildMI(*BB, BB->end(), dl,
11682 TII->get(IsThumb1 ? ARM::tBcc : IsThumb2 ? ARM::t2Bcc : ARM::Bcc))
11683 .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
11684
11685 // loopMBB can loop back to loopMBB or fall through to exitMBB.
11686 BB->addSuccessor(loopMBB);
11687 BB->addSuccessor(exitMBB);
11688
11689 // Add epilogue to handle BytesLeft.
11690 BB = exitMBB;
11691 auto StartOfExit = exitMBB->begin();
11692
11693 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11694 // [destOut] = STRB_POST(scratch, destLoop, 1)
11695 unsigned srcIn = srcLoop;
11696 unsigned destIn = destLoop;
11697 for (unsigned i = 0; i < BytesLeft; i++) {
11698 Register srcOut = MRI.createVirtualRegister(TRC);
11699 Register destOut = MRI.createVirtualRegister(TRC);
11700 Register scratch = MRI.createVirtualRegister(TRC);
11701 emitPostLd(BB, StartOfExit, TII, dl, 1, scratch, srcIn, srcOut,
11702 IsThumb1, IsThumb2);
11703 emitPostSt(BB, StartOfExit, TII, dl, 1, scratch, destIn, destOut,
11704 IsThumb1, IsThumb2);
11705 srcIn = srcOut;
11706 destIn = destOut;
11707 }
11708
11709 MI.eraseFromParent(); // The instruction is gone now.
11710 return BB;
11711}
11712
11714ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
11715 MachineBasicBlock *MBB) const {
11716 const TargetMachine &TM = getTargetMachine();
11717 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
11718 DebugLoc DL = MI.getDebugLoc();
11719
11720 assert(TM.getTargetTriple().isOSWindows() &&
11721 "__chkstk is only supported on Windows");
11722 assert(Subtarget->isThumb2() && "Windows on ARM requires Thumb-2 mode");
11723
11724 // __chkstk takes the number of words to allocate on the stack in R4, and
11725 // returns the stack adjustment in number of bytes in R4. This will not
11726 // clober any other registers (other than the obvious lr).
11727 //
11728 // Although, technically, IP should be considered a register which may be
11729 // clobbered, the call itself will not touch it. Windows on ARM is a pure
11730 // thumb-2 environment, so there is no interworking required. As a result, we
11731 // do not expect a veneer to be emitted by the linker, clobbering IP.
11732 //
11733 // Each module receives its own copy of __chkstk, so no import thunk is
11734 // required, again, ensuring that IP is not clobbered.
11735 //
11736 // Finally, although some linkers may theoretically provide a trampoline for
11737 // out of range calls (which is quite common due to a 32M range limitation of
11738 // branches for Thumb), we can generate the long-call version via
11739 // -mcmodel=large, alleviating the need for the trampoline which may clobber
11740 // IP.
11741
11742 RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE);
11743 if (ChkStkLibcall == RTLIB::Unsupported)
11744 reportFatalUsageError("no available implementation of __chkstk");
11745
11746 const char *ChkStk = getLibcallImplName(ChkStkLibcall).data();
11747 switch (TM.getCodeModel()) {
11748 case CodeModel::Tiny:
11749 llvm_unreachable("Tiny code model not available on ARM.");
11750 case CodeModel::Small:
11751 case CodeModel::Medium:
11752 case CodeModel::Kernel:
11753 BuildMI(*MBB, MI, DL, TII.get(ARM::tBL))
11755 .addExternalSymbol(ChkStk)
11758 .addReg(ARM::R12,
11760 .addReg(ARM::CPSR,
11762 break;
11763 case CodeModel::Large: {
11764 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
11765 Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11766
11767 BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
11768 .addExternalSymbol(ChkStk);
11774 .addReg(ARM::R12,
11776 .addReg(ARM::CPSR,
11778 break;
11779 }
11780 }
11781
11782 BuildMI(*MBB, MI, DL, TII.get(ARM::t2SUBrr), ARM::SP)
11783 .addReg(ARM::SP, RegState::Kill)
11784 .addReg(ARM::R4, RegState::Kill)
11787 .add(condCodeOp());
11788
11789 MI.eraseFromParent();
11790 return MBB;
11791}
11792
11794ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
11795 MachineBasicBlock *MBB) const {
11796 DebugLoc DL = MI.getDebugLoc();
11797 MachineFunction *MF = MBB->getParent();
11798 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11799
11800 MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
11801 MF->insert(++MBB->getIterator(), ContBB);
11802 ContBB->splice(ContBB->begin(), MBB,
11803 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
11805 MBB->addSuccessor(ContBB);
11806
11807 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11808 BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
11809 MF->push_back(TrapBB);
11810 MBB->addSuccessor(TrapBB);
11811
11812 BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
11813 .addReg(MI.getOperand(0).getReg())
11814 .addImm(0)
11816 BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
11817 .addMBB(TrapBB)
11819 .addReg(ARM::CPSR);
11820
11821 MI.eraseFromParent();
11822 return ContBB;
11823}
11824
11825// The CPSR operand of SelectItr might be missing a kill marker
11826// because there were multiple uses of CPSR, and ISel didn't know
11827// which to mark. Figure out whether SelectItr should have had a
11828// kill marker, and set it if it should. Returns the correct kill
11829// marker value.
11832 const TargetRegisterInfo* TRI) {
11833 // Scan forward through BB for a use/def of CPSR.
11834 MachineBasicBlock::iterator miI(std::next(SelectItr));
11835 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
11836 const MachineInstr& mi = *miI;
11837 if (mi.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
11838 return false;
11839 if (mi.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
11840 break; // Should have kill-flag - update below.
11841 }
11842
11843 // If we hit the end of the block, check whether CPSR is live into a
11844 // successor.
11845 if (miI == BB->end()) {
11846 for (MachineBasicBlock *Succ : BB->successors())
11847 if (Succ->isLiveIn(ARM::CPSR))
11848 return false;
11849 }
11850
11851 // We found a def, or hit the end of the basic block and CPSR wasn't live
11852 // out. SelectMI should have a kill flag on CPSR.
11853 SelectItr->addRegisterKilled(ARM::CPSR, TRI);
11854 return true;
11855}
11856
11857/// Adds logic in loop entry MBB to calculate loop iteration count and adds
11858/// t2WhileLoopSetup and t2WhileLoopStart to generate WLS loop
11860 MachineBasicBlock *TpLoopBody,
11861 MachineBasicBlock *TpExit, Register OpSizeReg,
11862 const TargetInstrInfo *TII, DebugLoc Dl,
11863 MachineRegisterInfo &MRI) {
11864 // Calculates loop iteration count = ceil(n/16) = (n + 15) >> 4.
11865 Register AddDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11866 BuildMI(TpEntry, Dl, TII->get(ARM::t2ADDri), AddDestReg)
11867 .addUse(OpSizeReg)
11868 .addImm(15)
11870 .addReg(0);
11871
11872 Register LsrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11873 BuildMI(TpEntry, Dl, TII->get(ARM::t2LSRri), LsrDestReg)
11874 .addUse(AddDestReg, RegState::Kill)
11875 .addImm(4)
11877 .addReg(0);
11878
11879 Register TotalIterationsReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11880 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopSetup), TotalIterationsReg)
11881 .addUse(LsrDestReg, RegState::Kill);
11882
11883 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopStart))
11884 .addUse(TotalIterationsReg)
11885 .addMBB(TpExit);
11886
11887 BuildMI(TpEntry, Dl, TII->get(ARM::t2B))
11888 .addMBB(TpLoopBody)
11890
11891 return TotalIterationsReg;
11892}
11893
11894/// Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and
11895/// t2DoLoopEnd. These are used by later passes to generate tail predicated
11896/// loops.
11897static void genTPLoopBody(MachineBasicBlock *TpLoopBody,
11898 MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit,
11899 const TargetInstrInfo *TII, DebugLoc Dl,
11900 MachineRegisterInfo &MRI, Register OpSrcReg,
11901 Register OpDestReg, Register ElementCountReg,
11902 Register TotalIterationsReg, bool IsMemcpy) {
11903 // First insert 4 PHI nodes for: Current pointer to Src (if memcpy), Dest
11904 // array, loop iteration counter, predication counter.
11905
11906 Register SrcPhiReg, CurrSrcReg;
11907 if (IsMemcpy) {
11908 // Current position in the src array
11909 SrcPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11910 CurrSrcReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11911 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), SrcPhiReg)
11912 .addUse(OpSrcReg)
11913 .addMBB(TpEntry)
11914 .addUse(CurrSrcReg)
11915 .addMBB(TpLoopBody);
11916 }
11917
11918 // Current position in the dest array
11919 Register DestPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11920 Register CurrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11921 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), DestPhiReg)
11922 .addUse(OpDestReg)
11923 .addMBB(TpEntry)
11924 .addUse(CurrDestReg)
11925 .addMBB(TpLoopBody);
11926
11927 // Current loop counter
11928 Register LoopCounterPhiReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11929 Register RemainingLoopIterationsReg =
11930 MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11931 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), LoopCounterPhiReg)
11932 .addUse(TotalIterationsReg)
11933 .addMBB(TpEntry)
11934 .addUse(RemainingLoopIterationsReg)
11935 .addMBB(TpLoopBody);
11936
11937 // Predication counter
11938 Register PredCounterPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11939 Register RemainingElementsReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11940 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), PredCounterPhiReg)
11941 .addUse(ElementCountReg)
11942 .addMBB(TpEntry)
11943 .addUse(RemainingElementsReg)
11944 .addMBB(TpLoopBody);
11945
11946 // Pass predication counter to VCTP
11947 Register VccrReg = MRI.createVirtualRegister(&ARM::VCCRRegClass);
11948 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VCTP8), VccrReg)
11949 .addUse(PredCounterPhiReg)
11951 .addReg(0)
11952 .addReg(0);
11953
11954 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2SUBri), RemainingElementsReg)
11955 .addUse(PredCounterPhiReg)
11956 .addImm(16)
11958 .addReg(0);
11959
11960 // VLDRB (only if memcpy) and VSTRB instructions, predicated using VPR
11961 Register SrcValueReg;
11962 if (IsMemcpy) {
11963 SrcValueReg = MRI.createVirtualRegister(&ARM::MQPRRegClass);
11964 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VLDRBU8_post))
11965 .addDef(CurrSrcReg)
11966 .addDef(SrcValueReg)
11967 .addReg(SrcPhiReg)
11968 .addImm(16)
11970 .addUse(VccrReg)
11971 .addReg(0);
11972 } else
11973 SrcValueReg = OpSrcReg;
11974
11975 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VSTRBU8_post))
11976 .addDef(CurrDestReg)
11977 .addUse(SrcValueReg)
11978 .addReg(DestPhiReg)
11979 .addImm(16)
11981 .addUse(VccrReg)
11982 .addReg(0);
11983
11984 // Add the pseudoInstrs for decrementing the loop counter and marking the
11985 // end:t2DoLoopDec and t2DoLoopEnd
11986 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopDec), RemainingLoopIterationsReg)
11987 .addUse(LoopCounterPhiReg)
11988 .addImm(1);
11989
11990 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopEnd))
11991 .addUse(RemainingLoopIterationsReg)
11992 .addMBB(TpLoopBody);
11993
11994 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2B))
11995 .addMBB(TpExit)
11997}
11998
12000 // KCFI is supported in all ARM/Thumb modes
12001 return true;
12002}
12003
12007 const TargetInstrInfo *TII) const {
12008 assert(MBBI->isCall() && MBBI->getCFIType() &&
12009 "Invalid call instruction for a KCFI check");
12010
12011 MachineOperand *TargetOp = nullptr;
12012 switch (MBBI->getOpcode()) {
12013 // ARM mode opcodes
12014 case ARM::BLX:
12015 case ARM::BLX_pred:
12016 case ARM::BLX_noip:
12017 case ARM::BLX_pred_noip:
12018 case ARM::BX_CALL:
12019 TargetOp = &MBBI->getOperand(0);
12020 break;
12021 case ARM::TCRETURNri:
12022 case ARM::TCRETURNrinotr12:
12023 case ARM::TAILJMPr:
12024 case ARM::TAILJMPr4:
12025 TargetOp = &MBBI->getOperand(0);
12026 break;
12027 // Thumb mode opcodes (Thumb1 and Thumb2)
12028 // Note: Most Thumb call instructions have predicate operands before the
12029 // target register Format: tBLXr pred, predreg, target_register, ...
12030 case ARM::tBLXr: // Thumb1/Thumb2: BLX register (requires V5T)
12031 case ARM::tBLXr_noip: // Thumb1/Thumb2: BLX register, no IP clobber
12032 case ARM::tBX_CALL: // Thumb1 only: BX call (push LR, BX)
12033 TargetOp = &MBBI->getOperand(2);
12034 break;
12035 // Tail call instructions don't have predicates, target is operand 0
12036 case ARM::tTAILJMPr: // Thumb1/Thumb2: Tail call via register
12037 TargetOp = &MBBI->getOperand(0);
12038 break;
12039 default:
12040 llvm_unreachable("Unexpected CFI call opcode");
12041 }
12042
12043 assert(TargetOp && TargetOp->isReg() && "Invalid target operand");
12044 TargetOp->setIsRenamable(false);
12045
12046 // Select the appropriate KCFI_CHECK variant based on the instruction set
12047 unsigned KCFICheckOpcode;
12048 if (Subtarget->isThumb()) {
12049 if (Subtarget->isThumb2()) {
12050 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb2;
12051 } else {
12052 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb1;
12053 }
12054 } else {
12055 KCFICheckOpcode = ARM::KCFI_CHECK_ARM;
12056 }
12057
12058 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(KCFICheckOpcode))
12059 .addReg(TargetOp->getReg())
12060 .addImm(MBBI->getCFIType())
12061 .getInstr();
12062}
12063
12066 MachineBasicBlock *BB) const {
12067 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
12068 DebugLoc dl = MI.getDebugLoc();
12069 bool isThumb2 = Subtarget->isThumb2();
12070 switch (MI.getOpcode()) {
12071 default: {
12072 MI.print(errs());
12073 llvm_unreachable("Unexpected instr type to insert");
12074 }
12075
12076 // Thumb1 post-indexed loads are really just single-register LDMs.
12077 case ARM::tLDR_postidx: {
12078 MachineOperand Def(MI.getOperand(1));
12079 BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD))
12080 .add(Def) // Rn_wb
12081 .add(MI.getOperand(2)) // Rn
12082 .add(MI.getOperand(3)) // PredImm
12083 .add(MI.getOperand(4)) // PredReg
12084 .add(MI.getOperand(0)) // Rt
12085 .cloneMemRefs(MI);
12086 MI.eraseFromParent();
12087 return BB;
12088 }
12089
12090 case ARM::MVE_MEMCPYLOOPINST:
12091 case ARM::MVE_MEMSETLOOPINST: {
12092
12093 // Transformation below expands MVE_MEMCPYLOOPINST/MVE_MEMSETLOOPINST Pseudo
12094 // into a Tail Predicated (TP) Loop. It adds the instructions to calculate
12095 // the iteration count =ceil(size_in_bytes/16)) in the TP entry block and
12096 // adds the relevant instructions in the TP loop Body for generation of a
12097 // WLSTP loop.
12098
12099 // Below is relevant portion of the CFG after the transformation.
12100 // The Machine Basic Blocks are shown along with branch conditions (in
12101 // brackets). Note that TP entry/exit MBBs depict the entry/exit of this
12102 // portion of the CFG and may not necessarily be the entry/exit of the
12103 // function.
12104
12105 // (Relevant) CFG after transformation:
12106 // TP entry MBB
12107 // |
12108 // |-----------------|
12109 // (n <= 0) (n > 0)
12110 // | |
12111 // | TP loop Body MBB<--|
12112 // | | |
12113 // \ |___________|
12114 // \ /
12115 // TP exit MBB
12116
12117 MachineFunction *MF = BB->getParent();
12118 MachineFunctionProperties &Properties = MF->getProperties();
12119 MachineRegisterInfo &MRI = MF->getRegInfo();
12120
12121 Register OpDestReg = MI.getOperand(0).getReg();
12122 Register OpSrcReg = MI.getOperand(1).getReg();
12123 Register OpSizeReg = MI.getOperand(2).getReg();
12124
12125 // Allocate the required MBBs and add to parent function.
12126 MachineBasicBlock *TpEntry = BB;
12127 MachineBasicBlock *TpLoopBody = MF->CreateMachineBasicBlock();
12128 MachineBasicBlock *TpExit;
12129
12130 MF->push_back(TpLoopBody);
12131
12132 // If any instructions are present in the current block after
12133 // MVE_MEMCPYLOOPINST or MVE_MEMSETLOOPINST, split the current block and
12134 // move the instructions into the newly created exit block. If there are no
12135 // instructions add an explicit branch to the FallThrough block and then
12136 // split.
12137 //
12138 // The split is required for two reasons:
12139 // 1) A terminator(t2WhileLoopStart) will be placed at that site.
12140 // 2) Since a TPLoopBody will be added later, any phis in successive blocks
12141 // need to be updated. splitAt() already handles this.
12142 TpExit = BB->splitAt(MI, false);
12143 if (TpExit == BB) {
12144 assert(BB->canFallThrough() && "Exit Block must be Fallthrough of the "
12145 "block containing memcpy/memset Pseudo");
12146 TpExit = BB->getFallThrough();
12147 BuildMI(BB, dl, TII->get(ARM::t2B))
12148 .addMBB(TpExit)
12150 TpExit = BB->splitAt(MI, false);
12151 }
12152
12153 // Add logic for iteration count
12154 Register TotalIterationsReg =
12155 genTPEntry(TpEntry, TpLoopBody, TpExit, OpSizeReg, TII, dl, MRI);
12156
12157 // Add the vectorized (and predicated) loads/store instructions
12158 bool IsMemcpy = MI.getOpcode() == ARM::MVE_MEMCPYLOOPINST;
12159 genTPLoopBody(TpLoopBody, TpEntry, TpExit, TII, dl, MRI, OpSrcReg,
12160 OpDestReg, OpSizeReg, TotalIterationsReg, IsMemcpy);
12161
12162 // Required to avoid conflict with the MachineVerifier during testing.
12163 Properties.resetNoPHIs();
12164
12165 // Connect the blocks
12166 TpEntry->addSuccessor(TpLoopBody);
12167 TpLoopBody->addSuccessor(TpLoopBody);
12168 TpLoopBody->addSuccessor(TpExit);
12169
12170 // Reorder for a more natural layout
12171 TpLoopBody->moveAfter(TpEntry);
12172 TpExit->moveAfter(TpLoopBody);
12173
12174 // Finally, remove the memcpy Pseudo Instruction
12175 MI.eraseFromParent();
12176
12177 // Return the exit block as it may contain other instructions requiring a
12178 // custom inserter
12179 return TpExit;
12180 }
12181
12182 // The Thumb2 pre-indexed stores have the same MI operands, they just
12183 // define them differently in the .td files from the isel patterns, so
12184 // they need pseudos.
12185 case ARM::t2STR_preidx:
12186 MI.setDesc(TII->get(ARM::t2STR_PRE));
12187 return BB;
12188 case ARM::t2STRB_preidx:
12189 MI.setDesc(TII->get(ARM::t2STRB_PRE));
12190 return BB;
12191 case ARM::t2STRH_preidx:
12192 MI.setDesc(TII->get(ARM::t2STRH_PRE));
12193 return BB;
12194
12195 case ARM::STRi_preidx:
12196 case ARM::STRBi_preidx: {
12197 unsigned NewOpc = MI.getOpcode() == ARM::STRi_preidx ? ARM::STR_PRE_IMM
12198 : ARM::STRB_PRE_IMM;
12199 // Decode the offset.
12200 unsigned Offset = MI.getOperand(4).getImm();
12201 bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub;
12203 if (isSub)
12204 Offset = -Offset;
12205
12206 MachineMemOperand *MMO = *MI.memoperands_begin();
12207 BuildMI(*BB, MI, dl, TII->get(NewOpc))
12208 .add(MI.getOperand(0)) // Rn_wb
12209 .add(MI.getOperand(1)) // Rt
12210 .add(MI.getOperand(2)) // Rn
12211 .addImm(Offset) // offset (skip GPR==zero_reg)
12212 .add(MI.getOperand(5)) // pred
12213 .add(MI.getOperand(6))
12214 .addMemOperand(MMO);
12215 MI.eraseFromParent();
12216 return BB;
12217 }
12218 case ARM::STRr_preidx:
12219 case ARM::STRBr_preidx:
12220 case ARM::STRH_preidx: {
12221 unsigned NewOpc;
12222 switch (MI.getOpcode()) {
12223 default: llvm_unreachable("unexpected opcode!");
12224 case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break;
12225 case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break;
12226 case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break;
12227 }
12228 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc));
12229 for (const MachineOperand &MO : MI.operands())
12230 MIB.add(MO);
12231 MI.eraseFromParent();
12232 return BB;
12233 }
12234
12235 case ARM::tMOVCCr_pseudo: {
12236 // To "insert" a SELECT_CC instruction, we actually have to insert the
12237 // diamond control-flow pattern. The incoming instruction knows the
12238 // destination vreg to set, the condition code register to branch on, the
12239 // true/false values to select between, and a branch opcode to use.
12240 const BasicBlock *LLVM_BB = BB->getBasicBlock();
12242
12243 // thisMBB:
12244 // ...
12245 // TrueVal = ...
12246 // cmpTY ccX, r1, r2
12247 // bCC copy1MBB
12248 // fallthrough --> copy0MBB
12249 MachineBasicBlock *thisMBB = BB;
12250 MachineFunction *F = BB->getParent();
12251 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12252 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
12253 F->insert(It, copy0MBB);
12254 F->insert(It, sinkMBB);
12255
12256 // Set the call frame size on entry to the new basic blocks.
12257 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12258 copy0MBB->setCallFrameSize(CallFrameSize);
12259 sinkMBB->setCallFrameSize(CallFrameSize);
12260
12261 // Check whether CPSR is live past the tMOVCCr_pseudo.
12262 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
12263 if (!MI.killsRegister(ARM::CPSR, /*TRI=*/nullptr) &&
12264 !checkAndUpdateCPSRKill(MI, thisMBB, TRI)) {
12265 copy0MBB->addLiveIn(ARM::CPSR);
12266 sinkMBB->addLiveIn(ARM::CPSR);
12267 }
12268
12269 // Transfer the remainder of BB and its successor edges to sinkMBB.
12270 sinkMBB->splice(sinkMBB->begin(), BB,
12271 std::next(MachineBasicBlock::iterator(MI)), BB->end());
12273
12274 BB->addSuccessor(copy0MBB);
12275 BB->addSuccessor(sinkMBB);
12276
12277 BuildMI(BB, dl, TII->get(ARM::tBcc))
12278 .addMBB(sinkMBB)
12279 .addImm(MI.getOperand(3).getImm())
12280 .addReg(MI.getOperand(4).getReg());
12281
12282 // copy0MBB:
12283 // %FalseValue = ...
12284 // # fallthrough to sinkMBB
12285 BB = copy0MBB;
12286
12287 // Update machine-CFG edges
12288 BB->addSuccessor(sinkMBB);
12289
12290 // sinkMBB:
12291 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12292 // ...
12293 BB = sinkMBB;
12294 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), MI.getOperand(0).getReg())
12295 .addReg(MI.getOperand(1).getReg())
12296 .addMBB(copy0MBB)
12297 .addReg(MI.getOperand(2).getReg())
12298 .addMBB(thisMBB);
12299
12300 MI.eraseFromParent(); // The pseudo instruction is gone now.
12301 return BB;
12302 }
12303
12304 case ARM::BCCi64:
12305 case ARM::BCCZi64: {
12306 // If there is an unconditional branch to the other successor, remove it.
12307 BB->erase(std::next(MachineBasicBlock::iterator(MI)), BB->end());
12308
12309 // Compare both parts that make up the double comparison separately for
12310 // equality.
12311 bool RHSisZero = MI.getOpcode() == ARM::BCCZi64;
12312
12313 Register LHS1 = MI.getOperand(1).getReg();
12314 Register LHS2 = MI.getOperand(2).getReg();
12315 if (RHSisZero) {
12316 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12317 .addReg(LHS1)
12318 .addImm(0)
12320 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12321 .addReg(LHS2).addImm(0)
12322 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12323 } else {
12324 Register RHS1 = MI.getOperand(3).getReg();
12325 Register RHS2 = MI.getOperand(4).getReg();
12326 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12327 .addReg(LHS1)
12328 .addReg(RHS1)
12330 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12331 .addReg(LHS2).addReg(RHS2)
12332 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12333 }
12334
12335 MachineBasicBlock *destMBB = MI.getOperand(RHSisZero ? 3 : 5).getMBB();
12336 MachineBasicBlock *exitMBB = OtherSucc(BB, destMBB);
12337 if (MI.getOperand(0).getImm() == ARMCC::NE)
12338 std::swap(destMBB, exitMBB);
12339
12340 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))
12341 .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
12342 if (isThumb2)
12343 BuildMI(BB, dl, TII->get(ARM::t2B))
12344 .addMBB(exitMBB)
12346 else
12347 BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);
12348
12349 MI.eraseFromParent(); // The pseudo instruction is gone now.
12350 return BB;
12351 }
12352
12353 case ARM::Int_eh_sjlj_setjmp:
12354 case ARM::Int_eh_sjlj_setjmp_nofp:
12355 case ARM::tInt_eh_sjlj_setjmp:
12356 case ARM::t2Int_eh_sjlj_setjmp:
12357 case ARM::t2Int_eh_sjlj_setjmp_nofp:
12358 return BB;
12359
12360 case ARM::Int_eh_sjlj_setup_dispatch:
12361 EmitSjLjDispatchBlock(MI, BB);
12362 return BB;
12363 case ARM::COPY_STRUCT_BYVAL_I32:
12364 ++NumLoopByVals;
12365 return EmitStructByval(MI, BB);
12366 case ARM::WIN__CHKSTK:
12367 return EmitLowered__chkstk(MI, BB);
12368 case ARM::WIN__DBZCHK:
12369 return EmitLowered__dbzchk(MI, BB);
12370 }
12371}
12372
12373/// Attaches vregs to MEMCPY that it will use as scratch registers
12374/// when it is expanded into LDM/STM. This is done as a post-isel lowering
12375/// instead of as a custom inserter because we need the use list from the SDNode.
12376static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget,
12377 MachineInstr &MI, const SDNode *Node) {
12378 bool isThumb1 = Subtarget->isThumb1Only();
12379
12380 MachineFunction *MF = MI.getParent()->getParent();
12381 MachineRegisterInfo &MRI = MF->getRegInfo();
12382 MachineInstrBuilder MIB(*MF, MI);
12383
12384 // If the new dst/src is unused mark it as dead.
12385 if (!Node->hasAnyUseOfValue(0)) {
12386 MI.getOperand(0).setIsDead(true);
12387 }
12388 if (!Node->hasAnyUseOfValue(1)) {
12389 MI.getOperand(1).setIsDead(true);
12390 }
12391
12392 // The MEMCPY both defines and kills the scratch registers.
12393 for (unsigned I = 0; I != MI.getOperand(4).getImm(); ++I) {
12394 Register TmpReg = MRI.createVirtualRegister(isThumb1 ? &ARM::tGPRRegClass
12395 : &ARM::GPRRegClass);
12397 }
12398}
12399
12401 SDNode *Node) const {
12402 if (MI.getOpcode() == ARM::MEMCPY) {
12403 attachMEMCPYScratchRegs(Subtarget, MI, Node);
12404 return;
12405 }
12406
12407 const MCInstrDesc *MCID = &MI.getDesc();
12408 // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB,
12409 // RSC. Coming out of isel, they have an implicit CPSR def, but the optional
12410 // operand is still set to noreg. If needed, set the optional operand's
12411 // register to CPSR, and remove the redundant implicit def.
12412 //
12413 // e.g. ADCS (..., implicit-def CPSR) -> ADC (... opt:def CPSR).
12414
12415 // Rename pseudo opcodes.
12416 unsigned NewOpc = convertAddSubFlagsOpcode(MI.getOpcode());
12417 unsigned ccOutIdx;
12418 if (NewOpc) {
12419 const ARMBaseInstrInfo *TII = Subtarget->getInstrInfo();
12420 MCID = &TII->get(NewOpc);
12421
12422 assert(MCID->getNumOperands() ==
12423 MI.getDesc().getNumOperands() + 5 - MI.getDesc().getSize()
12424 && "converted opcode should be the same except for cc_out"
12425 " (and, on Thumb1, pred)");
12426
12427 MI.setDesc(*MCID);
12428
12429 // Add the optional cc_out operand
12430 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
12431
12432 // On Thumb1, move all input operands to the end, then add the predicate
12433 if (Subtarget->isThumb1Only()) {
12434 for (unsigned c = MCID->getNumOperands() - 4; c--;) {
12435 MI.addOperand(MI.getOperand(1));
12436 MI.removeOperand(1);
12437 }
12438
12439 // Restore the ties
12440 for (unsigned i = MI.getNumOperands(); i--;) {
12441 const MachineOperand& op = MI.getOperand(i);
12442 if (op.isReg() && op.isUse()) {
12443 int DefIdx = MCID->getOperandConstraint(i, MCOI::TIED_TO);
12444 if (DefIdx != -1)
12445 MI.tieOperands(DefIdx, i);
12446 }
12447 }
12448
12450 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/false));
12451 ccOutIdx = 1;
12452 } else
12453 ccOutIdx = MCID->getNumOperands() - 1;
12454 } else
12455 ccOutIdx = MCID->getNumOperands() - 1;
12456
12457 // Any ARM instruction that sets the 's' bit should specify an optional
12458 // "cc_out" operand in the last operand position.
12459 if (!MI.hasOptionalDef() || !MCID->operands()[ccOutIdx].isOptionalDef()) {
12460 assert(!NewOpc && "Optional cc_out operand required");
12461 return;
12462 }
12463 // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it
12464 // since we already have an optional CPSR def.
12465 bool definesCPSR = false;
12466 bool deadCPSR = false;
12467 for (unsigned i = MCID->getNumOperands(), e = MI.getNumOperands(); i != e;
12468 ++i) {
12469 const MachineOperand &MO = MI.getOperand(i);
12470 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
12471 definesCPSR = true;
12472 if (MO.isDead())
12473 deadCPSR = true;
12474 MI.removeOperand(i);
12475 break;
12476 }
12477 }
12478 if (!definesCPSR) {
12479 assert(!NewOpc && "Optional cc_out operand required");
12480 return;
12481 }
12482 assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag");
12483 if (deadCPSR) {
12484 assert(!MI.getOperand(ccOutIdx).getReg() &&
12485 "expect uninitialized optional cc_out operand");
12486 // Thumb1 instructions must have the S bit even if the CPSR is dead.
12487 if (!Subtarget->isThumb1Only())
12488 return;
12489 }
12490
12491 // If this instruction was defined with an optional CPSR def and its dag node
12492 // had a live implicit CPSR def, then activate the optional CPSR def.
12493 MachineOperand &MO = MI.getOperand(ccOutIdx);
12494 MO.setReg(ARM::CPSR);
12495 MO.setIsDef(true);
12496}
12497
12498//===----------------------------------------------------------------------===//
12499// ARM Optimization Hooks
12500//===----------------------------------------------------------------------===//
12501
12502// Helper function that checks if N is a null or all ones constant.
12503static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
12505}
12506
12507// Return true if N is conditionally 0 or all ones.
12508// Detects these expressions where cc is an i1 value:
12509//
12510// (select cc 0, y) [AllOnes=0]
12511// (select cc y, 0) [AllOnes=0]
12512// (zext cc) [AllOnes=0]
12513// (sext cc) [AllOnes=0/1]
12514// (select cc -1, y) [AllOnes=1]
12515// (select cc y, -1) [AllOnes=1]
12516//
12517// Invert is set when N is the null/all ones constant when CC is false.
12518// OtherOp is set to the alternative value of N.
12520 SDValue &CC, bool &Invert,
12521 SDValue &OtherOp,
12522 SelectionDAG &DAG) {
12523 switch (N->getOpcode()) {
12524 default: return false;
12525 case ISD::SELECT: {
12526 CC = N->getOperand(0);
12527 SDValue N1 = N->getOperand(1);
12528 SDValue N2 = N->getOperand(2);
12529 if (isZeroOrAllOnes(N1, AllOnes)) {
12530 Invert = false;
12531 OtherOp = N2;
12532 return true;
12533 }
12534 if (isZeroOrAllOnes(N2, AllOnes)) {
12535 Invert = true;
12536 OtherOp = N1;
12537 return true;
12538 }
12539 return false;
12540 }
12541 case ISD::ZERO_EXTEND:
12542 // (zext cc) can never be the all ones value.
12543 if (AllOnes)
12544 return false;
12545 [[fallthrough]];
12546 case ISD::SIGN_EXTEND: {
12547 SDLoc dl(N);
12548 EVT VT = N->getValueType(0);
12549 CC = N->getOperand(0);
12550 if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC)
12551 return false;
12552 Invert = !AllOnes;
12553 if (AllOnes)
12554 // When looking for an AllOnes constant, N is an sext, and the 'other'
12555 // value is 0.
12556 OtherOp = DAG.getConstant(0, dl, VT);
12557 else if (N->getOpcode() == ISD::ZERO_EXTEND)
12558 // When looking for a 0 constant, N can be zext or sext.
12559 OtherOp = DAG.getConstant(1, dl, VT);
12560 else
12561 OtherOp = DAG.getAllOnesConstant(dl, VT);
12562 return true;
12563 }
12564 }
12565}
12566
12567// Combine a constant select operand into its use:
12568//
12569// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
12570// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
12571// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
12572// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
12573// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
12574//
12575// The transform is rejected if the select doesn't have a constant operand that
12576// is null, or all ones when AllOnes is set.
12577//
12578// Also recognize sext/zext from i1:
12579//
12580// (add (zext cc), x) -> (select cc (add x, 1), x)
12581// (add (sext cc), x) -> (select cc (add x, -1), x)
12582//
12583// These transformations eventually create predicated instructions.
12584//
12585// @param N The node to transform.
12586// @param Slct The N operand that is a select.
12587// @param OtherOp The other N operand (x above).
12588// @param DCI Context.
12589// @param AllOnes Require the select constant to be all ones instead of null.
12590// @returns The new node, or SDValue() on failure.
12591static
12594 bool AllOnes = false) {
12595 SelectionDAG &DAG = DCI.DAG;
12596 EVT VT = N->getValueType(0);
12597 SDValue NonConstantVal;
12598 SDValue CCOp;
12599 bool SwapSelectOps;
12600 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
12601 NonConstantVal, DAG))
12602 return SDValue();
12603
12604 // Slct is now know to be the desired identity constant when CC is true.
12605 SDValue TrueVal = OtherOp;
12606 SDValue FalseVal = DAG.getNode(N->getOpcode(), SDLoc(N), VT,
12607 OtherOp, NonConstantVal);
12608 // Unless SwapSelectOps says CC should be false.
12609 if (SwapSelectOps)
12610 std::swap(TrueVal, FalseVal);
12611
12612 return DAG.getNode(ISD::SELECT, SDLoc(N), VT,
12613 CCOp, TrueVal, FalseVal);
12614}
12615
12616// Attempt combineSelectAndUse on each operand of a commutative operator N.
12617static
12620 SDValue N0 = N->getOperand(0);
12621 SDValue N1 = N->getOperand(1);
12622 if (N0.getNode()->hasOneUse())
12623 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
12624 return Result;
12625 if (N1.getNode()->hasOneUse())
12626 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
12627 return Result;
12628 return SDValue();
12629}
12630
12632 // VUZP shuffle node.
12633 if (N->getOpcode() == ARMISD::VUZP)
12634 return true;
12635
12636 // "VUZP" on i32 is an alias for VTRN.
12637 if (N->getOpcode() == ARMISD::VTRN && N->getValueType(0) == MVT::v2i32)
12638 return true;
12639
12640 return false;
12641}
12642
12645 const ARMSubtarget *Subtarget) {
12646 // Look for ADD(VUZP.0, VUZP.1).
12647 if (!IsVUZPShuffleNode(N0.getNode()) || N0.getNode() != N1.getNode() ||
12648 N0 == N1)
12649 return SDValue();
12650
12651 // Make sure the ADD is a 64-bit add; there is no 128-bit VPADD.
12652 if (!N->getValueType(0).is64BitVector())
12653 return SDValue();
12654
12655 // Generate vpadd.
12656 SelectionDAG &DAG = DCI.DAG;
12657 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12658 SDLoc dl(N);
12659 SDNode *Unzip = N0.getNode();
12660 EVT VT = N->getValueType(0);
12661
12663 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpadd, dl,
12664 TLI.getPointerTy(DAG.getDataLayout())));
12665 Ops.push_back(Unzip->getOperand(0));
12666 Ops.push_back(Unzip->getOperand(1));
12667
12668 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12669}
12670
12673 const ARMSubtarget *Subtarget) {
12674 // Check for two extended operands.
12675 if (!(N0.getOpcode() == ISD::SIGN_EXTEND &&
12676 N1.getOpcode() == ISD::SIGN_EXTEND) &&
12677 !(N0.getOpcode() == ISD::ZERO_EXTEND &&
12678 N1.getOpcode() == ISD::ZERO_EXTEND))
12679 return SDValue();
12680
12681 SDValue N00 = N0.getOperand(0);
12682 SDValue N10 = N1.getOperand(0);
12683
12684 // Look for ADD(SEXT(VUZP.0), SEXT(VUZP.1))
12685 if (!IsVUZPShuffleNode(N00.getNode()) || N00.getNode() != N10.getNode() ||
12686 N00 == N10)
12687 return SDValue();
12688
12689 // We only recognize Q register paddl here; this can't be reached until
12690 // after type legalization.
12691 if (!N00.getValueType().is64BitVector() ||
12693 return SDValue();
12694
12695 // Generate vpaddl.
12696 SelectionDAG &DAG = DCI.DAG;
12697 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12698 SDLoc dl(N);
12699 EVT VT = N->getValueType(0);
12700
12702 // Form vpaddl.sN or vpaddl.uN depending on the kind of extension.
12703 unsigned Opcode;
12704 if (N0.getOpcode() == ISD::SIGN_EXTEND)
12705 Opcode = Intrinsic::arm_neon_vpaddls;
12706 else
12707 Opcode = Intrinsic::arm_neon_vpaddlu;
12708 Ops.push_back(DAG.getConstant(Opcode, dl,
12709 TLI.getPointerTy(DAG.getDataLayout())));
12710 EVT ElemTy = N00.getValueType().getVectorElementType();
12711 unsigned NumElts = VT.getVectorNumElements();
12712 EVT ConcatVT = EVT::getVectorVT(*DAG.getContext(), ElemTy, NumElts * 2);
12713 SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), ConcatVT,
12714 N00.getOperand(0), N00.getOperand(1));
12715 Ops.push_back(Concat);
12716
12717 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12718}
12719
12720// FIXME: This function shouldn't be necessary; if we lower BUILD_VECTOR in
12721// an appropriate manner, we end up with ADD(VUZP(ZEXT(N))), which is
12722// much easier to match.
12723static SDValue
12726 const ARMSubtarget *Subtarget) {
12727 // Only perform optimization if after legalize, and if NEON is available. We
12728 // also expected both operands to be BUILD_VECTORs.
12729 if (DCI.isBeforeLegalize() || !Subtarget->hasNEON()
12730 || N0.getOpcode() != ISD::BUILD_VECTOR
12731 || N1.getOpcode() != ISD::BUILD_VECTOR)
12732 return SDValue();
12733
12734 // Check output type since VPADDL operand elements can only be 8, 16, or 32.
12735 EVT VT = N->getValueType(0);
12736 if (!VT.isInteger() || VT.getVectorElementType() == MVT::i64)
12737 return SDValue();
12738
12739 // Check that the vector operands are of the right form.
12740 // N0 and N1 are BUILD_VECTOR nodes with N number of EXTRACT_VECTOR
12741 // operands, where N is the size of the formed vector.
12742 // Each EXTRACT_VECTOR should have the same input vector and odd or even
12743 // index such that we have a pair wise add pattern.
12744
12745 // Grab the vector that all EXTRACT_VECTOR nodes should be referencing.
12747 return SDValue();
12748 SDValue Vec = N0->getOperand(0)->getOperand(0);
12749 SDNode *V = Vec.getNode();
12750 unsigned nextIndex = 0;
12751
12752 // For each operands to the ADD which are BUILD_VECTORs,
12753 // check to see if each of their operands are an EXTRACT_VECTOR with
12754 // the same vector and appropriate index.
12755 for (unsigned i = 0, e = N0->getNumOperands(); i != e; ++i) {
12758
12759 SDValue ExtVec0 = N0->getOperand(i);
12760 SDValue ExtVec1 = N1->getOperand(i);
12761
12762 // First operand is the vector, verify its the same.
12763 if (V != ExtVec0->getOperand(0).getNode() ||
12764 V != ExtVec1->getOperand(0).getNode())
12765 return SDValue();
12766
12767 // Second is the constant, verify its correct.
12770
12771 // For the constant, we want to see all the even or all the odd.
12772 if (!C0 || !C1 || C0->getZExtValue() != nextIndex
12773 || C1->getZExtValue() != nextIndex+1)
12774 return SDValue();
12775
12776 // Increment index.
12777 nextIndex+=2;
12778 } else
12779 return SDValue();
12780 }
12781
12782 // Don't generate vpaddl+vmovn; we'll match it to vpadd later. Also make sure
12783 // we're using the entire input vector, otherwise there's a size/legality
12784 // mismatch somewhere.
12785 if (nextIndex != Vec.getValueType().getVectorNumElements() ||
12787 return SDValue();
12788
12789 // Create VPADDL node.
12790 SelectionDAG &DAG = DCI.DAG;
12791 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12792
12793 SDLoc dl(N);
12794
12795 // Build operand list.
12797 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddls, dl,
12798 TLI.getPointerTy(DAG.getDataLayout())));
12799
12800 // Input is the vector.
12801 Ops.push_back(Vec);
12802
12803 // Get widened type and narrowed type.
12804 MVT widenType;
12805 unsigned numElem = VT.getVectorNumElements();
12806
12807 EVT inputLaneType = Vec.getValueType().getVectorElementType();
12808 switch (inputLaneType.getSimpleVT().SimpleTy) {
12809 case MVT::i8: widenType = MVT::getVectorVT(MVT::i16, numElem); break;
12810 case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break;
12811 case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break;
12812 default:
12813 llvm_unreachable("Invalid vector element type for padd optimization.");
12814 }
12815
12816 SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, widenType, Ops);
12817 unsigned ExtOp = VT.bitsGT(tmp.getValueType()) ? ISD::ANY_EXTEND : ISD::TRUNCATE;
12818 return DAG.getNode(ExtOp, dl, VT, tmp);
12819}
12820
12822 if (V->getOpcode() == ISD::UMUL_LOHI ||
12823 V->getOpcode() == ISD::SMUL_LOHI)
12824 return V;
12825 return SDValue();
12826}
12827
12828static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode,
12830 const ARMSubtarget *Subtarget) {
12831 if (!Subtarget->hasBaseDSP())
12832 return SDValue();
12833
12834 // SMLALBB, SMLALBT, SMLALTB, SMLALTT multiply two 16-bit values and
12835 // accumulates the product into a 64-bit value. The 16-bit values will
12836 // be sign extended somehow or SRA'd into 32-bit values
12837 // (addc (adde (mul 16bit, 16bit), lo), hi)
12838 SDValue Mul = AddcNode->getOperand(0);
12839 SDValue Lo = AddcNode->getOperand(1);
12840 if (Mul.getOpcode() != ISD::MUL) {
12841 Lo = AddcNode->getOperand(0);
12842 Mul = AddcNode->getOperand(1);
12843 if (Mul.getOpcode() != ISD::MUL)
12844 return SDValue();
12845 }
12846
12847 SDValue SRA = AddeNode->getOperand(0);
12848 SDValue Hi = AddeNode->getOperand(1);
12849 if (SRA.getOpcode() != ISD::SRA) {
12850 SRA = AddeNode->getOperand(1);
12851 Hi = AddeNode->getOperand(0);
12852 if (SRA.getOpcode() != ISD::SRA)
12853 return SDValue();
12854 }
12855 if (auto Const = dyn_cast<ConstantSDNode>(SRA.getOperand(1))) {
12856 if (Const->getZExtValue() != 31)
12857 return SDValue();
12858 } else
12859 return SDValue();
12860
12861 if (SRA.getOperand(0) != Mul)
12862 return SDValue();
12863
12864 SelectionDAG &DAG = DCI.DAG;
12865 SDLoc dl(AddcNode);
12866 unsigned Opcode = 0;
12867 SDValue Op0;
12868 SDValue Op1;
12869
12870 if (isS16(Mul.getOperand(0), DAG) && isS16(Mul.getOperand(1), DAG)) {
12871 Opcode = ARMISD::SMLALBB;
12872 Op0 = Mul.getOperand(0);
12873 Op1 = Mul.getOperand(1);
12874 } else if (isS16(Mul.getOperand(0), DAG) && isSRA16(Mul.getOperand(1))) {
12875 Opcode = ARMISD::SMLALBT;
12876 Op0 = Mul.getOperand(0);
12877 Op1 = Mul.getOperand(1).getOperand(0);
12878 } else if (isSRA16(Mul.getOperand(0)) && isS16(Mul.getOperand(1), DAG)) {
12879 Opcode = ARMISD::SMLALTB;
12880 Op0 = Mul.getOperand(0).getOperand(0);
12881 Op1 = Mul.getOperand(1);
12882 } else if (isSRA16(Mul.getOperand(0)) && isSRA16(Mul.getOperand(1))) {
12883 Opcode = ARMISD::SMLALTT;
12884 Op0 = Mul->getOperand(0).getOperand(0);
12885 Op1 = Mul->getOperand(1).getOperand(0);
12886 }
12887
12888 if (!Op0 || !Op1)
12889 return SDValue();
12890
12891 SDValue SMLAL = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
12892 Op0, Op1, Lo, Hi);
12893 // Replace the ADDs' nodes uses by the MLA node's values.
12894 SDValue HiMLALResult(SMLAL.getNode(), 1);
12895 SDValue LoMLALResult(SMLAL.getNode(), 0);
12896
12897 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult);
12898 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult);
12899
12900 // Return original node to notify the driver to stop replacing.
12901 SDValue resNode(AddcNode, 0);
12902 return resNode;
12903}
12904
12907 const ARMSubtarget *Subtarget) {
12908 // Look for multiply add opportunities.
12909 // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where
12910 // each add nodes consumes a value from ISD::UMUL_LOHI and there is
12911 // a glue link from the first add to the second add.
12912 // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by
12913 // a S/UMLAL instruction.
12914 // UMUL_LOHI
12915 // / :lo \ :hi
12916 // V \ [no multiline comment]
12917 // loAdd -> ADDC |
12918 // \ :carry /
12919 // V V
12920 // ADDE <- hiAdd
12921 //
12922 // In the special case where only the higher part of a signed result is used
12923 // and the add to the low part of the result of ISD::UMUL_LOHI adds or subtracts
12924 // a constant with the exact value of 0x80000000, we recognize we are dealing
12925 // with a "rounded multiply and add" (or subtract) and transform it into
12926 // either a ARMISD::SMMLAR or ARMISD::SMMLSR respectively.
12927
12928 assert((AddeSubeNode->getOpcode() == ARMISD::ADDE ||
12929 AddeSubeNode->getOpcode() == ARMISD::SUBE) &&
12930 "Expect an ADDE or SUBE");
12931
12932 assert(AddeSubeNode->getNumOperands() == 3 &&
12933 AddeSubeNode->getOperand(2).getValueType() == MVT::i32 &&
12934 "ADDE node has the wrong inputs");
12935
12936 // Check that we are chained to the right ADDC or SUBC node.
12937 SDNode *AddcSubcNode = AddeSubeNode->getOperand(2).getNode();
12938 if ((AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12939 AddcSubcNode->getOpcode() != ARMISD::ADDC) ||
12940 (AddeSubeNode->getOpcode() == ARMISD::SUBE &&
12941 AddcSubcNode->getOpcode() != ARMISD::SUBC))
12942 return SDValue();
12943
12944 SDValue AddcSubcOp0 = AddcSubcNode->getOperand(0);
12945 SDValue AddcSubcOp1 = AddcSubcNode->getOperand(1);
12946
12947 // Check if the two operands are from the same mul_lohi node.
12948 if (AddcSubcOp0.getNode() == AddcSubcOp1.getNode())
12949 return SDValue();
12950
12951 assert(AddcSubcNode->getNumValues() == 2 &&
12952 AddcSubcNode->getValueType(0) == MVT::i32 &&
12953 "Expect ADDC with two result values. First: i32");
12954
12955 // Check that the ADDC adds the low result of the S/UMUL_LOHI. If not, it
12956 // maybe a SMLAL which multiplies two 16-bit values.
12957 if (AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12958 AddcSubcOp0->getOpcode() != ISD::UMUL_LOHI &&
12959 AddcSubcOp0->getOpcode() != ISD::SMUL_LOHI &&
12960 AddcSubcOp1->getOpcode() != ISD::UMUL_LOHI &&
12961 AddcSubcOp1->getOpcode() != ISD::SMUL_LOHI)
12962 return AddCombineTo64BitSMLAL16(AddcSubcNode, AddeSubeNode, DCI, Subtarget);
12963
12964 // Check for the triangle shape.
12965 SDValue AddeSubeOp0 = AddeSubeNode->getOperand(0);
12966 SDValue AddeSubeOp1 = AddeSubeNode->getOperand(1);
12967
12968 // Make sure that the ADDE/SUBE operands are not coming from the same node.
12969 if (AddeSubeOp0.getNode() == AddeSubeOp1.getNode())
12970 return SDValue();
12971
12972 // Find the MUL_LOHI node walking up ADDE/SUBE's operands.
12973 bool IsLeftOperandMUL = false;
12974 SDValue MULOp = findMUL_LOHI(AddeSubeOp0);
12975 if (MULOp == SDValue())
12976 MULOp = findMUL_LOHI(AddeSubeOp1);
12977 else
12978 IsLeftOperandMUL = true;
12979 if (MULOp == SDValue())
12980 return SDValue();
12981
12982 // Figure out the right opcode.
12983 unsigned Opc = MULOp->getOpcode();
12984 unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
12985
12986 // Figure out the high and low input values to the MLAL node.
12987 SDValue *HiAddSub = nullptr;
12988 SDValue *LoMul = nullptr;
12989 SDValue *LowAddSub = nullptr;
12990
12991 // Ensure that ADDE/SUBE is from high result of ISD::xMUL_LOHI.
12992 if ((AddeSubeOp0 != MULOp.getValue(1)) && (AddeSubeOp1 != MULOp.getValue(1)))
12993 return SDValue();
12994
12995 if (IsLeftOperandMUL)
12996 HiAddSub = &AddeSubeOp1;
12997 else
12998 HiAddSub = &AddeSubeOp0;
12999
13000 // Ensure that LoMul and LowAddSub are taken from correct ISD::SMUL_LOHI node
13001 // whose low result is fed to the ADDC/SUBC we are checking.
13002
13003 if (AddcSubcOp0 == MULOp.getValue(0)) {
13004 LoMul = &AddcSubcOp0;
13005 LowAddSub = &AddcSubcOp1;
13006 }
13007 if (AddcSubcOp1 == MULOp.getValue(0)) {
13008 LoMul = &AddcSubcOp1;
13009 LowAddSub = &AddcSubcOp0;
13010 }
13011
13012 if (!LoMul)
13013 return SDValue();
13014
13015 // If HiAddSub is the same node as ADDC/SUBC or is a predecessor of ADDC/SUBC
13016 // the replacement below will create a cycle.
13017 if (AddcSubcNode == HiAddSub->getNode() ||
13018 AddcSubcNode->isPredecessorOf(HiAddSub->getNode()))
13019 return SDValue();
13020
13021 // Create the merged node.
13022 SelectionDAG &DAG = DCI.DAG;
13023
13024 // Start building operand list.
13026 Ops.push_back(LoMul->getOperand(0));
13027 Ops.push_back(LoMul->getOperand(1));
13028
13029 // Check whether we can use SMMLAR, SMMLSR or SMMULR instead. For this to be
13030 // the case, we must be doing signed multiplication and only use the higher
13031 // part of the result of the MLAL, furthermore the LowAddSub must be a constant
13032 // addition or subtraction with the value of 0x800000.
13033 if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && Subtarget->useMulOps() &&
13034 FinalOpc == ARMISD::SMLAL && !AddeSubeNode->hasAnyUseOfValue(1) &&
13035 LowAddSub->getNode()->getOpcode() == ISD::Constant &&
13036 static_cast<ConstantSDNode *>(LowAddSub->getNode())->getZExtValue() ==
13037 0x80000000) {
13038 Ops.push_back(*HiAddSub);
13039 if (AddcSubcNode->getOpcode() == ARMISD::SUBC) {
13040 FinalOpc = ARMISD::SMMLSR;
13041 } else {
13042 FinalOpc = ARMISD::SMMLAR;
13043 }
13044 SDValue NewNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode), MVT::i32, Ops);
13045 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), NewNode);
13046
13047 return SDValue(AddeSubeNode, 0);
13048 } else if (AddcSubcNode->getOpcode() == ARMISD::SUBC)
13049 // SMMLS is generated during instruction selection and the rest of this
13050 // function can not handle the case where AddcSubcNode is a SUBC.
13051 return SDValue();
13052
13053 // Finish building the operand list for {U/S}MLAL
13054 Ops.push_back(*LowAddSub);
13055 Ops.push_back(*HiAddSub);
13056
13057 SDValue MLALNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode),
13058 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13059
13060 // Replace the ADDs' nodes uses by the MLA node's values.
13061 SDValue HiMLALResult(MLALNode.getNode(), 1);
13062 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), HiMLALResult);
13063
13064 SDValue LoMLALResult(MLALNode.getNode(), 0);
13065 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcSubcNode, 0), LoMLALResult);
13066
13067 // Return original node to notify the driver to stop replacing.
13068 return SDValue(AddeSubeNode, 0);
13069}
13070
13073 const ARMSubtarget *Subtarget) {
13074 // UMAAL is similar to UMLAL except that it adds two unsigned values.
13075 // While trying to combine for the other MLAL nodes, first search for the
13076 // chance to use UMAAL. Check if Addc uses a node which has already
13077 // been combined into a UMLAL. The other pattern is UMLAL using Addc/Adde
13078 // as the addend, and it's handled in PerformUMLALCombine.
13079
13080 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13081 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13082
13083 // Check that we have a glued ADDC node.
13084 SDNode* AddcNode = AddeNode->getOperand(2).getNode();
13085 if (AddcNode->getOpcode() != ARMISD::ADDC)
13086 return SDValue();
13087
13088 // Find the converted UMAAL or quit if it doesn't exist.
13089 SDNode *UmlalNode = nullptr;
13090 SDValue AddHi;
13091 if (AddcNode->getOperand(0).getOpcode() == ARMISD::UMLAL) {
13092 UmlalNode = AddcNode->getOperand(0).getNode();
13093 AddHi = AddcNode->getOperand(1);
13094 } else if (AddcNode->getOperand(1).getOpcode() == ARMISD::UMLAL) {
13095 UmlalNode = AddcNode->getOperand(1).getNode();
13096 AddHi = AddcNode->getOperand(0);
13097 } else {
13098 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13099 }
13100
13101 // The ADDC should be glued to an ADDE node, which uses the same UMLAL as
13102 // the ADDC as well as Zero.
13103 if (!isNullConstant(UmlalNode->getOperand(3)))
13104 return SDValue();
13105
13106 if ((isNullConstant(AddeNode->getOperand(0)) &&
13107 AddeNode->getOperand(1).getNode() == UmlalNode) ||
13108 (AddeNode->getOperand(0).getNode() == UmlalNode &&
13109 isNullConstant(AddeNode->getOperand(1)))) {
13110 SelectionDAG &DAG = DCI.DAG;
13111 SDValue Ops[] = { UmlalNode->getOperand(0), UmlalNode->getOperand(1),
13112 UmlalNode->getOperand(2), AddHi };
13113 SDValue UMAAL = DAG.getNode(ARMISD::UMAAL, SDLoc(AddcNode),
13114 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13115
13116 // Replace the ADDs' nodes uses by the UMAAL node's values.
13117 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), SDValue(UMAAL.getNode(), 1));
13118 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), SDValue(UMAAL.getNode(), 0));
13119
13120 // Return original node to notify the driver to stop replacing.
13121 return SDValue(AddeNode, 0);
13122 }
13123 return SDValue();
13124}
13125
13127 const ARMSubtarget *Subtarget) {
13128 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13129 return SDValue();
13130
13131 // Check that we have a pair of ADDC and ADDE as operands.
13132 // Both addends of the ADDE must be zero.
13133 SDNode* AddcNode = N->getOperand(2).getNode();
13134 SDNode* AddeNode = N->getOperand(3).getNode();
13135 if ((AddcNode->getOpcode() == ARMISD::ADDC) &&
13136 (AddeNode->getOpcode() == ARMISD::ADDE) &&
13137 isNullConstant(AddeNode->getOperand(0)) &&
13138 isNullConstant(AddeNode->getOperand(1)) &&
13139 (AddeNode->getOperand(2).getNode() == AddcNode))
13140 return DAG.getNode(ARMISD::UMAAL, SDLoc(N),
13141 DAG.getVTList(MVT::i32, MVT::i32),
13142 {N->getOperand(0), N->getOperand(1),
13143 AddcNode->getOperand(0), AddcNode->getOperand(1)});
13144 else
13145 return SDValue();
13146}
13147
13150 const ARMSubtarget *Subtarget) {
13151 SelectionDAG &DAG(DCI.DAG);
13152
13153 if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
13154 // (SUBC (ADDE 0, 0, C), 1) -> C
13155 SDValue LHS = N->getOperand(0);
13156 SDValue RHS = N->getOperand(1);
13157 if (LHS->getOpcode() == ARMISD::ADDE &&
13158 isNullConstant(LHS->getOperand(0)) &&
13159 isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
13160 return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
13161 }
13162 }
13163
13164 if (Subtarget->isThumb1Only()) {
13165 SDValue RHS = N->getOperand(1);
13167 int32_t imm = C->getSExtValue();
13168 if (imm < 0 && imm > std::numeric_limits<int>::min()) {
13169 SDLoc DL(N);
13170 RHS = DAG.getConstant(-imm, DL, MVT::i32);
13171 unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
13172 : ARMISD::ADDC;
13173 return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
13174 }
13175 }
13176 }
13177
13178 return SDValue();
13179}
13180
13183 const ARMSubtarget *Subtarget) {
13184 if (Subtarget->isThumb1Only()) {
13185 SelectionDAG &DAG = DCI.DAG;
13186 SDValue RHS = N->getOperand(1);
13188 int64_t imm = C->getSExtValue();
13189 if (imm < 0) {
13190 SDLoc DL(N);
13191
13192 // The with-carry-in form matches bitwise not instead of the negation.
13193 // Effectively, the inverse interpretation of the carry flag already
13194 // accounts for part of the negation.
13195 RHS = DAG.getConstant(~imm, DL, MVT::i32);
13196
13197 unsigned Opcode = (N->getOpcode() == ARMISD::ADDE) ? ARMISD::SUBE
13198 : ARMISD::ADDE;
13199 return DAG.getNode(Opcode, DL, N->getVTList(),
13200 N->getOperand(0), RHS, N->getOperand(2));
13201 }
13202 }
13203 } else if (N->getOperand(1)->getOpcode() == ISD::SMUL_LOHI) {
13204 return AddCombineTo64bitMLAL(N, DCI, Subtarget);
13205 }
13206 return SDValue();
13207}
13208
13211 const ARMSubtarget *Subtarget) {
13212 if (!Subtarget->hasMVEIntegerOps())
13213 return SDValue();
13214
13215 SDLoc dl(N);
13216 SDValue SetCC;
13217 SDValue LHS;
13218 SDValue RHS;
13219 ISD::CondCode CC;
13220 SDValue TrueVal;
13221 SDValue FalseVal;
13222
13223 if (N->getOpcode() == ISD::SELECT &&
13224 N->getOperand(0)->getOpcode() == ISD::SETCC) {
13225 SetCC = N->getOperand(0);
13226 LHS = SetCC->getOperand(0);
13227 RHS = SetCC->getOperand(1);
13228 CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
13229 TrueVal = N->getOperand(1);
13230 FalseVal = N->getOperand(2);
13231 } else if (N->getOpcode() == ISD::SELECT_CC) {
13232 LHS = N->getOperand(0);
13233 RHS = N->getOperand(1);
13234 CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
13235 TrueVal = N->getOperand(2);
13236 FalseVal = N->getOperand(3);
13237 } else {
13238 return SDValue();
13239 }
13240
13241 unsigned int Opcode = 0;
13242 if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
13243 FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
13244 (CC == ISD::SETULT || CC == ISD::SETUGT)) {
13245 Opcode = ARMISD::VMINVu;
13246 if (CC == ISD::SETUGT)
13247 std::swap(TrueVal, FalseVal);
13248 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
13249 FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
13250 (CC == ISD::SETLT || CC == ISD::SETGT)) {
13251 Opcode = ARMISD::VMINVs;
13252 if (CC == ISD::SETGT)
13253 std::swap(TrueVal, FalseVal);
13254 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
13255 FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
13256 (CC == ISD::SETUGT || CC == ISD::SETULT)) {
13257 Opcode = ARMISD::VMAXVu;
13258 if (CC == ISD::SETULT)
13259 std::swap(TrueVal, FalseVal);
13260 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
13261 FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
13262 (CC == ISD::SETGT || CC == ISD::SETLT)) {
13263 Opcode = ARMISD::VMAXVs;
13264 if (CC == ISD::SETLT)
13265 std::swap(TrueVal, FalseVal);
13266 } else
13267 return SDValue();
13268
13269 // Normalise to the right hand side being the vector reduction
13270 switch (TrueVal->getOpcode()) {
13275 std::swap(LHS, RHS);
13276 std::swap(TrueVal, FalseVal);
13277 break;
13278 }
13279
13280 EVT VectorType = FalseVal->getOperand(0).getValueType();
13281
13282 if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
13283 VectorType != MVT::v4i32)
13284 return SDValue();
13285
13286 EVT VectorScalarType = VectorType.getVectorElementType();
13287
13288 // The values being selected must also be the ones being compared
13289 if (TrueVal != LHS || FalseVal != RHS)
13290 return SDValue();
13291
13292 EVT LeftType = LHS->getValueType(0);
13293 EVT RightType = RHS->getValueType(0);
13294
13295 // The types must match the reduced type too
13296 if (LeftType != VectorScalarType || RightType != VectorScalarType)
13297 return SDValue();
13298
13299 // Legalise the scalar to an i32
13300 if (VectorScalarType != MVT::i32)
13301 LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
13302
13303 // Generate the reduction as an i32 for legalisation purposes
13304 auto Reduction =
13305 DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
13306
13307 // The result isn't actually an i32 so truncate it back to its original type
13308 if (VectorScalarType != MVT::i32)
13309 Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
13310
13311 return Reduction;
13312}
13313
13314// A special combine for the vqdmulh family of instructions. This is one of the
13315// potential set of patterns that could patch this instruction. The base pattern
13316// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
13317// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
13318// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
13319// the max is unnecessary.
13321 EVT VT = N->getValueType(0);
13322 SDValue Shft;
13323 ConstantSDNode *Clamp;
13324
13325 if (!VT.isVector() || VT.getScalarSizeInBits() > 64)
13326 return SDValue();
13327
13328 if (N->getOpcode() == ISD::SMIN) {
13329 Shft = N->getOperand(0);
13330 Clamp = isConstOrConstSplat(N->getOperand(1));
13331 } else if (N->getOpcode() == ISD::VSELECT) {
13332 // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
13333 SDValue Cmp = N->getOperand(0);
13334 if (Cmp.getOpcode() != ISD::SETCC ||
13335 cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
13336 Cmp.getOperand(0) != N->getOperand(1) ||
13337 Cmp.getOperand(1) != N->getOperand(2))
13338 return SDValue();
13339 Shft = N->getOperand(1);
13340 Clamp = isConstOrConstSplat(N->getOperand(2));
13341 } else
13342 return SDValue();
13343
13344 if (!Clamp)
13345 return SDValue();
13346
13347 MVT ScalarType;
13348 int ShftAmt = 0;
13349 switch (Clamp->getSExtValue()) {
13350 case (1 << 7) - 1:
13351 ScalarType = MVT::i8;
13352 ShftAmt = 7;
13353 break;
13354 case (1 << 15) - 1:
13355 ScalarType = MVT::i16;
13356 ShftAmt = 15;
13357 break;
13358 case (1ULL << 31) - 1:
13359 ScalarType = MVT::i32;
13360 ShftAmt = 31;
13361 break;
13362 default:
13363 return SDValue();
13364 }
13365
13366 if (Shft.getOpcode() != ISD::SRA)
13367 return SDValue();
13369 if (!N1 || N1->getSExtValue() != ShftAmt)
13370 return SDValue();
13371
13372 SDValue Mul = Shft.getOperand(0);
13373 if (Mul.getOpcode() != ISD::MUL)
13374 return SDValue();
13375
13376 SDValue Ext0 = Mul.getOperand(0);
13377 SDValue Ext1 = Mul.getOperand(1);
13378 if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
13379 Ext1.getOpcode() != ISD::SIGN_EXTEND)
13380 return SDValue();
13381 EVT VecVT = Ext0.getOperand(0).getValueType();
13382 if (!VecVT.isPow2VectorType() || VecVT.getVectorNumElements() == 1)
13383 return SDValue();
13384 if (Ext1.getOperand(0).getValueType() != VecVT ||
13385 VecVT.getScalarType() != ScalarType ||
13386 VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
13387 return SDValue();
13388
13389 SDLoc DL(Mul);
13390 unsigned LegalLanes = 128 / (ShftAmt + 1);
13391 EVT LegalVecVT = MVT::getVectorVT(ScalarType, LegalLanes);
13392 // For types smaller than legal vectors extend to be legal and only use needed
13393 // lanes.
13394 if (VecVT.getSizeInBits() < 128) {
13395 EVT ExtVecVT =
13397 VecVT.getVectorNumElements());
13398 SDValue Inp0 =
13399 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext0.getOperand(0));
13400 SDValue Inp1 =
13401 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext1.getOperand(0));
13402 Inp0 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp0);
13403 Inp1 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp1);
13404 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13405 SDValue Trunc = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, ExtVecVT, VQDMULH);
13406 Trunc = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Trunc);
13407 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Trunc);
13408 }
13409
13410 // For larger types, split into legal sized chunks.
13411 assert(VecVT.getSizeInBits() % 128 == 0 && "Expected a power2 type");
13412 unsigned NumParts = VecVT.getSizeInBits() / 128;
13414 for (unsigned I = 0; I < NumParts; ++I) {
13415 SDValue Inp0 =
13416 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext0.getOperand(0),
13417 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13418 SDValue Inp1 =
13419 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext1.getOperand(0),
13420 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13421 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13422 Parts.push_back(VQDMULH);
13423 }
13424 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT,
13425 DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
13426}
13427
13430 const ARMSubtarget *Subtarget) {
13431 if (!Subtarget->hasMVEIntegerOps())
13432 return SDValue();
13433
13434 // Constant fold vselect 0, A, B -> B
13435 // and vselect 0xffff, A, B -> A
13436 if (N->getOperand(0).getOpcode() == ARMISD::PREDICATE_CAST &&
13437 isa<ConstantSDNode>(N->getOperand(0).getOperand(0))) {
13438 unsigned C = N->getOperand(0).getConstantOperandVal(0);
13439 if (C == 0)
13440 return N->getOperand(2);
13441 if (C == 0xffff)
13442 return N->getOperand(1);
13443 }
13444
13445 if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
13446 return V;
13447
13448 // Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
13449 //
13450 // We need to re-implement this optimization here as the implementation in the
13451 // Target-Independent DAGCombiner does not handle the kind of constant we make
13452 // (it calls isConstOrConstSplat with AllowTruncation set to false - and for
13453 // good reason, allowing truncation there would break other targets).
13454 //
13455 // Currently, this is only done for MVE, as it's the only target that benefits
13456 // from this transformation (e.g. VPNOT+VPSEL becomes a single VPSEL).
13457 if (N->getOperand(0).getOpcode() != ISD::XOR)
13458 return SDValue();
13459 SDValue XOR = N->getOperand(0);
13460
13461 // Check if the XOR's RHS is either a 1, or a BUILD_VECTOR of 1s.
13462 // It is important to check with truncation allowed as the BUILD_VECTORs we
13463 // generate in those situations will truncate their operands.
13464 ConstantSDNode *Const =
13465 isConstOrConstSplat(XOR->getOperand(1), /*AllowUndefs*/ false,
13466 /*AllowTruncation*/ true);
13467 if (!Const || !Const->isOne())
13468 return SDValue();
13469
13470 // Rewrite into vselect(cond, rhs, lhs).
13471 SDValue Cond = XOR->getOperand(0);
13472 SDValue LHS = N->getOperand(1);
13473 SDValue RHS = N->getOperand(2);
13474 EVT Type = N->getValueType(0);
13475 return DCI.DAG.getNode(ISD::VSELECT, SDLoc(N), Type, Cond, RHS, LHS);
13476}
13477
13478// Convert vsetcc([0,1,2,..], splat(n), ult) -> vctp n
13481 const ARMSubtarget *Subtarget) {
13482 SDValue Op0 = N->getOperand(0);
13483 SDValue Op1 = N->getOperand(1);
13484 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
13485 EVT VT = N->getValueType(0);
13486
13487 if (!Subtarget->hasMVEIntegerOps() ||
13489 return SDValue();
13490
13491 if (CC == ISD::SETUGE) {
13492 std::swap(Op0, Op1);
13493 CC = ISD::SETULT;
13494 }
13495
13496 if (CC != ISD::SETULT || VT.getScalarSizeInBits() != 1 ||
13498 return SDValue();
13499
13500 // Check first operand is BuildVector of 0,1,2,...
13501 for (unsigned I = 0; I < VT.getVectorNumElements(); I++) {
13502 if (!Op0.getOperand(I).isUndef() &&
13504 Op0.getConstantOperandVal(I) == I))
13505 return SDValue();
13506 }
13507
13508 // The second is a Splat of Op1S
13509 SDValue Op1S = DCI.DAG.getSplatValue(Op1);
13510 if (!Op1S)
13511 return SDValue();
13512
13513 unsigned Opc;
13514 switch (VT.getVectorNumElements()) {
13515 case 2:
13516 Opc = Intrinsic::arm_mve_vctp64;
13517 break;
13518 case 4:
13519 Opc = Intrinsic::arm_mve_vctp32;
13520 break;
13521 case 8:
13522 Opc = Intrinsic::arm_mve_vctp16;
13523 break;
13524 case 16:
13525 Opc = Intrinsic::arm_mve_vctp8;
13526 break;
13527 default:
13528 return SDValue();
13529 }
13530
13531 SDLoc DL(N);
13532 return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT,
13533 DCI.DAG.getConstant(Opc, DL, MVT::i32),
13534 DCI.DAG.getZExtOrTrunc(Op1S, DL, MVT::i32));
13535}
13536
13537/// PerformADDECombine - Target-specific dag combine transform from
13538/// ARMISD::ADDC, ARMISD::ADDE, and ISD::MUL_LOHI to MLAL or
13539/// ARMISD::ADDC, ARMISD::ADDE and ARMISD::UMLAL to ARMISD::UMAAL
13542 const ARMSubtarget *Subtarget) {
13543 // Only ARM and Thumb2 support UMLAL/SMLAL.
13544 if (Subtarget->isThumb1Only())
13545 return PerformAddeSubeCombine(N, DCI, Subtarget);
13546
13547 // Only perform the checks after legalize when the pattern is available.
13548 if (DCI.isBeforeLegalize()) return SDValue();
13549
13550 return AddCombineTo64bitUMAAL(N, DCI, Subtarget);
13551}
13552
13553/// PerformADDCombineWithOperands - Try DAG combinations for an ADD with
13554/// operands N0 and N1. This is a helper for PerformADDCombine that is
13555/// called with the default operands, and if that fails, with commuted
13556/// operands.
13559 const ARMSubtarget *Subtarget){
13560 // Attempt to create vpadd for this add.
13561 if (SDValue Result = AddCombineToVPADD(N, N0, N1, DCI, Subtarget))
13562 return Result;
13563
13564 // Attempt to create vpaddl for this add.
13565 if (SDValue Result = AddCombineVUZPToVPADDL(N, N0, N1, DCI, Subtarget))
13566 return Result;
13567 if (SDValue Result = AddCombineBUILD_VECTORToVPADDL(N, N0, N1, DCI,
13568 Subtarget))
13569 return Result;
13570
13571 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
13572 if (N0.getNode()->hasOneUse())
13573 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI))
13574 return Result;
13575 return SDValue();
13576}
13577
13579 EVT VT = N->getValueType(0);
13580 SDValue N0 = N->getOperand(0);
13581 SDValue N1 = N->getOperand(1);
13582 SDLoc dl(N);
13583
13584 auto IsVecReduce = [](SDValue Op) {
13585 switch (Op.getOpcode()) {
13586 case ISD::VECREDUCE_ADD:
13587 case ARMISD::VADDVs:
13588 case ARMISD::VADDVu:
13589 case ARMISD::VMLAVs:
13590 case ARMISD::VMLAVu:
13591 return true;
13592 }
13593 return false;
13594 };
13595
13596 auto DistrubuteAddAddVecReduce = [&](SDValue N0, SDValue N1) {
13597 // Distribute add(X, add(vecreduce(Y), vecreduce(Z))) ->
13598 // add(add(X, vecreduce(Y)), vecreduce(Z))
13599 // to make better use of vaddva style instructions.
13600 if (VT == MVT::i32 && N1.getOpcode() == ISD::ADD && !IsVecReduce(N0) &&
13601 IsVecReduce(N1.getOperand(0)) && IsVecReduce(N1.getOperand(1)) &&
13602 !isa<ConstantSDNode>(N0) && N1->hasOneUse()) {
13603 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0, N1.getOperand(0));
13604 return DAG.getNode(ISD::ADD, dl, VT, Add0, N1.getOperand(1));
13605 }
13606 // And turn add(add(A, reduce(B)), add(C, reduce(D))) ->
13607 // add(add(add(A, C), reduce(B)), reduce(D))
13608 if (VT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
13609 N1.getOpcode() == ISD::ADD && N0->hasOneUse() && N1->hasOneUse()) {
13610 unsigned N0RedOp = 0;
13611 if (!IsVecReduce(N0.getOperand(N0RedOp))) {
13612 N0RedOp = 1;
13613 if (!IsVecReduce(N0.getOperand(N0RedOp)))
13614 return SDValue();
13615 }
13616
13617 unsigned N1RedOp = 0;
13618 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13619 N1RedOp = 1;
13620 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13621 return SDValue();
13622
13623 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0.getOperand(1 - N0RedOp),
13624 N1.getOperand(1 - N1RedOp));
13625 SDValue Add1 =
13626 DAG.getNode(ISD::ADD, dl, VT, Add0, N0.getOperand(N0RedOp));
13627 return DAG.getNode(ISD::ADD, dl, VT, Add1, N1.getOperand(N1RedOp));
13628 }
13629 return SDValue();
13630 };
13631 if (SDValue R = DistrubuteAddAddVecReduce(N0, N1))
13632 return R;
13633 if (SDValue R = DistrubuteAddAddVecReduce(N1, N0))
13634 return R;
13635
13636 // Distribute add(vecreduce(load(Y)), vecreduce(load(Z)))
13637 // Or add(add(X, vecreduce(load(Y))), vecreduce(load(Z)))
13638 // by ascending load offsets. This can help cores prefetch if the order of
13639 // loads is more predictable.
13640 auto DistrubuteVecReduceLoad = [&](SDValue N0, SDValue N1, bool IsForward) {
13641 // Check if two reductions are known to load data where one is before/after
13642 // another. Return negative if N0 loads data before N1, positive if N1 is
13643 // before N0 and 0 otherwise if nothing is known.
13644 auto IsKnownOrderedLoad = [&](SDValue N0, SDValue N1) {
13645 // Look through to the first operand of a MUL, for the VMLA case.
13646 // Currently only looks at the first operand, in the hope they are equal.
13647 if (N0.getOpcode() == ISD::MUL)
13648 N0 = N0.getOperand(0);
13649 if (N1.getOpcode() == ISD::MUL)
13650 N1 = N1.getOperand(0);
13651
13652 // Return true if the two operands are loads to the same object and the
13653 // offset of the first is known to be less than the offset of the second.
13654 LoadSDNode *Load0 = dyn_cast<LoadSDNode>(N0);
13655 LoadSDNode *Load1 = dyn_cast<LoadSDNode>(N1);
13656 if (!Load0 || !Load1 || Load0->getChain() != Load1->getChain() ||
13657 !Load0->isSimple() || !Load1->isSimple() || Load0->isIndexed() ||
13658 Load1->isIndexed())
13659 return 0;
13660
13661 auto BaseLocDecomp0 = BaseIndexOffset::match(Load0, DAG);
13662 auto BaseLocDecomp1 = BaseIndexOffset::match(Load1, DAG);
13663
13664 if (!BaseLocDecomp0.getBase() ||
13665 BaseLocDecomp0.getBase() != BaseLocDecomp1.getBase() ||
13666 !BaseLocDecomp0.hasValidOffset() || !BaseLocDecomp1.hasValidOffset())
13667 return 0;
13668 if (BaseLocDecomp0.getOffset() < BaseLocDecomp1.getOffset())
13669 return -1;
13670 if (BaseLocDecomp0.getOffset() > BaseLocDecomp1.getOffset())
13671 return 1;
13672 return 0;
13673 };
13674
13675 SDValue X;
13676 if (N0.getOpcode() == ISD::ADD && N0->hasOneUse()) {
13677 if (IsVecReduce(N0.getOperand(0)) && IsVecReduce(N0.getOperand(1))) {
13678 int IsBefore = IsKnownOrderedLoad(N0.getOperand(0).getOperand(0),
13679 N0.getOperand(1).getOperand(0));
13680 if (IsBefore < 0) {
13681 X = N0.getOperand(0);
13682 N0 = N0.getOperand(1);
13683 } else if (IsBefore > 0) {
13684 X = N0.getOperand(1);
13685 N0 = N0.getOperand(0);
13686 } else
13687 return SDValue();
13688 } else if (IsVecReduce(N0.getOperand(0))) {
13689 X = N0.getOperand(1);
13690 N0 = N0.getOperand(0);
13691 } else if (IsVecReduce(N0.getOperand(1))) {
13692 X = N0.getOperand(0);
13693 N0 = N0.getOperand(1);
13694 } else
13695 return SDValue();
13696 } else if (IsForward && IsVecReduce(N0) && IsVecReduce(N1) &&
13697 IsKnownOrderedLoad(N0.getOperand(0), N1.getOperand(0)) < 0) {
13698 // Note this is backward to how you would expect. We create
13699 // add(reduce(load + 16), reduce(load + 0)) so that the
13700 // add(reduce(load+16), X) is combined into VADDVA(X, load+16)), leaving
13701 // the X as VADDV(load + 0)
13702 return DAG.getNode(ISD::ADD, dl, VT, N1, N0);
13703 } else
13704 return SDValue();
13705
13706 if (!IsVecReduce(N0) || !IsVecReduce(N1))
13707 return SDValue();
13708
13709 if (IsKnownOrderedLoad(N1.getOperand(0), N0.getOperand(0)) >= 0)
13710 return SDValue();
13711
13712 // Switch from add(add(X, N0), N1) to add(add(X, N1), N0)
13713 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, X, N1);
13714 return DAG.getNode(ISD::ADD, dl, VT, Add0, N0);
13715 };
13716 if (SDValue R = DistrubuteVecReduceLoad(N0, N1, true))
13717 return R;
13718 if (SDValue R = DistrubuteVecReduceLoad(N1, N0, false))
13719 return R;
13720 return SDValue();
13721}
13722
13724 const ARMSubtarget *Subtarget) {
13725 if (!Subtarget->hasMVEIntegerOps())
13726 return SDValue();
13727
13729 return R;
13730
13731 EVT VT = N->getValueType(0);
13732 SDValue N0 = N->getOperand(0);
13733 SDValue N1 = N->getOperand(1);
13734 SDLoc dl(N);
13735
13736 if (VT != MVT::i64)
13737 return SDValue();
13738
13739 // We are looking for a i64 add of a VADDLVx. Due to these being i64's, this
13740 // will look like:
13741 // t1: i32,i32 = ARMISD::VADDLVs x
13742 // t2: i64 = build_pair t1, t1:1
13743 // t3: i64 = add t2, y
13744 // Otherwise we try to push the add up above VADDLVAx, to potentially allow
13745 // the add to be simplified separately.
13746 // We also need to check for sext / zext and commutitive adds.
13747 auto MakeVecReduce = [&](unsigned Opcode, unsigned OpcodeA, SDValue NA,
13748 SDValue NB) {
13749 if (NB->getOpcode() != ISD::BUILD_PAIR)
13750 return SDValue();
13751 SDValue VecRed = NB->getOperand(0);
13752 if ((VecRed->getOpcode() != Opcode && VecRed->getOpcode() != OpcodeA) ||
13753 VecRed.getResNo() != 0 ||
13754 NB->getOperand(1) != SDValue(VecRed.getNode(), 1))
13755 return SDValue();
13756
13757 if (VecRed->getOpcode() == OpcodeA) {
13758 // add(NA, VADDLVA(Inp), Y) -> VADDLVA(add(NA, Inp), Y)
13759 SDValue Inp = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
13760 VecRed.getOperand(0), VecRed.getOperand(1));
13761 NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA);
13762 }
13763
13765 std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32);
13766
13767 unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0;
13768 for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++)
13769 Ops.push_back(VecRed->getOperand(I));
13770 SDValue Red =
13771 DAG.getNode(OpcodeA, dl, DAG.getVTList({MVT::i32, MVT::i32}), Ops);
13772 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Red,
13773 SDValue(Red.getNode(), 1));
13774 };
13775
13776 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N0, N1))
13777 return M;
13778 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N0, N1))
13779 return M;
13780 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N1, N0))
13781 return M;
13782 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N1, N0))
13783 return M;
13784 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N0, N1))
13785 return M;
13786 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N0, N1))
13787 return M;
13788 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N1, N0))
13789 return M;
13790 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N1, N0))
13791 return M;
13792 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N0, N1))
13793 return M;
13794 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N0, N1))
13795 return M;
13796 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N1, N0))
13797 return M;
13798 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
13799 return M;
13800 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
13801 return M;
13802 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
13803 return M;
13804 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
13805 return M;
13806 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
13807 return M;
13808 return SDValue();
13809}
13810
13811bool
13813 CombineLevel Level) const {
13814 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
13815 N->getOpcode() == ISD::SRL) &&
13816 "Expected shift op");
13817
13818 SDValue ShiftLHS = N->getOperand(0);
13819 if (!ShiftLHS->hasOneUse())
13820 return false;
13821
13822 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
13823 !ShiftLHS.getOperand(0)->hasOneUse())
13824 return false;
13825
13826 if (Level == BeforeLegalizeTypes)
13827 return true;
13828
13829 if (N->getOpcode() != ISD::SHL)
13830 return true;
13831
13832 if (Subtarget->isThumb1Only()) {
13833 // Avoid making expensive immediates by commuting shifts. (This logic
13834 // only applies to Thumb1 because ARM and Thumb2 immediates can be shifted
13835 // for free.)
13836 if (N->getOpcode() != ISD::SHL)
13837 return true;
13838 SDValue N1 = N->getOperand(0);
13839 if (N1->getOpcode() != ISD::ADD && N1->getOpcode() != ISD::AND &&
13840 N1->getOpcode() != ISD::OR && N1->getOpcode() != ISD::XOR)
13841 return true;
13842 if (auto *Const = dyn_cast<ConstantSDNode>(N1->getOperand(1))) {
13843 if (Const->getAPIntValue().ult(256))
13844 return false;
13845 if (N1->getOpcode() == ISD::ADD && Const->getAPIntValue().slt(0) &&
13846 Const->getAPIntValue().sgt(-256))
13847 return false;
13848 }
13849 return true;
13850 }
13851
13852 // Turn off commute-with-shift transform after legalization, so it doesn't
13853 // conflict with PerformSHLSimplify. (We could try to detect when
13854 // PerformSHLSimplify would trigger more precisely, but it isn't
13855 // really necessary.)
13856 return false;
13857}
13858
13860 const SDNode *N) const {
13861 assert(N->getOpcode() == ISD::XOR &&
13862 (N->getOperand(0).getOpcode() == ISD::SHL ||
13863 N->getOperand(0).getOpcode() == ISD::SRL) &&
13864 "Expected XOR(SHIFT) pattern");
13865
13866 // Only commute if the entire NOT mask is a hidden shifted mask.
13867 auto *XorC = dyn_cast<ConstantSDNode>(N->getOperand(1));
13868 auto *ShiftC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1));
13869 if (XorC && ShiftC) {
13870 unsigned MaskIdx, MaskLen;
13871 if (XorC->getAPIntValue().isShiftedMask(MaskIdx, MaskLen)) {
13872 unsigned ShiftAmt = ShiftC->getZExtValue();
13873 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
13874 if (N->getOperand(0).getOpcode() == ISD::SHL)
13875 return MaskIdx == ShiftAmt && MaskLen == (BitWidth - ShiftAmt);
13876 return MaskIdx == 0 && MaskLen == (BitWidth - ShiftAmt);
13877 }
13878 }
13879
13880 return false;
13881}
13882
13884 const SDNode *N) const {
13885 assert(((N->getOpcode() == ISD::SHL &&
13886 N->getOperand(0).getOpcode() == ISD::SRL) ||
13887 (N->getOpcode() == ISD::SRL &&
13888 N->getOperand(0).getOpcode() == ISD::SHL)) &&
13889 "Expected shift-shift mask");
13890
13891 if (!Subtarget->isThumb1Only())
13892 return true;
13893
13894 EVT VT = N->getValueType(0);
13895 if (VT.getScalarSizeInBits() > 32)
13896 return true;
13897
13898 return false;
13899}
13900
13902 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
13903 SDValue Y) const {
13904 return Subtarget->hasMVEIntegerOps() && isTypeLegal(VT) &&
13905 SelectOpcode == ISD::VSELECT;
13906}
13907
13909 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps()) {
13910 if (Subtarget->isThumb1Only())
13911 return VT.getScalarSizeInBits() <= 32;
13912 return true;
13913 }
13914 return VT.isScalarInteger();
13915}
13916
13918 EVT VT) const {
13919 if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
13920 return false;
13921
13922 switch (FPVT.getSimpleVT().SimpleTy) {
13923 case MVT::f16:
13924 return Subtarget->hasVFP2Base();
13925 case MVT::f32:
13926 return Subtarget->hasVFP2Base();
13927 case MVT::f64:
13928 return Subtarget->hasFP64();
13929 case MVT::v4f32:
13930 case MVT::v8f16:
13931 return Subtarget->hasMVEFloatOps();
13932 default:
13933 return false;
13934 }
13935}
13936
13939 const ARMSubtarget *ST) {
13940 // Allow the generic combiner to identify potential bswaps.
13941 if (DCI.isBeforeLegalize())
13942 return SDValue();
13943
13944 // DAG combiner will fold:
13945 // (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
13946 // (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2
13947 // Other code patterns that can be also be modified have the following form:
13948 // b + ((a << 1) | 510)
13949 // b + ((a << 1) & 510)
13950 // b + ((a << 1) ^ 510)
13951 // b + ((a << 1) + 510)
13952
13953 // Many instructions can perform the shift for free, but it requires both
13954 // the operands to be registers. If c1 << c2 is too large, a mov immediate
13955 // instruction will needed. So, unfold back to the original pattern if:
13956 // - if c1 and c2 are small enough that they don't require mov imms.
13957 // - the user(s) of the node can perform an shl
13958
13959 // No shifted operands for 16-bit instructions.
13960 if (ST->isThumb1Only())
13961 return SDValue();
13962
13963 // Check that all the users could perform the shl themselves.
13964 for (auto *U : N->users()) {
13965 switch(U->getOpcode()) {
13966 default:
13967 return SDValue();
13968 case ISD::SUB:
13969 case ISD::ADD:
13970 case ISD::AND:
13971 case ISD::OR:
13972 case ISD::XOR:
13973 case ISD::SETCC:
13974 case ARMISD::CMP:
13975 // Check that the user isn't already using a constant because there
13976 // aren't any instructions that support an immediate operand and a
13977 // shifted operand.
13978 if (isa<ConstantSDNode>(U->getOperand(0)) ||
13979 isa<ConstantSDNode>(U->getOperand(1)))
13980 return SDValue();
13981
13982 // Check that it's not already using a shift.
13983 if (U->getOperand(0).getOpcode() == ISD::SHL ||
13984 U->getOperand(1).getOpcode() == ISD::SHL)
13985 return SDValue();
13986 break;
13987 }
13988 }
13989
13990 if (N->getOpcode() != ISD::ADD && N->getOpcode() != ISD::OR &&
13991 N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND)
13992 return SDValue();
13993
13994 if (N->getOperand(0).getOpcode() != ISD::SHL)
13995 return SDValue();
13996
13997 SDValue SHL = N->getOperand(0);
13998
13999 auto *C1ShlC2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
14000 auto *C2 = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
14001 if (!C1ShlC2 || !C2)
14002 return SDValue();
14003
14004 APInt C2Int = C2->getAPIntValue();
14005 APInt C1Int = C1ShlC2->getAPIntValue();
14006 unsigned C2Width = C2Int.getBitWidth();
14007 if (C2Int.uge(C2Width))
14008 return SDValue();
14009 uint64_t C2Value = C2Int.getZExtValue();
14010
14011 // Check that performing a lshr will not lose any information.
14012 APInt Mask = APInt::getHighBitsSet(C2Width, C2Width - C2Value);
14013 if ((C1Int & Mask) != C1Int)
14014 return SDValue();
14015
14016 // Shift the first constant.
14017 C1Int.lshrInPlace(C2Int);
14018
14019 // The immediates are encoded as an 8-bit value that can be rotated.
14020 auto LargeImm = [](const APInt &Imm) {
14021 unsigned Zeros = Imm.countl_zero() + Imm.countr_zero();
14022 return Imm.getBitWidth() - Zeros > 8;
14023 };
14024
14025 if (LargeImm(C1Int) || LargeImm(C2Int))
14026 return SDValue();
14027
14028 SelectionDAG &DAG = DCI.DAG;
14029 SDLoc dl(N);
14030 SDValue X = SHL.getOperand(0);
14031 SDValue BinOp = DAG.getNode(N->getOpcode(), dl, MVT::i32, X,
14032 DAG.getConstant(C1Int, dl, MVT::i32));
14033 // Shift left to compensate for the lshr of C1Int.
14034 SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
14035
14036 LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
14037 SHL.dump(); N->dump());
14038 LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
14039 return Res;
14040}
14041
14042
14043/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
14044///
14047 const ARMSubtarget *Subtarget) {
14048 SDValue N0 = N->getOperand(0);
14049 SDValue N1 = N->getOperand(1);
14050
14051 // Only works one way, because it needs an immediate operand.
14052 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14053 return Result;
14054
14055 if (SDValue Result = PerformADDVecReduce(N, DCI.DAG, Subtarget))
14056 return Result;
14057
14058 // First try with the default operand order.
14059 if (SDValue Result = PerformADDCombineWithOperands(N, N0, N1, DCI, Subtarget))
14060 return Result;
14061
14062 // If that didn't work, try again with the operands commuted.
14063 return PerformADDCombineWithOperands(N, N1, N0, DCI, Subtarget);
14064}
14065
14066// Combine (sub 0, (csinc X, Y, CC)) -> (csinv -X, Y, CC)
14067// providing -X is as cheap as X (currently, just a constant).
14069 if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
14070 return SDValue();
14071 SDValue CSINC = N->getOperand(1);
14072 if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
14073 return SDValue();
14074
14076 if (!X)
14077 return SDValue();
14078
14079 return DAG.getNode(ARMISD::CSINV, SDLoc(N), MVT::i32,
14080 DAG.getNode(ISD::SUB, SDLoc(N), MVT::i32, N->getOperand(0),
14081 CSINC.getOperand(0)),
14082 CSINC.getOperand(1), CSINC.getOperand(2),
14083 CSINC.getOperand(3));
14084}
14085
14087 // Free to negate.
14089 return 0;
14090
14091 // Will save one instruction.
14092 if (Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)))
14093 return -1;
14094
14095 // Can freely negate by converting sra <-> srl.
14096 if (Op.getOpcode() == ISD::SRA || Op.getOpcode() == ISD::SRL) {
14097 ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1));
14098 if (Op.hasOneUse() && ShiftAmt &&
14099 ShiftAmt->getZExtValue() == Op.getValueType().getScalarSizeInBits() - 1)
14100 return 0;
14101 }
14102
14103 // Will have to create sub.
14104 return 1;
14105}
14106
14107// Try to fold
14108//
14109// (neg (cmov X, Y)) -> (cmov (neg X), (neg Y))
14110//
14111// The folding helps cmov to be matched with csneg without generating
14112// redundant neg instruction.
14114 assert(N->getOpcode() == ISD::SUB);
14115 if (!isNullConstant(N->getOperand(0)))
14116 return SDValue();
14117
14118 SDValue CMov = N->getOperand(1);
14119 if (CMov.getOpcode() != ARMISD::CMOV || !CMov->hasOneUse())
14120 return SDValue();
14121
14122 SDValue N0 = CMov.getOperand(0);
14123 SDValue N1 = CMov.getOperand(1);
14124
14125 // Only perform the fold if we actually save something.
14126 if (getNegationCost(N0) + getNegationCost(N1) > 0)
14127 return SDValue();
14128
14129 SDLoc DL(N);
14130 EVT VT = CMov.getValueType();
14131
14132 SDValue N0N = DAG.getNegative(N0, DL, VT);
14133 SDValue N1N = DAG.getNegative(N1, DL, VT);
14134 return DAG.getNode(ARMISD::CMOV, DL, VT, N0N, N1N, CMov.getOperand(2),
14135 CMov.getOperand(3));
14136}
14137
14138/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
14139///
14142 const ARMSubtarget *Subtarget) {
14143 SDValue N0 = N->getOperand(0);
14144 SDValue N1 = N->getOperand(1);
14145
14146 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
14147 if (N1.getNode()->hasOneUse())
14148 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI))
14149 return Result;
14150
14151 if (SDValue R = PerformSubCSINCCombine(N, DCI.DAG))
14152 return R;
14153
14154 if (SDValue Val = performNegCMovCombine(N, DCI.DAG))
14155 return Val;
14156
14157 if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector())
14158 return SDValue();
14159
14160 // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x))
14161 // so that we can readily pattern match more mve instructions which can use
14162 // a scalar operand.
14163 SDValue VDup = N->getOperand(1);
14164 if (VDup->getOpcode() != ARMISD::VDUP)
14165 return SDValue();
14166
14167 SDValue VMov = N->getOperand(0);
14168 if (VMov->getOpcode() == ISD::BITCAST)
14169 VMov = VMov->getOperand(0);
14170
14171 if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov))
14172 return SDValue();
14173
14174 SDLoc dl(N);
14175 SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32,
14176 DCI.DAG.getConstant(0, dl, MVT::i32),
14177 VDup->getOperand(0));
14178 return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate);
14179}
14180
14181/// PerformVMULCombine
14182/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the
14183/// special multiplier accumulator forwarding.
14184/// vmul d3, d0, d2
14185/// vmla d3, d1, d2
14186/// is faster than
14187/// vadd d3, d0, d1
14188/// vmul d3, d3, d2
14189// However, for (A + B) * (A + B),
14190// vadd d2, d0, d1
14191// vmul d3, d0, d2
14192// vmla d3, d1, d2
14193// is slower than
14194// vadd d2, d0, d1
14195// vmul d3, d2, d2
14198 const ARMSubtarget *Subtarget) {
14199 if (!Subtarget->hasVMLxForwarding())
14200 return SDValue();
14201
14202 SelectionDAG &DAG = DCI.DAG;
14203 SDValue N0 = N->getOperand(0);
14204 SDValue N1 = N->getOperand(1);
14205 unsigned Opcode = N0.getOpcode();
14206 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14207 Opcode != ISD::FADD && Opcode != ISD::FSUB) {
14208 Opcode = N1.getOpcode();
14209 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14210 Opcode != ISD::FADD && Opcode != ISD::FSUB)
14211 return SDValue();
14212 std::swap(N0, N1);
14213 }
14214
14215 if (N0 == N1)
14216 return SDValue();
14217
14218 EVT VT = N->getValueType(0);
14219 SDLoc DL(N);
14220 SDValue N00 = N0->getOperand(0);
14221 SDValue N01 = N0->getOperand(1);
14222 return DAG.getNode(Opcode, DL, VT,
14223 DAG.getNode(ISD::MUL, DL, VT, N00, N1),
14224 DAG.getNode(ISD::MUL, DL, VT, N01, N1));
14225}
14226
14228 const ARMSubtarget *Subtarget) {
14229 EVT VT = N->getValueType(0);
14230 if (VT != MVT::v2i64)
14231 return SDValue();
14232
14233 SDValue N0 = N->getOperand(0);
14234 SDValue N1 = N->getOperand(1);
14235
14236 auto IsSignExt = [&](SDValue Op) {
14237 if (Op->getOpcode() != ISD::SIGN_EXTEND_INREG)
14238 return SDValue();
14239 EVT VT = cast<VTSDNode>(Op->getOperand(1))->getVT();
14240 if (VT.getScalarSizeInBits() == 32)
14241 return Op->getOperand(0);
14242 return SDValue();
14243 };
14244 auto IsZeroExt = [&](SDValue Op) {
14245 // Zero extends are a little more awkward. At the point we are matching
14246 // this, we are looking for an AND with a (-1, 0, -1, 0) buildvector mask.
14247 // That might be before of after a bitcast depending on how the and is
14248 // placed. Because this has to look through bitcasts, it is currently only
14249 // supported on LE.
14250 if (!Subtarget->isLittle())
14251 return SDValue();
14252
14253 SDValue And = Op;
14254 if (And->getOpcode() == ISD::BITCAST)
14255 And = And->getOperand(0);
14256 if (And->getOpcode() != ISD::AND)
14257 return SDValue();
14258 SDValue Mask = And->getOperand(1);
14259 if (Mask->getOpcode() == ISD::BITCAST)
14260 Mask = Mask->getOperand(0);
14261
14262 if (Mask->getOpcode() != ISD::BUILD_VECTOR ||
14263 Mask.getValueType() != MVT::v4i32)
14264 return SDValue();
14265 if (isAllOnesConstant(Mask->getOperand(0)) &&
14266 isNullConstant(Mask->getOperand(1)) &&
14267 isAllOnesConstant(Mask->getOperand(2)) &&
14268 isNullConstant(Mask->getOperand(3)))
14269 return And->getOperand(0);
14270 return SDValue();
14271 };
14272
14273 SDLoc dl(N);
14274 if (SDValue Op0 = IsSignExt(N0)) {
14275 if (SDValue Op1 = IsSignExt(N1)) {
14276 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14277 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14278 return DAG.getNode(ARMISD::VMULLs, dl, VT, New0a, New1a);
14279 }
14280 }
14281 if (SDValue Op0 = IsZeroExt(N0)) {
14282 if (SDValue Op1 = IsZeroExt(N1)) {
14283 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14284 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14285 return DAG.getNode(ARMISD::VMULLu, dl, VT, New0a, New1a);
14286 }
14287 }
14288
14289 return SDValue();
14290}
14291
14294 const ARMSubtarget *Subtarget) {
14295 SelectionDAG &DAG = DCI.DAG;
14296
14297 EVT VT = N->getValueType(0);
14298 if (Subtarget->hasMVEIntegerOps() && VT == MVT::v2i64)
14299 return PerformMVEVMULLCombine(N, DAG, Subtarget);
14300
14301 if (Subtarget->isThumb1Only())
14302 return SDValue();
14303
14304 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14305 return SDValue();
14306
14307 if (VT.is64BitVector() || VT.is128BitVector())
14308 return PerformVMULCombine(N, DCI, Subtarget);
14309 if (VT != MVT::i32)
14310 return SDValue();
14311
14312 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14313 if (!C)
14314 return SDValue();
14315
14316 int64_t MulAmt = C->getSExtValue();
14317 unsigned ShiftAmt = llvm::countr_zero<uint64_t>(MulAmt);
14318
14319 ShiftAmt = ShiftAmt & (32 - 1);
14320 SDValue V = N->getOperand(0);
14321 SDLoc DL(N);
14322
14323 SDValue Res;
14324 MulAmt >>= ShiftAmt;
14325
14326 if (MulAmt >= 0) {
14327 if (llvm::has_single_bit<uint32_t>(MulAmt - 1)) {
14328 // (mul x, 2^N + 1) => (add (shl x, N), x)
14329 Res = DAG.getNode(ISD::ADD, DL, VT,
14330 V,
14331 DAG.getNode(ISD::SHL, DL, VT,
14332 V,
14333 DAG.getConstant(Log2_32(MulAmt - 1), DL,
14334 MVT::i32)));
14335 } else if (llvm::has_single_bit<uint32_t>(MulAmt + 1)) {
14336 // (mul x, 2^N - 1) => (sub (shl x, N), x)
14337 Res = DAG.getNode(ISD::SUB, DL, VT,
14338 DAG.getNode(ISD::SHL, DL, VT,
14339 V,
14340 DAG.getConstant(Log2_32(MulAmt + 1), DL,
14341 MVT::i32)),
14342 V);
14343 } else
14344 return SDValue();
14345 } else {
14346 uint64_t MulAmtAbs = -MulAmt;
14347 if (llvm::has_single_bit<uint32_t>(MulAmtAbs + 1)) {
14348 // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
14349 Res = DAG.getNode(ISD::SUB, DL, VT,
14350 V,
14351 DAG.getNode(ISD::SHL, DL, VT,
14352 V,
14353 DAG.getConstant(Log2_32(MulAmtAbs + 1), DL,
14354 MVT::i32)));
14355 } else if (llvm::has_single_bit<uint32_t>(MulAmtAbs - 1)) {
14356 // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
14357 Res = DAG.getNode(ISD::ADD, DL, VT,
14358 V,
14359 DAG.getNode(ISD::SHL, DL, VT,
14360 V,
14361 DAG.getConstant(Log2_32(MulAmtAbs - 1), DL,
14362 MVT::i32)));
14363 Res = DAG.getNode(ISD::SUB, DL, VT,
14364 DAG.getConstant(0, DL, MVT::i32), Res);
14365 } else
14366 return SDValue();
14367 }
14368
14369 if (ShiftAmt != 0)
14370 Res = DAG.getNode(ISD::SHL, DL, VT,
14371 Res, DAG.getConstant(ShiftAmt, DL, MVT::i32));
14372
14373 // Do not add new nodes to DAG combiner worklist.
14374 DCI.CombineTo(N, Res, false);
14375 return SDValue();
14376}
14377
14380 const ARMSubtarget *Subtarget) {
14381 // Allow DAGCombine to pattern-match before we touch the canonical form.
14382 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14383 return SDValue();
14384
14385 if (N->getValueType(0) != MVT::i32)
14386 return SDValue();
14387
14388 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14389 if (!N1C)
14390 return SDValue();
14391
14392 uint32_t C1 = (uint32_t)N1C->getZExtValue();
14393 // Don't transform uxtb/uxth.
14394 if (C1 == 255 || C1 == 65535)
14395 return SDValue();
14396
14397 SDNode *N0 = N->getOperand(0).getNode();
14398 if (!N0->hasOneUse())
14399 return SDValue();
14400
14401 if (N0->getOpcode() != ISD::SHL && N0->getOpcode() != ISD::SRL)
14402 return SDValue();
14403
14404 bool LeftShift = N0->getOpcode() == ISD::SHL;
14405
14407 if (!N01C)
14408 return SDValue();
14409
14410 uint32_t C2 = (uint32_t)N01C->getZExtValue();
14411 if (!C2 || C2 >= 32)
14412 return SDValue();
14413
14414 // Clear irrelevant bits in the mask.
14415 if (LeftShift)
14416 C1 &= (-1U << C2);
14417 else
14418 C1 &= (-1U >> C2);
14419
14420 SelectionDAG &DAG = DCI.DAG;
14421 SDLoc DL(N);
14422
14423 // We have a pattern of the form "(and (shl x, c2) c1)" or
14424 // "(and (srl x, c2) c1)", where c1 is a shifted mask. Try to
14425 // transform to a pair of shifts, to save materializing c1.
14426
14427 // First pattern: right shift, then mask off leading bits.
14428 // FIXME: Use demanded bits?
14429 if (!LeftShift && isMask_32(C1)) {
14430 uint32_t C3 = llvm::countl_zero(C1);
14431 if (C2 < C3) {
14432 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14433 DAG.getConstant(C3 - C2, DL, MVT::i32));
14434 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14435 DAG.getConstant(C3, DL, MVT::i32));
14436 }
14437 }
14438
14439 // First pattern, reversed: left shift, then mask off trailing bits.
14440 if (LeftShift && isMask_32(~C1)) {
14441 uint32_t C3 = llvm::countr_zero(C1);
14442 if (C2 < C3) {
14443 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14444 DAG.getConstant(C3 - C2, DL, MVT::i32));
14445 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14446 DAG.getConstant(C3, DL, MVT::i32));
14447 }
14448 }
14449
14450 // Second pattern: left shift, then mask off leading bits.
14451 // FIXME: Use demanded bits?
14452 if (LeftShift && isShiftedMask_32(C1)) {
14453 uint32_t Trailing = llvm::countr_zero(C1);
14454 uint32_t C3 = llvm::countl_zero(C1);
14455 if (Trailing == C2 && C2 + C3 < 32) {
14456 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14457 DAG.getConstant(C2 + C3, DL, MVT::i32));
14458 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14459 DAG.getConstant(C3, DL, MVT::i32));
14460 }
14461 }
14462
14463 // Second pattern, reversed: right shift, then mask off trailing bits.
14464 // FIXME: Handle other patterns of known/demanded bits.
14465 if (!LeftShift && isShiftedMask_32(C1)) {
14466 uint32_t Leading = llvm::countl_zero(C1);
14467 uint32_t C3 = llvm::countr_zero(C1);
14468 if (Leading == C2 && C2 + C3 < 32) {
14469 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14470 DAG.getConstant(C2 + C3, DL, MVT::i32));
14471 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14472 DAG.getConstant(C3, DL, MVT::i32));
14473 }
14474 }
14475
14476 // Transform "(and (shl x, c2) c1)" into "(shl (and x, c1>>c2), c2)"
14477 // if "c1 >> c2" is a cheaper immediate than "c1"
14478 if (LeftShift &&
14479 HasLowerConstantMaterializationCost(C1 >> C2, C1, Subtarget)) {
14480
14481 SDValue And = DAG.getNode(ISD::AND, DL, MVT::i32, N0->getOperand(0),
14482 DAG.getConstant(C1 >> C2, DL, MVT::i32));
14483 return DAG.getNode(ISD::SHL, DL, MVT::i32, And,
14484 DAG.getConstant(C2, DL, MVT::i32));
14485 }
14486
14487 return SDValue();
14488}
14489
14492 const ARMSubtarget *Subtarget) {
14493 // Attempt to use immediate-form VBIC
14494 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14495 SDLoc dl(N);
14496 EVT VT = N->getValueType(0);
14497 SelectionDAG &DAG = DCI.DAG;
14498
14499 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) || VT == MVT::v2i1 ||
14500 VT == MVT::v4i1 || VT == MVT::v8i1 || VT == MVT::v16i1)
14501 return SDValue();
14502
14503 APInt SplatBits, SplatUndef;
14504 unsigned SplatBitSize;
14505 bool HasAnyUndefs;
14506 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14507 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14508 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14509 SplatBitSize == 64) {
14510 EVT VbicVT;
14511 SDValue Val = isVMOVModifiedImm((~SplatBits).getZExtValue(),
14512 SplatUndef.getZExtValue(), SplatBitSize,
14513 DAG, dl, VbicVT, VT, OtherModImm);
14514 if (Val.getNode()) {
14515 SDValue Input =
14516 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VbicVT, N->getOperand(0));
14517 SDValue Vbic = DAG.getNode(ARMISD::VBICIMM, dl, VbicVT, Input, Val);
14518 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vbic);
14519 }
14520 }
14521 }
14522
14523 if (!Subtarget->isThumb1Only()) {
14524 // fold (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))
14525 if (SDValue Result = combineSelectAndUseCommutative(N, true, DCI))
14526 return Result;
14527
14528 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14529 return Result;
14530 }
14531
14532 if (Subtarget->isThumb1Only())
14533 if (SDValue Result = CombineANDShift(N, DCI, Subtarget))
14534 return Result;
14535
14536 return SDValue();
14537}
14538
14539// Try combining OR nodes to SMULWB, SMULWT.
14542 const ARMSubtarget *Subtarget) {
14543 if (!Subtarget->hasV6Ops() ||
14544 (Subtarget->isThumb() &&
14545 (!Subtarget->hasThumb2() || !Subtarget->hasDSP())))
14546 return SDValue();
14547
14548 SDValue SRL = OR->getOperand(0);
14549 SDValue SHL = OR->getOperand(1);
14550
14551 if (SRL.getOpcode() != ISD::SRL || SHL.getOpcode() != ISD::SHL) {
14552 SRL = OR->getOperand(1);
14553 SHL = OR->getOperand(0);
14554 }
14555 if (!isSRL16(SRL) || !isSHL16(SHL))
14556 return SDValue();
14557
14558 // The first operands to the shifts need to be the two results from the
14559 // same smul_lohi node.
14560 if ((SRL.getOperand(0).getNode() != SHL.getOperand(0).getNode()) ||
14561 SRL.getOperand(0).getOpcode() != ISD::SMUL_LOHI)
14562 return SDValue();
14563
14564 SDNode *SMULLOHI = SRL.getOperand(0).getNode();
14565 if (SRL.getOperand(0) != SDValue(SMULLOHI, 0) ||
14566 SHL.getOperand(0) != SDValue(SMULLOHI, 1))
14567 return SDValue();
14568
14569 // Now we have:
14570 // (or (srl (smul_lohi ?, ?), 16), (shl (smul_lohi ?, ?), 16)))
14571 // For SMUL[B|T] smul_lohi will take a 32-bit and a 16-bit arguments.
14572 // For SMUWB the 16-bit value will signed extended somehow.
14573 // For SMULWT only the SRA is required.
14574 // Check both sides of SMUL_LOHI
14575 SDValue OpS16 = SMULLOHI->getOperand(0);
14576 SDValue OpS32 = SMULLOHI->getOperand(1);
14577
14578 SelectionDAG &DAG = DCI.DAG;
14579 if (!isS16(OpS16, DAG) && !isSRA16(OpS16)) {
14580 OpS16 = OpS32;
14581 OpS32 = SMULLOHI->getOperand(0);
14582 }
14583
14584 SDLoc dl(OR);
14585 unsigned Opcode = 0;
14586 if (isS16(OpS16, DAG))
14587 Opcode = ARMISD::SMULWB;
14588 else if (isSRA16(OpS16)) {
14589 Opcode = ARMISD::SMULWT;
14590 OpS16 = OpS16->getOperand(0);
14591 }
14592 else
14593 return SDValue();
14594
14595 SDValue Res = DAG.getNode(Opcode, dl, MVT::i32, OpS32, OpS16);
14596 DAG.ReplaceAllUsesOfValueWith(SDValue(OR, 0), Res);
14597 return SDValue(OR, 0);
14598}
14599
14602 const ARMSubtarget *Subtarget) {
14603 // BFI is only available on V6T2+
14604 if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
14605 return SDValue();
14606
14607 EVT VT = N->getValueType(0);
14608 SDValue N0 = N->getOperand(0);
14609 SDValue N1 = N->getOperand(1);
14610 SelectionDAG &DAG = DCI.DAG;
14611 SDLoc DL(N);
14612 // 1) or (and A, mask), val => ARMbfi A, val, mask
14613 // iff (val & mask) == val
14614 //
14615 // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14616 // 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
14617 // && mask == ~mask2
14618 // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
14619 // && ~mask == mask2
14620 // (i.e., copy a bitfield value into another bitfield of the same width)
14621
14622 if (VT != MVT::i32)
14623 return SDValue();
14624
14625 SDValue N00 = N0.getOperand(0);
14626
14627 // The value and the mask need to be constants so we can verify this is
14628 // actually a bitfield set. If the mask is 0xffff, we can do better
14629 // via a movt instruction, so don't use BFI in that case.
14630 SDValue MaskOp = N0.getOperand(1);
14632 if (!MaskC)
14633 return SDValue();
14634 unsigned Mask = MaskC->getZExtValue();
14635 if (Mask == 0xffff)
14636 return SDValue();
14637 SDValue Res;
14638 // Case (1): or (and A, mask), val => ARMbfi A, val, mask
14640 if (N1C) {
14641 unsigned Val = N1C->getZExtValue();
14642 if ((Val & ~Mask) != Val)
14643 return SDValue();
14644
14645 if (ARM::isBitFieldInvertedMask(Mask)) {
14646 Val >>= llvm::countr_zero(~Mask);
14647
14648 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
14649 DAG.getConstant(Val, DL, MVT::i32),
14650 DAG.getConstant(Mask, DL, MVT::i32));
14651
14652 DCI.CombineTo(N, Res, false);
14653 // Return value from the original node to inform the combiner than N is
14654 // now dead.
14655 return SDValue(N, 0);
14656 }
14657 } else if (N1.getOpcode() == ISD::AND) {
14658 // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14660 if (!N11C)
14661 return SDValue();
14662 unsigned Mask2 = N11C->getZExtValue();
14663
14664 // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
14665 // as is to match.
14666 if (ARM::isBitFieldInvertedMask(Mask) &&
14667 (Mask == ~Mask2)) {
14668 // The pack halfword instruction works better for masks that fit it,
14669 // so use that when it's available.
14670 if (Subtarget->hasDSP() &&
14671 (Mask == 0xffff || Mask == 0xffff0000))
14672 return SDValue();
14673 // 2a
14674 unsigned amt = llvm::countr_zero(Mask2);
14675 Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
14676 DAG.getConstant(amt, DL, MVT::i32));
14677 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
14678 DAG.getConstant(Mask, DL, MVT::i32));
14679 DCI.CombineTo(N, Res, false);
14680 // Return value from the original node to inform the combiner than N is
14681 // now dead.
14682 return SDValue(N, 0);
14683 } else if (ARM::isBitFieldInvertedMask(~Mask) &&
14684 (~Mask == Mask2)) {
14685 // The pack halfword instruction works better for masks that fit it,
14686 // so use that when it's available.
14687 if (Subtarget->hasDSP() &&
14688 (Mask2 == 0xffff || Mask2 == 0xffff0000))
14689 return SDValue();
14690 // 2b
14691 unsigned lsb = llvm::countr_zero(Mask);
14692 Res = DAG.getNode(ISD::SRL, DL, VT, N00,
14693 DAG.getConstant(lsb, DL, MVT::i32));
14694 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
14695 DAG.getConstant(Mask2, DL, MVT::i32));
14696 DCI.CombineTo(N, Res, false);
14697 // Return value from the original node to inform the combiner than N is
14698 // now dead.
14699 return SDValue(N, 0);
14700 }
14701 }
14702
14703 if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
14704 N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
14706 // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
14707 // where lsb(mask) == #shamt and masked bits of B are known zero.
14708 SDValue ShAmt = N00.getOperand(1);
14709 unsigned ShAmtC = ShAmt->getAsZExtVal();
14710 unsigned LSB = llvm::countr_zero(Mask);
14711 if (ShAmtC != LSB)
14712 return SDValue();
14713
14714 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
14715 DAG.getConstant(~Mask, DL, MVT::i32));
14716
14717 DCI.CombineTo(N, Res, false);
14718 // Return value from the original node to inform the combiner than N is
14719 // now dead.
14720 return SDValue(N, 0);
14721 }
14722
14723 return SDValue();
14724}
14725
14726static bool isValidMVECond(unsigned CC, bool IsFloat) {
14727 switch (CC) {
14728 case ARMCC::EQ:
14729 case ARMCC::NE:
14730 case ARMCC::LE:
14731 case ARMCC::GT:
14732 case ARMCC::GE:
14733 case ARMCC::LT:
14734 return true;
14735 case ARMCC::HS:
14736 case ARMCC::HI:
14737 return !IsFloat;
14738 default:
14739 return false;
14740 };
14741}
14742
14744 if (N->getOpcode() == ARMISD::VCMP)
14745 return (ARMCC::CondCodes)N->getConstantOperandVal(2);
14746 else if (N->getOpcode() == ARMISD::VCMPZ)
14747 return (ARMCC::CondCodes)N->getConstantOperandVal(1);
14748 else
14749 llvm_unreachable("Not a VCMP/VCMPZ!");
14750}
14751
14754 return isValidMVECond(CC, N->getOperand(0).getValueType().isFloatingPoint());
14755}
14756
14758 const ARMSubtarget *Subtarget) {
14759 // Try to invert "or A, B" -> "and ~A, ~B", as the "and" is easier to chain
14760 // together with predicates
14761 EVT VT = N->getValueType(0);
14762 SDLoc DL(N);
14763 SDValue N0 = N->getOperand(0);
14764 SDValue N1 = N->getOperand(1);
14765
14766 auto IsFreelyInvertable = [&](SDValue V) {
14767 if (V->getOpcode() == ARMISD::VCMP || V->getOpcode() == ARMISD::VCMPZ)
14768 return CanInvertMVEVCMP(V);
14769 return false;
14770 };
14771
14772 // At least one operand must be freely invertable.
14773 if (!(IsFreelyInvertable(N0) || IsFreelyInvertable(N1)))
14774 return SDValue();
14775
14776 SDValue NewN0 = DAG.getLogicalNOT(DL, N0, VT);
14777 SDValue NewN1 = DAG.getLogicalNOT(DL, N1, VT);
14778 SDValue And = DAG.getNode(ISD::AND, DL, VT, NewN0, NewN1);
14779 return DAG.getLogicalNOT(DL, And, VT);
14780}
14781
14782// Try to form a NEON shift-{right, left}-and-insert (VSRI/VSLI) from:
14783// (or (and X, splat (i32 C1)), (srl Y, splat (i32 C2))) -> VSRI X, Y, #C2
14784// (or (and X, splat (i32 C1)), (shl Y, splat (i32 C2))) -> VSLI X, Y, #C2
14785// where C1 is a mask that preserves the bits not written by the shift/insert,
14786// i.e. `C1 == (1 << C2) - 1`.
14788 SDValue ShiftOp, EVT VT,
14789 SDLoc dl) {
14790 // Match (and X, Mask)
14791 if (AndOp.getOpcode() != ISD::AND)
14792 return SDValue();
14793
14794 SDValue X = AndOp.getOperand(0);
14795 SDValue Mask = AndOp.getOperand(1);
14796
14797 ConstantSDNode *MaskC = isConstOrConstSplat(Mask, false, true);
14798 if (!MaskC)
14799 return SDValue();
14800 APInt MaskBits =
14801 MaskC->getAPIntValue().trunc(Mask.getScalarValueSizeInBits());
14802
14803 // Match shift (srl/shl Y, CntVec)
14804 int64_t Cnt = 0;
14805 bool IsShiftRight = false;
14806 SDValue Y;
14807
14808 if (ShiftOp.getOpcode() == ARMISD::VSHRuIMM) {
14809 IsShiftRight = true;
14810 Y = ShiftOp.getOperand(0);
14811 Cnt = ShiftOp.getConstantOperandVal(1);
14812 } else if (ShiftOp.getOpcode() == ARMISD::VSHLIMM) {
14813 Y = ShiftOp.getOperand(0);
14814 Cnt = ShiftOp.getConstantOperandVal(1);
14815 } else {
14816 return SDValue();
14817 }
14818
14819 unsigned ElemBits = VT.getScalarSizeInBits();
14820 APInt RequiredMask = IsShiftRight
14821 ? APInt::getHighBitsSet(ElemBits, (unsigned)Cnt)
14822 : APInt::getLowBitsSet(ElemBits, (unsigned)Cnt);
14823 if (MaskBits != RequiredMask)
14824 return SDValue();
14825
14826 unsigned Opc = IsShiftRight ? ARMISD::VSRIIMM : ARMISD::VSLIIMM;
14827 return DAG.getNode(Opc, dl, VT, X, Y, DAG.getConstant(Cnt, dl, MVT::i32));
14828}
14829
14830/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
14832 const ARMSubtarget *Subtarget) {
14833 // Attempt to use immediate-form VORR
14834 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14835 SDLoc dl(N);
14836 EVT VT = N->getValueType(0);
14837 SelectionDAG &DAG = DCI.DAG;
14838
14839 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14840 return SDValue();
14841
14842 if (Subtarget->hasMVEIntegerOps() && (VT == MVT::v2i1 || VT == MVT::v4i1 ||
14843 VT == MVT::v8i1 || VT == MVT::v16i1))
14844 return PerformORCombine_i1(N, DAG, Subtarget);
14845
14846 APInt SplatBits, SplatUndef;
14847 unsigned SplatBitSize;
14848 bool HasAnyUndefs;
14849 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14850 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14851 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14852 SplatBitSize == 64) {
14853 EVT VorrVT;
14854 SDValue Val =
14855 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
14856 SplatBitSize, DAG, dl, VorrVT, VT, OtherModImm);
14857 if (Val.getNode()) {
14858 SDValue Input =
14859 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VorrVT, N->getOperand(0));
14860 SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
14861 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vorr);
14862 }
14863 }
14864 }
14865
14866 if (!Subtarget->isThumb1Only()) {
14867 // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
14868 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14869 return Result;
14870 if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
14871 return Result;
14872 }
14873
14874 SDValue N0 = N->getOperand(0);
14875 SDValue N1 = N->getOperand(1);
14876
14877 // (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
14878 // (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
14879 if (VT.isVector() &&
14880 ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
14881 (Subtarget->hasMVEIntegerOps() &&
14882 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
14883 if (SDValue ShiftInsert =
14884 PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
14885 return ShiftInsert;
14886
14887 if (SDValue ShiftInsert =
14888 PerformORCombineToShiftInsert(DAG, N1, N0, VT, dl))
14889 return ShiftInsert;
14890 }
14891
14892 // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
14893 if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
14895
14896 // The code below optimizes (or (and X, Y), Z).
14897 // The AND operand needs to have a single user to make these optimizations
14898 // profitable.
14899 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
14900 return SDValue();
14901
14902 APInt SplatUndef;
14903 unsigned SplatBitSize;
14904 bool HasAnyUndefs;
14905
14906 APInt SplatBits0, SplatBits1;
14909 // Ensure that the second operand of both ands are constants
14910 if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
14911 HasAnyUndefs) && !HasAnyUndefs) {
14912 if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
14913 HasAnyUndefs) && !HasAnyUndefs) {
14914 // Ensure that the bit width of the constants are the same and that
14915 // the splat arguments are logical inverses as per the pattern we
14916 // are trying to simplify.
14917 if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
14918 SplatBits0 == ~SplatBits1) {
14919 // Canonicalize the vector type to make instruction selection
14920 // simpler.
14921 EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
14922 SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
14923 N0->getOperand(1),
14924 N0->getOperand(0),
14925 N1->getOperand(0));
14926 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Result);
14927 }
14928 }
14929 }
14930 }
14931
14932 // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
14933 // reasonable.
14934 if (N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
14935 if (SDValue Res = PerformORCombineToBFI(N, DCI, Subtarget))
14936 return Res;
14937 }
14938
14939 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14940 return Result;
14941
14942 // (or x, (csinc 0, 0, cc)) -> (csinc x, 0, cc)
14943 // providing that the x is 0 or 1.
14944 SDValue CSINC = N1;
14945 SDValue Other = N0;
14946 if (CSINC.getOpcode() != ARMISD::CSINC)
14947 std::swap(CSINC, Other);
14948 if (CSINC.getOpcode() == ARMISD::CSINC &&
14949 isNullConstant(CSINC.getOperand(0)) &&
14950 isNullConstant(CSINC.getOperand(1)) &&
14952 return DAG.getNode(ARMISD::CSINC, dl, VT, Other, CSINC.getOperand(1),
14953 CSINC.getOperand(2), CSINC.getOperand(3));
14954
14955 return SDValue();
14956}
14957
14960 const ARMSubtarget *Subtarget) {
14961 EVT VT = N->getValueType(0);
14962 SelectionDAG &DAG = DCI.DAG;
14963
14964 if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14965 return SDValue();
14966
14967 if (!Subtarget->isThumb1Only()) {
14968 // fold (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
14969 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14970 return Result;
14971
14972 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14973 return Result;
14974 }
14975
14976 if (Subtarget->hasMVEIntegerOps()) {
14977 // fold (xor(vcmp/z, 1)) into a vcmp with the opposite condition.
14978 SDValue N0 = N->getOperand(0);
14979 SDValue N1 = N->getOperand(1);
14980 const TargetLowering *TLI = Subtarget->getTargetLowering();
14981 if (TLI->isConstTrueVal(N1) &&
14982 (N0->getOpcode() == ARMISD::VCMP || N0->getOpcode() == ARMISD::VCMPZ)) {
14983 if (CanInvertMVEVCMP(N0)) {
14984 SDLoc DL(N0);
14986
14988 Ops.push_back(N0->getOperand(0));
14989 if (N0->getOpcode() == ARMISD::VCMP)
14990 Ops.push_back(N0->getOperand(1));
14991 Ops.push_back(DAG.getConstant(CC, DL, MVT::i32));
14992 return DAG.getNode(N0->getOpcode(), DL, N0->getValueType(0), Ops);
14993 }
14994 }
14995 }
14996
14997 return SDValue();
14998}
14999
15000// ParseBFI - given a BFI instruction in N, extract the "from" value (Rn) and return it,
15001// and fill in FromMask and ToMask with (consecutive) bits in "from" to be extracted and
15002// their position in "to" (Rd).
15003static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask) {
15004 assert(N->getOpcode() == ARMISD::BFI);
15005
15006 SDValue From = N->getOperand(1);
15007 ToMask = ~N->getConstantOperandAPInt(2);
15008 FromMask = APInt::getLowBitsSet(ToMask.getBitWidth(), ToMask.popcount());
15009
15010 // If the Base came from a SHR #C, we can deduce that it is really testing bit
15011 // #C in the base of the SHR.
15012 if (From->getOpcode() == ISD::SRL &&
15013 isa<ConstantSDNode>(From->getOperand(1))) {
15014 APInt Shift = From->getConstantOperandAPInt(1);
15015 assert(Shift.getLimitedValue() < 32 && "Shift too large!");
15016 FromMask <<= Shift.getLimitedValue(31);
15017 From = From->getOperand(0);
15018 }
15019
15020 return From;
15021}
15022
15023// If A and B contain one contiguous set of bits, does A | B == A . B?
15024//
15025// Neither A nor B must be zero.
15026static bool BitsProperlyConcatenate(const APInt &A, const APInt &B) {
15027 unsigned LastActiveBitInA = A.countr_zero();
15028 unsigned FirstActiveBitInB = B.getBitWidth() - B.countl_zero() - 1;
15029 return LastActiveBitInA - 1 == FirstActiveBitInB;
15030}
15031
15033 // We have a BFI in N. Find a BFI it can combine with, if one exists.
15034 APInt ToMask, FromMask;
15035 SDValue From = ParseBFI(N, ToMask, FromMask);
15036 SDValue To = N->getOperand(0);
15037
15038 SDValue V = To;
15039 if (V.getOpcode() != ARMISD::BFI)
15040 return SDValue();
15041
15042 APInt NewToMask, NewFromMask;
15043 SDValue NewFrom = ParseBFI(V.getNode(), NewToMask, NewFromMask);
15044 if (NewFrom != From)
15045 return SDValue();
15046
15047 // Do the written bits conflict with any we've seen so far?
15048 if ((NewToMask & ToMask).getBoolValue())
15049 // Conflicting bits.
15050 return SDValue();
15051
15052 // Are the new bits contiguous when combined with the old bits?
15053 if (BitsProperlyConcatenate(ToMask, NewToMask) &&
15054 BitsProperlyConcatenate(FromMask, NewFromMask))
15055 return V;
15056 if (BitsProperlyConcatenate(NewToMask, ToMask) &&
15057 BitsProperlyConcatenate(NewFromMask, FromMask))
15058 return V;
15059
15060 return SDValue();
15061}
15062
15064 SDValue N0 = N->getOperand(0);
15065 SDValue N1 = N->getOperand(1);
15066
15067 if (N1.getOpcode() == ISD::AND) {
15068 // (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
15069 // the bits being cleared by the AND are not demanded by the BFI.
15071 if (!N11C)
15072 return SDValue();
15073 unsigned InvMask = N->getConstantOperandVal(2);
15074 unsigned LSB = llvm::countr_zero(~InvMask);
15075 unsigned Width = llvm::bit_width<unsigned>(~InvMask) - LSB;
15076 assert(Width <
15077 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
15078 "undefined behavior");
15079 unsigned Mask = (1u << Width) - 1;
15080 unsigned Mask2 = N11C->getZExtValue();
15081 if ((Mask & (~Mask2)) == 0)
15082 return DAG.getNode(ARMISD::BFI, SDLoc(N), N->getValueType(0),
15083 N->getOperand(0), N1.getOperand(0), N->getOperand(2));
15084 return SDValue();
15085 }
15086
15087 // Look for another BFI to combine with.
15088 if (SDValue CombineBFI = FindBFIToCombineWith(N)) {
15089 // We've found a BFI.
15090 APInt ToMask1, FromMask1;
15091 SDValue From1 = ParseBFI(N, ToMask1, FromMask1);
15092
15093 APInt ToMask2, FromMask2;
15094 SDValue From2 = ParseBFI(CombineBFI.getNode(), ToMask2, FromMask2);
15095 assert(From1 == From2);
15096 (void)From2;
15097
15098 // Create a new BFI, combining the two together.
15099 APInt NewFromMask = FromMask1 | FromMask2;
15100 APInt NewToMask = ToMask1 | ToMask2;
15101
15102 EVT VT = N->getValueType(0);
15103 SDLoc dl(N);
15104
15105 if (NewFromMask[0] == 0)
15106 From1 = DAG.getNode(ISD::SRL, dl, VT, From1,
15107 DAG.getConstant(NewFromMask.countr_zero(), dl, VT));
15108 return DAG.getNode(ARMISD::BFI, dl, VT, CombineBFI.getOperand(0), From1,
15109 DAG.getConstant(~NewToMask, dl, VT));
15110 }
15111
15112 // Reassociate BFI(BFI (A, B, M1), C, M2) to BFI(BFI (A, C, M2), B, M1) so
15113 // that lower bit insertions are performed first, providing that M1 and M2
15114 // do no overlap. This can allow multiple BFI instructions to be combined
15115 // together by the other folds above.
15116 if (N->getOperand(0).getOpcode() == ARMISD::BFI) {
15117 APInt ToMask1 = ~N->getConstantOperandAPInt(2);
15118 APInt ToMask2 = ~N0.getConstantOperandAPInt(2);
15119
15120 if (!N0.hasOneUse() || (ToMask1 & ToMask2) != 0 ||
15121 ToMask1.countl_zero() < ToMask2.countl_zero())
15122 return SDValue();
15123
15124 EVT VT = N->getValueType(0);
15125 SDLoc dl(N);
15126 SDValue BFI1 = DAG.getNode(ARMISD::BFI, dl, VT, N0.getOperand(0),
15127 N->getOperand(1), N->getOperand(2));
15128 return DAG.getNode(ARMISD::BFI, dl, VT, BFI1, N0.getOperand(1),
15129 N0.getOperand(2));
15130 }
15131
15132 return SDValue();
15133}
15134
15135// Check that N is CMPZ(CSINC(0, 0, CC, X)),
15136// or CMPZ(CMOV(1, 0, CC, X))
15137// return X if valid.
15139 if (Cmp->getOpcode() != ARMISD::CMPZ || !isNullConstant(Cmp->getOperand(1)))
15140 return SDValue();
15141 SDValue CSInc = Cmp->getOperand(0);
15142
15143 // Ignore any `And 1` nodes that may not yet have been removed. We are
15144 // looking for a value that produces 1/0, so these have no effect on the
15145 // code.
15146 while (CSInc.getOpcode() == ISD::AND &&
15147 isa<ConstantSDNode>(CSInc.getOperand(1)) &&
15148 CSInc.getConstantOperandVal(1) == 1 && CSInc->hasOneUse())
15149 CSInc = CSInc.getOperand(0);
15150
15151 if (CSInc.getOpcode() == ARMISD::CSINC &&
15152 isNullConstant(CSInc.getOperand(0)) &&
15153 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15155 return CSInc.getOperand(3);
15156 }
15157 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(0)) &&
15158 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15160 return CSInc.getOperand(3);
15161 }
15162 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(CSInc.getOperand(1)) &&
15163 isNullConstant(CSInc.getOperand(0)) && CSInc->hasOneUse()) {
15166 return CSInc.getOperand(3);
15167 }
15168 return SDValue();
15169}
15170
15172 // Given CMPZ(CSINC(C, 0, 0, EQ), 0), we can just use C directly. As in
15173 // t92: flags = ARMISD::CMPZ t74, 0
15174 // t93: i32 = ARMISD::CSINC 0, 0, 1, t92
15175 // t96: flags = ARMISD::CMPZ t93, 0
15176 // t114: i32 = ARMISD::CSINV 0, 0, 0, t96
15178 if (SDValue C = IsCMPZCSINC(N, Cond))
15179 if (Cond == ARMCC::EQ)
15180 return C;
15181 return SDValue();
15182}
15183
15185 // Fold away an unnecessary CMPZ/CSINC
15186 // CSXYZ A, B, C1 (CMPZ (CSINC 0, 0, C2, D), 0) ->
15187 // if C1==EQ -> CSXYZ A, B, C2, D
15188 // if C1==NE -> CSXYZ A, B, NOT(C2), D
15190 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
15191 if (N->getConstantOperandVal(2) == ARMCC::EQ)
15192 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15193 N->getOperand(1),
15194 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
15195 if (N->getConstantOperandVal(2) == ARMCC::NE)
15196 return DAG.getNode(
15197 N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15198 N->getOperand(1),
15200 }
15201 return SDValue();
15202}
15203
15204/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
15205/// ARMISD::VMOVRRD.
15208 const ARMSubtarget *Subtarget) {
15209 // vmovrrd(vmovdrr x, y) -> x,y
15210 SDValue InDouble = N->getOperand(0);
15211 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
15212 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
15213
15214 // vmovrrd(load f64) -> (load i32), (load i32)
15215 SDNode *InNode = InDouble.getNode();
15216 if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
15217 InNode->getValueType(0) == MVT::f64 &&
15218 InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
15219 !cast<LoadSDNode>(InNode)->isVolatile()) {
15220 // TODO: Should this be done for non-FrameIndex operands?
15221 LoadSDNode *LD = cast<LoadSDNode>(InNode);
15222
15223 SelectionDAG &DAG = DCI.DAG;
15224 SDLoc DL(LD);
15225 SDValue BasePtr = LD->getBasePtr();
15226 SDValue NewLD1 =
15227 DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, LD->getPointerInfo(),
15228 LD->getAlign(), LD->getMemOperand()->getFlags());
15229
15230 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
15231 DAG.getConstant(4, DL, MVT::i32));
15232
15233 SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, LD->getChain(), OffsetPtr,
15234 LD->getPointerInfo().getWithOffset(4),
15235 commonAlignment(LD->getAlign(), 4),
15236 LD->getMemOperand()->getFlags());
15237
15238 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
15239 if (DCI.DAG.getDataLayout().isBigEndian())
15240 std::swap (NewLD1, NewLD2);
15241 SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
15242 return Result;
15243 }
15244
15245 // VMOVRRD(extract(..(build_vector(a, b, c, d)))) -> a,b or c,d
15246 // VMOVRRD(extract(insert_vector(insert_vector(.., a, l1), b, l2))) -> a,b
15247 if (InDouble.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15248 isa<ConstantSDNode>(InDouble.getOperand(1))) {
15249 SDValue BV = InDouble.getOperand(0);
15250 // Look up through any nop bitcasts and vector_reg_casts. bitcasts may
15251 // change lane order under big endian.
15252 bool BVSwap = BV.getOpcode() == ISD::BITCAST;
15253 while (
15254 (BV.getOpcode() == ISD::BITCAST ||
15255 BV.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
15256 (BV.getValueType() == MVT::v2f64 || BV.getValueType() == MVT::v2i64)) {
15257 BVSwap = BV.getOpcode() == ISD::BITCAST;
15258 BV = BV.getOperand(0);
15259 }
15260 if (BV.getValueType() != MVT::v4i32)
15261 return SDValue();
15262
15263 // Handle buildvectors, pulling out the correct lane depending on
15264 // endianness.
15265 unsigned Offset = InDouble.getConstantOperandVal(1) == 1 ? 2 : 0;
15266 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
15267 SDValue Op0 = BV.getOperand(Offset);
15268 SDValue Op1 = BV.getOperand(Offset + 1);
15269 if (!Subtarget->isLittle() && BVSwap)
15270 std::swap(Op0, Op1);
15271
15272 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15273 }
15274
15275 // A chain of insert_vectors, grabbing the correct value of the chain of
15276 // inserts.
15277 SDValue Op0, Op1;
15278 while (BV.getOpcode() == ISD::INSERT_VECTOR_ELT) {
15279 if (isa<ConstantSDNode>(BV.getOperand(2))) {
15280 if (BV.getConstantOperandVal(2) == Offset && !Op0)
15281 Op0 = BV.getOperand(1);
15282 if (BV.getConstantOperandVal(2) == Offset + 1 && !Op1)
15283 Op1 = BV.getOperand(1);
15284 }
15285 BV = BV.getOperand(0);
15286 }
15287 if (!Subtarget->isLittle() && BVSwap)
15288 std::swap(Op0, Op1);
15289 if (Op0 && Op1)
15290 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15291 }
15292
15293 return SDValue();
15294}
15295
15296/// PerformVMOVDRRCombine - Target-specific dag combine xforms for
15297/// ARMISD::VMOVDRR. This is also used for BUILD_VECTORs with 2 operands.
15299 // N=vmovrrd(X); vmovdrr(N:0, N:1) -> bit_convert(X)
15300 SDValue Op0 = N->getOperand(0);
15301 SDValue Op1 = N->getOperand(1);
15302 if (Op0.getOpcode() == ISD::BITCAST)
15303 Op0 = Op0.getOperand(0);
15304 if (Op1.getOpcode() == ISD::BITCAST)
15305 Op1 = Op1.getOperand(0);
15306 if (Op0.getOpcode() == ARMISD::VMOVRRD &&
15307 Op0.getNode() == Op1.getNode() &&
15308 Op0.getResNo() == 0 && Op1.getResNo() == 1)
15309 return DAG.getNode(ISD::BITCAST, SDLoc(N),
15310 N->getValueType(0), Op0.getOperand(0));
15311 return SDValue();
15312}
15313
15316 SDValue Op0 = N->getOperand(0);
15317
15318 // VMOVhr (VMOVrh (X)) -> X
15319 if (Op0->getOpcode() == ARMISD::VMOVrh)
15320 return Op0->getOperand(0);
15321
15322 // FullFP16: half values are passed in S-registers, and we don't
15323 // need any of the bitcast and moves:
15324 //
15325 // t2: f32,ch1,gl1? = CopyFromReg ch, Register:f32 %0, gl?
15326 // t5: i32 = bitcast t2
15327 // t18: f16 = ARMISD::VMOVhr t5
15328 // =>
15329 // tN: f16,ch2,gl2? = CopyFromReg ch, Register::f32 %0, gl?
15330 if (Op0->getOpcode() == ISD::BITCAST) {
15331 SDValue Copy = Op0->getOperand(0);
15332 if (Copy.getValueType() == MVT::f32 &&
15333 Copy->getOpcode() == ISD::CopyFromReg) {
15334 bool HasGlue = Copy->getNumOperands() == 3;
15335 SDValue Ops[] = {Copy->getOperand(0), Copy->getOperand(1),
15336 HasGlue ? Copy->getOperand(2) : SDValue()};
15337 EVT OutTys[] = {N->getValueType(0), MVT::Other, MVT::Glue};
15338 SDValue NewCopy =
15340 DCI.DAG.getVTList(ArrayRef(OutTys, HasGlue ? 3 : 2)),
15341 ArrayRef(Ops, HasGlue ? 3 : 2));
15342
15343 // Update Users, Chains, and Potential Glue.
15344 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), NewCopy.getValue(0));
15345 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(1), NewCopy.getValue(1));
15346 if (HasGlue)
15347 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(2),
15348 NewCopy.getValue(2));
15349
15350 return NewCopy;
15351 }
15352 }
15353
15354 // fold (VMOVhr (load x)) -> (load (f16*)x)
15355 if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(Op0)) {
15356 if (LN0->hasOneUse() && LN0->isUnindexed() &&
15357 LN0->getMemoryVT() == MVT::i16) {
15358 SDValue Load =
15359 DCI.DAG.getLoad(N->getValueType(0), SDLoc(N), LN0->getChain(),
15360 LN0->getBasePtr(), LN0->getMemOperand());
15361 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15362 DCI.DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Load.getValue(1));
15363 return Load;
15364 }
15365 }
15366
15367 // Only the bottom 16 bits of the source register are used.
15368 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15369 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15370 if (TLI.SimplifyDemandedBits(Op0, DemandedMask, DCI))
15371 return SDValue(N, 0);
15372
15373 return SDValue();
15374}
15375
15377 SDValue N0 = N->getOperand(0);
15378 EVT VT = N->getValueType(0);
15379
15380 // fold (VMOVrh (fpconst x)) -> const x
15382 APFloat V = C->getValueAPF();
15383 return DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
15384 }
15385
15386 // fold (VMOVrh (load x)) -> (zextload (i16*)x)
15387 if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
15388 LoadSDNode *LN0 = cast<LoadSDNode>(N0);
15389
15390 SDValue Load =
15391 DAG.getExtLoad(ISD::ZEXTLOAD, SDLoc(N), VT, LN0->getChain(),
15392 LN0->getBasePtr(), MVT::i16, LN0->getMemOperand());
15393 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15394 DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
15395 return Load;
15396 }
15397
15398 // Fold VMOVrh(extract(x, n)) -> vgetlaneu(x, n)
15399 if (N0->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15401 return DAG.getNode(ARMISD::VGETLANEu, SDLoc(N), VT, N0->getOperand(0),
15402 N0->getOperand(1));
15403
15404 return SDValue();
15405}
15406
15407/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
15408/// are normal, non-volatile loads. If so, it is profitable to bitcast an
15409/// i64 vector to have f64 elements, since the value can then be loaded
15410/// directly into a VFP register.
15412 unsigned NumElts = N->getValueType(0).getVectorNumElements();
15413 for (unsigned i = 0; i < NumElts; ++i) {
15414 SDNode *Elt = N->getOperand(i).getNode();
15415 if (ISD::isNormalLoad(Elt) && !cast<LoadSDNode>(Elt)->isVolatile())
15416 return true;
15417 }
15418 return false;
15419}
15420
15421/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for
15422/// ISD::BUILD_VECTOR.
15425 const ARMSubtarget *Subtarget) {
15426 // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X):
15427 // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value
15428 // into a pair of GPRs, which is fine when the value is used as a scalar,
15429 // but if the i64 value is converted to a vector, we need to undo the VMOVRRD.
15430 SelectionDAG &DAG = DCI.DAG;
15431 if (N->getNumOperands() == 2)
15432 if (SDValue RV = PerformVMOVDRRCombine(N, DAG))
15433 return RV;
15434
15435 // Load i64 elements as f64 values so that type legalization does not split
15436 // them up into i32 values.
15437 EVT VT = N->getValueType(0);
15438 if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N))
15439 return SDValue();
15440 SDLoc dl(N);
15442 unsigned NumElts = VT.getVectorNumElements();
15443 for (unsigned i = 0; i < NumElts; ++i) {
15444 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i));
15445 Ops.push_back(V);
15446 // Make the DAGCombiner fold the bitcast.
15447 DCI.AddToWorklist(V.getNode());
15448 }
15449 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts);
15450 SDValue BV = DAG.getBuildVector(FloatVT, dl, Ops);
15451 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
15452}
15453
15454/// Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
15455static SDValue
15457 // ARMISD::BUILD_VECTOR is introduced when legalizing ISD::BUILD_VECTOR.
15458 // At that time, we may have inserted bitcasts from integer to float.
15459 // If these bitcasts have survived DAGCombine, change the lowering of this
15460 // BUILD_VECTOR in something more vector friendly, i.e., that does not
15461 // force to use floating point types.
15462
15463 // Make sure we can change the type of the vector.
15464 // This is possible iff:
15465 // 1. The vector is only used in a bitcast to a integer type. I.e.,
15466 // 1.1. Vector is used only once.
15467 // 1.2. Use is a bit convert to an integer type.
15468 // 2. The size of its operands are 32-bits (64-bits are not legal).
15469 EVT VT = N->getValueType(0);
15470 EVT EltVT = VT.getVectorElementType();
15471
15472 // Check 1.1. and 2.
15473 if (EltVT.getSizeInBits() != 32 || !N->hasOneUse())
15474 return SDValue();
15475
15476 // By construction, the input type must be float.
15477 assert(EltVT == MVT::f32 && "Unexpected type!");
15478
15479 // Check 1.2.
15480 SDNode *Use = *N->user_begin();
15481 if (Use->getOpcode() != ISD::BITCAST ||
15482 Use->getValueType(0).isFloatingPoint())
15483 return SDValue();
15484
15485 // Check profitability.
15486 // Model is, if more than half of the relevant operands are bitcast from
15487 // i32, turn the build_vector into a sequence of insert_vector_elt.
15488 // Relevant operands are everything that is not statically
15489 // (i.e., at compile time) bitcasted.
15490 unsigned NumOfBitCastedElts = 0;
15491 unsigned NumElts = VT.getVectorNumElements();
15492 unsigned NumOfRelevantElts = NumElts;
15493 for (unsigned Idx = 0; Idx < NumElts; ++Idx) {
15494 SDValue Elt = N->getOperand(Idx);
15495 if (Elt->getOpcode() == ISD::BITCAST) {
15496 // Assume only bit cast to i32 will go away.
15497 if (Elt->getOperand(0).getValueType() == MVT::i32)
15498 ++NumOfBitCastedElts;
15499 } else if (Elt.isUndef() || isa<ConstantSDNode>(Elt))
15500 // Constants are statically casted, thus do not count them as
15501 // relevant operands.
15502 --NumOfRelevantElts;
15503 }
15504
15505 // Check if more than half of the elements require a non-free bitcast.
15506 if (NumOfBitCastedElts <= NumOfRelevantElts / 2)
15507 return SDValue();
15508
15509 SelectionDAG &DAG = DCI.DAG;
15510 // Create the new vector type.
15511 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
15512 // Check if the type is legal.
15513 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15514 if (!TLI.isTypeLegal(VecVT))
15515 return SDValue();
15516
15517 // Combine:
15518 // ARMISD::BUILD_VECTOR E1, E2, ..., EN.
15519 // => BITCAST INSERT_VECTOR_ELT
15520 // (INSERT_VECTOR_ELT (...), (BITCAST EN-1), N-1),
15521 // (BITCAST EN), N.
15522 SDValue Vec = DAG.getUNDEF(VecVT);
15523 SDLoc dl(N);
15524 for (unsigned Idx = 0 ; Idx < NumElts; ++Idx) {
15525 SDValue V = N->getOperand(Idx);
15526 if (V.isUndef())
15527 continue;
15528 if (V.getOpcode() == ISD::BITCAST &&
15529 V->getOperand(0).getValueType() == MVT::i32)
15530 // Fold obvious case.
15531 V = V.getOperand(0);
15532 else {
15533 V = DAG.getNode(ISD::BITCAST, SDLoc(V), MVT::i32, V);
15534 // Make the DAGCombiner fold the bitcasts.
15535 DCI.AddToWorklist(V.getNode());
15536 }
15537 SDValue LaneIdx = DAG.getConstant(Idx, dl, MVT::i32);
15538 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Vec, V, LaneIdx);
15539 }
15540 Vec = DAG.getNode(ISD::BITCAST, dl, VT, Vec);
15541 // Make the DAGCombiner fold the bitcasts.
15542 DCI.AddToWorklist(Vec.getNode());
15543 return Vec;
15544}
15545
15546static SDValue
15548 EVT VT = N->getValueType(0);
15549 SDValue Op = N->getOperand(0);
15550 SDLoc dl(N);
15551
15552 // PREDICATE_CAST(PREDICATE_CAST(x)) == PREDICATE_CAST(x)
15553 if (Op->getOpcode() == ARMISD::PREDICATE_CAST) {
15554 // If the valuetypes are the same, we can remove the cast entirely.
15555 if (Op->getOperand(0).getValueType() == VT)
15556 return Op->getOperand(0);
15557 return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15558 }
15559
15560 // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
15561 // more VPNOT which might get folded as else predicates.
15562 if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
15563 SDValue X =
15564 DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15565 SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
15566 DCI.DAG.getConstant(65535, dl, MVT::i32));
15567 return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
15568 }
15569
15570 // Only the bottom 16 bits of the source register are used.
15571 if (Op.getValueType() == MVT::i32) {
15572 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15573 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15574 if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
15575 return SDValue(N, 0);
15576 }
15577 return SDValue();
15578}
15579
15581 const ARMSubtarget *ST) {
15582 EVT VT = N->getValueType(0);
15583 SDValue Op = N->getOperand(0);
15584 SDLoc dl(N);
15585
15586 // Under Little endian, a VECTOR_REG_CAST is equivalent to a BITCAST
15587 if (ST->isLittle())
15588 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
15589
15590 // VT VECTOR_REG_CAST (VT Op) -> Op
15591 if (Op.getValueType() == VT)
15592 return Op;
15593 // VECTOR_REG_CAST undef -> undef
15594 if (Op.isUndef())
15595 return DAG.getUNDEF(VT);
15596
15597 // VECTOR_REG_CAST(VECTOR_REG_CAST(x)) == VECTOR_REG_CAST(x)
15598 if (Op->getOpcode() == ARMISD::VECTOR_REG_CAST) {
15599 // If the valuetypes are the same, we can remove the cast entirely.
15600 if (Op->getOperand(0).getValueType() == VT)
15601 return Op->getOperand(0);
15602 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Op->getOperand(0));
15603 }
15604
15605 return SDValue();
15606}
15607
15609 const ARMSubtarget *Subtarget) {
15610 if (!Subtarget->hasMVEIntegerOps())
15611 return SDValue();
15612
15613 EVT VT = N->getValueType(0);
15614 SDValue Op0 = N->getOperand(0);
15615 SDValue Op1 = N->getOperand(1);
15616 ARMCC::CondCodes Cond = (ARMCC::CondCodes)N->getConstantOperandVal(2);
15617 SDLoc dl(N);
15618
15619 // vcmp X, 0, cc -> vcmpz X, cc
15620 if (isZeroVector(Op1))
15621 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op0, N->getOperand(2));
15622
15623 unsigned SwappedCond = getSwappedCondition(Cond);
15624 if (isValidMVECond(SwappedCond, VT.isFloatingPoint())) {
15625 // vcmp 0, X, cc -> vcmpz X, reversed(cc)
15626 if (isZeroVector(Op0))
15627 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op1,
15628 DAG.getConstant(SwappedCond, dl, MVT::i32));
15629 // vcmp vdup(Y), X, cc -> vcmp X, vdup(Y), reversed(cc)
15630 if (Op0->getOpcode() == ARMISD::VDUP && Op1->getOpcode() != ARMISD::VDUP)
15631 return DAG.getNode(ARMISD::VCMP, dl, VT, Op1, Op0,
15632 DAG.getConstant(SwappedCond, dl, MVT::i32));
15633 }
15634
15635 return SDValue();
15636}
15637
15638/// PerformInsertEltCombine - Target-specific dag combine xforms for
15639/// ISD::INSERT_VECTOR_ELT.
15642 // Bitcast an i64 load inserted into a vector to f64.
15643 // Otherwise, the i64 value will be legalized to a pair of i32 values.
15644 EVT VT = N->getValueType(0);
15645 SDNode *Elt = N->getOperand(1).getNode();
15646 if (VT.getVectorElementType() != MVT::i64 ||
15647 !ISD::isNormalLoad(Elt) || cast<LoadSDNode>(Elt)->isVolatile())
15648 return SDValue();
15649
15650 SelectionDAG &DAG = DCI.DAG;
15651 SDLoc dl(N);
15652 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
15654 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0));
15655 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1));
15656 // Make the DAGCombiner fold the bitcasts.
15657 DCI.AddToWorklist(Vec.getNode());
15658 DCI.AddToWorklist(V.getNode());
15659 SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT,
15660 Vec, V, N->getOperand(2));
15661 return DAG.getNode(ISD::BITCAST, dl, VT, InsElt);
15662}
15663
15664// Convert a pair of extracts from the same base vector to a VMOVRRD. Either
15665// directly or bitcast to an integer if the original is a float vector.
15666// extract(x, n); extract(x, n+1) -> VMOVRRD(extract v2f64 x, n/2)
15667// bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD(extract x, n/2)
15668static SDValue
15670 EVT VT = N->getValueType(0);
15671 SDLoc dl(N);
15672
15673 if (!DCI.isAfterLegalizeDAG() || VT != MVT::i32 ||
15674 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(MVT::f64))
15675 return SDValue();
15676
15677 SDValue Ext = SDValue(N, 0);
15678 if (Ext.getOpcode() == ISD::BITCAST &&
15679 Ext.getOperand(0).getValueType() == MVT::f32)
15680 Ext = Ext.getOperand(0);
15681 if (Ext.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
15683 Ext.getConstantOperandVal(1) % 2 != 0)
15684 return SDValue();
15685 if (Ext->hasOneUse() && (Ext->user_begin()->getOpcode() == ISD::SINT_TO_FP ||
15686 Ext->user_begin()->getOpcode() == ISD::UINT_TO_FP))
15687 return SDValue();
15688
15689 SDValue Op0 = Ext.getOperand(0);
15690 EVT VecVT = Op0.getValueType();
15691 unsigned ResNo = Op0.getResNo();
15692 unsigned Lane = Ext.getConstantOperandVal(1);
15693 if (VecVT.getVectorNumElements() != 4)
15694 return SDValue();
15695
15696 // Find another extract, of Lane + 1
15697 auto OtherIt = find_if(Op0->users(), [&](SDNode *V) {
15698 return V->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15699 isa<ConstantSDNode>(V->getOperand(1)) &&
15700 V->getConstantOperandVal(1) == Lane + 1 &&
15701 V->getOperand(0).getResNo() == ResNo;
15702 });
15703 if (OtherIt == Op0->users().end())
15704 return SDValue();
15705
15706 // For float extracts, we need to be converting to a i32 for both vector
15707 // lanes.
15708 SDValue OtherExt(*OtherIt, 0);
15709 if (OtherExt.getValueType() != MVT::i32) {
15710 if (!OtherExt->hasOneUse() ||
15711 OtherExt->user_begin()->getOpcode() != ISD::BITCAST ||
15712 OtherExt->user_begin()->getValueType(0) != MVT::i32)
15713 return SDValue();
15714 OtherExt = SDValue(*OtherExt->user_begin(), 0);
15715 }
15716
15717 // Convert the type to a f64 and extract with a VMOVRRD.
15718 SDValue F64 = DCI.DAG.getNode(
15719 ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
15720 DCI.DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v2f64, Op0),
15721 DCI.DAG.getConstant(Ext.getConstantOperandVal(1) / 2, dl, MVT::i32));
15722 SDValue VMOVRRD =
15723 DCI.DAG.getNode(ARMISD::VMOVRRD, dl, {MVT::i32, MVT::i32}, F64);
15724
15725 DCI.CombineTo(OtherExt.getNode(), SDValue(VMOVRRD.getNode(), 1));
15726 return VMOVRRD;
15727}
15728
15731 const ARMSubtarget *ST) {
15732 SDValue Op0 = N->getOperand(0);
15733 EVT VT = N->getValueType(0);
15734 SDLoc dl(N);
15735
15736 // extract (vdup x) -> x
15737 if (Op0->getOpcode() == ARMISD::VDUP) {
15738 SDValue X = Op0->getOperand(0);
15739 if (VT == MVT::f16 && X.getValueType() == MVT::i32)
15740 return DCI.DAG.getNode(ARMISD::VMOVhr, dl, VT, X);
15741 if (VT == MVT::i32 && X.getValueType() == MVT::f16)
15742 return DCI.DAG.getNode(ARMISD::VMOVrh, dl, VT, X);
15743 if (VT == MVT::f32 && X.getValueType() == MVT::i32)
15744 return DCI.DAG.getNode(ISD::BITCAST, dl, VT, X);
15745
15746 while (X.getValueType() != VT && X->getOpcode() == ISD::BITCAST)
15747 X = X->getOperand(0);
15748 if (X.getValueType() == VT)
15749 return X;
15750 }
15751
15752 // extract ARM_BUILD_VECTOR -> x
15753 if (Op0->getOpcode() == ARMISD::BUILD_VECTOR &&
15754 isa<ConstantSDNode>(N->getOperand(1)) &&
15755 N->getConstantOperandVal(1) < Op0.getNumOperands()) {
15756 return Op0.getOperand(N->getConstantOperandVal(1));
15757 }
15758
15759 // extract(bitcast(BUILD_VECTOR(VMOVDRR(a, b), ..))) -> a or b
15760 if (Op0.getValueType() == MVT::v4i32 &&
15761 isa<ConstantSDNode>(N->getOperand(1)) &&
15762 Op0.getOpcode() == ISD::BITCAST &&
15764 Op0.getOperand(0).getValueType() == MVT::v2f64) {
15765 SDValue BV = Op0.getOperand(0);
15766 unsigned Offset = N->getConstantOperandVal(1);
15767 SDValue MOV = BV.getOperand(Offset < 2 ? 0 : 1);
15768 if (MOV.getOpcode() == ARMISD::VMOVDRR)
15769 return MOV.getOperand(ST->isLittle() ? Offset % 2 : 1 - Offset % 2);
15770 }
15771
15772 // extract x, n; extract x, n+1 -> VMOVRRD x
15773 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
15774 return R;
15775
15776 // extract (MVETrunc(x)) -> extract x
15777 if (Op0->getOpcode() == ARMISD::MVETRUNC) {
15778 unsigned Idx = N->getConstantOperandVal(1);
15779 unsigned Vec =
15781 unsigned SubIdx =
15783 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Op0.getOperand(Vec),
15784 DCI.DAG.getConstant(SubIdx, dl, MVT::i32));
15785 }
15786
15787 // extract(bitcast(BUILD_VECTOR(extract(bitcast(a)), ..))) -> extract(a)
15788 if (ST->isLittle() && Op0.getOpcode() == ISD::BITCAST &&
15790 isa<ConstantSDNode>(N->getOperand(1)) &&
15793 unsigned Lane = N->getConstantOperandVal(1);
15794 EVT ExtVT = Op0.getValueType();
15795 EVT BVVT = Op0.getOperand(0).getValueType();
15796 unsigned BVLane =
15797 (Lane * BVVT.getVectorNumElements()) / ExtVT.getVectorNumElements();
15798 assert(BVLane < Op0.getOperand(0).getNumOperands());
15799 SDValue Ext = Op0.getOperand(0).getOperand(BVLane);
15800 if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15801 Ext.getOperand(0).getOpcode() == ISD::BITCAST &&
15803 Ext.getOperand(0).getOperand(0).getValueType() == ExtVT) {
15804 unsigned InnerLane = Ext.getConstantOperandVal(1);
15805 unsigned BVSubLane = Lane - (BVLane * ExtVT.getVectorNumElements()) /
15806 BVVT.getVectorNumElements();
15807 unsigned FinalLane = (InnerLane * ExtVT.getVectorNumElements()) /
15808 BVVT.getVectorNumElements() +
15809 BVSubLane;
15810 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT,
15811 Ext.getOperand(0).getOperand(0),
15812 DCI.DAG.getConstant(FinalLane, dl, MVT::i32));
15813 }
15814 }
15815
15816 return SDValue();
15817}
15818
15820 SDValue Op = N->getOperand(0);
15821 EVT VT = N->getValueType(0);
15822
15823 // sext_inreg(VGETLANEu) -> VGETLANEs
15824 if (Op.getOpcode() == ARMISD::VGETLANEu &&
15825 cast<VTSDNode>(N->getOperand(1))->getVT() ==
15826 Op.getOperand(0).getValueType().getScalarType())
15827 return DAG.getNode(ARMISD::VGETLANEs, SDLoc(N), VT, Op.getOperand(0),
15828 Op.getOperand(1));
15829
15830 return SDValue();
15831}
15832
15833static SDValue
15835 SDValue Vec = N->getOperand(0);
15836 SDValue SubVec = N->getOperand(1);
15837 uint64_t IdxVal = N->getConstantOperandVal(2);
15838 EVT VecVT = Vec.getValueType();
15839 EVT SubVT = SubVec.getValueType();
15840
15841 // Only do this for legal fixed vector types.
15842 if (!VecVT.isFixedLengthVector() ||
15843 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(VecVT) ||
15845 return SDValue();
15846
15847 // Ignore widening patterns.
15848 if (IdxVal == 0 && Vec.isUndef())
15849 return SDValue();
15850
15851 // Subvector must be half the width and an "aligned" insertion.
15852 unsigned NumSubElts = SubVT.getVectorNumElements();
15853 if ((SubVT.getSizeInBits() * 2) != VecVT.getSizeInBits() ||
15854 (IdxVal != 0 && IdxVal != NumSubElts))
15855 return SDValue();
15856
15857 // Fold insert_subvector -> concat_vectors
15858 // insert_subvector(Vec,Sub,lo) -> concat_vectors(Sub,extract(Vec,hi))
15859 // insert_subvector(Vec,Sub,hi) -> concat_vectors(extract(Vec,lo),Sub)
15860 SDLoc DL(N);
15861 SDValue Lo, Hi;
15862 if (IdxVal == 0) {
15863 Lo = SubVec;
15864 Hi = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15865 DCI.DAG.getVectorIdxConstant(NumSubElts, DL));
15866 } else {
15867 Lo = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15868 DCI.DAG.getVectorIdxConstant(0, DL));
15869 Hi = SubVec;
15870 }
15871 return DCI.DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Lo, Hi);
15872}
15873
15874// shuffle(MVETrunc(x, y)) -> VMOVN(x, y)
15876 SelectionDAG &DAG) {
15877 SDValue Trunc = N->getOperand(0);
15878 EVT VT = Trunc.getValueType();
15879 if (Trunc.getOpcode() != ARMISD::MVETRUNC || !N->getOperand(1).isUndef())
15880 return SDValue();
15881
15882 SDLoc DL(Trunc);
15883 if (isVMOVNTruncMask(N->getMask(), VT, false))
15884 return DAG.getNode(
15885 ARMISD::VMOVN, DL, VT,
15886 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15887 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15888 DAG.getConstant(1, DL, MVT::i32));
15889 else if (isVMOVNTruncMask(N->getMask(), VT, true))
15890 return DAG.getNode(
15891 ARMISD::VMOVN, DL, VT,
15892 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15893 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15894 DAG.getConstant(1, DL, MVT::i32));
15895 return SDValue();
15896}
15897
15898/// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for
15899/// ISD::VECTOR_SHUFFLE.
15902 return R;
15903
15904 // The LLVM shufflevector instruction does not require the shuffle mask
15905 // length to match the operand vector length, but ISD::VECTOR_SHUFFLE does
15906 // have that requirement. When translating to ISD::VECTOR_SHUFFLE, if the
15907 // operands do not match the mask length, they are extended by concatenating
15908 // them with undef vectors. That is probably the right thing for other
15909 // targets, but for NEON it is better to concatenate two double-register
15910 // size vector operands into a single quad-register size vector. Do that
15911 // transformation here:
15912 // shuffle(concat(v1, undef), concat(v2, undef)) ->
15913 // shuffle(concat(v1, v2), undef)
15914 SDValue Op0 = N->getOperand(0);
15915 SDValue Op1 = N->getOperand(1);
15916 if (Op0.getOpcode() != ISD::CONCAT_VECTORS ||
15917 Op1.getOpcode() != ISD::CONCAT_VECTORS ||
15918 Op0.getNumOperands() != 2 ||
15919 Op1.getNumOperands() != 2)
15920 return SDValue();
15921 SDValue Concat0Op1 = Op0.getOperand(1);
15922 SDValue Concat1Op1 = Op1.getOperand(1);
15923 if (!Concat0Op1.isUndef() || !Concat1Op1.isUndef())
15924 return SDValue();
15925 // Skip the transformation if any of the types are illegal.
15926 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15927 EVT VT = N->getValueType(0);
15928 if (!TLI.isTypeLegal(VT) ||
15929 !TLI.isTypeLegal(Concat0Op1.getValueType()) ||
15930 !TLI.isTypeLegal(Concat1Op1.getValueType()))
15931 return SDValue();
15932
15933 SDValue NewConcat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT,
15934 Op0.getOperand(0), Op1.getOperand(0));
15935 // Translate the shuffle mask.
15936 SmallVector<int, 16> NewMask;
15937 unsigned NumElts = VT.getVectorNumElements();
15938 unsigned HalfElts = NumElts/2;
15940 for (unsigned n = 0; n < NumElts; ++n) {
15941 int MaskElt = SVN->getMaskElt(n);
15942 int NewElt = -1;
15943 if (MaskElt < (int)HalfElts)
15944 NewElt = MaskElt;
15945 else if (MaskElt >= (int)NumElts && MaskElt < (int)(NumElts + HalfElts))
15946 NewElt = HalfElts + MaskElt - NumElts;
15947 NewMask.push_back(NewElt);
15948 }
15949 return DAG.getVectorShuffle(VT, SDLoc(N), NewConcat,
15950 DAG.getUNDEF(VT), NewMask);
15951}
15952
15953/// Load/store instruction that can be merged with a base address
15954/// update
15959 unsigned AddrOpIdx;
15960};
15961
15963 /// Instruction that updates a pointer
15965 /// Pointer increment operand
15967 /// Pointer increment value if it is a constant, or 0 otherwise
15968 unsigned ConstInc;
15969};
15970
15972 // Check that the add is independent of the load/store.
15973 // Otherwise, folding it would create a cycle. Search through Addr
15974 // as well, since the User may not be a direct user of Addr and
15975 // only share a base pointer.
15978 Worklist.push_back(N);
15979 Worklist.push_back(User);
15980 const unsigned MaxSteps = 1024;
15981 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
15982 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
15983 return false;
15984 return true;
15985}
15986
15988 struct BaseUpdateUser &User,
15989 bool SimpleConstIncOnly,
15991 SelectionDAG &DAG = DCI.DAG;
15992 SDNode *N = Target.N;
15993 MemSDNode *MemN = cast<MemSDNode>(N);
15994 SDLoc dl(N);
15995
15996 // Find the new opcode for the updating load/store.
15997 bool isLoadOp = true;
15998 bool isLaneOp = false;
15999 // Workaround for vst1x and vld1x intrinsics which do not have alignment
16000 // as an operand.
16001 bool hasAlignment = true;
16002 unsigned NewOpc = 0;
16003 unsigned NumVecs = 0;
16004 if (Target.isIntrinsic) {
16005 unsigned IntNo = N->getConstantOperandVal(1);
16006 switch (IntNo) {
16007 default:
16008 llvm_unreachable("unexpected intrinsic for Neon base update");
16009 case Intrinsic::arm_neon_vld1:
16010 NewOpc = ARMISD::VLD1_UPD;
16011 NumVecs = 1;
16012 break;
16013 case Intrinsic::arm_neon_vld2:
16014 NewOpc = ARMISD::VLD2_UPD;
16015 NumVecs = 2;
16016 break;
16017 case Intrinsic::arm_neon_vld3:
16018 NewOpc = ARMISD::VLD3_UPD;
16019 NumVecs = 3;
16020 break;
16021 case Intrinsic::arm_neon_vld4:
16022 NewOpc = ARMISD::VLD4_UPD;
16023 NumVecs = 4;
16024 break;
16025 case Intrinsic::arm_neon_vld1x2:
16026 NewOpc = ARMISD::VLD1x2_UPD;
16027 NumVecs = 2;
16028 hasAlignment = false;
16029 break;
16030 case Intrinsic::arm_neon_vld1x3:
16031 NewOpc = ARMISD::VLD1x3_UPD;
16032 NumVecs = 3;
16033 hasAlignment = false;
16034 break;
16035 case Intrinsic::arm_neon_vld1x4:
16036 NewOpc = ARMISD::VLD1x4_UPD;
16037 NumVecs = 4;
16038 hasAlignment = false;
16039 break;
16040 case Intrinsic::arm_neon_vld2dup:
16041 NewOpc = ARMISD::VLD2DUP_UPD;
16042 NumVecs = 2;
16043 break;
16044 case Intrinsic::arm_neon_vld3dup:
16045 NewOpc = ARMISD::VLD3DUP_UPD;
16046 NumVecs = 3;
16047 break;
16048 case Intrinsic::arm_neon_vld4dup:
16049 NewOpc = ARMISD::VLD4DUP_UPD;
16050 NumVecs = 4;
16051 break;
16052 case Intrinsic::arm_neon_vld2lane:
16053 NewOpc = ARMISD::VLD2LN_UPD;
16054 NumVecs = 2;
16055 isLaneOp = true;
16056 break;
16057 case Intrinsic::arm_neon_vld3lane:
16058 NewOpc = ARMISD::VLD3LN_UPD;
16059 NumVecs = 3;
16060 isLaneOp = true;
16061 break;
16062 case Intrinsic::arm_neon_vld4lane:
16063 NewOpc = ARMISD::VLD4LN_UPD;
16064 NumVecs = 4;
16065 isLaneOp = true;
16066 break;
16067 case Intrinsic::arm_neon_vst1:
16068 NewOpc = ARMISD::VST1_UPD;
16069 NumVecs = 1;
16070 isLoadOp = false;
16071 break;
16072 case Intrinsic::arm_neon_vst2:
16073 NewOpc = ARMISD::VST2_UPD;
16074 NumVecs = 2;
16075 isLoadOp = false;
16076 break;
16077 case Intrinsic::arm_neon_vst3:
16078 NewOpc = ARMISD::VST3_UPD;
16079 NumVecs = 3;
16080 isLoadOp = false;
16081 break;
16082 case Intrinsic::arm_neon_vst4:
16083 NewOpc = ARMISD::VST4_UPD;
16084 NumVecs = 4;
16085 isLoadOp = false;
16086 break;
16087 case Intrinsic::arm_neon_vst2lane:
16088 NewOpc = ARMISD::VST2LN_UPD;
16089 NumVecs = 2;
16090 isLoadOp = false;
16091 isLaneOp = true;
16092 break;
16093 case Intrinsic::arm_neon_vst3lane:
16094 NewOpc = ARMISD::VST3LN_UPD;
16095 NumVecs = 3;
16096 isLoadOp = false;
16097 isLaneOp = true;
16098 break;
16099 case Intrinsic::arm_neon_vst4lane:
16100 NewOpc = ARMISD::VST4LN_UPD;
16101 NumVecs = 4;
16102 isLoadOp = false;
16103 isLaneOp = true;
16104 break;
16105 case Intrinsic::arm_neon_vst1x2:
16106 NewOpc = ARMISD::VST1x2_UPD;
16107 NumVecs = 2;
16108 isLoadOp = false;
16109 hasAlignment = false;
16110 break;
16111 case Intrinsic::arm_neon_vst1x3:
16112 NewOpc = ARMISD::VST1x3_UPD;
16113 NumVecs = 3;
16114 isLoadOp = false;
16115 hasAlignment = false;
16116 break;
16117 case Intrinsic::arm_neon_vst1x4:
16118 NewOpc = ARMISD::VST1x4_UPD;
16119 NumVecs = 4;
16120 isLoadOp = false;
16121 hasAlignment = false;
16122 break;
16123 }
16124 } else {
16125 isLaneOp = true;
16126 switch (N->getOpcode()) {
16127 default:
16128 llvm_unreachable("unexpected opcode for Neon base update");
16129 case ARMISD::VLD1DUP:
16130 NewOpc = ARMISD::VLD1DUP_UPD;
16131 NumVecs = 1;
16132 break;
16133 case ARMISD::VLD2DUP:
16134 NewOpc = ARMISD::VLD2DUP_UPD;
16135 NumVecs = 2;
16136 break;
16137 case ARMISD::VLD3DUP:
16138 NewOpc = ARMISD::VLD3DUP_UPD;
16139 NumVecs = 3;
16140 break;
16141 case ARMISD::VLD4DUP:
16142 NewOpc = ARMISD::VLD4DUP_UPD;
16143 NumVecs = 4;
16144 break;
16145 case ISD::LOAD:
16146 NewOpc = ARMISD::VLD1_UPD;
16147 NumVecs = 1;
16148 isLaneOp = false;
16149 break;
16150 case ISD::STORE:
16151 NewOpc = ARMISD::VST1_UPD;
16152 NumVecs = 1;
16153 isLaneOp = false;
16154 isLoadOp = false;
16155 break;
16156 }
16157 }
16158
16159 // Find the size of memory referenced by the load/store.
16160 EVT VecTy;
16161 if (isLoadOp) {
16162 VecTy = N->getValueType(0);
16163 } else if (Target.isIntrinsic) {
16164 VecTy = N->getOperand(Target.AddrOpIdx + 1).getValueType();
16165 } else {
16166 assert(Target.isStore &&
16167 "Node has to be a load, a store, or an intrinsic!");
16168 VecTy = N->getOperand(1).getValueType();
16169 }
16170
16171 bool isVLDDUPOp =
16172 NewOpc == ARMISD::VLD1DUP_UPD || NewOpc == ARMISD::VLD2DUP_UPD ||
16173 NewOpc == ARMISD::VLD3DUP_UPD || NewOpc == ARMISD::VLD4DUP_UPD;
16174
16175 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16176 if (isLaneOp || isVLDDUPOp)
16177 NumBytes /= VecTy.getVectorNumElements();
16178
16179 if (NumBytes >= 3 * 16 && User.ConstInc != NumBytes) {
16180 // VLD3/4 and VST3/4 for 128-bit vectors are implemented with two
16181 // separate instructions that make it harder to use a non-constant update.
16182 return false;
16183 }
16184
16185 if (SimpleConstIncOnly && User.ConstInc != NumBytes)
16186 return false;
16187
16188 if (!isValidBaseUpdate(N, User.N))
16189 return false;
16190
16191 // OK, we found an ADD we can fold into the base update.
16192 // Now, create a _UPD node, taking care of not breaking alignment.
16193
16194 EVT AlignedVecTy = VecTy;
16195 Align Alignment = MemN->getAlign();
16196
16197 // If this is a less-than-standard-aligned load/store, change the type to
16198 // match the standard alignment.
16199 // The alignment is overlooked when selecting _UPD variants; and it's
16200 // easier to introduce bitcasts here than fix that.
16201 // There are 3 ways to get to this base-update combine:
16202 // - intrinsics: they are assumed to be properly aligned (to the standard
16203 // alignment of the memory type), so we don't need to do anything.
16204 // - ARMISD::VLDx nodes: they are only generated from the aforementioned
16205 // intrinsics, so, likewise, there's nothing to do.
16206 // - generic load/store instructions: the alignment is specified as an
16207 // explicit operand, rather than implicitly as the standard alignment
16208 // of the memory type (like the intrinsics). We need to change the
16209 // memory type to match the explicit alignment. That way, we don't
16210 // generate non-standard-aligned ARMISD::VLDx nodes.
16211 if (isa<LSBaseSDNode>(N)) {
16212 if (Alignment.value() < VecTy.getScalarSizeInBits() / 8) {
16213 MVT EltTy = MVT::getIntegerVT(Alignment.value() * 8);
16214 assert(NumVecs == 1 && "Unexpected multi-element generic load/store.");
16215 assert(!isLaneOp && "Unexpected generic load/store lane.");
16216 unsigned NumElts = NumBytes / (EltTy.getSizeInBits() / 8);
16217 AlignedVecTy = MVT::getVectorVT(EltTy, NumElts);
16218 }
16219 // Don't set an explicit alignment on regular load/stores that we want
16220 // to transform to VLD/VST 1_UPD nodes.
16221 // This matches the behavior of regular load/stores, which only get an
16222 // explicit alignment if the MMO alignment is larger than the standard
16223 // alignment of the memory type.
16224 // Intrinsics, however, always get an explicit alignment, set to the
16225 // alignment of the MMO.
16226 Alignment = Align(1);
16227 }
16228
16229 // Create the new updating load/store node.
16230 // First, create an SDVTList for the new updating node's results.
16231 EVT Tys[6];
16232 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16233 unsigned n;
16234 for (n = 0; n < NumResultVecs; ++n)
16235 Tys[n] = AlignedVecTy;
16236 Tys[n++] = MVT::i32;
16237 Tys[n] = MVT::Other;
16238 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16239
16240 // Then, gather the new node's operands.
16242 Ops.push_back(N->getOperand(0)); // incoming chain
16243 Ops.push_back(N->getOperand(Target.AddrOpIdx));
16244 Ops.push_back(User.Inc);
16245
16246 if (StoreSDNode *StN = dyn_cast<StoreSDNode>(N)) {
16247 // Try to match the intrinsic's signature
16248 Ops.push_back(StN->getValue());
16249 } else {
16250 // Loads (and of course intrinsics) match the intrinsics' signature,
16251 // so just add all but the alignment operand.
16252 unsigned LastOperand =
16253 hasAlignment ? N->getNumOperands() - 1 : N->getNumOperands();
16254 for (unsigned i = Target.AddrOpIdx + 1; i < LastOperand; ++i)
16255 Ops.push_back(N->getOperand(i));
16256 }
16257
16258 // For all node types, the alignment operand is always the last one.
16259 Ops.push_back(DAG.getConstant(Alignment.value(), dl, MVT::i32));
16260
16261 // If this is a non-standard-aligned STORE, the penultimate operand is the
16262 // stored value. Bitcast it to the aligned type.
16263 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::STORE) {
16264 SDValue &StVal = Ops[Ops.size() - 2];
16265 StVal = DAG.getNode(ISD::BITCAST, dl, AlignedVecTy, StVal);
16266 }
16267
16268 EVT LoadVT = isLaneOp ? VecTy.getVectorElementType() : AlignedVecTy;
16269 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, LoadVT,
16270 MemN->getMemOperand());
16271
16272 // Update the uses.
16273 SmallVector<SDValue, 5> NewResults;
16274 for (unsigned i = 0; i < NumResultVecs; ++i)
16275 NewResults.push_back(SDValue(UpdN.getNode(), i));
16276
16277 // If this is an non-standard-aligned LOAD, the first result is the loaded
16278 // value. Bitcast it to the expected result type.
16279 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::LOAD) {
16280 SDValue &LdVal = NewResults[0];
16281 LdVal = DAG.getNode(ISD::BITCAST, dl, VecTy, LdVal);
16282 }
16283
16284 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16285 DCI.CombineTo(N, NewResults);
16286 DCI.CombineTo(User.N, SDValue(UpdN.getNode(), NumResultVecs));
16287
16288 return true;
16289}
16290
16291// If (opcode ptr inc) is and ADD-like instruction, return the
16292// increment value. Otherwise return 0.
16293static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr,
16294 SDValue Inc, const SelectionDAG &DAG) {
16296 if (!CInc)
16297 return 0;
16298
16299 switch (Opcode) {
16300 case ARMISD::VLD1_UPD:
16301 case ISD::ADD:
16302 return CInc->getZExtValue();
16303 case ISD::OR: {
16304 if (DAG.haveNoCommonBitsSet(Ptr, Inc)) {
16305 // (OR ptr inc) is the same as (ADD ptr inc)
16306 return CInc->getZExtValue();
16307 }
16308 return 0;
16309 }
16310 default:
16311 return 0;
16312 }
16313}
16314
16316 switch (N->getOpcode()) {
16317 case ISD::ADD:
16318 case ISD::OR: {
16319 if (isa<ConstantSDNode>(N->getOperand(1))) {
16320 *Ptr = N->getOperand(0);
16321 *CInc = N->getOperand(1);
16322 return true;
16323 }
16324 return false;
16325 }
16326 case ARMISD::VLD1_UPD: {
16327 if (isa<ConstantSDNode>(N->getOperand(2))) {
16328 *Ptr = N->getOperand(1);
16329 *CInc = N->getOperand(2);
16330 return true;
16331 }
16332 return false;
16333 }
16334 default:
16335 return false;
16336 }
16337}
16338
16339/// CombineBaseUpdate - Target-specific DAG combine function for VLDDUP,
16340/// NEON load/store intrinsics, and generic vector load/stores, to merge
16341/// base address updates.
16342/// For generic load/stores, the memory type is assumed to be a vector.
16343/// The caller is assumed to have checked legality.
16346 const bool isIntrinsic = (N->getOpcode() == ISD::INTRINSIC_VOID ||
16347 N->getOpcode() == ISD::INTRINSIC_W_CHAIN);
16348 const bool isStore = N->getOpcode() == ISD::STORE;
16349 const unsigned AddrOpIdx = ((isIntrinsic || isStore) ? 2 : 1);
16350 BaseUpdateTarget Target = {N, isIntrinsic, isStore, AddrOpIdx};
16351
16352 // Limit the number of possible base-updates we look at to prevent degenerate
16353 // cases.
16354 unsigned MaxBaseUpdates = ArmMaxBaseUpdatesToCheck;
16355
16356 SDValue Addr = N->getOperand(AddrOpIdx);
16357
16359
16360 // Search for a use of the address operand that is an increment.
16361 for (SDUse &Use : Addr->uses()) {
16362 SDNode *User = Use.getUser();
16363 if (Use.getResNo() != Addr.getResNo() || User->getNumOperands() != 2)
16364 continue;
16365
16366 SDValue Inc = User->getOperand(Use.getOperandNo() == 1 ? 0 : 1);
16367 unsigned ConstInc =
16368 getPointerConstIncrement(User->getOpcode(), Addr, Inc, DCI.DAG);
16369
16370 if (ConstInc || User->getOpcode() == ISD::ADD) {
16371 BaseUpdates.push_back({User, Inc, ConstInc});
16372 if (BaseUpdates.size() >= MaxBaseUpdates)
16373 break;
16374 }
16375 }
16376
16377 // If the address is a constant pointer increment itself, find
16378 // another constant increment that has the same base operand
16379 SDValue Base;
16380 SDValue CInc;
16381 if (findPointerConstIncrement(Addr.getNode(), &Base, &CInc)) {
16382 unsigned Offset =
16383 getPointerConstIncrement(Addr->getOpcode(), Base, CInc, DCI.DAG);
16384 if (Offset) {
16385 for (SDUse &Use : Base->uses()) {
16386
16387 SDNode *User = Use.getUser();
16388 if (Use.getResNo() != Base.getResNo() || User == Addr.getNode() ||
16389 User->getNumOperands() != 2)
16390 continue;
16391
16392 SDValue UserInc = User->getOperand(Use.getOperandNo() == 0 ? 1 : 0);
16393 unsigned UserOffset =
16394 getPointerConstIncrement(User->getOpcode(), Base, UserInc, DCI.DAG);
16395
16396 if (!UserOffset || UserOffset <= Offset)
16397 continue;
16398
16399 unsigned NewConstInc = UserOffset - Offset;
16400 SDValue NewInc = DCI.DAG.getConstant(NewConstInc, SDLoc(N), MVT::i32);
16401 BaseUpdates.push_back({User, NewInc, NewConstInc});
16402 if (BaseUpdates.size() >= MaxBaseUpdates)
16403 break;
16404 }
16405 }
16406 }
16407
16408 // Try to fold the load/store with an update that matches memory
16409 // access size. This should work well for sequential loads.
16410 unsigned NumValidUpd = BaseUpdates.size();
16411 for (unsigned I = 0; I < NumValidUpd; I++) {
16412 BaseUpdateUser &User = BaseUpdates[I];
16413 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/true, DCI))
16414 return SDValue();
16415 }
16416
16417 // Try to fold with other users. Non-constant updates are considered
16418 // first, and constant updates are sorted to not break a sequence of
16419 // strided accesses (if there is any).
16420 llvm::stable_sort(BaseUpdates,
16421 [](const BaseUpdateUser &LHS, const BaseUpdateUser &RHS) {
16422 return LHS.ConstInc < RHS.ConstInc;
16423 });
16424 for (BaseUpdateUser &User : BaseUpdates) {
16425 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/false, DCI))
16426 return SDValue();
16427 }
16428 return SDValue();
16429}
16430
16433 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16434 return SDValue();
16435
16436 return CombineBaseUpdate(N, DCI);
16437}
16438
16441 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16442 return SDValue();
16443
16444 SelectionDAG &DAG = DCI.DAG;
16445 SDValue Addr = N->getOperand(2);
16446 MemSDNode *MemN = cast<MemSDNode>(N);
16447 SDLoc dl(N);
16448
16449 // For the stores, where there are multiple intrinsics we only actually want
16450 // to post-inc the last of the them.
16451 unsigned IntNo = N->getConstantOperandVal(1);
16452 if (IntNo == Intrinsic::arm_mve_vst2q && N->getConstantOperandVal(5) != 1)
16453 return SDValue();
16454 if (IntNo == Intrinsic::arm_mve_vst4q && N->getConstantOperandVal(7) != 3)
16455 return SDValue();
16456
16457 // Search for a use of the address operand that is an increment.
16458 for (SDUse &Use : Addr->uses()) {
16459 SDNode *User = Use.getUser();
16460 if (User->getOpcode() != ISD::ADD || Use.getResNo() != Addr.getResNo())
16461 continue;
16462
16463 // Check that the add is independent of the load/store. Otherwise, folding
16464 // it would create a cycle. We can avoid searching through Addr as it's a
16465 // predecessor to both.
16468 Visited.insert(Addr.getNode());
16469 Worklist.push_back(N);
16470 Worklist.push_back(User);
16471 const unsigned MaxSteps = 1024;
16472 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16473 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16474 continue;
16475
16476 // Find the new opcode for the updating load/store.
16477 bool isLoadOp = true;
16478 unsigned NewOpc = 0;
16479 unsigned NumVecs = 0;
16480 switch (IntNo) {
16481 default:
16482 llvm_unreachable("unexpected intrinsic for MVE VLDn combine");
16483 case Intrinsic::arm_mve_vld2q:
16484 NewOpc = ARMISD::VLD2_UPD;
16485 NumVecs = 2;
16486 break;
16487 case Intrinsic::arm_mve_vld4q:
16488 NewOpc = ARMISD::VLD4_UPD;
16489 NumVecs = 4;
16490 break;
16491 case Intrinsic::arm_mve_vst2q:
16492 NewOpc = ARMISD::VST2_UPD;
16493 NumVecs = 2;
16494 isLoadOp = false;
16495 break;
16496 case Intrinsic::arm_mve_vst4q:
16497 NewOpc = ARMISD::VST4_UPD;
16498 NumVecs = 4;
16499 isLoadOp = false;
16500 break;
16501 }
16502
16503 // Find the size of memory referenced by the load/store.
16504 EVT VecTy;
16505 if (isLoadOp) {
16506 VecTy = N->getValueType(0);
16507 } else {
16508 VecTy = N->getOperand(3).getValueType();
16509 }
16510
16511 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16512
16513 // If the increment is a constant, it must match the memory ref size.
16514 SDValue Inc = User->getOperand(User->getOperand(0) == Addr ? 1 : 0);
16516 if (!CInc || CInc->getZExtValue() != NumBytes)
16517 continue;
16518
16519 // Create the new updating load/store node.
16520 // First, create an SDVTList for the new updating node's results.
16521 EVT Tys[6];
16522 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16523 unsigned n;
16524 for (n = 0; n < NumResultVecs; ++n)
16525 Tys[n] = VecTy;
16526 Tys[n++] = MVT::i32;
16527 Tys[n] = MVT::Other;
16528 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16529
16530 // Then, gather the new node's operands.
16532 Ops.push_back(N->getOperand(0)); // incoming chain
16533 Ops.push_back(N->getOperand(2)); // ptr
16534 Ops.push_back(Inc);
16535
16536 for (unsigned i = 3; i < N->getNumOperands(); ++i)
16537 Ops.push_back(N->getOperand(i));
16538
16539 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, VecTy,
16540 MemN->getMemOperand());
16541
16542 // Update the uses.
16543 SmallVector<SDValue, 5> NewResults;
16544 for (unsigned i = 0; i < NumResultVecs; ++i)
16545 NewResults.push_back(SDValue(UpdN.getNode(), i));
16546
16547 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16548 DCI.CombineTo(N, NewResults);
16549 DCI.CombineTo(User, SDValue(UpdN.getNode(), NumResultVecs));
16550
16551 break;
16552 }
16553
16554 return SDValue();
16555}
16556
16557/// CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a
16558/// vldN-lane (N > 1) intrinsic, and if all the other uses of that intrinsic
16559/// are also VDUPLANEs. If so, combine them to a vldN-dup operation and
16560/// return true.
16562 SelectionDAG &DAG = DCI.DAG;
16563 EVT VT = N->getValueType(0);
16564 // vldN-dup instructions only support 64-bit vectors for N > 1.
16565 if (!VT.is64BitVector())
16566 return false;
16567
16568 // Check if the VDUPLANE operand is a vldN-dup intrinsic.
16569 SDNode *VLD = N->getOperand(0).getNode();
16570 if (VLD->getOpcode() != ISD::INTRINSIC_W_CHAIN)
16571 return false;
16572 unsigned NumVecs = 0;
16573 unsigned NewOpc = 0;
16574 unsigned IntNo = VLD->getConstantOperandVal(1);
16575 if (IntNo == Intrinsic::arm_neon_vld2lane) {
16576 NumVecs = 2;
16577 NewOpc = ARMISD::VLD2DUP;
16578 } else if (IntNo == Intrinsic::arm_neon_vld3lane) {
16579 NumVecs = 3;
16580 NewOpc = ARMISD::VLD3DUP;
16581 } else if (IntNo == Intrinsic::arm_neon_vld4lane) {
16582 NumVecs = 4;
16583 NewOpc = ARMISD::VLD4DUP;
16584 } else {
16585 return false;
16586 }
16587
16588 // First check that all the vldN-lane uses are VDUPLANEs and that the lane
16589 // numbers match the load.
16590 unsigned VLDLaneNo = VLD->getConstantOperandVal(NumVecs + 3);
16591 for (SDUse &Use : VLD->uses()) {
16592 // Ignore uses of the chain result.
16593 if (Use.getResNo() == NumVecs)
16594 continue;
16595 SDNode *User = Use.getUser();
16596 if (User->getOpcode() != ARMISD::VDUPLANE ||
16597 VLDLaneNo != User->getConstantOperandVal(1))
16598 return false;
16599 }
16600
16601 // Create the vldN-dup node.
16602 EVT Tys[5];
16603 unsigned n;
16604 for (n = 0; n < NumVecs; ++n)
16605 Tys[n] = VT;
16606 Tys[n] = MVT::Other;
16607 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumVecs + 1));
16608 SDValue Ops[] = { VLD->getOperand(0), VLD->getOperand(2) };
16610 SDValue VLDDup = DAG.getMemIntrinsicNode(NewOpc, SDLoc(VLD), SDTys,
16611 Ops, VLDMemInt->getMemoryVT(),
16612 VLDMemInt->getMemOperand());
16613
16614 // Update the uses.
16615 for (SDUse &Use : VLD->uses()) {
16616 unsigned ResNo = Use.getResNo();
16617 // Ignore uses of the chain result.
16618 if (ResNo == NumVecs)
16619 continue;
16620 DCI.CombineTo(Use.getUser(), SDValue(VLDDup.getNode(), ResNo));
16621 }
16622
16623 // Now the vldN-lane intrinsic is dead except for its chain result.
16624 // Update uses of the chain.
16625 std::vector<SDValue> VLDDupResults;
16626 for (unsigned n = 0; n < NumVecs; ++n)
16627 VLDDupResults.push_back(SDValue(VLDDup.getNode(), n));
16628 VLDDupResults.push_back(SDValue(VLDDup.getNode(), NumVecs));
16629 DCI.CombineTo(VLD, VLDDupResults);
16630
16631 return true;
16632}
16633
16634/// PerformVDUPLANECombine - Target-specific dag combine xforms for
16635/// ARMISD::VDUPLANE.
16638 const ARMSubtarget *Subtarget) {
16639 SDValue Op = N->getOperand(0);
16640 EVT VT = N->getValueType(0);
16641
16642 // On MVE, we just convert the VDUPLANE to a VDUP with an extract.
16643 if (Subtarget->hasMVEIntegerOps()) {
16644 EVT ExtractVT = VT.getVectorElementType();
16645 // We need to ensure we are creating a legal type.
16646 if (!DCI.DAG.getTargetLoweringInfo().isTypeLegal(ExtractVT))
16647 ExtractVT = MVT::i32;
16648 SDValue Extract = DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), ExtractVT,
16649 N->getOperand(0), N->getOperand(1));
16650 return DCI.DAG.getNode(ARMISD::VDUP, SDLoc(N), VT, Extract);
16651 }
16652
16653 // If the source is a vldN-lane (N > 1) intrinsic, and all the other uses
16654 // of that intrinsic are also VDUPLANEs, combine them to a vldN-dup operation.
16655 if (CombineVLDDUP(N, DCI))
16656 return SDValue(N, 0);
16657
16658 // If the source is already a VMOVIMM or VMVNIMM splat, the VDUPLANE is
16659 // redundant. Ignore bit_converts for now; element sizes are checked below.
16660 while (Op.getOpcode() == ISD::BITCAST)
16661 Op = Op.getOperand(0);
16662 if (Op.getOpcode() != ARMISD::VMOVIMM && Op.getOpcode() != ARMISD::VMVNIMM)
16663 return SDValue();
16664
16665 // Make sure the VMOV element size is not bigger than the VDUPLANE elements.
16666 unsigned EltSize = Op.getScalarValueSizeInBits();
16667 // The canonical VMOV for a zero vector uses a 32-bit element size.
16668 unsigned Imm = Op.getConstantOperandVal(0);
16669 unsigned EltBits;
16670 if (ARM_AM::decodeVMOVModImm(Imm, EltBits) == 0)
16671 EltSize = 8;
16672 if (EltSize > VT.getScalarSizeInBits())
16673 return SDValue();
16674
16675 return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
16676}
16677
16678/// PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
16680 const ARMSubtarget *Subtarget) {
16681 SDValue Op = N->getOperand(0);
16682 SDLoc dl(N);
16683
16684 if (Subtarget->hasMVEIntegerOps()) {
16685 // Convert VDUP f32 -> VDUP BITCAST i32 under MVE, as we know the value will
16686 // need to come from a GPR.
16687 if (Op.getValueType() == MVT::f32)
16688 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16689 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op));
16690 else if (Op.getValueType() == MVT::f16)
16691 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16692 DAG.getNode(ARMISD::VMOVrh, dl, MVT::i32, Op));
16693 }
16694
16695 if (!Subtarget->hasNEON())
16696 return SDValue();
16697
16698 // Match VDUP(LOAD) -> VLD1DUP.
16699 // We match this pattern here rather than waiting for isel because the
16700 // transform is only legal for unindexed loads.
16701 LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode());
16702 if (LD && Op.hasOneUse() && LD->isUnindexed() &&
16703 LD->getMemoryVT() == N->getValueType(0).getVectorElementType()) {
16704 SDValue Ops[] = {LD->getOperand(0), LD->getOperand(1),
16705 DAG.getConstant(LD->getAlign().value(), SDLoc(N), MVT::i32)};
16706 SDVTList SDTys = DAG.getVTList(N->getValueType(0), MVT::Other);
16707 SDValue VLDDup =
16709 LD->getMemoryVT(), LD->getMemOperand());
16710 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), VLDDup.getValue(1));
16711 return VLDDup;
16712 }
16713
16714 return SDValue();
16715}
16716
16719 const ARMSubtarget *Subtarget) {
16720 EVT VT = N->getValueType(0);
16721
16722 // If this is a legal vector load, try to combine it into a VLD1_UPD.
16723 if (Subtarget->hasNEON() && ISD::isNormalLoad(N) && VT.isVector() &&
16725 return CombineBaseUpdate(N, DCI);
16726
16727 return SDValue();
16728}
16729
16730// Optimize trunc store (of multiple scalars) to shuffle and store. First,
16731// pack all of the elements in one place. Next, store to memory in fewer
16732// chunks.
16734 SelectionDAG &DAG) {
16735 SDValue StVal = St->getValue();
16736 EVT VT = StVal.getValueType();
16737 if (!St->isTruncatingStore() || !VT.isVector())
16738 return SDValue();
16739 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
16740 EVT StVT = St->getMemoryVT();
16741 unsigned NumElems = VT.getVectorNumElements();
16742 assert(StVT != VT && "Cannot truncate to the same type");
16743 unsigned FromEltSz = VT.getScalarSizeInBits();
16744 unsigned ToEltSz = StVT.getScalarSizeInBits();
16745
16746 // From, To sizes and ElemCount must be pow of two
16747 if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz))
16748 return SDValue();
16749
16750 // We are going to use the original vector elt for storing.
16751 // Accumulated smaller vector elements must be a multiple of the store size.
16752 if (0 != (NumElems * FromEltSz) % ToEltSz)
16753 return SDValue();
16754
16755 unsigned SizeRatio = FromEltSz / ToEltSz;
16756 assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
16757
16758 // Create a type on which we perform the shuffle.
16759 EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
16760 NumElems * SizeRatio);
16761 assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
16762
16763 SDLoc DL(St);
16764 SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
16765 SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
16766 for (unsigned i = 0; i < NumElems; ++i)
16767 ShuffleVec[i] = DAG.getDataLayout().isBigEndian() ? (i + 1) * SizeRatio - 1
16768 : i * SizeRatio;
16769
16770 // Can't shuffle using an illegal type.
16771 if (!TLI.isTypeLegal(WideVecVT))
16772 return SDValue();
16773
16774 SDValue Shuff = DAG.getVectorShuffle(
16775 WideVecVT, DL, WideVec, DAG.getUNDEF(WideVec.getValueType()), ShuffleVec);
16776 // At this point all of the data is stored at the bottom of the
16777 // register. We now need to save it to mem.
16778
16779 // Find the largest store unit
16780 MVT StoreType = MVT::i8;
16781 for (MVT Tp : MVT::integer_valuetypes()) {
16782 if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
16783 StoreType = Tp;
16784 }
16785 // Didn't find a legal store type.
16786 if (!TLI.isTypeLegal(StoreType))
16787 return SDValue();
16788
16789 // Bitcast the original vector into a vector of store-size units
16790 EVT StoreVecVT =
16791 EVT::getVectorVT(*DAG.getContext(), StoreType,
16792 VT.getSizeInBits() / EVT(StoreType).getSizeInBits());
16793 assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
16794 SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
16796 SDValue Increment = DAG.getConstant(StoreType.getSizeInBits() / 8, DL,
16797 TLI.getPointerTy(DAG.getDataLayout()));
16798 SDValue BasePtr = St->getBasePtr();
16799
16800 // Perform one or more big stores into memory.
16801 unsigned E = (ToEltSz * NumElems) / StoreType.getSizeInBits();
16802 for (unsigned I = 0; I < E; I++) {
16803 SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreType,
16804 ShuffWide, DAG.getIntPtrConstant(I, DL));
16805 SDValue Ch =
16806 DAG.getStore(St->getChain(), DL, SubVec, BasePtr, St->getPointerInfo(),
16807 St->getAlign(), St->getMemOperand()->getFlags());
16808 BasePtr =
16809 DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr, Increment);
16810 Chains.push_back(Ch);
16811 }
16812 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
16813}
16814
16815// Try taking a single vector store from an fpround (which would otherwise turn
16816// into an expensive buildvector) and splitting it into a series of narrowing
16817// stores.
16819 SelectionDAG &DAG) {
16820 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16821 return SDValue();
16822 SDValue Trunc = St->getValue();
16823 if (Trunc->getOpcode() != ISD::FP_ROUND)
16824 return SDValue();
16825 EVT FromVT = Trunc->getOperand(0).getValueType();
16826 EVT ToVT = Trunc.getValueType();
16827 if (!ToVT.isVector())
16828 return SDValue();
16830 EVT ToEltVT = ToVT.getVectorElementType();
16831 EVT FromEltVT = FromVT.getVectorElementType();
16832
16833 if (FromEltVT != MVT::f32 || ToEltVT != MVT::f16)
16834 return SDValue();
16835
16836 unsigned NumElements = 4;
16837 if (FromVT.getVectorNumElements() % NumElements != 0)
16838 return SDValue();
16839
16840 // Test if the Trunc will be convertible to a VMOVN with a shuffle, and if so
16841 // use the VMOVN over splitting the store. We are looking for patterns of:
16842 // !rev: 0 N 1 N+1 2 N+2 ...
16843 // rev: N 0 N+1 1 N+2 2 ...
16844 // The shuffle may either be a single source (in which case N = NumElts/2) or
16845 // two inputs extended with concat to the same size (in which case N =
16846 // NumElts).
16847 auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
16848 ArrayRef<int> M = SVN->getMask();
16849 unsigned NumElts = ToVT.getVectorNumElements();
16850 if (SVN->getOperand(1).isUndef())
16851 NumElts /= 2;
16852
16853 unsigned Off0 = Rev ? NumElts : 0;
16854 unsigned Off1 = Rev ? 0 : NumElts;
16855
16856 for (unsigned I = 0; I < NumElts; I += 2) {
16857 if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
16858 return false;
16859 if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
16860 return false;
16861 }
16862
16863 return true;
16864 };
16865
16866 if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
16867 if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
16868 return SDValue();
16869
16870 LLVMContext &C = *DAG.getContext();
16871 SDLoc DL(St);
16872 // Details about the old store
16873 SDValue Ch = St->getChain();
16874 SDValue BasePtr = St->getBasePtr();
16875 Align Alignment = St->getBaseAlign();
16877 AAMDNodes AAInfo = St->getAAInfo();
16878
16879 // We split the store into slices of NumElements. fp16 trunc stores are vcvt
16880 // and then stored as truncating integer stores.
16881 EVT NewFromVT = EVT::getVectorVT(C, FromEltVT, NumElements);
16882 EVT NewToVT = EVT::getVectorVT(
16883 C, EVT::getIntegerVT(C, ToEltVT.getSizeInBits()), NumElements);
16884
16886 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
16887 unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
16888 SDValue NewPtr =
16889 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16890
16891 SDValue Extract =
16892 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
16893 DAG.getConstant(i * NumElements, DL, MVT::i32));
16894
16895 SDValue FPTrunc =
16896 DAG.getNode(ARMISD::VCVTN, DL, MVT::v8f16, DAG.getUNDEF(MVT::v8f16),
16897 Extract, DAG.getConstant(0, DL, MVT::i32));
16898 Extract = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v4i32, FPTrunc);
16899
16901 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16902 NewToVT, Alignment, MMOFlags, AAInfo);
16903 Stores.push_back(Store);
16904 }
16905 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16906}
16907
16908// Try taking a single vector store from an MVETRUNC (which would otherwise turn
16909// into an expensive buildvector) and splitting it into a series of narrowing
16910// stores.
16912 SelectionDAG &DAG) {
16913 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16914 return SDValue();
16915 SDValue Trunc = St->getValue();
16916 if (Trunc->getOpcode() != ARMISD::MVETRUNC)
16917 return SDValue();
16918 EVT FromVT = Trunc->getOperand(0).getValueType();
16919 EVT ToVT = Trunc.getValueType();
16920
16921 LLVMContext &C = *DAG.getContext();
16922 SDLoc DL(St);
16923 // Details about the old store
16924 SDValue Ch = St->getChain();
16925 SDValue BasePtr = St->getBasePtr();
16926 Align Alignment = St->getBaseAlign();
16928 AAMDNodes AAInfo = St->getAAInfo();
16929
16930 EVT NewToVT = EVT::getVectorVT(C, ToVT.getVectorElementType(),
16931 FromVT.getVectorNumElements());
16932
16934 for (unsigned i = 0; i < Trunc.getNumOperands(); i++) {
16935 unsigned NewOffset =
16936 i * FromVT.getVectorNumElements() * ToVT.getScalarSizeInBits() / 8;
16937 SDValue NewPtr =
16938 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16939
16940 SDValue Extract = Trunc.getOperand(i);
16942 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16943 NewToVT, Alignment, MMOFlags, AAInfo);
16944 Stores.push_back(Store);
16945 }
16946 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16947}
16948
16949// Given a floating point store from an extracted vector, with an integer
16950// VGETLANE that already exists, store the existing VGETLANEu directly. This can
16951// help reduce fp register pressure, doesn't require the fp extract and allows
16952// use of more integer post-inc stores not available with vstr.
16954 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16955 return SDValue();
16956 SDValue Extract = St->getValue();
16957 EVT VT = Extract.getValueType();
16958 // For now only uses f16. This may be useful for f32 too, but that will
16959 // be bitcast(extract), not the VGETLANEu we currently check here.
16960 if (VT != MVT::f16 || Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
16961 return SDValue();
16962
16963 SDNode *GetLane =
16964 DAG.getNodeIfExists(ARMISD::VGETLANEu, DAG.getVTList(MVT::i32),
16965 {Extract.getOperand(0), Extract.getOperand(1)});
16966 if (!GetLane)
16967 return SDValue();
16968
16969 LLVMContext &C = *DAG.getContext();
16970 SDLoc DL(St);
16971 // Create a new integer store to replace the existing floating point version.
16972 SDValue Ch = St->getChain();
16973 SDValue BasePtr = St->getBasePtr();
16974 Align Alignment = St->getBaseAlign();
16976 AAMDNodes AAInfo = St->getAAInfo();
16977 EVT NewToVT = EVT::getIntegerVT(C, VT.getSizeInBits());
16978 SDValue Store = DAG.getTruncStore(Ch, DL, SDValue(GetLane, 0), BasePtr,
16979 St->getPointerInfo(), NewToVT, Alignment,
16980 MMOFlags, AAInfo);
16981
16982 return Store;
16983}
16984
16985/// PerformSTORECombine - Target-specific dag combine xforms for
16986/// ISD::STORE.
16989 const ARMSubtarget *Subtarget) {
16991 if (St->isVolatile())
16992 return SDValue();
16993 SDValue StVal = St->getValue();
16994 EVT VT = StVal.getValueType();
16995
16996 if (Subtarget->hasNEON())
16998 return Store;
16999
17000 if (Subtarget->hasMVEFloatOps())
17001 if (SDValue NewToken = PerformSplittingToNarrowingStores(St, DCI.DAG))
17002 return NewToken;
17003
17004 if (Subtarget->hasMVEIntegerOps()) {
17005 if (SDValue NewChain = PerformExtractFpToIntStores(St, DCI.DAG))
17006 return NewChain;
17007 if (SDValue NewToken =
17009 return NewToken;
17010 }
17011
17012 if (!ISD::isNormalStore(St))
17013 return SDValue();
17014
17015 // Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
17016 // ARM stores of arguments in the same cache line.
17017 if (StVal.getOpcode() == ARMISD::VMOVDRR && StVal->hasOneUse()) {
17018 SelectionDAG &DAG = DCI.DAG;
17019 bool isBigEndian = DAG.getDataLayout().isBigEndian();
17020 SDLoc DL(St);
17021 SDValue BasePtr = St->getBasePtr();
17022 SDValue NewST1 =
17023 DAG.getStore(St->getChain(), DL, StVal.getOperand(isBigEndian ? 1 : 0),
17024 BasePtr, St->getPointerInfo(), St->getBaseAlign(),
17025 St->getMemOperand()->getFlags());
17026
17027 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
17028 DAG.getConstant(4, DL, MVT::i32));
17029 return DAG.getStore(NewST1.getValue(0), DL,
17030 StVal.getOperand(isBigEndian ? 0 : 1), OffsetPtr,
17032 St->getBaseAlign(), St->getMemOperand()->getFlags());
17033 }
17034
17035 if (StVal.getValueType() == MVT::i64 &&
17037 // Bitcast an i64 store extracted from a vector to f64.
17038 // Otherwise, the i64 value will be legalized to a pair of i32 values.
17039 SelectionDAG &DAG = DCI.DAG;
17040 SDLoc dl(StVal);
17041 SDValue IntVec = StVal.getOperand(0);
17042 EVT FloatVT =
17043 EVT::getVectorVT(*DAG.getContext(), MVT::f64,
17045 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
17046 SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Vec,
17047 StVal.getOperand(1));
17048 dl = SDLoc(N);
17049 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
17050 // Make the DAGCombiner fold the bitcasts.
17051 DCI.AddToWorklist(Vec.getNode());
17052 DCI.AddToWorklist(ExtElt.getNode());
17053 DCI.AddToWorklist(V.getNode());
17054 return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
17055 St->getPointerInfo(), St->getAlign(),
17056 St->getMemOperand()->getFlags(), St->getAAInfo());
17057 }
17058
17059 // If this is a legal vector store, try to combine it into a VST1_UPD.
17060 if (Subtarget->hasNEON() && ISD::isNormalStore(N) && VT.isVector() &&
17062 return CombineBaseUpdate(N, DCI);
17063
17064 return SDValue();
17065}
17066
17067/// PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD)
17068/// can replace combinations of VMUL and VCVT (floating-point to integer)
17069/// when the VMUL has a constant operand that is a power of 2.
17070///
17071/// Example (assume d17 = <float 8.000000e+00, float 8.000000e+00>):
17072/// vmul.f32 d16, d17, d16
17073/// vcvt.s32.f32 d16, d16
17074/// becomes:
17075/// vcvt.s32.f32 d16, d16, #3
17077 const ARMSubtarget *Subtarget) {
17078 if (!Subtarget->hasNEON())
17079 return SDValue();
17080
17081 SDValue Op = N->getOperand(0);
17082 if (!Op.getValueType().isVector() || !Op.getValueType().isSimple() ||
17083 Op.getOpcode() != ISD::FMUL)
17084 return SDValue();
17085
17086 SDValue ConstVec = Op->getOperand(1);
17087 if (!isa<BuildVectorSDNode>(ConstVec))
17088 return SDValue();
17089
17090 MVT FloatTy = Op.getSimpleValueType().getVectorElementType();
17091 uint32_t FloatBits = FloatTy.getSizeInBits();
17092 MVT IntTy = N->getSimpleValueType(0).getVectorElementType();
17093 uint32_t IntBits = IntTy.getSizeInBits();
17094 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17095 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17096 // These instructions only exist converting from f32 to i32. We can handle
17097 // smaller integers by generating an extra truncate, but larger ones would
17098 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17099 // these instructions only support v2i32/v4i32 types.
17100 return SDValue();
17101 }
17102
17103 BitVector UndefElements;
17105 int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33);
17106 if (C == -1 || C == 0 || C > 32)
17107 return SDValue();
17108
17109 SDLoc dl(N);
17110 bool isSigned = N->getOpcode() == ISD::FP_TO_SINT;
17111 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfp2fxs :
17112 Intrinsic::arm_neon_vcvtfp2fxu;
17113 SDValue FixConv = DAG.getNode(
17114 ISD::INTRINSIC_WO_CHAIN, dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32,
17115 DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), Op->getOperand(0),
17116 DAG.getConstant(C, dl, MVT::i32));
17117
17118 if (IntBits < FloatBits)
17119 FixConv = DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), FixConv);
17120
17121 return FixConv;
17122}
17123
17125 const ARMSubtarget *Subtarget) {
17126 if (!Subtarget->hasMVEFloatOps())
17127 return SDValue();
17128
17129 // Turn (fadd x, (vselect c, y, -0.0)) into (vselect c, (fadd x, y), x)
17130 // The second form can be more easily turned into a predicated vadd, and
17131 // possibly combined into a fma to become a predicated vfma.
17132 SDValue Op0 = N->getOperand(0);
17133 SDValue Op1 = N->getOperand(1);
17134 EVT VT = N->getValueType(0);
17135 SDLoc DL(N);
17136
17137 // The identity element for a fadd is -0.0 or +0.0 when the nsz flag is set,
17138 // which these VMOV's represent.
17139 auto isIdentitySplat = [&](SDValue Op, bool NSZ) {
17140 if (Op.getOpcode() != ISD::BITCAST ||
17141 Op.getOperand(0).getOpcode() != ARMISD::VMOVIMM)
17142 return false;
17143 uint64_t ImmVal = Op.getOperand(0).getConstantOperandVal(0);
17144 if (VT == MVT::v4f32 && (ImmVal == 1664 || (ImmVal == 0 && NSZ)))
17145 return true;
17146 if (VT == MVT::v8f16 && (ImmVal == 2688 || (ImmVal == 0 && NSZ)))
17147 return true;
17148 return false;
17149 };
17150
17151 if (Op0.getOpcode() == ISD::VSELECT && Op1.getOpcode() != ISD::VSELECT)
17152 std::swap(Op0, Op1);
17153
17154 if (Op1.getOpcode() != ISD::VSELECT)
17155 return SDValue();
17156
17157 SDNodeFlags FaddFlags = N->getFlags();
17158 bool NSZ = FaddFlags.hasNoSignedZeros();
17159 if (!isIdentitySplat(Op1.getOperand(2), NSZ))
17160 return SDValue();
17161
17162 SDValue FAdd =
17163 DAG.getNode(ISD::FADD, DL, VT, Op0, Op1.getOperand(1), FaddFlags);
17164 return DAG.getNode(ISD::VSELECT, DL, VT, Op1.getOperand(0), FAdd, Op0, FaddFlags);
17165}
17166
17168 SDValue LHS = N->getOperand(0);
17169 SDValue RHS = N->getOperand(1);
17170 EVT VT = N->getValueType(0);
17171 SDLoc DL(N);
17172
17173 if (!N->getFlags().hasAllowReassociation())
17174 return SDValue();
17175
17176 // Combine fadd(a, vcmla(b, c, d)) -> vcmla(fadd(a, b), b, c)
17177 auto ReassocComplex = [&](SDValue A, SDValue B) {
17178 if (A.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
17179 return SDValue();
17180 unsigned Opc = A.getConstantOperandVal(0);
17181 if (Opc != Intrinsic::arm_mve_vcmlaq)
17182 return SDValue();
17183 SDValue VCMLA = DAG.getNode(
17184 ISD::INTRINSIC_WO_CHAIN, DL, VT, A.getOperand(0), A.getOperand(1),
17185 DAG.getNode(ISD::FADD, DL, VT, A.getOperand(2), B, N->getFlags()),
17186 A.getOperand(3), A.getOperand(4));
17187 VCMLA->setFlags(A->getFlags());
17188 return VCMLA;
17189 };
17190 if (SDValue R = ReassocComplex(LHS, RHS))
17191 return R;
17192 if (SDValue R = ReassocComplex(RHS, LHS))
17193 return R;
17194
17195 return SDValue();
17196}
17197
17199 const ARMSubtarget *Subtarget) {
17200 if (SDValue S = PerformFAddVSelectCombine(N, DAG, Subtarget))
17201 return S;
17202 if (SDValue S = PerformFADDVCMLACombine(N, DAG))
17203 return S;
17204 return SDValue();
17205}
17206
17207/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD)
17208/// can replace combinations of VCVT (integer to floating-point) and VMUL
17209/// when the VMUL has a constant operand that is a power of 2.
17210///
17211/// Example (assume d17 = <float 0.125, float 0.125>):
17212/// vcvt.f32.s32 d16, d16
17213/// vmul.f32 d16, d16, d17
17214/// becomes:
17215/// vcvt.f32.s32 d16, d16, #3
17217 const ARMSubtarget *Subtarget) {
17218 if (!Subtarget->hasNEON())
17219 return SDValue();
17220
17221 SDValue Op = N->getOperand(0);
17222 unsigned OpOpcode = Op.getNode()->getOpcode();
17223 if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple() ||
17224 (OpOpcode != ISD::SINT_TO_FP && OpOpcode != ISD::UINT_TO_FP))
17225 return SDValue();
17226
17227 SDValue ConstVec = N->getOperand(1);
17228 if (!isa<BuildVectorSDNode>(ConstVec))
17229 return SDValue();
17230
17231 MVT FloatTy = N->getSimpleValueType(0).getVectorElementType();
17232 uint32_t FloatBits = FloatTy.getSizeInBits();
17233 MVT IntTy = Op.getOperand(0).getSimpleValueType().getVectorElementType();
17234 uint32_t IntBits = IntTy.getSizeInBits();
17235 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17236 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17237 // These instructions only exist converting from i32 to f32. We can handle
17238 // smaller integers by generating an extra extend, but larger ones would
17239 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17240 // these instructions only support v2i32/v4i32 types.
17241 return SDValue();
17242 }
17243
17244 ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true);
17245 APFloat Recip(0.0f);
17246 if (!CN || !CN->getValueAPF().getExactInverse(&Recip))
17247 return SDValue();
17248
17249 bool IsExact;
17250 APSInt IntVal(33);
17251 if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
17252 APFloat::opOK ||
17253 !IsExact)
17254 return SDValue();
17255
17256 int32_t C = IntVal.exactLogBase2();
17257 if (C == -1 || C == 0 || C > 32)
17258 return SDValue();
17259
17260 SDLoc DL(N);
17261 bool isSigned = OpOpcode == ISD::SINT_TO_FP;
17262 SDValue ConvInput = Op.getOperand(0);
17263 if (IntBits < FloatBits)
17265 NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput);
17266
17267 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp
17268 : Intrinsic::arm_neon_vcvtfxu2fp;
17269 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
17270 DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput,
17271 DAG.getConstant(C, DL, MVT::i32));
17272}
17273
17275 const ARMSubtarget *ST) {
17276 if (!ST->hasMVEIntegerOps())
17277 return SDValue();
17278
17279 assert(N->getOpcode() == ISD::VECREDUCE_ADD);
17280 EVT ResVT = N->getValueType(0);
17281 SDValue N0 = N->getOperand(0);
17282 SDLoc dl(N);
17283
17284 // Try to turn vecreduce_add(add(x, y)) into vecreduce(x) + vecreduce(y)
17285 if (ResVT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
17286 (N0.getValueType() == MVT::v4i32 || N0.getValueType() == MVT::v8i16 ||
17287 N0.getValueType() == MVT::v16i8)) {
17288 SDValue Red0 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(0));
17289 SDValue Red1 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(1));
17290 return DAG.getNode(ISD::ADD, dl, ResVT, Red0, Red1);
17291 }
17292
17293 // We are looking for something that will have illegal types if left alone,
17294 // but that we can convert to a single instruction under MVE. For example
17295 // vecreduce_add(sext(A, v8i32)) => VADDV.s16 A
17296 // or
17297 // vecreduce_add(mul(zext(A, v16i32), zext(B, v16i32))) => VMLADAV.u8 A, B
17298
17299 // The legal cases are:
17300 // VADDV u/s 8/16/32
17301 // VMLAV u/s 8/16/32
17302 // VADDLV u/s 32
17303 // VMLALV u/s 16/32
17304
17305 // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
17306 // extend it and use v4i32 instead.
17307 auto ExtTypeMatches = [](SDValue A, ArrayRef<MVT> ExtTypes) {
17308 EVT AVT = A.getValueType();
17309 return any_of(ExtTypes, [&](MVT Ty) {
17310 return AVT.getVectorNumElements() == Ty.getVectorNumElements() &&
17311 AVT.bitsLE(Ty);
17312 });
17313 };
17314 auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
17315 EVT AVT = A.getValueType();
17316 if (!AVT.is128BitVector())
17317 A = DAG.getNode(
17318 ExtendCode, dl,
17320 *DAG.getContext(),
17322 A);
17323 return A;
17324 };
17325 auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
17326 if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
17327 return SDValue();
17328 SDValue A = N0->getOperand(0);
17329 if (ExtTypeMatches(A, ExtTypes))
17330 return ExtendIfNeeded(A, ExtendCode);
17331 return SDValue();
17332 };
17333 auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
17334 ArrayRef<MVT> ExtTypes, SDValue &Mask) {
17335 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17337 return SDValue();
17338 Mask = N0->getOperand(0);
17339 SDValue Ext = N0->getOperand(1);
17340 if (Ext->getOpcode() != ExtendCode)
17341 return SDValue();
17342 SDValue A = Ext->getOperand(0);
17343 if (ExtTypeMatches(A, ExtTypes))
17344 return ExtendIfNeeded(A, ExtendCode);
17345 return SDValue();
17346 };
17347 auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17348 SDValue &A, SDValue &B) {
17349 // For a vmla we are trying to match a larger pattern:
17350 // ExtA = sext/zext A
17351 // ExtB = sext/zext B
17352 // Mul = mul ExtA, ExtB
17353 // vecreduce.add Mul
17354 // There might also be en extra extend between the mul and the addreduce, so
17355 // long as the bitwidth is high enough to make them equivalent (for example
17356 // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
17357 if (ResVT != RetTy)
17358 return false;
17359 SDValue Mul = N0;
17360 if (Mul->getOpcode() == ExtendCode &&
17361 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17362 ResVT.getScalarSizeInBits())
17363 Mul = Mul->getOperand(0);
17364 if (Mul->getOpcode() != ISD::MUL)
17365 return false;
17366 SDValue ExtA = Mul->getOperand(0);
17367 SDValue ExtB = Mul->getOperand(1);
17368 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17369 return false;
17370 A = ExtA->getOperand(0);
17371 B = ExtB->getOperand(0);
17372 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17373 A = ExtendIfNeeded(A, ExtendCode);
17374 B = ExtendIfNeeded(B, ExtendCode);
17375 return true;
17376 }
17377 return false;
17378 };
17379 auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17380 SDValue &A, SDValue &B, SDValue &Mask) {
17381 // Same as the pattern above with a select for the zero predicated lanes
17382 // ExtA = sext/zext A
17383 // ExtB = sext/zext B
17384 // Mul = mul ExtA, ExtB
17385 // N0 = select Mask, Mul, 0
17386 // vecreduce.add N0
17387 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17389 return false;
17390 Mask = N0->getOperand(0);
17391 SDValue Mul = N0->getOperand(1);
17392 if (Mul->getOpcode() == ExtendCode &&
17393 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17394 ResVT.getScalarSizeInBits())
17395 Mul = Mul->getOperand(0);
17396 if (Mul->getOpcode() != ISD::MUL)
17397 return false;
17398 SDValue ExtA = Mul->getOperand(0);
17399 SDValue ExtB = Mul->getOperand(1);
17400 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17401 return false;
17402 A = ExtA->getOperand(0);
17403 B = ExtB->getOperand(0);
17404 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17405 A = ExtendIfNeeded(A, ExtendCode);
17406 B = ExtendIfNeeded(B, ExtendCode);
17407 return true;
17408 }
17409 return false;
17410 };
17411 auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
17412 // Split illegal MVT::v16i8->i64 vector reductions into two legal v8i16->i64
17413 // reductions. The operands are extended with MVEEXT, but as they are
17414 // reductions the lane orders do not matter. MVEEXT may be combined with
17415 // loads to produce two extending loads, or else they will be expanded to
17416 // VREV/VMOVL.
17417 EVT VT = Ops[0].getValueType();
17418 if (VT == MVT::v16i8) {
17419 assert((Opcode == ARMISD::VMLALVs || Opcode == ARMISD::VMLALVu) &&
17420 "Unexpected illegal long reduction opcode");
17421 bool IsUnsigned = Opcode == ARMISD::VMLALVu;
17422
17423 SDValue Ext0 =
17424 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17425 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[0]);
17426 SDValue Ext1 =
17427 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17428 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[1]);
17429
17430 SDValue MLA0 = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
17431 Ext0, Ext1);
17432 SDValue MLA1 =
17433 DAG.getNode(IsUnsigned ? ARMISD::VMLALVAu : ARMISD::VMLALVAs, dl,
17434 DAG.getVTList(MVT::i32, MVT::i32), MLA0, MLA0.getValue(1),
17435 Ext0.getValue(1), Ext1.getValue(1));
17436 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, MLA1, MLA1.getValue(1));
17437 }
17438 SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
17439 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
17440 SDValue(Node.getNode(), 1));
17441 };
17442
17443 SDValue A, B;
17444 SDValue Mask;
17445 if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17446 return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
17447 if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17448 return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
17449 if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17450 A, B))
17451 return Create64bitNode(ARMISD::VMLALVs, {A, B});
17452 if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17453 A, B))
17454 return Create64bitNode(ARMISD::VMLALVu, {A, B});
17455 if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
17456 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17457 DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
17458 if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
17459 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17460 DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
17461
17462 if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17463 Mask))
17464 return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
17465 if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17466 Mask))
17467 return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
17468 if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17469 Mask))
17470 return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
17471 if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17472 Mask))
17473 return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
17474 if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
17475 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17476 DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
17477 if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
17478 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17479 DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
17480
17481 if (SDValue A = IsVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}))
17482 return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
17483 if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
17484 return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
17485 if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}))
17486 return Create64bitNode(ARMISD::VADDLVs, {A});
17487 if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}))
17488 return Create64bitNode(ARMISD::VADDLVu, {A});
17489 if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
17490 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17491 DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
17492 if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
17493 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17494 DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
17495
17496 if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17497 return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
17498 if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17499 return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
17500 if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}, Mask))
17501 return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
17502 if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}, Mask))
17503 return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
17504 if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
17505 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17506 DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
17507 if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
17508 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17509 DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
17510
17511 // Some complications. We can get a case where the two inputs of the mul are
17512 // the same, then the output sext will have been helpfully converted to a
17513 // zext. Turn it back.
17514 SDValue Op = N0;
17515 if (Op->getOpcode() == ISD::VSELECT)
17516 Op = Op->getOperand(1);
17517 if (Op->getOpcode() == ISD::ZERO_EXTEND &&
17518 Op->getOperand(0)->getOpcode() == ISD::MUL) {
17519 SDValue Mul = Op->getOperand(0);
17520 if (Mul->getOperand(0) == Mul->getOperand(1) &&
17521 Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
17522 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
17523 if (Op != N0)
17524 Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
17525 N0->getOperand(0), Ext, N0->getOperand(2));
17526 return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
17527 }
17528 }
17529
17530 return SDValue();
17531}
17532
17533// Looks for vaddv(shuffle) or vmlav(shuffle, shuffle), with a shuffle where all
17534// the lanes are used. Due to the reduction being commutative the shuffle can be
17535// removed.
17537 unsigned VecOp = N->getOperand(0).getValueType().isVector() ? 0 : 2;
17538 auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp));
17539 if (!Shuf || !Shuf->getOperand(1).isUndef())
17540 return SDValue();
17541
17542 // Check all elements are used once in the mask.
17543 ArrayRef<int> Mask = Shuf->getMask();
17544 APInt SetElts(Mask.size(), 0);
17545 for (int E : Mask) {
17546 if (E < 0 || E >= (int)Mask.size())
17547 return SDValue();
17548 SetElts.setBit(E);
17549 }
17550 if (!SetElts.isAllOnes())
17551 return SDValue();
17552
17553 if (N->getNumOperands() != VecOp + 1) {
17554 auto *Shuf2 = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp + 1));
17555 if (!Shuf2 || !Shuf2->getOperand(1).isUndef() || Shuf2->getMask() != Mask)
17556 return SDValue();
17557 }
17558
17560 for (SDValue Op : N->ops()) {
17561 if (Op.getValueType().isVector())
17562 Ops.push_back(Op.getOperand(0));
17563 else
17564 Ops.push_back(Op);
17565 }
17566 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Ops);
17567}
17568
17571 SDValue Op0 = N->getOperand(0);
17572 SDValue Op1 = N->getOperand(1);
17573 unsigned IsTop = N->getConstantOperandVal(2);
17574
17575 // VMOVNT a undef -> a
17576 // VMOVNB a undef -> a
17577 // VMOVNB undef a -> a
17578 if (Op1->isUndef())
17579 return Op0;
17580 if (Op0->isUndef() && !IsTop)
17581 return Op1;
17582
17583 // VMOVNt(c, VQMOVNb(a, b)) => VQMOVNt(c, b)
17584 // VMOVNb(c, VQMOVNb(a, b)) => VQMOVNb(c, b)
17585 if ((Op1->getOpcode() == ARMISD::VQMOVNs ||
17586 Op1->getOpcode() == ARMISD::VQMOVNu) &&
17587 Op1->getConstantOperandVal(2) == 0)
17588 return DCI.DAG.getNode(Op1->getOpcode(), SDLoc(Op1), N->getValueType(0),
17589 Op0, Op1->getOperand(1), N->getOperand(2));
17590
17591 // Only the bottom lanes from Qm (Op1) and either the top or bottom lanes from
17592 // Qd (Op0) are demanded from a VMOVN, depending on whether we are inserting
17593 // into the top or bottom lanes.
17594 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17595 APInt Op1DemandedElts = APInt::getSplat(NumElts, APInt::getLowBitsSet(2, 1));
17596 APInt Op0DemandedElts =
17597 IsTop ? Op1DemandedElts
17598 : APInt::getSplat(NumElts, APInt::getHighBitsSet(2, 1));
17599
17600 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17601 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17602 return SDValue(N, 0);
17603 if (TLI.SimplifyDemandedVectorElts(Op1, Op1DemandedElts, DCI))
17604 return SDValue(N, 0);
17605
17606 return SDValue();
17607}
17608
17611 SDValue Op0 = N->getOperand(0);
17612 unsigned IsTop = N->getConstantOperandVal(2);
17613
17614 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17615 APInt Op0DemandedElts =
17616 APInt::getSplat(NumElts, IsTop ? APInt::getLowBitsSet(2, 1)
17617 : APInt::getHighBitsSet(2, 1));
17618
17619 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17620 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17621 return SDValue(N, 0);
17622 return SDValue();
17623}
17624
17627 EVT VT = N->getValueType(0);
17628 SDValue LHS = N->getOperand(0);
17629 SDValue RHS = N->getOperand(1);
17630
17631 auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
17632 auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
17633 // Turn VQDMULH(shuffle, shuffle) -> shuffle(VQDMULH)
17634 if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&
17635 LHS.getOperand(1).isUndef() && RHS.getOperand(1).isUndef() &&
17636 (LHS.hasOneUse() || RHS.hasOneUse() || LHS == RHS)) {
17637 SDLoc DL(N);
17638 SDValue NewBinOp = DCI.DAG.getNode(N->getOpcode(), DL, VT,
17639 LHS.getOperand(0), RHS.getOperand(0));
17640 SDValue UndefV = LHS.getOperand(1);
17641 return DCI.DAG.getVectorShuffle(VT, DL, NewBinOp, UndefV, Shuf0->getMask());
17642 }
17643 return SDValue();
17644}
17645
17647 SDLoc DL(N);
17648 SDValue Op0 = N->getOperand(0);
17649 SDValue Op1 = N->getOperand(1);
17650
17651 // Turn X << -C -> X >> C and viceversa. The negative shifts can come up from
17652 // uses of the intrinsics.
17653 if (auto C = dyn_cast<ConstantSDNode>(N->getOperand(2))) {
17654 int ShiftAmt = C->getSExtValue();
17655 if (ShiftAmt == 0) {
17656 SDValue Merge = DAG.getMergeValues({Op0, Op1}, DL);
17657 DAG.ReplaceAllUsesWith(N, Merge.getNode());
17658 return SDValue();
17659 }
17660
17661 if (ShiftAmt >= -32 && ShiftAmt < 0) {
17662 unsigned NewOpcode =
17663 N->getOpcode() == ARMISD::LSLL ? ARMISD::LSRL : ARMISD::LSLL;
17664 SDValue NewShift = DAG.getNode(NewOpcode, DL, N->getVTList(), Op0, Op1,
17665 DAG.getConstant(-ShiftAmt, DL, MVT::i32));
17666 DAG.ReplaceAllUsesWith(N, NewShift.getNode());
17667 return NewShift;
17668 }
17669 }
17670
17671 return SDValue();
17672}
17673
17674/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
17676 DAGCombinerInfo &DCI) const {
17677 SelectionDAG &DAG = DCI.DAG;
17678 unsigned IntNo = N->getConstantOperandVal(0);
17679 switch (IntNo) {
17680 default:
17681 // Don't do anything for most intrinsics.
17682 break;
17683
17684 // Vector shifts: check for immediate versions and lower them.
17685 // Note: This is done during DAG combining instead of DAG legalizing because
17686 // the build_vectors for 64-bit vector element shift counts are generally
17687 // not legal, and it is hard to see their values after they get legalized to
17688 // loads from a constant pool.
17689 case Intrinsic::arm_neon_vshifts:
17690 case Intrinsic::arm_neon_vshiftu:
17691 case Intrinsic::arm_neon_vrshifts:
17692 case Intrinsic::arm_neon_vrshiftu:
17693 case Intrinsic::arm_neon_vrshiftn:
17694 case Intrinsic::arm_neon_vqshifts:
17695 case Intrinsic::arm_neon_vqshiftu:
17696 case Intrinsic::arm_neon_vqshiftsu:
17697 case Intrinsic::arm_neon_vqshiftns:
17698 case Intrinsic::arm_neon_vqshiftnu:
17699 case Intrinsic::arm_neon_vqshiftnsu:
17700 case Intrinsic::arm_neon_vqrshiftns:
17701 case Intrinsic::arm_neon_vqrshiftnu:
17702 case Intrinsic::arm_neon_vqrshiftnsu: {
17703 EVT VT = N->getOperand(1).getValueType();
17704 int64_t Cnt;
17705 unsigned VShiftOpc = 0;
17706
17707 switch (IntNo) {
17708 case Intrinsic::arm_neon_vshifts:
17709 case Intrinsic::arm_neon_vshiftu:
17710 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) {
17711 VShiftOpc = ARMISD::VSHLIMM;
17712 break;
17713 }
17714 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) {
17715 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? ARMISD::VSHRsIMM
17716 : ARMISD::VSHRuIMM);
17717 break;
17718 }
17719 return SDValue();
17720
17721 case Intrinsic::arm_neon_vrshifts:
17722 case Intrinsic::arm_neon_vrshiftu:
17723 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt))
17724 break;
17725 return SDValue();
17726
17727 case Intrinsic::arm_neon_vqshifts:
17728 case Intrinsic::arm_neon_vqshiftu:
17729 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17730 break;
17731 return SDValue();
17732
17733 case Intrinsic::arm_neon_vqshiftsu:
17734 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17735 break;
17736 llvm_unreachable("invalid shift count for vqshlu intrinsic");
17737
17738 case Intrinsic::arm_neon_vrshiftn:
17739 case Intrinsic::arm_neon_vqshiftns:
17740 case Intrinsic::arm_neon_vqshiftnu:
17741 case Intrinsic::arm_neon_vqshiftnsu:
17742 case Intrinsic::arm_neon_vqrshiftns:
17743 case Intrinsic::arm_neon_vqrshiftnu:
17744 case Intrinsic::arm_neon_vqrshiftnsu:
17745 // Narrowing shifts require an immediate right shift.
17746 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt))
17747 break;
17748 llvm_unreachable("invalid shift count for narrowing vector shift "
17749 "intrinsic");
17750
17751 default:
17752 llvm_unreachable("unhandled vector shift");
17753 }
17754
17755 switch (IntNo) {
17756 case Intrinsic::arm_neon_vshifts:
17757 case Intrinsic::arm_neon_vshiftu:
17758 // Opcode already set above.
17759 break;
17760 case Intrinsic::arm_neon_vrshifts:
17761 VShiftOpc = ARMISD::VRSHRsIMM;
17762 break;
17763 case Intrinsic::arm_neon_vrshiftu:
17764 VShiftOpc = ARMISD::VRSHRuIMM;
17765 break;
17766 case Intrinsic::arm_neon_vrshiftn:
17767 VShiftOpc = ARMISD::VRSHRNIMM;
17768 break;
17769 case Intrinsic::arm_neon_vqshifts:
17770 VShiftOpc = ARMISD::VQSHLsIMM;
17771 break;
17772 case Intrinsic::arm_neon_vqshiftu:
17773 VShiftOpc = ARMISD::VQSHLuIMM;
17774 break;
17775 case Intrinsic::arm_neon_vqshiftsu:
17776 VShiftOpc = ARMISD::VQSHLsuIMM;
17777 break;
17778 case Intrinsic::arm_neon_vqshiftns:
17779 VShiftOpc = ARMISD::VQSHRNsIMM;
17780 break;
17781 case Intrinsic::arm_neon_vqshiftnu:
17782 VShiftOpc = ARMISD::VQSHRNuIMM;
17783 break;
17784 case Intrinsic::arm_neon_vqshiftnsu:
17785 VShiftOpc = ARMISD::VQSHRNsuIMM;
17786 break;
17787 case Intrinsic::arm_neon_vqrshiftns:
17788 VShiftOpc = ARMISD::VQRSHRNsIMM;
17789 break;
17790 case Intrinsic::arm_neon_vqrshiftnu:
17791 VShiftOpc = ARMISD::VQRSHRNuIMM;
17792 break;
17793 case Intrinsic::arm_neon_vqrshiftnsu:
17794 VShiftOpc = ARMISD::VQRSHRNsuIMM;
17795 break;
17796 }
17797
17798 SDLoc dl(N);
17799 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17800 N->getOperand(1), DAG.getConstant(Cnt, dl, MVT::i32));
17801 }
17802
17803 case Intrinsic::arm_neon_vshiftins: {
17804 EVT VT = N->getOperand(1).getValueType();
17805 int64_t Cnt;
17806 unsigned VShiftOpc = 0;
17807
17808 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt))
17809 VShiftOpc = ARMISD::VSLIIMM;
17810 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt))
17811 VShiftOpc = ARMISD::VSRIIMM;
17812 else {
17813 llvm_unreachable("invalid shift count for vsli/vsri intrinsic");
17814 }
17815
17816 SDLoc dl(N);
17817 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17818 N->getOperand(1), N->getOperand(2),
17819 DAG.getConstant(Cnt, dl, MVT::i32));
17820 }
17821
17822 case Intrinsic::arm_neon_vqrshifts:
17823 case Intrinsic::arm_neon_vqrshiftu:
17824 // No immediate versions of these to check for.
17825 break;
17826
17827 case Intrinsic::arm_neon_vbsl: {
17828 SDLoc dl(N);
17829 return DAG.getNode(ARMISD::VBSP, dl, N->getValueType(0), N->getOperand(1),
17830 N->getOperand(2), N->getOperand(3));
17831 }
17832 case Intrinsic::arm_mve_vqdmlah:
17833 case Intrinsic::arm_mve_vqdmlash:
17834 case Intrinsic::arm_mve_vqrdmlah:
17835 case Intrinsic::arm_mve_vqrdmlash:
17836 case Intrinsic::arm_mve_vmla_n_predicated:
17837 case Intrinsic::arm_mve_vmlas_n_predicated:
17838 case Intrinsic::arm_mve_vqdmlah_predicated:
17839 case Intrinsic::arm_mve_vqdmlash_predicated:
17840 case Intrinsic::arm_mve_vqrdmlah_predicated:
17841 case Intrinsic::arm_mve_vqrdmlash_predicated: {
17842 // These intrinsics all take an i32 scalar operand which is narrowed to the
17843 // size of a single lane of the vector type they return. So we don't need
17844 // any bits of that operand above that point, which allows us to eliminate
17845 // uxth/sxth.
17846 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
17847 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17848 if (SimplifyDemandedBits(N->getOperand(3), DemandedMask, DCI))
17849 return SDValue();
17850 break;
17851 }
17852
17853 case Intrinsic::arm_mve_minv:
17854 case Intrinsic::arm_mve_maxv:
17855 case Intrinsic::arm_mve_minav:
17856 case Intrinsic::arm_mve_maxav:
17857 case Intrinsic::arm_mve_minv_predicated:
17858 case Intrinsic::arm_mve_maxv_predicated:
17859 case Intrinsic::arm_mve_minav_predicated:
17860 case Intrinsic::arm_mve_maxav_predicated: {
17861 // These intrinsics all take an i32 scalar operand which is narrowed to the
17862 // size of a single lane of the vector type they take as the other input.
17863 unsigned BitWidth = N->getOperand(2)->getValueType(0).getScalarSizeInBits();
17864 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17865 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
17866 return SDValue();
17867 break;
17868 }
17869
17870 case Intrinsic::arm_mve_addv: {
17871 // Turn this intrinsic straight into the appropriate ARMISD::VADDV node,
17872 // which allow PerformADDVecReduce to turn it into VADDLV when possible.
17873 bool Unsigned = N->getConstantOperandVal(2);
17874 unsigned Opc = Unsigned ? ARMISD::VADDVu : ARMISD::VADDVs;
17875 return DAG.getNode(Opc, SDLoc(N), N->getVTList(), N->getOperand(1));
17876 }
17877
17878 case Intrinsic::arm_mve_addlv:
17879 case Intrinsic::arm_mve_addlv_predicated: {
17880 // Same for these, but ARMISD::VADDLV has to be followed by a BUILD_PAIR
17881 // which recombines the two outputs into an i64
17882 bool Unsigned = N->getConstantOperandVal(2);
17883 unsigned Opc = IntNo == Intrinsic::arm_mve_addlv ?
17884 (Unsigned ? ARMISD::VADDLVu : ARMISD::VADDLVs) :
17885 (Unsigned ? ARMISD::VADDLVpu : ARMISD::VADDLVps);
17886
17888 for (unsigned i = 1, e = N->getNumOperands(); i < e; i++)
17889 if (i != 2) // skip the unsigned flag
17890 Ops.push_back(N->getOperand(i));
17891
17892 SDLoc dl(N);
17893 SDValue val = DAG.getNode(Opc, dl, {MVT::i32, MVT::i32}, Ops);
17894 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, val.getValue(0),
17895 val.getValue(1));
17896 }
17897 }
17898
17899 return SDValue();
17900}
17901
17903 EVT VT = Y.getValueType();
17904 if (!VT.isVector())
17905 return hasAndNotCompare(Y);
17906 if (Subtarget->hasMVEIntegerOps())
17907 return VT.is128BitVector();
17908 if (Subtarget->hasNEON())
17909 return VT.is64BitVector() || VT.is128BitVector();
17910 return false;
17911}
17912
17913/// PerformShiftCombine - Checks for immediate versions of vector shifts and
17914/// lowers them. As with the vector shift intrinsics, this is done during DAG
17915/// combining instead of DAG legalizing because the build_vectors for 64-bit
17916/// vector element shift counts are generally not legal, and it is hard to see
17917/// their values after they get legalized to loads from a constant pool.
17920 const ARMSubtarget *ST) {
17921 SelectionDAG &DAG = DCI.DAG;
17922 EVT VT = N->getValueType(0);
17923
17924 if (ST->isThumb1Only() && N->getOpcode() == ISD::SHL && VT == MVT::i32 &&
17925 N->getOperand(0)->getOpcode() == ISD::AND &&
17926 N->getOperand(0)->hasOneUse()) {
17927 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
17928 return SDValue();
17929 // Look for the pattern (shl (and x, AndMask), ShiftAmt). This doesn't
17930 // usually show up because instcombine prefers to canonicalize it to
17931 // (and (shl x, ShiftAmt) (shl AndMask, ShiftAmt)), but the shift can come
17932 // out of GEP lowering in some cases.
17933 SDValue N0 = N->getOperand(0);
17934 ConstantSDNode *ShiftAmtNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
17935 if (!ShiftAmtNode)
17936 return SDValue();
17937 uint32_t ShiftAmt = static_cast<uint32_t>(ShiftAmtNode->getZExtValue());
17938 ConstantSDNode *AndMaskNode = dyn_cast<ConstantSDNode>(N0->getOperand(1));
17939 if (!AndMaskNode)
17940 return SDValue();
17941 uint32_t AndMask = static_cast<uint32_t>(AndMaskNode->getZExtValue());
17942 // Don't transform uxtb/uxth.
17943 if (AndMask == 255 || AndMask == 65535)
17944 return SDValue();
17945 if (isMask_32(AndMask)) {
17946 uint32_t MaskedBits = llvm::countl_zero(AndMask);
17947 if (MaskedBits > ShiftAmt) {
17948 SDLoc DL(N);
17949 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
17950 DAG.getConstant(MaskedBits, DL, MVT::i32));
17951 return DAG.getNode(
17952 ISD::SRL, DL, MVT::i32, SHL,
17953 DAG.getConstant(MaskedBits - ShiftAmt, DL, MVT::i32));
17954 }
17955 }
17956 }
17957
17958 // Nothing to be done for scalar shifts.
17959 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
17960 if (!VT.isVector() || !TLI.isTypeLegal(VT))
17961 return SDValue();
17962 if (ST->hasMVEIntegerOps())
17963 return SDValue();
17964
17965 int64_t Cnt;
17966
17967 switch (N->getOpcode()) {
17968 default: llvm_unreachable("unexpected shift opcode");
17969
17970 case ISD::SHL:
17971 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) {
17972 SDLoc dl(N);
17973 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
17974 DAG.getConstant(Cnt, dl, MVT::i32));
17975 }
17976 break;
17977
17978 case ISD::SRA:
17979 case ISD::SRL:
17980 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
17981 unsigned VShiftOpc =
17982 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
17983 SDLoc dl(N);
17984 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
17985 DAG.getConstant(Cnt, dl, MVT::i32));
17986 }
17987 }
17988 return SDValue();
17989}
17990
17991// Look for a sign/zero/fpextend extend of a larger than legal load. This can be
17992// split into multiple extending loads, which are simpler to deal with than an
17993// arbitrary extend. For fp extends we use an integer extending load and a VCVTL
17994// to convert the type to an f32.
17996 SDValue N0 = N->getOperand(0);
17997 if (N0.getOpcode() != ISD::LOAD)
17998 return SDValue();
18000 if (!LD->isSimple() || !N0.hasOneUse() || LD->isIndexed() ||
18001 LD->getExtensionType() != ISD::NON_EXTLOAD)
18002 return SDValue();
18003 EVT FromVT = LD->getValueType(0);
18004 EVT ToVT = N->getValueType(0);
18005 if (!ToVT.isVector())
18006 return SDValue();
18008 EVT ToEltVT = ToVT.getVectorElementType();
18009 EVT FromEltVT = FromVT.getVectorElementType();
18010
18011 unsigned NumElements = 0;
18012 if (ToEltVT == MVT::i32 && FromEltVT == MVT::i8)
18013 NumElements = 4;
18014 if (ToEltVT == MVT::f32 && FromEltVT == MVT::f16)
18015 NumElements = 4;
18016 if (NumElements == 0 ||
18017 (FromEltVT != MVT::f16 && FromVT.getVectorNumElements() == NumElements) ||
18018 FromVT.getVectorNumElements() % NumElements != 0 ||
18019 !isPowerOf2_32(NumElements))
18020 return SDValue();
18021
18022 LLVMContext &C = *DAG.getContext();
18023 SDLoc DL(LD);
18024 // Details about the old load
18025 SDValue Ch = LD->getChain();
18026 SDValue BasePtr = LD->getBasePtr();
18027 Align Alignment = LD->getBaseAlign();
18028 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18029 AAMDNodes AAInfo = LD->getAAInfo();
18030
18031 ISD::LoadExtType NewExtType =
18032 N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18033 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
18034 EVT NewFromVT = EVT::getVectorVT(
18035 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
18036 EVT NewToVT = EVT::getVectorVT(
18037 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18038
18041 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18042 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18043 SDValue NewPtr =
18044 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18045
18046 SDValue NewLoad =
18047 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18048 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18049 Alignment, MMOFlags, AAInfo);
18050 Loads.push_back(NewLoad);
18051 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18052 }
18053
18054 // Float truncs need to extended with VCVTB's into their floating point types.
18055 if (FromEltVT == MVT::f16) {
18057
18058 for (unsigned i = 0; i < Loads.size(); i++) {
18059 SDValue LoadBC =
18060 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v8f16, Loads[i]);
18061 SDValue FPExt = DAG.getNode(ARMISD::VCVTL, DL, MVT::v4f32, LoadBC,
18062 DAG.getConstant(0, DL, MVT::i32));
18063 Extends.push_back(FPExt);
18064 }
18065
18066 Loads = Extends;
18067 }
18068
18069 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18070 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18071 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Loads);
18072}
18073
18074/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND,
18075/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND.
18077 const ARMSubtarget *ST) {
18078 SDValue N0 = N->getOperand(0);
18079 EVT VT = N->getValueType(0);
18080 SDLoc DL(N);
18081
18082 // Check for sign- and zero-extensions of vector extract operations of 8- and
18083 // 16-bit vector elements. NEON and MVE support these directly. They are
18084 // handled during DAG combining because type legalization will promote them
18085 // to 32-bit types and it is messy to recognize the operations after that.
18086 if ((ST->hasNEON() || ST->hasMVEIntegerOps()) &&
18088 SDValue Vec = N0.getOperand(0);
18089 SDValue Lane = N0.getOperand(1);
18090 EVT EltVT = N0.getValueType();
18091 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18092
18093 if (VT == MVT::i32 &&
18094 (EltVT == MVT::i8 || EltVT == MVT::i16) &&
18095 TLI.isTypeLegal(Vec.getValueType()) &&
18096 isa<ConstantSDNode>(Lane)) {
18097
18098 unsigned Opc = 0;
18099 switch (N->getOpcode()) {
18100 default: llvm_unreachable("unexpected opcode");
18101 case ISD::SIGN_EXTEND:
18102 Opc = ARMISD::VGETLANEs;
18103 break;
18104 case ISD::ZERO_EXTEND:
18105 case ISD::ANY_EXTEND:
18106 Opc = ARMISD::VGETLANEu;
18107 break;
18108 }
18109 return DAG.getNode(Opc, DL, VT, Vec, Lane);
18110 }
18111 }
18112
18113 if (ST->hasMVEIntegerOps())
18114 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18115 return NewLoad;
18116
18117 // Combine sext(buildvector(..)) to buildvector(sext(..)) to help avoid
18118 // difficult to lower i1 buildvector.
18119 if (ST->hasMVEIntegerOps() && N0.getValueType().getScalarSizeInBits() == 1 &&
18120 N0.getOpcode() == ISD::BUILD_VECTOR && VT.getScalarSizeInBits() <= 32) {
18122 for (unsigned I = 0; I < N0.getNumOperands(); I++) {
18123 SDValue InReg = N0.getOperand(I);
18124 if (N->getOpcode() == ISD::ZERO_EXTEND)
18125 InReg = DAG.getNode(ISD::AND, DL, InReg.getValueType(), InReg,
18126 DAG.getConstant(1, DL, InReg.getValueType()));
18127 else if (N->getOpcode() == ISD::SIGN_EXTEND)
18128 InReg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InReg.getValueType(),
18129 InReg, DAG.getValueType(MVT::i1));
18130 SDValue Ext = DAG.getNode(N->getOpcode(), DL, MVT::i32, InReg);
18131 Ops.push_back(Ext);
18132 }
18133 return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
18134 }
18135
18136 return SDValue();
18137}
18138
18140 const ARMSubtarget *ST) {
18141 if (ST->hasMVEFloatOps())
18142 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18143 return NewLoad;
18144
18145 return SDValue();
18146}
18147
18148// Lower smin(smax(x, C1), C2) to ssat or usat, if they have saturating
18149// constant bounds.
18151 const ARMSubtarget *Subtarget) {
18152 if ((Subtarget->isThumb() || !Subtarget->hasV6Ops()) &&
18153 !Subtarget->isThumb2())
18154 return SDValue();
18155
18156 EVT VT = Op.getValueType();
18157 SDValue Op0 = Op.getOperand(0);
18158
18159 if (VT != MVT::i32 ||
18160 (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
18161 !isa<ConstantSDNode>(Op.getOperand(1)) ||
18163 return SDValue();
18164
18165 SDValue Min = Op;
18166 SDValue Max = Op0;
18167 SDValue Input = Op0.getOperand(0);
18168 if (Min.getOpcode() == ISD::SMAX)
18169 std::swap(Min, Max);
18170
18171 if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX)
18172 return SDValue();
18173
18174 APInt MinC = Min.getConstantOperandAPInt(1);
18175 APInt MaxC = Max.getConstantOperandAPInt(1);
18176 if (MaxC.sgt(MinC))
18177 return SDValue();
18178
18179 SDLoc DL(Op);
18180
18181 // A clamp whose bounds are already a saturation range maps to a single
18182 // SSAT / USAT.
18183 if ((MinC + 1).isPowerOf2()) {
18184 if (MinC == ~MaxC)
18185 return DAG.getNode(ARMISD::SSAT, DL, VT, Input,
18186 DAG.getConstant(MinC.countr_one(), DL, VT));
18187 if (MaxC == 0)
18188 return DAG.getNode(ARMISD::USAT, DL, VT, Input,
18189 DAG.getConstant(MinC.countr_one(), DL, VT));
18190 }
18191
18192 // For power-of-two clamp widths, convert the range to be zero-centered,
18193 // apply SSAT, and convert the result back.
18194 //
18195 // Width = Hi - Lo + 1
18196 // Center = Lo + Width / 2
18197 // Result = ssat(X - Center) + Center
18198 //
18199 // The idea is to shift the input so that the clamp range is centered
18200 // around zero, apply ssat, and then shift the result back.
18201 //
18202 // For example clamp(X, -118, 137) -> Width = 256, Center = 10, so it becomes
18203 // ssat(X - 10, 8) + 10
18204
18205 APInt Width = MinC - MaxC + 1;
18206 if (!Width.isPowerOf2() || Width.isOne())
18207 return SDValue();
18208 unsigned SatBit = Width.logBase2() - 1; // ssat to SatBit + 1 signed bits
18209 APInt Center = MaxC + Width.lshr(1);
18210
18211 // The rewrite is only valid when X - Center does not overflow;
18212 SDValue NegC = DAG.getConstant(-Center, DL, VT);
18214 return SDValue();
18215
18216 SDValue Shifted = DAG.getNode(ISD::ADD, DL, VT, Input, NegC);
18217 SDValue Sat = DAG.getNode(ARMISD::SSAT, DL, VT, Shifted,
18218 DAG.getConstant(SatBit, DL, VT));
18219 return DAG.getNode(ISD::ADD, DL, VT, Sat, DAG.getConstant(Center, DL, VT));
18220}
18221
18222/// PerformMinMaxCombine - Target-specific DAG combining for creating truncating
18223/// saturates.
18225 const ARMSubtarget *ST) {
18226 EVT VT = N->getValueType(0);
18227 SDValue N0 = N->getOperand(0);
18228
18229 if (VT == MVT::i32)
18230 return PerformMinMaxToSatCombine(SDValue(N, 0), DAG, ST);
18231
18232 if (!ST->hasMVEIntegerOps())
18233 return SDValue();
18234
18235 if (SDValue V = PerformVQDMULHCombine(N, DAG))
18236 return V;
18237
18238 if (VT != MVT::v4i32 && VT != MVT::v8i16)
18239 return SDValue();
18240
18241 auto IsSignedSaturate = [&](SDNode *Min, SDNode *Max) {
18242 // Check one is a smin and the other is a smax
18243 if (Min->getOpcode() != ISD::SMIN)
18244 std::swap(Min, Max);
18245 if (Min->getOpcode() != ISD::SMIN || Max->getOpcode() != ISD::SMAX)
18246 return false;
18247
18248 APInt SaturateC;
18249 if (VT == MVT::v4i32)
18250 SaturateC = APInt(32, (1 << 15) - 1, true);
18251 else //if (VT == MVT::v8i16)
18252 SaturateC = APInt(16, (1 << 7) - 1, true);
18253
18254 APInt MinC, MaxC;
18255 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18256 MinC != SaturateC)
18257 return false;
18258 if (!ISD::isConstantSplatVector(Max->getOperand(1).getNode(), MaxC) ||
18259 MaxC != ~SaturateC)
18260 return false;
18261 return true;
18262 };
18263
18264 if (IsSignedSaturate(N, N0.getNode())) {
18265 SDLoc DL(N);
18266 MVT ExtVT, HalfVT;
18267 if (VT == MVT::v4i32) {
18268 HalfVT = MVT::v8i16;
18269 ExtVT = MVT::v4i16;
18270 } else { // if (VT == MVT::v8i16)
18271 HalfVT = MVT::v16i8;
18272 ExtVT = MVT::v8i8;
18273 }
18274
18275 // Create a VQMOVNB with undef top lanes, then signed extended into the top
18276 // half. That extend will hopefully be removed if only the bottom bits are
18277 // demanded (though a truncating store, for example).
18278 SDValue VQMOVN =
18279 DAG.getNode(ARMISD::VQMOVNs, DL, HalfVT, DAG.getUNDEF(HalfVT),
18280 N0->getOperand(0), DAG.getConstant(0, DL, MVT::i32));
18281 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18282 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Bitcast,
18283 DAG.getValueType(ExtVT));
18284 }
18285
18286 auto IsUnsignedSaturate = [&](SDNode *Min) {
18287 // For unsigned, we just need to check for <= 0xffff
18288 if (Min->getOpcode() != ISD::UMIN)
18289 return false;
18290
18291 APInt SaturateC;
18292 if (VT == MVT::v4i32)
18293 SaturateC = APInt(32, (1 << 16) - 1, true);
18294 else //if (VT == MVT::v8i16)
18295 SaturateC = APInt(16, (1 << 8) - 1, true);
18296
18297 APInt MinC;
18298 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18299 MinC != SaturateC)
18300 return false;
18301 return true;
18302 };
18303
18304 if (IsUnsignedSaturate(N)) {
18305 SDLoc DL(N);
18306 MVT HalfVT;
18307 unsigned ExtConst;
18308 if (VT == MVT::v4i32) {
18309 HalfVT = MVT::v8i16;
18310 ExtConst = 0x0000FFFF;
18311 } else { //if (VT == MVT::v8i16)
18312 HalfVT = MVT::v16i8;
18313 ExtConst = 0x00FF;
18314 }
18315
18316 // Create a VQMOVNB with undef top lanes, then ZExt into the top half with
18317 // an AND. That extend will hopefully be removed if only the bottom bits are
18318 // demanded (though a truncating store, for example).
18319 SDValue VQMOVN =
18320 DAG.getNode(ARMISD::VQMOVNu, DL, HalfVT, DAG.getUNDEF(HalfVT), N0,
18321 DAG.getConstant(0, DL, MVT::i32));
18322 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18323 return DAG.getNode(ISD::AND, DL, VT, Bitcast,
18324 DAG.getConstant(ExtConst, DL, VT));
18325 }
18326
18327 return SDValue();
18328}
18329
18332 if (!C)
18333 return nullptr;
18334 const APInt *CV = &C->getAPIntValue();
18335 return CV->isPowerOf2() ? CV : nullptr;
18336}
18337
18339 // If we have a CMOV, OR and AND combination such as:
18340 // if (x & CN)
18341 // y |= CM;
18342 //
18343 // And:
18344 // * CN is a single bit;
18345 // * All bits covered by CM are known zero in y
18346 //
18347 // Then we can convert this into a sequence of BFI instructions. This will
18348 // always be a win if CM is a single bit, will always be no worse than the
18349 // TST&OR sequence if CM is two bits, and for thumb will be no worse if CM is
18350 // three bits (due to the extra IT instruction).
18351
18352 SDValue Op0 = CMOV->getOperand(0);
18353 SDValue Op1 = CMOV->getOperand(1);
18354 auto CC = CMOV->getConstantOperandAPInt(2).getLimitedValue();
18355 SDValue CmpZ = CMOV->getOperand(3);
18356
18357 // The compare must be against zero.
18358 if (!isNullConstant(CmpZ->getOperand(1)))
18359 return SDValue();
18360
18361 assert(CmpZ->getOpcode() == ARMISD::CMPZ);
18362 SDValue And = CmpZ->getOperand(0);
18363 if (And->getOpcode() != ISD::AND)
18364 return SDValue();
18365 const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
18366 if (!AndC)
18367 return SDValue();
18368 SDValue X = And->getOperand(0);
18369
18370 if (CC == ARMCC::EQ) {
18371 // We're performing an "equal to zero" compare. Swap the operands so we
18372 // canonicalize on a "not equal to zero" compare.
18373 std::swap(Op0, Op1);
18374 } else {
18375 assert(CC == ARMCC::NE && "How can a CMPZ node not be EQ or NE?");
18376 }
18377
18378 if (Op1->getOpcode() != ISD::OR)
18379 return SDValue();
18380
18382 if (!OrC)
18383 return SDValue();
18384 SDValue Y = Op1->getOperand(0);
18385
18386 if (Op0 != Y)
18387 return SDValue();
18388
18389 // Now, is it profitable to continue?
18390 APInt OrCI = OrC->getAPIntValue();
18391 unsigned Heuristic = Subtarget->isThumb() ? 3 : 2;
18392 if (OrCI.popcount() > Heuristic)
18393 return SDValue();
18394
18395 // Lastly, can we determine that the bits defined by OrCI
18396 // are zero in Y?
18398 if ((OrCI & Known.Zero) != OrCI)
18399 return SDValue();
18400
18401 // OK, we can do the combine.
18402 SDValue V = Y;
18403 SDLoc dl(X);
18404 EVT VT = X.getValueType();
18405 unsigned BitInX = AndC->logBase2();
18406
18407 if (BitInX != 0) {
18408 // We must shift X first.
18409 X = DAG.getNode(ISD::SRL, dl, VT, X,
18410 DAG.getConstant(BitInX, dl, VT));
18411 }
18412
18413 for (unsigned BitInY = 0, NumActiveBits = OrCI.getActiveBits();
18414 BitInY < NumActiveBits; ++BitInY) {
18415 if (OrCI[BitInY] == 0)
18416 continue;
18417 APInt Mask(VT.getSizeInBits(), 0);
18418 Mask.setBit(BitInY);
18419 V = DAG.getNode(ARMISD::BFI, dl, VT, V, X,
18420 // Confusingly, the operand is an *inverted* mask.
18421 DAG.getConstant(~Mask, dl, VT));
18422 }
18423
18424 return V;
18425}
18426
18427// Given N, the value controlling the conditional branch, search for the loop
18428// intrinsic, returning it, along with how the value is used. We need to handle
18429// patterns such as the following:
18430// (brcond (xor (setcc (loop.decrement), 0, ne), 1), exit)
18431// (brcond (setcc (loop.decrement), 0, eq), exit)
18432// (brcond (setcc (loop.decrement), 0, ne), header)
18434 bool &Negate) {
18435 switch (N->getOpcode()) {
18436 default:
18437 break;
18438 case ISD::XOR: {
18439 if (!isa<ConstantSDNode>(N.getOperand(1)))
18440 return SDValue();
18441 if (!cast<ConstantSDNode>(N.getOperand(1))->isOne())
18442 return SDValue();
18443 Negate = !Negate;
18444 return SearchLoopIntrinsic(N.getOperand(0), CC, Imm, Negate);
18445 }
18446 case ISD::SETCC: {
18447 auto *Const = dyn_cast<ConstantSDNode>(N.getOperand(1));
18448 if (!Const)
18449 return SDValue();
18450 if (Const->isZero())
18451 Imm = 0;
18452 else if (Const->isOne())
18453 Imm = 1;
18454 else
18455 return SDValue();
18456 CC = cast<CondCodeSDNode>(N.getOperand(2))->get();
18457 return SearchLoopIntrinsic(N->getOperand(0), CC, Imm, Negate);
18458 }
18460 unsigned IntOp = N.getConstantOperandVal(1);
18461 if (IntOp != Intrinsic::test_start_loop_iterations &&
18462 IntOp != Intrinsic::loop_decrement_reg)
18463 return SDValue();
18464 return N;
18465 }
18466 }
18467 return SDValue();
18468}
18469
18472 const ARMSubtarget *ST) {
18473
18474 // The hwloop intrinsics that we're interested are used for control-flow,
18475 // either for entering or exiting the loop:
18476 // - test.start.loop.iterations will test whether its operand is zero. If it
18477 // is zero, the proceeding branch should not enter the loop.
18478 // - loop.decrement.reg also tests whether its operand is zero. If it is
18479 // zero, the proceeding branch should not branch back to the beginning of
18480 // the loop.
18481 // So here, we need to check that how the brcond is using the result of each
18482 // of the intrinsics to ensure that we're branching to the right place at the
18483 // right time.
18484
18485 ISD::CondCode CC;
18486 SDValue Cond;
18487 int Imm = 1;
18488 bool Negate = false;
18489 SDValue Chain = N->getOperand(0);
18490 SDValue Dest;
18491
18492 if (N->getOpcode() == ISD::BRCOND) {
18493 CC = ISD::SETEQ;
18494 Cond = N->getOperand(1);
18495 Dest = N->getOperand(2);
18496 } else {
18497 assert(N->getOpcode() == ISD::BR_CC && "Expected BRCOND or BR_CC!");
18498 CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
18499 Cond = N->getOperand(2);
18500 Dest = N->getOperand(4);
18501 if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(3))) {
18502 if (!Const->isOne() && !Const->isZero())
18503 return SDValue();
18504 Imm = Const->getZExtValue();
18505 } else
18506 return SDValue();
18507 }
18508
18509 SDValue Int = SearchLoopIntrinsic(Cond, CC, Imm, Negate);
18510 if (!Int)
18511 return SDValue();
18512
18513 if (Negate)
18514 CC = ISD::getSetCCInverse(CC, /* Integer inverse */ MVT::i32);
18515
18516 auto IsTrueIfZero = [](ISD::CondCode CC, int Imm) {
18517 return (CC == ISD::SETEQ && Imm == 0) ||
18518 (CC == ISD::SETNE && Imm == 1) ||
18519 (CC == ISD::SETLT && Imm == 1) ||
18520 (CC == ISD::SETULT && Imm == 1);
18521 };
18522
18523 auto IsFalseIfZero = [](ISD::CondCode CC, int Imm) {
18524 return (CC == ISD::SETEQ && Imm == 1) ||
18525 (CC == ISD::SETNE && Imm == 0) ||
18526 (CC == ISD::SETGT && Imm == 0) ||
18527 (CC == ISD::SETUGT && Imm == 0) ||
18528 (CC == ISD::SETGE && Imm == 1) ||
18529 (CC == ISD::SETUGE && Imm == 1);
18530 };
18531
18532 assert((IsTrueIfZero(CC, Imm) || IsFalseIfZero(CC, Imm)) &&
18533 "unsupported condition");
18534
18535 SDLoc dl(Int);
18536 SelectionDAG &DAG = DCI.DAG;
18537 SDValue Elements = Int.getOperand(2);
18538 unsigned IntOp = Int->getConstantOperandVal(1);
18539 assert((N->hasOneUse() && N->user_begin()->getOpcode() == ISD::BR) &&
18540 "expected single br user");
18541 SDNode *Br = *N->user_begin();
18542 SDValue OtherTarget = Br->getOperand(1);
18543
18544 // Update the unconditional branch to branch to the given Dest.
18545 auto UpdateUncondBr = [](SDNode *Br, SDValue Dest, SelectionDAG &DAG) {
18546 SDValue NewBrOps[] = { Br->getOperand(0), Dest };
18547 SDValue NewBr = DAG.getNode(ISD::BR, SDLoc(Br), MVT::Other, NewBrOps);
18548 DAG.ReplaceAllUsesOfValueWith(SDValue(Br, 0), NewBr);
18549 };
18550
18551 if (IntOp == Intrinsic::test_start_loop_iterations) {
18552 SDValue Res;
18553 SDValue Setup = DAG.getNode(ARMISD::WLSSETUP, dl, MVT::i32, Elements);
18554 // We expect this 'instruction' to branch when the counter is zero.
18555 if (IsTrueIfZero(CC, Imm)) {
18556 SDValue Ops[] = {Chain, Setup, Dest};
18557 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18558 } else {
18559 // The logic is the reverse of what we need for WLS, so find the other
18560 // basic block target: the target of the proceeding br.
18561 UpdateUncondBr(Br, Dest, DAG);
18562
18563 SDValue Ops[] = {Chain, Setup, OtherTarget};
18564 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18565 }
18566 // Update LR count to the new value
18567 DAG.ReplaceAllUsesOfValueWith(Int.getValue(0), Setup);
18568 // Update chain
18569 DAG.ReplaceAllUsesOfValueWith(Int.getValue(2), Int.getOperand(0));
18570 return Res;
18571 } else {
18572 SDValue Size =
18573 DAG.getTargetConstant(Int.getConstantOperandVal(3), dl, MVT::i32);
18574 SDValue Args[] = { Int.getOperand(0), Elements, Size, };
18575 SDValue LoopDec = DAG.getNode(ARMISD::LOOP_DEC, dl,
18576 DAG.getVTList(MVT::i32, MVT::Other), Args);
18577 DAG.ReplaceAllUsesWith(Int.getNode(), LoopDec.getNode());
18578
18579 // We expect this instruction to branch when the count is not zero.
18580 SDValue Target = IsFalseIfZero(CC, Imm) ? Dest : OtherTarget;
18581
18582 // Update the unconditional branch to target the loop preheader if we've
18583 // found the condition has been reversed.
18584 if (Target == OtherTarget)
18585 UpdateUncondBr(Br, Dest, DAG);
18586
18587 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
18588 SDValue(LoopDec.getNode(), 1), Chain);
18589
18590 SDValue EndArgs[] = { Chain, SDValue(LoopDec.getNode(), 0), Target };
18591 return DAG.getNode(ARMISD::LE, dl, MVT::Other, EndArgs);
18592 }
18593 return SDValue();
18594}
18595
18596/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
18597SDValue
18599 SDValue Cmp = N->getOperand(3);
18600 if (Cmp.getOpcode() != ARMISD::CMPZ)
18601 // Only looking at NE cases.
18602 return SDValue();
18603
18604 SDLoc dl(N);
18605 SDValue LHS = Cmp.getOperand(0);
18606 SDValue RHS = Cmp.getOperand(1);
18607 SDValue Chain = N->getOperand(0);
18608 SDValue BB = N->getOperand(1);
18609 SDValue ARMcc = N->getOperand(2);
18611
18612 // (brcond Chain BB ne (cmpz (and (cmov 0 1 CC Flags) 1) 0))
18613 // -> (brcond Chain BB CC Flags)
18614 if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
18615 LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
18616 LHS->getOperand(0)->hasOneUse() &&
18617 isNullConstant(LHS->getOperand(0)->getOperand(0)) &&
18618 isOneConstant(LHS->getOperand(0)->getOperand(1)) &&
18619 isOneConstant(LHS->getOperand(1)) && isNullConstant(RHS)) {
18620 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, BB,
18621 LHS->getOperand(0)->getOperand(2),
18622 LHS->getOperand(0)->getOperand(3));
18623 }
18624
18625 return SDValue();
18626}
18627
18628/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
18629SDValue
18631 SDLoc dl(N);
18632 EVT VT = N->getValueType(0);
18633 SDValue FalseVal = N->getOperand(0);
18634 SDValue TrueVal = N->getOperand(1);
18635 SDValue ARMcc = N->getOperand(2);
18636 SDValue Cmp = N->getOperand(3);
18637
18638 // Try to form CSINV etc.
18639 unsigned Opcode;
18640 bool InvertCond;
18641 if (SDValue CSetOp =
18642 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
18643 if (InvertCond) {
18644 ARMCC::CondCodes CondCode =
18645 (ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
18646 CondCode = ARMCC::getOppositeCondition(CondCode);
18647 ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
18648 }
18649 return DAG.getNode(Opcode, dl, VT, CSetOp, CSetOp, ARMcc, Cmp);
18650 }
18651
18652 if (Cmp.getOpcode() != ARMISD::CMPZ)
18653 // Only looking at EQ and NE cases.
18654 return SDValue();
18655
18656 SDValue LHS = Cmp.getOperand(0);
18657 SDValue RHS = Cmp.getOperand(1);
18659
18660 // BFI is only available on V6T2+.
18661 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops()) {
18663 if (R)
18664 return R;
18665 }
18666
18667 // Simplify
18668 // mov r1, r0
18669 // cmp r1, x
18670 // mov r0, y
18671 // moveq r0, x
18672 // to
18673 // cmp r0, x
18674 // movne r0, y
18675 //
18676 // mov r1, r0
18677 // cmp r1, x
18678 // mov r0, x
18679 // movne r0, y
18680 // to
18681 // cmp r0, x
18682 // movne r0, y
18683 /// FIXME: Turn this into a target neutral optimization?
18684 SDValue Res;
18685 if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) {
18686 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, Cmp);
18687 } else if (CC == ARMCC::EQ && TrueVal == RHS) {
18688 SDValue ARMcc;
18689 SDValue NewCmp = getARMCmp(LHS, RHS, ISD::SETNE, ARMcc, DAG, dl);
18690 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, FalseVal, ARMcc, NewCmp);
18691 }
18692
18693 // (cmov F T ne (cmpz (cmov 0 1 CC Flags) 0))
18694 // -> (cmov F T CC Flags)
18695 if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse() &&
18696 isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
18697 isNullConstant(RHS)) {
18698 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
18699 LHS->getOperand(2), LHS->getOperand(3));
18700 }
18701
18702 if (!VT.isInteger())
18703 return SDValue();
18704
18705 // Fold away an unnecessary CMPZ/CMOV
18706 // CMOV A, B, C1, (CMPZ (CMOV 1, 0, C2, D), 0) ->
18707 // if C1==EQ -> CMOV A, B, C2, D
18708 // if C1==NE -> CMOV A, B, NOT(C2), D
18709 if (N->getConstantOperandVal(2) == ARMCC::EQ ||
18710 N->getConstantOperandVal(2) == ARMCC::NE) {
18712 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
18713 if (N->getConstantOperandVal(2) == ARMCC::NE)
18715 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
18716 N->getOperand(1),
18717 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
18718 }
18719 }
18720
18721 // Materialize a boolean comparison for integers so we can avoid branching.
18722 if (isNullConstant(FalseVal)) {
18723 if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
18724 if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
18725 // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
18726 // right 5 bits will make that 32 be 1, otherwise it will be 0.
18727 // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
18728 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18729 Res = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Sub),
18730 DAG.getConstant(5, dl, MVT::i32));
18731 } else {
18732 // CMOV 0, 1, ==, (CMPZ x, y) ->
18733 // (UADDO_CARRY (SUB x, y), t:0, t:1)
18734 // where t = (USUBO_CARRY 0, (SUB x, y), 0)
18735 //
18736 // The USUBO_CARRY computes 0 - (x - y) and this will give a borrow when
18737 // x != y. In other words, a carry C == 1 when x == y, C == 0
18738 // otherwise.
18739 // The final UADDO_CARRY computes
18740 // x - y + (0 - (x - y)) + C == C
18741 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18742 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18743 SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
18744 // ISD::USUBO_CARRY returns a borrow but we want the carry here
18745 // actually.
18746 SDValue Carry =
18747 DAG.getNode(ISD::SUB, dl, MVT::i32,
18748 DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
18749 Res = DAG.getNode(ISD::UADDO_CARRY, dl, VTs, Sub, Neg, Carry);
18750 }
18751 } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
18752 (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
18753 // This seems pointless but will allow us to combine it further below.
18754 // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18755 SDValue Sub =
18756 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18757 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
18758 Sub.getValue(1));
18759 FalseVal = Sub;
18760 }
18761 } else if (isNullConstant(TrueVal)) {
18762 if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
18763 (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
18764 // This seems pointless but will allow us to combine it further below
18765 // Note that we change == for != as this is the dual for the case above.
18766 // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18767 SDValue Sub =
18768 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18769 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
18770 DAG.getConstant(ARMCC::NE, dl, MVT::i32),
18771 Sub.getValue(1));
18772 FalseVal = Sub;
18773 }
18774 }
18775
18776 // On Thumb1, the DAG above may be further combined if z is a power of 2
18777 // (z == 2 ^ K).
18778 // CMOV (SUBC x, y), z, !=, (SUBC x, y):1 ->
18779 // t1 = (USUBO (SUB x, y), 1)
18780 // t2 = (USUBO_CARRY (SUB x, y), t1:0, t1:1)
18781 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18782 //
18783 // This also handles the special case of comparing against zero; it's
18784 // essentially, the same pattern, except there's no SUBC:
18785 // CMOV x, z, !=, (CMPZ x, 0) ->
18786 // t1 = (USUBO x, 1)
18787 // t2 = (USUBO_CARRY x, t1:0, t1:1)
18788 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18789 const APInt *TrueConst;
18790 if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
18791 ((FalseVal.getOpcode() == ARMISD::SUBC && FalseVal.getOperand(0) == LHS &&
18792 FalseVal.getOperand(1) == RHS) ||
18793 (FalseVal == LHS && isNullConstant(RHS))) &&
18794 (TrueConst = isPowerOf2Constant(TrueVal))) {
18795 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18796 unsigned ShiftAmount = TrueConst->logBase2();
18797 if (ShiftAmount)
18798 TrueVal = DAG.getConstant(1, dl, VT);
18799 SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
18800 Res = DAG.getNode(ISD::USUBO_CARRY, dl, VTs, FalseVal, Subc,
18801 Subc.getValue(1));
18802
18803 if (ShiftAmount)
18804 Res = DAG.getNode(ISD::SHL, dl, VT, Res,
18805 DAG.getConstant(ShiftAmount, dl, MVT::i32));
18806 }
18807
18808 if (Res.getNode()) {
18810 // Capture demanded bits information that would be otherwise lost.
18811 if (Known.Zero == 0xfffffffe)
18812 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18813 DAG.getValueType(MVT::i1));
18814 else if (Known.Zero == 0xffffff00)
18815 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18816 DAG.getValueType(MVT::i8));
18817 else if (Known.Zero == 0xffff0000)
18818 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18819 DAG.getValueType(MVT::i16));
18820 }
18821
18822 return Res;
18823}
18824
18827 const ARMSubtarget *ST) {
18828 SelectionDAG &DAG = DCI.DAG;
18829 SDValue Src = N->getOperand(0);
18830 EVT DstVT = N->getValueType(0);
18831
18832 // Convert v4f32 bitcast (v4i32 vdup (i32)) -> v4f32 vdup (i32) under MVE.
18833 if (ST->hasMVEIntegerOps() && Src.getOpcode() == ARMISD::VDUP) {
18834 EVT SrcVT = Src.getValueType();
18835 if (SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits())
18836 return DAG.getNode(ARMISD::VDUP, SDLoc(N), DstVT, Src.getOperand(0));
18837 }
18838
18839 // We may have a bitcast of something that has already had this bitcast
18840 // combine performed on it, so skip past any VECTOR_REG_CASTs.
18841 if (Src.getOpcode() == ARMISD::VECTOR_REG_CAST &&
18842 Src.getOperand(0).getValueType().getScalarSizeInBits() <=
18843 Src.getValueType().getScalarSizeInBits())
18844 Src = Src.getOperand(0);
18845
18846 // Bitcast from element-wise VMOV or VMVN doesn't need VREV if the VREV that
18847 // would be generated is at least the width of the element type.
18848 EVT SrcVT = Src.getValueType();
18849 if ((Src.getOpcode() == ARMISD::VMOVIMM ||
18850 Src.getOpcode() == ARMISD::VMVNIMM ||
18851 Src.getOpcode() == ARMISD::VMOVFPIMM) &&
18852 SrcVT.getScalarSizeInBits() <= DstVT.getScalarSizeInBits() &&
18853 DAG.getDataLayout().isBigEndian())
18854 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(N), DstVT, Src);
18855
18856 // bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD x
18857 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
18858 return R;
18859
18860 return SDValue();
18861}
18862
18863// Some combines for the MVETrunc truncations legalizer helper. Also lowers the
18864// node into stack operations after legalizeOps.
18867 SelectionDAG &DAG = DCI.DAG;
18868 EVT VT = N->getValueType(0);
18869 SDLoc DL(N);
18870
18871 // MVETrunc(Undef, Undef) -> Undef
18872 if (all_of(N->ops(), [](SDValue Op) { return Op.isUndef(); }))
18873 return DAG.getUNDEF(VT);
18874
18875 // MVETrunc(MVETrunc a b, MVETrunc c, d) -> MVETrunc
18876 if (N->getNumOperands() == 2 &&
18877 N->getOperand(0).getOpcode() == ARMISD::MVETRUNC &&
18878 N->getOperand(1).getOpcode() == ARMISD::MVETRUNC)
18879 return DAG.getNode(ARMISD::MVETRUNC, DL, VT, N->getOperand(0).getOperand(0),
18880 N->getOperand(0).getOperand(1),
18881 N->getOperand(1).getOperand(0),
18882 N->getOperand(1).getOperand(1));
18883
18884 // MVETrunc(shuffle, shuffle) -> VMOVN
18885 if (N->getNumOperands() == 2 &&
18886 N->getOperand(0).getOpcode() == ISD::VECTOR_SHUFFLE &&
18887 N->getOperand(1).getOpcode() == ISD::VECTOR_SHUFFLE) {
18888 auto *S0 = cast<ShuffleVectorSDNode>(N->getOperand(0).getNode());
18889 auto *S1 = cast<ShuffleVectorSDNode>(N->getOperand(1).getNode());
18890
18891 if (S0->getOperand(0) == S1->getOperand(0) &&
18892 S0->getOperand(1) == S1->getOperand(1)) {
18893 // Construct complete shuffle mask
18894 SmallVector<int, 8> Mask(S0->getMask());
18895 Mask.append(S1->getMask().begin(), S1->getMask().end());
18896
18897 if (isVMOVNTruncMask(Mask, VT, false))
18898 return DAG.getNode(
18899 ARMISD::VMOVN, DL, VT,
18900 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18901 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18902 DAG.getConstant(1, DL, MVT::i32));
18903 if (isVMOVNTruncMask(Mask, VT, true))
18904 return DAG.getNode(
18905 ARMISD::VMOVN, DL, VT,
18906 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18907 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18908 DAG.getConstant(1, DL, MVT::i32));
18909 }
18910 }
18911
18912 // For MVETrunc of a buildvector or shuffle, it can be beneficial to lower the
18913 // truncate to a buildvector to allow the generic optimisations to kick in.
18914 if (all_of(N->ops(), [](SDValue Op) {
18915 return Op.getOpcode() == ISD::BUILD_VECTOR ||
18916 Op.getOpcode() == ISD::VECTOR_SHUFFLE ||
18917 (Op.getOpcode() == ISD::BITCAST &&
18918 Op.getOperand(0).getOpcode() == ISD::BUILD_VECTOR);
18919 })) {
18920 SmallVector<SDValue, 8> Extracts;
18921 for (unsigned Op = 0; Op < N->getNumOperands(); Op++) {
18922 SDValue O = N->getOperand(Op);
18923 for (unsigned i = 0; i < O.getValueType().getVectorNumElements(); i++) {
18924 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, O,
18925 DAG.getConstant(i, DL, MVT::i32));
18926 Extracts.push_back(Ext);
18927 }
18928 }
18929 return DAG.getBuildVector(VT, DL, Extracts);
18930 }
18931
18932 // If we are late in the legalization process and nothing has optimised
18933 // the trunc to anything better, lower it to a stack store and reload,
18934 // performing the truncation whilst keeping the lanes in the correct order:
18935 // VSTRH.32 a, stack; VSTRH.32 b, stack+8; VLDRW.32 stack;
18936 if (!DCI.isAfterLegalizeDAG())
18937 return SDValue();
18938
18939 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
18940 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
18941 int NumIns = N->getNumOperands();
18942 assert((NumIns == 2 || NumIns == 4) &&
18943 "Expected 2 or 4 inputs to an MVETrunc");
18944 EVT StoreVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
18945 if (N->getNumOperands() == 4)
18946 StoreVT = StoreVT.getHalfNumVectorElementsVT(*DAG.getContext());
18947
18948 SmallVector<SDValue> Chains;
18949 for (int I = 0; I < NumIns; I++) {
18950 SDValue Ptr = DAG.getNode(
18951 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
18952 DAG.getConstant(I * 16 / NumIns, DL, StackPtr.getValueType()));
18954 DAG.getMachineFunction(), SPFI, I * 16 / NumIns);
18955 SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), DL, N->getOperand(I),
18956 Ptr, MPI, StoreVT, Align(4));
18957 Chains.push_back(Ch);
18958 }
18959
18960 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18961 MachinePointerInfo MPI =
18963 return DAG.getLoad(VT, DL, Chain, StackPtr, MPI, Align(4));
18964}
18965
18966// Take a MVEEXT(load x) and split that into (extload x, extload x+8)
18968 SelectionDAG &DAG) {
18969 SDValue N0 = N->getOperand(0);
18971 if (!LD || !LD->isSimple() || !N0.hasOneUse() || LD->isIndexed())
18972 return SDValue();
18973
18974 EVT FromVT = LD->getMemoryVT();
18975 EVT ToVT = N->getValueType(0);
18976 if (!ToVT.isVector())
18977 return SDValue();
18978 assert(FromVT.getVectorNumElements() == ToVT.getVectorNumElements() * 2);
18979 EVT ToEltVT = ToVT.getVectorElementType();
18980 EVT FromEltVT = FromVT.getVectorElementType();
18981
18982 unsigned NumElements = 0;
18983 if (ToEltVT == MVT::i32 && (FromEltVT == MVT::i16 || FromEltVT == MVT::i8))
18984 NumElements = 4;
18985 if (ToEltVT == MVT::i16 && FromEltVT == MVT::i8)
18986 NumElements = 8;
18987 assert(NumElements != 0);
18988
18989 ISD::LoadExtType NewExtType =
18990 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18991 if (LD->getExtensionType() != ISD::NON_EXTLOAD &&
18992 LD->getExtensionType() != ISD::EXTLOAD &&
18993 LD->getExtensionType() != NewExtType)
18994 return SDValue();
18995
18996 LLVMContext &C = *DAG.getContext();
18997 SDLoc DL(LD);
18998 // Details about the old load
18999 SDValue Ch = LD->getChain();
19000 SDValue BasePtr = LD->getBasePtr();
19001 Align Alignment = LD->getBaseAlign();
19002 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
19003 AAMDNodes AAInfo = LD->getAAInfo();
19004
19005 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
19006 EVT NewFromVT = EVT::getVectorVT(
19007 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
19008 EVT NewToVT = EVT::getVectorVT(
19009 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
19010
19013 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
19014 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
19015 SDValue NewPtr =
19016 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
19017
19018 SDValue NewLoad =
19019 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
19020 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
19021 Alignment, MMOFlags, AAInfo);
19022 Loads.push_back(NewLoad);
19023 Chains.push_back(SDValue(NewLoad.getNode(), 1));
19024 }
19025
19026 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
19027 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
19028 return DAG.getMergeValues(Loads, DL);
19029}
19030
19031// Perform combines for MVEEXT. If it has not be optimized to anything better
19032// before lowering, it gets converted to stack store and extloads performing the
19033// extend whilst still keeping the same lane ordering.
19036 SelectionDAG &DAG = DCI.DAG;
19037 EVT VT = N->getValueType(0);
19038 SDLoc DL(N);
19039 assert(N->getNumValues() == 2 && "Expected MVEEXT with 2 elements");
19040 assert((VT == MVT::v4i32 || VT == MVT::v8i16) && "Unexpected MVEEXT type");
19041
19042 EVT ExtVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19043 *DAG.getContext());
19044 auto Extend = [&](SDValue V) {
19045 SDValue VVT = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, V);
19046 return N->getOpcode() == ARMISD::MVESEXT
19047 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, VVT,
19048 DAG.getValueType(ExtVT))
19049 : DAG.getZeroExtendInReg(VVT, DL, ExtVT);
19050 };
19051
19052 // MVEEXT(VDUP) -> SIGN_EXTEND_INREG(VDUP)
19053 if (N->getOperand(0).getOpcode() == ARMISD::VDUP) {
19054 SDValue Ext = Extend(N->getOperand(0));
19055 return DAG.getMergeValues({Ext, Ext}, DL);
19056 }
19057
19058 // MVEEXT(shuffle) -> SIGN_EXTEND_INREG/ZERO_EXTEND_INREG
19059 if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N->getOperand(0))) {
19060 ArrayRef<int> Mask = SVN->getMask();
19061 assert(Mask.size() == 2 * VT.getVectorNumElements());
19062 assert(Mask.size() == SVN->getValueType(0).getVectorNumElements());
19063 unsigned Rev = VT == MVT::v4i32 ? ARMISD::VREV32 : ARMISD::VREV16;
19064 SDValue Op0 = SVN->getOperand(0);
19065 SDValue Op1 = SVN->getOperand(1);
19066
19067 auto CheckInregMask = [&](int Start, int Offset) {
19068 for (int Idx = 0, E = VT.getVectorNumElements(); Idx < E; ++Idx)
19069 if (Mask[Start + Idx] >= 0 && Mask[Start + Idx] != Idx * 2 + Offset)
19070 return false;
19071 return true;
19072 };
19073 SDValue V0 = SDValue(N, 0);
19074 SDValue V1 = SDValue(N, 1);
19075 if (CheckInregMask(0, 0))
19076 V0 = Extend(Op0);
19077 else if (CheckInregMask(0, 1))
19078 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19079 else if (CheckInregMask(0, Mask.size()))
19080 V0 = Extend(Op1);
19081 else if (CheckInregMask(0, Mask.size() + 1))
19082 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19083
19084 if (CheckInregMask(VT.getVectorNumElements(), Mask.size()))
19085 V1 = Extend(Op1);
19086 else if (CheckInregMask(VT.getVectorNumElements(), Mask.size() + 1))
19087 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19088 else if (CheckInregMask(VT.getVectorNumElements(), 0))
19089 V1 = Extend(Op0);
19090 else if (CheckInregMask(VT.getVectorNumElements(), 1))
19091 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19092
19093 if (V0.getNode() != N || V1.getNode() != N)
19094 return DAG.getMergeValues({V0, V1}, DL);
19095 }
19096
19097 // MVEEXT(load) -> extload, extload
19098 if (N->getOperand(0)->getOpcode() == ISD::LOAD)
19100 return L;
19101
19102 if (!DCI.isAfterLegalizeDAG())
19103 return SDValue();
19104
19105 // Lower to a stack store and reload:
19106 // VSTRW.32 a, stack; VLDRH.32 stack; VLDRH.32 stack+8;
19107 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19108 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19109 int NumOuts = N->getNumValues();
19110 assert((NumOuts == 2 || NumOuts == 4) &&
19111 "Expected 2 or 4 outputs to an MVEEXT");
19112 EVT LoadVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19113 *DAG.getContext());
19114 if (N->getNumOperands() == 4)
19115 LoadVT = LoadVT.getHalfNumVectorElementsVT(*DAG.getContext());
19116
19117 MachinePointerInfo MPI =
19119 SDValue Chain = DAG.getStore(DAG.getEntryNode(), DL, N->getOperand(0),
19120 StackPtr, MPI, Align(4));
19121
19123 for (int I = 0; I < NumOuts; I++) {
19124 SDValue Ptr = DAG.getNode(
19125 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19126 DAG.getConstant(I * 16 / NumOuts, DL, StackPtr.getValueType()));
19128 DAG.getMachineFunction(), SPFI, I * 16 / NumOuts);
19129 SDValue Load = DAG.getExtLoad(
19130 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD, DL,
19131 VT, Chain, Ptr, MPI, LoadVT, Align(4));
19132 Loads.push_back(Load);
19133 }
19134
19135 return DAG.getMergeValues(Loads, DL);
19136}
19137
19139 DAGCombinerInfo &DCI) const {
19140 switch (N->getOpcode()) {
19141 default: break;
19142 case ISD::SELECT_CC:
19143 case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
19144 case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
19145 case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
19146 case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
19147 case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
19148 case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget);
19149 case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget);
19150 case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget);
19151 case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
19152 case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
19153 case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
19154 case ISD::BRCOND:
19155 case ISD::BR_CC: return PerformHWLoopCombine(N, DCI, Subtarget);
19156 case ARMISD::ADDC:
19157 case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
19158 case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI, Subtarget);
19159 case ARMISD::BFI: return PerformBFICombine(N, DCI.DAG);
19160 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
19161 case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG);
19162 case ARMISD::VMOVhr: return PerformVMOVhrCombine(N, DCI);
19163 case ARMISD::VMOVrh: return PerformVMOVrhCombine(N, DCI.DAG);
19164 case ISD::STORE: return PerformSTORECombine(N, DCI, Subtarget);
19165 case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI, Subtarget);
19168 return PerformExtractEltCombine(N, DCI, Subtarget);
19172 case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI, Subtarget);
19173 case ARMISD::VDUP: return PerformVDUPCombine(N, DCI.DAG, Subtarget);
19174 case ISD::FP_TO_SINT:
19175 case ISD::FP_TO_UINT:
19176 return PerformVCVTCombine(N, DCI.DAG, Subtarget);
19177 case ISD::FADD:
19178 return PerformFADDCombine(N, DCI.DAG, Subtarget);
19179 case ISD::FMUL:
19180 return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget);
19182 return PerformIntrinsicCombine(N, DCI);
19183 case ISD::SHL:
19184 case ISD::SRA:
19185 case ISD::SRL:
19186 return PerformShiftCombine(N, DCI, Subtarget);
19187 case ISD::SIGN_EXTEND:
19188 case ISD::ZERO_EXTEND:
19189 case ISD::ANY_EXTEND:
19190 return PerformExtendCombine(N, DCI.DAG, Subtarget);
19191 case ISD::FP_EXTEND:
19192 return PerformFPExtendCombine(N, DCI.DAG, Subtarget);
19193 case ISD::SMIN:
19194 case ISD::UMIN:
19195 case ISD::SMAX:
19196 case ISD::UMAX:
19197 return PerformMinMaxCombine(N, DCI.DAG, Subtarget);
19198 case ARMISD::CMOV:
19199 return PerformCMOVCombine(N, DCI.DAG);
19200 case ARMISD::BRCOND:
19201 return PerformBRCONDCombine(N, DCI.DAG);
19202 case ARMISD::CMPZ:
19203 return PerformCMPZCombine(N, DCI.DAG);
19204 case ARMISD::CSINC:
19205 case ARMISD::CSINV:
19206 case ARMISD::CSNEG:
19207 return PerformCSETCombine(N, DCI.DAG);
19208 case ISD::LOAD:
19209 return PerformLOADCombine(N, DCI, Subtarget);
19210 case ARMISD::VLD1DUP:
19211 case ARMISD::VLD2DUP:
19212 case ARMISD::VLD3DUP:
19213 case ARMISD::VLD4DUP:
19214 return PerformVLDCombine(N, DCI);
19216 return PerformARMBUILD_VECTORCombine(N, DCI);
19217 case ISD::BITCAST:
19218 return PerformBITCASTCombine(N, DCI, Subtarget);
19219 case ARMISD::PREDICATE_CAST:
19220 return PerformPREDICATE_CASTCombine(N, DCI);
19221 case ARMISD::VECTOR_REG_CAST:
19222 return PerformVECTOR_REG_CASTCombine(N, DCI.DAG, Subtarget);
19223 case ARMISD::MVETRUNC:
19224 return PerformMVETruncCombine(N, DCI);
19225 case ARMISD::MVESEXT:
19226 case ARMISD::MVEZEXT:
19227 return PerformMVEExtCombine(N, DCI);
19228 case ARMISD::VCMP:
19229 return PerformVCMPCombine(N, DCI.DAG, Subtarget);
19230 case ISD::VECREDUCE_ADD:
19231 return PerformVECREDUCE_ADDCombine(N, DCI.DAG, Subtarget);
19232 case ARMISD::VADDVs:
19233 case ARMISD::VADDVu:
19234 case ARMISD::VADDLVs:
19235 case ARMISD::VADDLVu:
19236 case ARMISD::VADDLVAs:
19237 case ARMISD::VADDLVAu:
19238 case ARMISD::VMLAVs:
19239 case ARMISD::VMLAVu:
19240 case ARMISD::VMLALVs:
19241 case ARMISD::VMLALVu:
19242 case ARMISD::VMLALVAs:
19243 case ARMISD::VMLALVAu:
19244 return PerformReduceShuffleCombine(N, DCI.DAG);
19245 case ARMISD::VMOVN:
19246 return PerformVMOVNCombine(N, DCI);
19247 case ARMISD::VQMOVNs:
19248 case ARMISD::VQMOVNu:
19249 return PerformVQMOVNCombine(N, DCI);
19250 case ARMISD::VQDMULH:
19251 return PerformVQDMULHCombine(N, DCI);
19252 case ARMISD::ASRL:
19253 case ARMISD::LSRL:
19254 case ARMISD::LSLL:
19255 return PerformLongShiftCombine(N, DCI.DAG);
19256 case ARMISD::SMULWB: {
19257 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19258 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19259 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19260 return SDValue();
19261 break;
19262 }
19263 case ARMISD::SMULWT: {
19264 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19265 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19266 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19267 return SDValue();
19268 break;
19269 }
19270 case ARMISD::SMLALBB:
19271 case ARMISD::QADD16b:
19272 case ARMISD::QSUB16b:
19273 case ARMISD::UQADD16b:
19274 case ARMISD::UQSUB16b: {
19275 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19276 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19277 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19278 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19279 return SDValue();
19280 break;
19281 }
19282 case ARMISD::SMLALBT: {
19283 unsigned LowWidth = N->getOperand(0).getValueType().getSizeInBits();
19284 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19285 unsigned HighWidth = N->getOperand(1).getValueType().getSizeInBits();
19286 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19287 if ((SimplifyDemandedBits(N->getOperand(0), LowMask, DCI)) ||
19288 (SimplifyDemandedBits(N->getOperand(1), HighMask, DCI)))
19289 return SDValue();
19290 break;
19291 }
19292 case ARMISD::SMLALTB: {
19293 unsigned HighWidth = N->getOperand(0).getValueType().getSizeInBits();
19294 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19295 unsigned LowWidth = N->getOperand(1).getValueType().getSizeInBits();
19296 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19297 if ((SimplifyDemandedBits(N->getOperand(0), HighMask, DCI)) ||
19298 (SimplifyDemandedBits(N->getOperand(1), LowMask, DCI)))
19299 return SDValue();
19300 break;
19301 }
19302 case ARMISD::SMLALTT: {
19303 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19304 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19305 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19306 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19307 return SDValue();
19308 break;
19309 }
19310 case ARMISD::QADD8b:
19311 case ARMISD::QSUB8b:
19312 case ARMISD::UQADD8b:
19313 case ARMISD::UQSUB8b: {
19314 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19315 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
19316 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19317 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19318 return SDValue();
19319 break;
19320 }
19321 case ARMISD::VBSP:
19322 if (N->getOperand(1) == N->getOperand(2))
19323 return N->getOperand(1);
19324 return SDValue();
19327 switch (N->getConstantOperandVal(1)) {
19328 case Intrinsic::arm_neon_vld1:
19329 case Intrinsic::arm_neon_vld1x2:
19330 case Intrinsic::arm_neon_vld1x3:
19331 case Intrinsic::arm_neon_vld1x4:
19332 case Intrinsic::arm_neon_vld2:
19333 case Intrinsic::arm_neon_vld3:
19334 case Intrinsic::arm_neon_vld4:
19335 case Intrinsic::arm_neon_vld2lane:
19336 case Intrinsic::arm_neon_vld3lane:
19337 case Intrinsic::arm_neon_vld4lane:
19338 case Intrinsic::arm_neon_vld2dup:
19339 case Intrinsic::arm_neon_vld3dup:
19340 case Intrinsic::arm_neon_vld4dup:
19341 case Intrinsic::arm_neon_vst1:
19342 case Intrinsic::arm_neon_vst1x2:
19343 case Intrinsic::arm_neon_vst1x3:
19344 case Intrinsic::arm_neon_vst1x4:
19345 case Intrinsic::arm_neon_vst2:
19346 case Intrinsic::arm_neon_vst3:
19347 case Intrinsic::arm_neon_vst4:
19348 case Intrinsic::arm_neon_vst2lane:
19349 case Intrinsic::arm_neon_vst3lane:
19350 case Intrinsic::arm_neon_vst4lane:
19351 return PerformVLDCombine(N, DCI);
19352 case Intrinsic::arm_mve_vld2q:
19353 case Intrinsic::arm_mve_vld4q:
19354 case Intrinsic::arm_mve_vst2q:
19355 case Intrinsic::arm_mve_vst4q:
19356 return PerformMVEVLDCombine(N, DCI);
19357 default: break;
19358 }
19359 break;
19360 }
19361 return SDValue();
19362}
19363
19365 EVT VT) const {
19366 return (VT == MVT::f32) && (Opc == ISD::LOAD || Opc == ISD::STORE);
19367}
19368
19370 Align Alignment,
19372 unsigned *Fast) const {
19373 // Depends what it gets converted into if the type is weird.
19374 if (!VT.isSimple())
19375 return false;
19376
19377 // The AllowsUnaligned flag models the SCTLR.A setting in ARM cpus
19378 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
19379 auto Ty = VT.getSimpleVT().SimpleTy;
19380
19381 if (Ty == MVT::i8 || Ty == MVT::i16 || Ty == MVT::i32) {
19382 // Unaligned access can use (for example) LRDB, LRDH, LDR
19383 if (AllowsUnaligned) {
19384 if (Fast)
19385 *Fast = Subtarget->hasV7Ops();
19386 return true;
19387 }
19388 }
19389
19390 if (Ty == MVT::f64 || Ty == MVT::v2f64) {
19391 // For any little-endian targets with neon, we can support unaligned ld/st
19392 // of D and Q (e.g. {D0,D1}) registers by using vld1.i8/vst1.i8.
19393 // A big-endian target may also explicitly support unaligned accesses
19394 if (Subtarget->hasNEON() && (AllowsUnaligned || Subtarget->isLittle())) {
19395 if (Fast)
19396 *Fast = 1;
19397 return true;
19398 }
19399 }
19400
19401 if (!Subtarget->hasMVEIntegerOps())
19402 return false;
19403
19404 // These are for predicates
19405 if ((Ty == MVT::v16i1 || Ty == MVT::v8i1 || Ty == MVT::v4i1 ||
19406 Ty == MVT::v2i1)) {
19407 if (Fast)
19408 *Fast = 1;
19409 return true;
19410 }
19411
19412 // These are for truncated stores/narrowing loads. They are fine so long as
19413 // the alignment is at least the size of the item being loaded
19414 if ((Ty == MVT::v4i8 || Ty == MVT::v8i8 || Ty == MVT::v4i16) &&
19415 Alignment >= VT.getScalarSizeInBits() / 8) {
19416 if (Fast)
19417 *Fast = true;
19418 return true;
19419 }
19420
19421 // In little-endian MVE, the store instructions VSTRB.U8, VSTRH.U16 and
19422 // VSTRW.U32 all store the vector register in exactly the same format, and
19423 // differ only in the range of their immediate offset field and the required
19424 // alignment. So there is always a store that can be used, regardless of
19425 // actual type.
19426 //
19427 // For big endian, that is not the case. But can still emit a (VSTRB.U8;
19428 // VREV64.8) pair and get the same effect. This will likely be better than
19429 // aligning the vector through the stack.
19430 if (Ty == MVT::v16i8 || Ty == MVT::v8i16 || Ty == MVT::v8f16 ||
19431 Ty == MVT::v4i32 || Ty == MVT::v4f32 || Ty == MVT::v2i64 ||
19432 Ty == MVT::v2f64) {
19433 if (Fast)
19434 *Fast = 1;
19435 return true;
19436 }
19437
19438 return false;
19439}
19440
19442 LLVMContext &Context, const MemOp &Op,
19443 const AttributeList &FuncAttributes) const {
19444 // See if we can use NEON instructions for this...
19445 if ((Op.isMemcpyOrMemmove() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
19446 !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
19447 unsigned Fast;
19448 if (Op.size() >= 16 &&
19449 (Op.isAligned(Align(16)) ||
19450 (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
19452 Fast))) {
19453 return MVT::v2f64;
19454 } else if (Op.size() >= 8 &&
19455 (Op.isAligned(Align(8)) ||
19457 MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
19458 Fast))) {
19459 return MVT::f64;
19460 }
19461 }
19462
19463 // Let the target-independent logic figure it out.
19464 return MVT::Other;
19465}
19466
19467// 64-bit integers are split into their high and low parts and held in two
19468// different registers, so the trunc is free since the low register can just
19469// be used.
19470bool ARMTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
19471 if (!SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
19472 return false;
19473 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
19474 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
19475 return (SrcBits == 64 && DestBits == 32);
19476}
19477
19479 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
19480 !DstVT.isInteger())
19481 return false;
19482 unsigned SrcBits = SrcVT.getSizeInBits();
19483 unsigned DestBits = DstVT.getSizeInBits();
19484 return (SrcBits == 64 && DestBits == 32);
19485}
19486
19488 if (Val.getOpcode() != ISD::LOAD)
19489 return false;
19490
19491 EVT VT1 = Val.getValueType();
19492 if (!VT1.isSimple() || !VT1.isInteger() ||
19493 !VT2.isSimple() || !VT2.isInteger())
19494 return false;
19495
19496 switch (VT1.getSimpleVT().SimpleTy) {
19497 default: break;
19498 case MVT::i1:
19499 case MVT::i8:
19500 case MVT::i16:
19501 // 8-bit and 16-bit loads implicitly zero-extend to 32-bits.
19502 return true;
19503 }
19504
19505 return false;
19506}
19507
19509 if (!VT.isSimple())
19510 return false;
19511
19512 // There are quite a few FP16 instructions (e.g. VNMLA, VNMLS, etc.) that
19513 // negate values directly (fneg is free). So, we don't want to let the DAG
19514 // combiner rewrite fneg into xors and some other instructions. For f16 and
19515 // FullFP16 argument passing, some bitcast nodes may be introduced,
19516 // triggering this DAG combine rewrite, so we are avoiding that with this.
19517 switch (VT.getSimpleVT().SimpleTy) {
19518 default: break;
19519 case MVT::f16:
19520 return Subtarget->hasFullFP16();
19521 }
19522
19523 return false;
19524}
19525
19527 if (!Subtarget->hasMVEIntegerOps())
19528 return nullptr;
19529 Type *SVIType = SVI->getType();
19530 Type *ScalarType = SVIType->getScalarType();
19531
19532 if (ScalarType->isFloatTy())
19533 return Type::getInt32Ty(SVIType->getContext());
19534 if (ScalarType->isHalfTy())
19535 return Type::getInt16Ty(SVIType->getContext());
19536 return nullptr;
19537}
19538
19540 EVT VT = ExtVal.getValueType();
19541
19542 if (!isTypeLegal(VT))
19543 return false;
19544
19545 if (auto *Ld = dyn_cast<MaskedLoadSDNode>(ExtVal.getOperand(0))) {
19546 if (Ld->isExpandingLoad())
19547 return false;
19548 }
19549
19550 if (Subtarget->hasMVEIntegerOps())
19551 return true;
19552
19553 // Don't create a loadext if we can fold the extension into a wide/long
19554 // instruction.
19555 // If there's more than one user instruction, the loadext is desirable no
19556 // matter what. There can be two uses by the same instruction.
19557 if (ExtVal->use_empty() ||
19558 !ExtVal->user_begin()->isOnlyUserOf(ExtVal.getNode()))
19559 return true;
19560
19561 SDNode *U = *ExtVal->user_begin();
19562 if ((U->getOpcode() == ISD::ADD || U->getOpcode() == ISD::SUB ||
19563 U->getOpcode() == ISD::SHL || U->getOpcode() == ARMISD::VSHLIMM))
19564 return false;
19565
19566 return true;
19567}
19568
19570 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
19571 return false;
19572
19573 if (!isTypeLegal(EVT::getEVT(Ty1)))
19574 return false;
19575
19576 assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");
19577
19578 // Assuming the caller doesn't have a zeroext or signext return parameter,
19579 // truncation all the way down to i1 is valid.
19580 return true;
19581}
19582
19583/// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
19584/// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
19585/// expanded to FMAs when this method returns true, otherwise fmuladd is
19586/// expanded to fmul + fadd.
19587///
19588/// ARM supports both fused and unfused multiply-add operations; we already
19589/// lower a pair of fmul and fadd to the latter so it's not clear that there
19590/// would be a gain or that the gain would be worthwhile enough to risk
19591/// correctness bugs.
19592///
19593/// For MVE, we set this to true as it helps simplify the need for some
19594/// patterns (and we don't have the non-fused floating point instruction).
19595bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
19596 EVT VT) const {
19597 if (Subtarget->useSoftFloat())
19598 return false;
19599
19600 if (!VT.isSimple())
19601 return false;
19602
19603 switch (VT.getSimpleVT().SimpleTy) {
19604 case MVT::v4f32:
19605 case MVT::v8f16:
19606 return Subtarget->hasMVEFloatOps();
19607 case MVT::f16:
19608 return Subtarget->useFPVFMx16();
19609 case MVT::f32:
19610 return Subtarget->useFPVFMx();
19611 case MVT::f64:
19612 return Subtarget->useFPVFMx64();
19613 default:
19614 break;
19615 }
19616
19617 return false;
19618}
19619
19620static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
19621 if (V < 0)
19622 return false;
19623
19624 unsigned Scale = 1;
19625 switch (VT.getSimpleVT().SimpleTy) {
19626 case MVT::i1:
19627 case MVT::i8:
19628 // Scale == 1;
19629 break;
19630 case MVT::i16:
19631 // Scale == 2;
19632 Scale = 2;
19633 break;
19634 default:
19635 // On thumb1 we load most things (i32, i64, floats, etc) with a LDR
19636 // Scale == 4;
19637 Scale = 4;
19638 break;
19639 }
19640
19641 if ((V & (Scale - 1)) != 0)
19642 return false;
19643 return isUInt<5>(V / Scale);
19644}
19645
19646static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
19647 const ARMSubtarget *Subtarget) {
19648 if (!VT.isInteger() && !VT.isFloatingPoint())
19649 return false;
19650 if (VT.isVector() && Subtarget->hasNEON())
19651 return false;
19652 if (VT.isVector() && VT.isFloatingPoint() && Subtarget->hasMVEIntegerOps() &&
19653 !Subtarget->hasMVEFloatOps())
19654 return false;
19655
19656 bool IsNeg = false;
19657 if (V < 0) {
19658 IsNeg = true;
19659 V = -V;
19660 }
19661
19662 unsigned NumBytes = std::max((unsigned)VT.getSizeInBits() / 8, 1U);
19663
19664 // MVE: size * imm7
19665 if (VT.isVector() && Subtarget->hasMVEIntegerOps()) {
19666 switch (VT.getSimpleVT().getVectorElementType().SimpleTy) {
19667 case MVT::i32:
19668 case MVT::f32:
19669 return isShiftedUInt<7,2>(V);
19670 case MVT::i16:
19671 case MVT::f16:
19672 return isShiftedUInt<7,1>(V);
19673 case MVT::i8:
19674 return isUInt<7>(V);
19675 default:
19676 return false;
19677 }
19678 }
19679
19680 // half VLDR: 2 * imm8
19681 if (VT.isFloatingPoint() && NumBytes == 2 && Subtarget->hasFPRegs16())
19682 return isShiftedUInt<8, 1>(V);
19683 // VLDR and LDRD: 4 * imm8
19684 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
19685 return isShiftedUInt<8, 2>(V);
19686
19687 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
19688 // + imm12 or - imm8
19689 if (IsNeg)
19690 return isUInt<8>(V);
19691 return isUInt<12>(V);
19692 }
19693
19694 return false;
19695}
19696
19697/// isLegalAddressImmediate - Return true if the integer value can be used
19698/// as the offset of the target addressing mode for load / store of the
19699/// given type.
19700static bool isLegalAddressImmediate(int64_t V, EVT VT,
19701 const ARMSubtarget *Subtarget) {
19702 if (V == 0)
19703 return true;
19704
19705 if (!VT.isSimple())
19706 return false;
19707
19708 if (Subtarget->isThumb1Only())
19709 return isLegalT1AddressImmediate(V, VT);
19710 else if (Subtarget->isThumb2())
19711 return isLegalT2AddressImmediate(V, VT, Subtarget);
19712
19713 // ARM mode.
19714 if (V < 0)
19715 V = - V;
19716 switch (VT.getSimpleVT().SimpleTy) {
19717 default: return false;
19718 case MVT::i1:
19719 case MVT::i8:
19720 case MVT::i32:
19721 // +- imm12
19722 return isUInt<12>(V);
19723 case MVT::i16:
19724 // +- imm8
19725 return isUInt<8>(V);
19726 case MVT::f32:
19727 case MVT::f64:
19728 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
19729 return false;
19730 return isShiftedUInt<8, 2>(V);
19731 }
19732}
19733
19735 EVT VT) const {
19736 int Scale = AM.Scale;
19737 if (Scale < 0)
19738 return false;
19739
19740 switch (VT.getSimpleVT().SimpleTy) {
19741 default: return false;
19742 case MVT::i1:
19743 case MVT::i8:
19744 case MVT::i16:
19745 case MVT::i32:
19746 if (Scale == 1)
19747 return true;
19748 // r + r << imm
19749 Scale = Scale & ~1;
19750 return Scale == 2 || Scale == 4 || Scale == 8;
19751 case MVT::i64:
19752 // FIXME: What are we trying to model here? ldrd doesn't have an r + r
19753 // version in Thumb mode.
19754 // r + r
19755 if (Scale == 1)
19756 return true;
19757 // r * 2 (this can be lowered to r + r).
19758 if (!AM.HasBaseReg && Scale == 2)
19759 return true;
19760 return false;
19761 case MVT::isVoid:
19762 // Note, we allow "void" uses (basically, uses that aren't loads or
19763 // stores), because arm allows folding a scale into many arithmetic
19764 // operations. This should be made more precise and revisited later.
19765
19766 // Allow r << imm, but the imm has to be a multiple of two.
19767 if (Scale & 1) return false;
19768 return isPowerOf2_32(Scale);
19769 }
19770}
19771
19773 EVT VT) const {
19774 const int Scale = AM.Scale;
19775
19776 // Negative scales are not supported in Thumb1.
19777 if (Scale < 0)
19778 return false;
19779
19780 // Thumb1 addressing modes do not support register scaling excepting the
19781 // following cases:
19782 // 1. Scale == 1 means no scaling.
19783 // 2. Scale == 2 this can be lowered to r + r if there is no base register.
19784 return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
19785}
19786
19787/// isLegalAddressingMode - Return true if the addressing mode represented
19788/// by AM is legal for this target, for a load/store of the specified type.
19790 const AddrMode &AM, Type *Ty,
19791 unsigned AS, Instruction *I) const {
19792 EVT VT = getValueType(DL, Ty, true);
19793 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget))
19794 return false;
19795
19796 // Can never fold addr of global into load/store.
19797 if (AM.BaseGV)
19798 return false;
19799
19800 switch (AM.Scale) {
19801 case 0: // no scale reg, must be "r+i" or "r", or "i".
19802 break;
19803 default:
19804 // ARM doesn't support any R+R*scale+imm addr modes.
19805 if (AM.BaseOffs)
19806 return false;
19807
19808 if (!VT.isSimple())
19809 return false;
19810
19811 if (Subtarget->isThumb1Only())
19812 return isLegalT1ScaledAddressingMode(AM, VT);
19813
19814 if (Subtarget->isThumb2())
19815 return isLegalT2ScaledAddressingMode(AM, VT);
19816
19817 int Scale = AM.Scale;
19818 switch (VT.getSimpleVT().SimpleTy) {
19819 default: return false;
19820 case MVT::i1:
19821 case MVT::i8:
19822 case MVT::i32:
19823 if (Scale < 0) Scale = -Scale;
19824 if (Scale == 1)
19825 return true;
19826 // r + r << imm
19827 return isPowerOf2_32(Scale & ~1);
19828 case MVT::i16:
19829 case MVT::i64:
19830 // r +/- r
19831 if (Scale == 1 || (AM.HasBaseReg && Scale == -1))
19832 return true;
19833 // r * 2 (this can be lowered to r + r).
19834 if (!AM.HasBaseReg && Scale == 2)
19835 return true;
19836 return false;
19837
19838 case MVT::isVoid:
19839 // Note, we allow "void" uses (basically, uses that aren't loads or
19840 // stores), because arm allows folding a scale into many arithmetic
19841 // operations. This should be made more precise and revisited later.
19842
19843 // Allow r << imm, but the imm has to be a multiple of two.
19844 if (Scale & 1) return false;
19845 return isPowerOf2_32(Scale);
19846 }
19847 }
19848 return true;
19849}
19850
19851/// isLegalICmpImmediate - Return true if the specified immediate is legal
19852/// icmp immediate, that is the target has icmp instructions which can compare
19853/// a register against the immediate without having to materialize the
19854/// immediate into a register.
19856 // Thumb2 and ARM modes can use cmn for negative immediates.
19857 if (!Subtarget->isThumb())
19858 return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
19859 ARM_AM::getSOImmVal(-(uint32_t)Imm) != -1;
19860 if (Subtarget->isThumb2())
19861 return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
19862 ARM_AM::getT2SOImmVal(-(uint32_t)Imm) != -1;
19863 // Thumb1 doesn't have cmn, and only 8-bit immediates.
19864 return Imm >= 0 && Imm <= 255;
19865}
19866
19867/// isLegalAddImmediate - Return true if the specified immediate is a legal add
19868/// *or sub* immediate, that is the target has add or sub instructions which can
19869/// add a register with the immediate without having to materialize the
19870/// immediate into a register.
19872 // Same encoding for add/sub, just flip the sign.
19873 uint64_t AbsImm = AbsoluteValue(Imm);
19874 if (!Subtarget->isThumb())
19875 return ARM_AM::getSOImmVal(AbsImm) != -1;
19876 if (Subtarget->isThumb2())
19877 return ARM_AM::getT2SOImmVal(AbsImm) != -1;
19878 // Thumb1 only has 8-bit unsigned immediate.
19879 return AbsImm <= 255;
19880}
19881
19882// Return false to prevent folding
19883// (mul (add r, c0), c1) -> (add (mul r, c1), c0*c1) in DAGCombine,
19884// if the folding leads to worse code.
19886 SDValue ConstNode) const {
19887 // Let the DAGCombiner decide for vector types and large types.
19888 const EVT VT = AddNode.getValueType();
19889 if (VT.isVector() || VT.getScalarSizeInBits() > 32)
19890 return true;
19891
19892 // It is worse if c0 is legal add immediate, while c1*c0 is not
19893 // and has to be composed by at least two instructions.
19894 const ConstantSDNode *C0Node = cast<ConstantSDNode>(AddNode.getOperand(1));
19895 const ConstantSDNode *C1Node = cast<ConstantSDNode>(ConstNode);
19896 const int64_t C0 = C0Node->getSExtValue();
19897 APInt CA = C0Node->getAPIntValue() * C1Node->getAPIntValue();
19899 return true;
19900 if (ConstantMaterializationCost((unsigned)CA.getZExtValue(), Subtarget) > 1)
19901 return false;
19902
19903 // Default to true and let the DAGCombiner decide.
19904 return true;
19905}
19906
19908 bool isSEXTLoad, SDValue &Base,
19909 SDValue &Offset, bool &isInc,
19910 SelectionDAG &DAG) {
19911 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19912 return false;
19913
19914 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
19915 // AddressingMode 3
19916 Base = Ptr->getOperand(0);
19918 int RHSC = (int)RHS->getZExtValue();
19919 if (RHSC < 0 && RHSC > -256) {
19920 assert(Ptr->getOpcode() == ISD::ADD);
19921 isInc = false;
19922 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19923 return true;
19924 }
19925 }
19926 isInc = (Ptr->getOpcode() == ISD::ADD);
19927 Offset = Ptr->getOperand(1);
19928 return true;
19929 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
19930 // AddressingMode 2
19932 int RHSC = (int)RHS->getZExtValue();
19933 if (RHSC < 0 && RHSC > -0x1000) {
19934 assert(Ptr->getOpcode() == ISD::ADD);
19935 isInc = false;
19936 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19937 Base = Ptr->getOperand(0);
19938 return true;
19939 }
19940 }
19941
19942 if (Ptr->getOpcode() == ISD::ADD) {
19943 isInc = true;
19944 ARM_AM::ShiftOpc ShOpcVal=
19946 if (ShOpcVal != ARM_AM::no_shift) {
19947 Base = Ptr->getOperand(1);
19948 Offset = Ptr->getOperand(0);
19949 } else {
19950 Base = Ptr->getOperand(0);
19951 Offset = Ptr->getOperand(1);
19952 }
19953 return true;
19954 }
19955
19956 isInc = (Ptr->getOpcode() == ISD::ADD);
19957 Base = Ptr->getOperand(0);
19958 Offset = Ptr->getOperand(1);
19959 return true;
19960 }
19961
19962 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
19963 return false;
19964}
19965
19967 bool isSEXTLoad, SDValue &Base,
19968 SDValue &Offset, bool &isInc,
19969 SelectionDAG &DAG) {
19970 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19971 return false;
19972
19973 Base = Ptr->getOperand(0);
19975 int RHSC = (int)RHS->getZExtValue();
19976 if (RHSC < 0 && RHSC > -0x100) { // 8 bits.
19977 assert(Ptr->getOpcode() == ISD::ADD);
19978 isInc = false;
19979 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19980 return true;
19981 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero.
19982 isInc = Ptr->getOpcode() == ISD::ADD;
19983 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
19984 return true;
19985 }
19986 }
19987
19988 return false;
19989}
19990
19991static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment,
19992 bool isSEXTLoad, bool IsMasked, bool isLE,
19994 bool &isInc, SelectionDAG &DAG) {
19995 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19996 return false;
19997 if (!isa<ConstantSDNode>(Ptr->getOperand(1)))
19998 return false;
19999
20000 // We allow LE non-masked loads to change the type (for example use a vldrb.8
20001 // as opposed to a vldrw.32). This can allow extra addressing modes or
20002 // alignments for what is otherwise an equivalent instruction.
20003 bool CanChangeType = isLE && !IsMasked;
20004
20006 int RHSC = (int)RHS->getZExtValue();
20007
20008 auto IsInRange = [&](int RHSC, int Limit, int Scale) {
20009 if (RHSC < 0 && RHSC > -Limit * Scale && RHSC % Scale == 0) {
20010 assert(Ptr->getOpcode() == ISD::ADD);
20011 isInc = false;
20012 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20013 return true;
20014 } else if (RHSC > 0 && RHSC < Limit * Scale && RHSC % Scale == 0) {
20015 isInc = Ptr->getOpcode() == ISD::ADD;
20016 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
20017 return true;
20018 }
20019 return false;
20020 };
20021
20022 // Try to find a matching instruction based on s/zext, Alignment, Offset and
20023 // (in BE/masked) type.
20024 Base = Ptr->getOperand(0);
20025 if (VT == MVT::v4i16) {
20026 if (Alignment >= 2 && IsInRange(RHSC, 0x80, 2))
20027 return true;
20028 } else if (VT == MVT::v4i8 || VT == MVT::v8i8) {
20029 if (IsInRange(RHSC, 0x80, 1))
20030 return true;
20031 } else if (Alignment >= 4 &&
20032 (CanChangeType || VT == MVT::v4i32 || VT == MVT::v4f32) &&
20033 IsInRange(RHSC, 0x80, 4))
20034 return true;
20035 else if (Alignment >= 2 &&
20036 (CanChangeType || VT == MVT::v8i16 || VT == MVT::v8f16) &&
20037 IsInRange(RHSC, 0x80, 2))
20038 return true;
20039 else if ((CanChangeType || VT == MVT::v16i8) && IsInRange(RHSC, 0x80, 1))
20040 return true;
20041 return false;
20042}
20043
20044/// getPreIndexedAddressParts - returns true by value, base pointer and
20045/// offset pointer and addressing mode by reference if the node's address
20046/// can be legally represented as pre-indexed load / store address.
20047bool
20049 SDValue &Offset,
20051 SelectionDAG &DAG) const {
20052 if (Subtarget->isThumb1Only())
20053 return false;
20054
20055 EVT VT;
20056 SDValue Ptr;
20057 Align Alignment;
20058 unsigned AS = 0;
20059 bool isSEXTLoad = false;
20060 bool IsMasked = false;
20061 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20062 Ptr = LD->getBasePtr();
20063 VT = LD->getMemoryVT();
20064 Alignment = LD->getAlign();
20065 AS = LD->getAddressSpace();
20066 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20067 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20068 Ptr = ST->getBasePtr();
20069 VT = ST->getMemoryVT();
20070 Alignment = ST->getAlign();
20071 AS = ST->getAddressSpace();
20072 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20073 Ptr = LD->getBasePtr();
20074 VT = LD->getMemoryVT();
20075 Alignment = LD->getAlign();
20076 AS = LD->getAddressSpace();
20077 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20078 IsMasked = true;
20080 Ptr = ST->getBasePtr();
20081 VT = ST->getMemoryVT();
20082 Alignment = ST->getAlign();
20083 AS = ST->getAddressSpace();
20084 IsMasked = true;
20085 } else
20086 return false;
20087
20088 unsigned Fast = 0;
20089 if (!allowsMisalignedMemoryAccesses(VT, AS, Alignment,
20091 // Only generate post-increment or pre-increment forms when a real
20092 // hardware instruction exists for them. Do not emit postinc/preinc
20093 // if the operation will end up as a libcall.
20094 return false;
20095 }
20096
20097 bool isInc;
20098 bool isLegal = false;
20099 if (VT.isVector())
20100 isLegal = Subtarget->hasMVEIntegerOps() &&
20102 Ptr.getNode(), VT, Alignment, isSEXTLoad, IsMasked,
20103 Subtarget->isLittle(), Base, Offset, isInc, DAG);
20104 else {
20105 if (Subtarget->isThumb2())
20106 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20107 Offset, isInc, DAG);
20108 else
20109 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20110 Offset, isInc, DAG);
20111 }
20112 if (!isLegal)
20113 return false;
20114
20115 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
20116 return true;
20117}
20118
20119/// getPostIndexedAddressParts - returns true by value, base pointer and
20120/// offset pointer and addressing mode by reference if this node can be
20121/// combined with a load / store to form a post-indexed load / store.
20123 SDValue &Base,
20124 SDValue &Offset,
20126 SelectionDAG &DAG) const {
20127 EVT VT;
20128 SDValue Ptr;
20129 Align Alignment;
20130 bool isSEXTLoad = false, isNonExt;
20131 bool IsMasked = false;
20132 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20133 VT = LD->getMemoryVT();
20134 Ptr = LD->getBasePtr();
20135 Alignment = LD->getAlign();
20136 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20137 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20138 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20139 VT = ST->getMemoryVT();
20140 Ptr = ST->getBasePtr();
20141 Alignment = ST->getAlign();
20142 isNonExt = !ST->isTruncatingStore();
20143 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20144 VT = LD->getMemoryVT();
20145 Ptr = LD->getBasePtr();
20146 Alignment = LD->getAlign();
20147 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20148 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20149 IsMasked = true;
20151 VT = ST->getMemoryVT();
20152 Ptr = ST->getBasePtr();
20153 Alignment = ST->getAlign();
20154 isNonExt = !ST->isTruncatingStore();
20155 IsMasked = true;
20156 } else
20157 return false;
20158
20159 if (Subtarget->isThumb1Only()) {
20160 // Thumb-1 can do a limited post-inc load or store as an updating LDM. It
20161 // must be non-extending/truncating, i32, with an offset of 4.
20162 assert(Op->getValueType(0) == MVT::i32 && "Non-i32 post-inc op?!");
20163 if (Op->getOpcode() != ISD::ADD || !isNonExt)
20164 return false;
20165 auto *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1));
20166 if (!RHS || RHS->getZExtValue() != 4)
20167 return false;
20168 if (Alignment < Align(4))
20169 return false;
20170
20171 Offset = Op->getOperand(1);
20172 Base = Op->getOperand(0);
20173 AM = ISD::POST_INC;
20174 return true;
20175 }
20176
20177 bool isInc;
20178 bool isLegal = false;
20179 if (VT.isVector())
20180 isLegal = Subtarget->hasMVEIntegerOps() &&
20181 getMVEIndexedAddressParts(Op, VT, Alignment, isSEXTLoad, IsMasked,
20182 Subtarget->isLittle(), Base, Offset,
20183 isInc, DAG);
20184 else {
20185 if (Subtarget->isThumb2())
20186 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20187 isInc, DAG);
20188 else
20189 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20190 isInc, DAG);
20191 }
20192 if (!isLegal)
20193 return false;
20194
20195 if (Ptr != Base) {
20196 // Swap base ptr and offset to catch more post-index load / store when
20197 // it's legal. In Thumb2 mode, offset must be an immediate.
20198 if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
20199 !Subtarget->isThumb2())
20201
20202 // Post-indexed load / store update the base pointer.
20203 if (Ptr != Base)
20204 return false;
20205 }
20206
20207 AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
20208 return true;
20209}
20210
20213 const APInt &DemandedElts,
20214 const SelectionDAG &DAG,
20215 unsigned Depth) const {
20216 unsigned BitWidth = Known.getBitWidth();
20217 Known.resetAll();
20218 switch (Op.getOpcode()) {
20219 default: break;
20220 case ARMISD::ADDC:
20221 case ARMISD::ADDE:
20222 case ARMISD::SUBC:
20223 case ARMISD::SUBE:
20224 // Special cases when we convert a carry to a boolean.
20225 if (Op.getResNo() == 0) {
20226 SDValue LHS = Op.getOperand(0);
20227 SDValue RHS = Op.getOperand(1);
20228 // (ADDE 0, 0, C) will give us a single bit.
20229 if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
20230 isNullConstant(RHS)) {
20232 return;
20233 }
20234 }
20235 break;
20236 case ARMISD::CMOV: {
20237 // Bits are known zero/one if known on the LHS and RHS.
20238 Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
20239 if (Known.isUnknown())
20240 return;
20241
20242 KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
20243 Known = Known.intersectWith(KnownRHS);
20244 return;
20245 }
20247 Intrinsic::ID IntID =
20248 static_cast<Intrinsic::ID>(Op->getConstantOperandVal(1));
20249 switch (IntID) {
20250 default: return;
20251 case Intrinsic::arm_ldaex:
20252 case Intrinsic::arm_ldrex: {
20253 EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
20254 unsigned MemBits = VT.getScalarSizeInBits();
20255 Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20256 return;
20257 }
20258 }
20259 }
20260 case ARMISD::BFI: {
20261 // Conservatively, we can recurse down the first operand
20262 // and just mask out all affected bits.
20263 Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20264
20265 // The operand to BFI is already a mask suitable for removing the bits it
20266 // sets.
20267 const APInt &Mask = Op.getConstantOperandAPInt(2);
20268 Known.Zero &= Mask;
20269 Known.One &= Mask;
20270 return;
20271 }
20272 case ARMISD::VGETLANEs:
20273 case ARMISD::VGETLANEu: {
20274 const SDValue &SrcSV = Op.getOperand(0);
20275 EVT VecVT = SrcSV.getValueType();
20276 assert(VecVT.isVector() && "VGETLANE expected a vector type");
20277 const unsigned NumSrcElts = VecVT.getVectorNumElements();
20278 ConstantSDNode *Pos = cast<ConstantSDNode>(Op.getOperand(1).getNode());
20279 assert(Pos->getAPIntValue().ult(NumSrcElts) &&
20280 "VGETLANE index out of bounds");
20281 unsigned Idx = Pos->getZExtValue();
20282 APInt DemandedElt = APInt::getOneBitSet(NumSrcElts, Idx);
20283 Known = DAG.computeKnownBits(SrcSV, DemandedElt, Depth + 1);
20284
20285 EVT VT = Op.getValueType();
20286 const unsigned DstSz = VT.getScalarSizeInBits();
20287 const unsigned SrcSz = VecVT.getVectorElementType().getSizeInBits();
20288 (void)SrcSz;
20289 assert(SrcSz == Known.getBitWidth());
20290 assert(DstSz > SrcSz);
20291 if (Op.getOpcode() == ARMISD::VGETLANEs)
20292 Known = Known.sext(DstSz);
20293 else {
20294 Known = Known.zext(DstSz);
20295 }
20296 assert(DstSz == Known.getBitWidth());
20297 break;
20298 }
20299 case ARMISD::VMOVrh: {
20300 KnownBits KnownOp = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20301 assert(KnownOp.getBitWidth() == 16);
20302 Known = KnownOp.zext(32);
20303 break;
20304 }
20305 case ARMISD::CSINC:
20306 case ARMISD::CSINV:
20307 case ARMISD::CSNEG: {
20308 KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20309 KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
20310
20311 // The result is either:
20312 // CSINC: KnownOp0 or KnownOp1 + 1
20313 // CSINV: KnownOp0 or ~KnownOp1
20314 // CSNEG: KnownOp0 or KnownOp1 * -1
20315 if (Op.getOpcode() == ARMISD::CSINC)
20316 KnownOp1 =
20317 KnownBits::add(KnownOp1, KnownBits::makeConstant(APInt(32, 1)));
20318 else if (Op.getOpcode() == ARMISD::CSINV)
20319 std::swap(KnownOp1.Zero, KnownOp1.One);
20320 else if (Op.getOpcode() == ARMISD::CSNEG)
20321 KnownOp1 = KnownBits::mul(KnownOp1,
20323
20324 Known = KnownOp0.intersectWith(KnownOp1);
20325 break;
20326 }
20327 case ARMISD::VORRIMM:
20328 case ARMISD::VBICIMM: {
20329 unsigned Encoded = Op.getConstantOperandVal(1);
20330 unsigned DecEltBits = 0;
20331 uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
20332
20333 unsigned EltBits = Op.getScalarValueSizeInBits();
20334 if (EltBits != DecEltBits) {
20335 // Be conservative: only update Known when EltBits == DecEltBits.
20336 // This is believed to always be true for VORRIMM/VBICIMM today, but if
20337 // that changes in the future, doing nothing here is safer than risking
20338 // subtle bugs.
20339 break;
20340 }
20341
20342 KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20343 bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
20344 APInt Imm(DecEltBits, DecodedVal);
20345
20346 Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
20347 Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
20348 break;
20349 }
20350 }
20351}
20352
20353static bool isLegalLogicalImmediate(unsigned Imm,
20354 const ARMSubtarget *Subtarget) {
20355 if (!Subtarget->isThumb())
20356 return ARM_AM::getSOImmVal(Imm) != -1;
20357 if (Subtarget->isThumb2())
20358 return ARM_AM::getT2SOImmVal(Imm) != -1;
20359 // Thumb1 only has 8-bit unsigned immediate.
20360 return Imm <= 255;
20361}
20362
20363/// Refine i32 AND/OR/XOR with a constant RHS using demanded bits: replace the
20364/// immediate with an equivalent constant that ARM/Thumb can encode as a
20365/// logical immediate (or that selects better lowering), without changing the
20366/// computed result on those demanded bits.
20367static bool optimizeLogicalImm(SDValue Op, unsigned Imm,
20368 const APInt &DemandedBits,
20369 const ARMSubtarget *Subtarget,
20371
20372 if (Imm == 0 || Imm == ~0U)
20373 return false;
20374
20375 unsigned Opc = Op.getOpcode();
20376 unsigned Demanded = DemandedBits.getZExtValue();
20377 EVT VT = Op.getValueType();
20378
20379 unsigned ShrunkImm = Imm & Demanded;
20380 unsigned ExpandedImm = Imm | ~Demanded;
20381
20382 auto IsLegalImm = [ShrunkImm, ExpandedImm](unsigned CandidateImm) -> bool {
20383 return (ShrunkImm & CandidateImm) == ShrunkImm &&
20384 (~ExpandedImm & CandidateImm) == 0;
20385 };
20386 auto UseImm = [Imm, Opc, Op, VT, &TLO](unsigned NewImm) -> bool {
20387 if (NewImm == Imm)
20388 return true;
20389 SDLoc DL(Op);
20390 SDValue NewC = TLO.DAG.getConstant(NewImm, DL, VT);
20391 SDValue NewOp =
20392 TLO.DAG.getNode(Opc, DL, VT, Op.getOperand(0), NewC, Op->getFlags());
20393 return TLO.CombineTo(Op, NewOp);
20394 };
20395
20396 // Shrunk immediate is 0: AND becomes zero; OR/XOR with 0 leaves the other
20397 // operand (still valid on demanded bits).
20398 if (ShrunkImm == 0) {
20399 ++NumOptimizedImms;
20400 return UseImm(ShrunkImm);
20401 }
20402
20403 // If the immediate is all ones: for AND this removes the operation; for
20404 // OR/XOR it remains a transform valid on demanded bits. (Target-independent
20405 // shrink may not fold this, so keep it to avoid obscure combine loops.)
20406 if (ExpandedImm == ~0U) {
20407 ++NumOptimizedImms;
20408 return UseImm(ExpandedImm);
20409 }
20410
20411 // Thumb1: prefer 0xFF / 0xFFFF when they fit the demanded-bit envelope so
20412 // lowering can match uxtb / uxth (AND immediates only; OR/XOR do not use
20413 // that). Run this before strict ShrunkImm: a tight 8-bit ShrunkImm can be
20414 // legal while 0xFF still matches the envelope and yields better isel (uxtb).
20415 if (Opc == ISD::AND && Subtarget->hasV6Ops()) {
20416 if (IsLegalImm(0xFF)) {
20417 ++NumOptimizedImms;
20418 return UseImm(0xFF);
20419 }
20420
20421 if (IsLegalImm(0xFFFF)) {
20422 ++NumOptimizedImms;
20423 return UseImm(0xFFFF);
20424 }
20425 }
20426
20427 // Don't optimize if it is legal.
20428 if (isLegalLogicalImmediate(Imm, Subtarget))
20429 return false;
20430
20431 // FIXME: Check for BIC being legal causes infinite loop due to target
20432 // independent DAG combine undoing this.
20433
20434 // Prefer strict shrink when ShrunkImm encodes for this target, before
20435 // complement expansion.
20436 if (isLegalLogicalImmediate(ShrunkImm, Subtarget)) {
20437 ++NumOptimizedImms;
20438 return UseImm(ShrunkImm);
20439 }
20440
20441 // Complement expansion: if all undemanded bits are already one, ExpandedImm
20442 // is Imm with every non-demanded bit set. When (~ExpandedImm) < 256, the
20443 // complement fits in an 8-bit unsigned value, i.e. bits 8–31 of ExpandedImm
20444 // are all ones; only the low byte may differ from ~0. Use that expanded
20445 // constant so isel sees a mask shape that fits logical-immediate patterns.
20446 if ((~ExpandedImm) < 256) {
20447 ++NumOptimizedImms;
20448 return UseImm(ExpandedImm);
20449 }
20450
20451 // FIXME: The check for v6 is because this interferes with some ubfx
20452 // optimizations.
20453 if (Opc == ISD::AND && isLegalLogicalImmediate(~ExpandedImm, Subtarget) &&
20454 !Subtarget->hasV6Ops()) {
20455 ++NumOptimizedImms;
20456 return UseImm(ExpandedImm);
20457 }
20458
20459 // Potential improvements:
20460 //
20461 // We could try to recognize lsls+lsrs or lsrs+lsls pairs here.
20462 // We could try to prefer Thumb1 immediates which can be lowered to a
20463 // two-instruction sequence.
20464
20465 return false;
20466}
20467
20469 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
20470 TargetLoweringOpt &TLO) const {
20471 // Delay this optimization to as late as possible.
20472 if (!TLO.LegalOps)
20473 return false;
20474
20475 EVT VT = Op.getValueType();
20476
20477 // Ignore vectors.
20478 if (VT.isVector())
20479 return false;
20480
20481 unsigned Size = VT.getSizeInBits();
20482
20483 if (Size != 32)
20484 return false;
20485
20486 // Exit early if we demand all bits.
20487 if (DemandedBits.isAllOnes())
20488 return false;
20489
20490 switch (Op.getOpcode()) {
20491 default:
20492 return false;
20493 case ISD::AND:
20494 case ISD::OR:
20495 case ISD::XOR:
20496 break;
20497 }
20498 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20499 if (!C)
20500 return false;
20501 unsigned Imm = C->getZExtValue();
20502 return optimizeLogicalImm(Op, Imm, DemandedBits, Subtarget, TLO);
20503}
20504
20506 SDValue Op, const APInt &OriginalDemandedBits,
20507 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
20508 unsigned Depth) const {
20509 unsigned Opc = Op.getOpcode();
20510
20511 switch (Opc) {
20512 case ARMISD::ASRL:
20513 case ARMISD::LSRL: {
20514 // If this is result 0 and the other result is unused, see if the demand
20515 // bits allow us to shrink this long shift into a standard small shift in
20516 // the opposite direction.
20517 if (Op.getResNo() == 0 && !Op->hasAnyUseOfValue(1) &&
20518 isa<ConstantSDNode>(Op->getOperand(2))) {
20519 unsigned ShAmt = Op->getConstantOperandVal(2);
20520 if (ShAmt < 32 && OriginalDemandedBits.isSubsetOf(APInt::getAllOnes(32)
20521 << (32 - ShAmt)))
20522 return TLO.CombineTo(
20523 Op, TLO.DAG.getNode(
20524 ISD::SHL, SDLoc(Op), MVT::i32, Op.getOperand(1),
20525 TLO.DAG.getConstant(32 - ShAmt, SDLoc(Op), MVT::i32)));
20526 }
20527 break;
20528 }
20529 case ARMISD::VBICIMM: {
20530 SDValue Op0 = Op.getOperand(0);
20531 unsigned ModImm = Op.getConstantOperandVal(1);
20532 unsigned EltBits = 0;
20533 uint64_t Mask = ARM_AM::decodeVMOVModImm(ModImm, EltBits);
20534 if ((OriginalDemandedBits & Mask) == 0)
20535 return TLO.CombineTo(Op, Op0);
20536 }
20537 }
20538
20540 Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
20541}
20542
20543//===----------------------------------------------------------------------===//
20544// ARM Inline Assembly Support
20545//===----------------------------------------------------------------------===//
20546
20547const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
20548 // At this point, we have to lower this constraint to something else, so we
20549 // lower it to an "r" or "w". However, by doing this we will force the result
20550 // to be in register, while the X constraint is much more permissive.
20551 //
20552 // Although we are correct (we are free to emit anything, without
20553 // constraints), we might break use cases that would expect us to be more
20554 // efficient and emit something else.
20555 if (!Subtarget->hasVFP2Base())
20556 return "r";
20557 if (ConstraintVT.isFloatingPoint())
20558 return "w";
20559 if (ConstraintVT.isVector() && Subtarget->hasNEON() &&
20560 (ConstraintVT.getSizeInBits() == 64 ||
20561 ConstraintVT.getSizeInBits() == 128))
20562 return "w";
20563
20564 return "r";
20565}
20566
20567/// getConstraintType - Given a constraint letter, return the type of
20568/// constraint it is for this target.
20571 unsigned S = Constraint.size();
20572 if (S == 1) {
20573 switch (Constraint[0]) {
20574 default: break;
20575 case 'l': return C_RegisterClass;
20576 case 'w': return C_RegisterClass;
20577 case 'h': return C_RegisterClass;
20578 case 'x': return C_RegisterClass;
20579 case 't': return C_RegisterClass;
20580 case 'j': return C_Immediate; // Constant for movw.
20581 // An address with a single base register. Due to the way we
20582 // currently handle addresses it is the same as an 'r' memory constraint.
20583 case 'Q': return C_Memory;
20584 }
20585 } else if (S == 2) {
20586 switch (Constraint[0]) {
20587 default: break;
20588 case 'T': return C_RegisterClass;
20589 // All 'U+' constraints are addresses.
20590 case 'U': return C_Memory;
20591 }
20592 }
20593 return TargetLowering::getConstraintType(Constraint);
20594}
20595
20596/// Examine constraint type and operand type and determine a weight value.
20597/// This object must already have been set up with the operand type
20598/// and the current alternative constraint selected.
20601 AsmOperandInfo &info, const char *constraint) const {
20603 Value *CallOperandVal = info.CallOperandVal;
20604 // If we don't have a value, we can't do a match,
20605 // but allow it at the lowest weight.
20606 if (!CallOperandVal)
20607 return CW_Default;
20608 Type *type = CallOperandVal->getType();
20609 // Look at the constraint type.
20610 switch (*constraint) {
20611 default:
20613 break;
20614 case 'l':
20615 if (type->isIntegerTy()) {
20616 if (Subtarget->isThumb())
20617 weight = CW_SpecificReg;
20618 else
20619 weight = CW_Register;
20620 }
20621 break;
20622 case 'w':
20623 if (type->isFloatingPointTy())
20624 weight = CW_Register;
20625 break;
20626 }
20627 return weight;
20628}
20629
20630static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
20631 if (PR == 0 || VT == MVT::Other)
20632 return false;
20633 if (ARM::SPRRegClass.contains(PR))
20634 return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32;
20635 if (ARM::DPRRegClass.contains(PR))
20636 return VT != MVT::f64 && !VT.is64BitVector();
20637 return false;
20638}
20639
20640using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
20641
20643 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
20644 switch (Constraint.size()) {
20645 case 1:
20646 // GCC ARM Constraint Letters
20647 switch (Constraint[0]) {
20648 case 'l': // Low regs or general regs.
20649 if (Subtarget->isThumb())
20650 return RCPair(0U, &ARM::tGPRRegClass);
20651 return RCPair(0U, &ARM::GPRRegClass);
20652 case 'h': // High regs or no regs.
20653 if (Subtarget->isThumb())
20654 return RCPair(0U, &ARM::hGPRRegClass);
20655 break;
20656 case 'r':
20657 if (Subtarget->isThumb1Only())
20658 return RCPair(0U, &ARM::tGPRRegClass);
20659 return RCPair(0U, &ARM::GPRRegClass);
20660 case 'w':
20661 if (VT == MVT::Other)
20662 break;
20663 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20664 return RCPair(0U, &ARM::SPRRegClass);
20665 if (VT.getSizeInBits() == 64)
20666 return RCPair(0U, &ARM::DPRRegClass);
20667 if (VT.getSizeInBits() == 128)
20668 return RCPair(0U, &ARM::QPRRegClass);
20669 break;
20670 case 'x':
20671 if (VT == MVT::Other)
20672 break;
20673 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20674 return RCPair(0U, &ARM::SPR_8RegClass);
20675 if (VT.getSizeInBits() == 64)
20676 return RCPair(0U, &ARM::DPR_8RegClass);
20677 if (VT.getSizeInBits() == 128)
20678 return RCPair(0U, &ARM::QPR_8RegClass);
20679 break;
20680 case 't':
20681 if (VT == MVT::Other)
20682 break;
20683 if (VT == MVT::f32 || VT == MVT::i32 || VT == MVT::f16 || VT == MVT::bf16)
20684 return RCPair(0U, &ARM::SPRRegClass);
20685 if (VT.getSizeInBits() == 64)
20686 return RCPair(0U, &ARM::DPR_VFP2RegClass);
20687 if (VT.getSizeInBits() == 128)
20688 return RCPair(0U, &ARM::QPR_VFP2RegClass);
20689 break;
20690 }
20691 break;
20692
20693 case 2:
20694 if (Constraint[0] == 'T') {
20695 switch (Constraint[1]) {
20696 default:
20697 break;
20698 case 'e':
20699 return RCPair(0U, &ARM::tGPREvenRegClass);
20700 case 'o':
20701 return RCPair(0U, &ARM::tGPROddRegClass);
20702 }
20703 }
20704 break;
20705
20706 default:
20707 break;
20708 }
20709
20710 if (StringRef("{cc}").equals_insensitive(Constraint))
20711 return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
20712
20713 // r14 is an alias of lr.
20714 if (StringRef("{r14}").equals_insensitive(Constraint))
20715 return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32));
20716
20717 auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
20718 if (isIncompatibleReg(RCP.first, VT))
20719 return {0, nullptr};
20720 return RCP;
20721}
20722
20723/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
20724/// vector. If it is invalid, don't add anything to Ops.
20726 StringRef Constraint,
20727 std::vector<SDValue> &Ops,
20728 SelectionDAG &DAG) const {
20729 SDValue Result;
20730
20731 // Currently only support length 1 constraints.
20732 if (Constraint.size() != 1)
20733 return;
20734
20735 char ConstraintLetter = Constraint[0];
20736 switch (ConstraintLetter) {
20737 default: break;
20738 case 'j':
20739 case 'I': case 'J': case 'K': case 'L':
20740 case 'M': case 'N': case 'O':
20742 if (!C)
20743 return;
20744
20745 int64_t CVal64 = C->getSExtValue();
20746 int CVal = (int) CVal64;
20747 // None of these constraints allow values larger than 32 bits. Check
20748 // that the value fits in an int.
20749 if (CVal != CVal64)
20750 return;
20751
20752 switch (ConstraintLetter) {
20753 case 'j':
20754 // Constant suitable for movw, must be between 0 and
20755 // 65535.
20756 if (Subtarget->hasV6T2Ops() || (Subtarget->hasV8MBaselineOps()))
20757 if (CVal >= 0 && CVal <= 65535)
20758 break;
20759 return;
20760 case 'I':
20761 if (Subtarget->isThumb1Only()) {
20762 // This must be a constant between 0 and 255, for ADD
20763 // immediates.
20764 if (CVal >= 0 && CVal <= 255)
20765 break;
20766 } else if (Subtarget->isThumb2()) {
20767 // A constant that can be used as an immediate value in a
20768 // data-processing instruction.
20769 if (ARM_AM::getT2SOImmVal(CVal) != -1)
20770 break;
20771 } else {
20772 // A constant that can be used as an immediate value in a
20773 // data-processing instruction.
20774 if (ARM_AM::getSOImmVal(CVal) != -1)
20775 break;
20776 }
20777 return;
20778
20779 case 'J':
20780 if (Subtarget->isThumb1Only()) {
20781 // This must be a constant between -255 and -1, for negated ADD
20782 // immediates. This can be used in GCC with an "n" modifier that
20783 // prints the negated value, for use with SUB instructions. It is
20784 // not useful otherwise but is implemented for compatibility.
20785 if (CVal >= -255 && CVal <= -1)
20786 break;
20787 } else {
20788 // This must be a constant between -4095 and 4095. This is suitable
20789 // for use as the immediate offset field in LDR and STR instructions
20790 // such as LDR r0,[r1,#offset].
20791 if (CVal >= -4095 && CVal <= 4095)
20792 break;
20793 }
20794 return;
20795
20796 case 'K':
20797 if (Subtarget->isThumb1Only()) {
20798 // A 32-bit value where only one byte has a nonzero value. Exclude
20799 // zero to match GCC. This constraint is used by GCC internally for
20800 // constants that can be loaded with a move/shift combination.
20801 // It is not useful otherwise but is implemented for compatibility.
20802 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal))
20803 break;
20804 } else if (Subtarget->isThumb2()) {
20805 // A constant whose bitwise inverse can be used as an immediate
20806 // value in a data-processing instruction. This can be used in GCC
20807 // with a "B" modifier that prints the inverted value, for use with
20808 // BIC and MVN instructions. It is not useful otherwise but is
20809 // implemented for compatibility.
20810 if (ARM_AM::getT2SOImmVal(~CVal) != -1)
20811 break;
20812 } else {
20813 // A constant whose bitwise inverse can be used as an immediate
20814 // value in a data-processing instruction. This can be used in GCC
20815 // with a "B" modifier that prints the inverted value, for use with
20816 // BIC and MVN instructions. It is not useful otherwise but is
20817 // implemented for compatibility.
20818 if (ARM_AM::getSOImmVal(~CVal) != -1)
20819 break;
20820 }
20821 return;
20822
20823 case 'L':
20824 if (Subtarget->isThumb1Only()) {
20825 // This must be a constant between -7 and 7,
20826 // for 3-operand ADD/SUB immediate instructions.
20827 if (CVal >= -7 && CVal < 7)
20828 break;
20829 } else if (Subtarget->isThumb2()) {
20830 // A constant whose negation can be used as an immediate value in a
20831 // data-processing instruction. This can be used in GCC with an "n"
20832 // modifier that prints the negated value, for use with SUB
20833 // instructions. It is not useful otherwise but is implemented for
20834 // compatibility.
20835 if (ARM_AM::getT2SOImmVal(-CVal) != -1)
20836 break;
20837 } else {
20838 // A constant whose negation can be used as an immediate value in a
20839 // data-processing instruction. This can be used in GCC with an "n"
20840 // modifier that prints the negated value, for use with SUB
20841 // instructions. It is not useful otherwise but is implemented for
20842 // compatibility.
20843 if (ARM_AM::getSOImmVal(-CVal) != -1)
20844 break;
20845 }
20846 return;
20847
20848 case 'M':
20849 if (Subtarget->isThumb1Only()) {
20850 // This must be a multiple of 4 between 0 and 1020, for
20851 // ADD sp + immediate.
20852 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0))
20853 break;
20854 } else {
20855 // A power of two or a constant between 0 and 32. This is used in
20856 // GCC for the shift amount on shifted register operands, but it is
20857 // useful in general for any shift amounts.
20858 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0))
20859 break;
20860 }
20861 return;
20862
20863 case 'N':
20864 if (Subtarget->isThumb1Only()) {
20865 // This must be a constant between 0 and 31, for shift amounts.
20866 if (CVal >= 0 && CVal <= 31)
20867 break;
20868 }
20869 return;
20870
20871 case 'O':
20872 if (Subtarget->isThumb1Only()) {
20873 // This must be a multiple of 4 between -508 and 508, for
20874 // ADD/SUB sp = sp + immediate.
20875 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0))
20876 break;
20877 }
20878 return;
20879 }
20880 Result = DAG.getSignedTargetConstant(CVal, SDLoc(Op), Op.getValueType());
20881 break;
20882 }
20883
20884 if (Result.getNode()) {
20885 Ops.push_back(Result);
20886 return;
20887 }
20888 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
20889}
20890
20891static RTLIB::Libcall getDivRemLibcall(
20892 const SDNode *N, MVT::SimpleValueType SVT) {
20893 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20894 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20895 "Unhandled Opcode in getDivRemLibcall");
20896 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20897 N->getOpcode() == ISD::SREM;
20898 RTLIB::Libcall LC;
20899 switch (SVT) {
20900 default: llvm_unreachable("Unexpected request for libcall!");
20901 case MVT::i8: LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break;
20902 case MVT::i16: LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break;
20903 case MVT::i32: LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break;
20904 case MVT::i64: LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break;
20905 }
20906 return LC;
20907}
20908
20910 const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
20911 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20912 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20913 "Unhandled Opcode in getDivRemArgList");
20914 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20915 N->getOpcode() == ISD::SREM;
20917 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
20918 EVT ArgVT = N->getOperand(i).getValueType();
20919 Type *ArgTy = ArgVT.getTypeForEVT(*Context);
20920 TargetLowering::ArgListEntry Entry(N->getOperand(i), ArgTy);
20921 Entry.IsSExt = isSigned;
20922 Entry.IsZExt = !isSigned;
20923 Args.push_back(Entry);
20924 }
20925 if (Subtarget->getTargetTriple().isOSWindows() && Args.size() >= 2)
20926 std::swap(Args[0], Args[1]);
20927 return Args;
20928}
20929
20930SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
20931 assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
20932 Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
20933 Subtarget->isTargetFuchsia() || Subtarget->isTargetWindows()) &&
20934 "Register-based DivRem lowering only");
20935 unsigned Opcode = Op->getOpcode();
20936 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
20937 "Invalid opcode for Div/Rem lowering");
20938 bool isSigned = (Opcode == ISD::SDIVREM);
20939 EVT VT = Op->getValueType(0);
20940 SDLoc dl(Op);
20941
20942 if (VT == MVT::i64 && isa<ConstantSDNode>(Op.getOperand(1))) {
20944 if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i32, DAG)) {
20945 SDValue Res0 =
20946 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[0], Result[1]);
20947 SDValue Res1 =
20948 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[2], Result[3]);
20949 return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
20950 {Res0, Res1});
20951 }
20952 }
20953
20954 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
20955
20956 // If the target has hardware divide, use divide + multiply + subtract:
20957 // div = a / b
20958 // rem = a - b * div
20959 // return {div, rem}
20960 // This should be lowered into UDIV/SDIV + MLS later on.
20961 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
20962 : Subtarget->hasDivideInARMMode();
20963 if (hasDivide && Op->getValueType(0).isSimple() &&
20964 Op->getSimpleValueType(0) == MVT::i32) {
20965 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
20966 const SDValue Dividend = Op->getOperand(0);
20967 const SDValue Divisor = Op->getOperand(1);
20968 SDValue Div = DAG.getNode(DivOpcode, dl, VT, Dividend, Divisor);
20969 SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Div, Divisor);
20970 SDValue Rem = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
20971
20972 SDValue Values[2] = {Div, Rem};
20973 return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VT, VT), Values);
20974 }
20975
20976 RTLIB::Libcall LC = getDivRemLibcall(Op.getNode(),
20977 VT.getSimpleVT().SimpleTy);
20978 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
20979
20980 SDValue InChain = DAG.getEntryNode();
20981
20983 DAG.getContext(),
20984 Subtarget);
20985
20986 SDValue Callee =
20987 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
20988
20989 Type *RetTy = StructType::get(Ty, Ty);
20990
20991 if (getTM().getTargetTriple().isOSWindows())
20992 InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
20993
20994 TargetLowering::CallLoweringInfo CLI(DAG);
20995 CLI.setDebugLoc(dl)
20996 .setChain(InChain)
20997 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
20998 Callee, std::move(Args))
20999 .setInRegister()
21002
21003 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
21004 return CallInfo.first;
21005}
21006
21007// Lowers REM using divmod helpers
21008// see RTABI section 4.2/4.3
21009SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
21010 EVT VT = N->getValueType(0);
21011
21012 if (VT == MVT::i64 && isa<ConstantSDNode>(N->getOperand(1))) {
21014 if (expandDIVREMByConstant(N, Result, MVT::i32, DAG))
21015 return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), N->getValueType(0),
21016 Result[0], Result[1]);
21017 }
21018
21019 // Build return types (div and rem)
21020 std::vector<Type*> RetTyParams;
21021 Type *RetTyElement;
21022
21023 switch (VT.getSimpleVT().SimpleTy) {
21024 default: llvm_unreachable("Unexpected request for libcall!");
21025 case MVT::i8: RetTyElement = Type::getInt8Ty(*DAG.getContext()); break;
21026 case MVT::i16: RetTyElement = Type::getInt16Ty(*DAG.getContext()); break;
21027 case MVT::i32: RetTyElement = Type::getInt32Ty(*DAG.getContext()); break;
21028 case MVT::i64: RetTyElement = Type::getInt64Ty(*DAG.getContext()); break;
21029 }
21030
21031 RetTyParams.push_back(RetTyElement);
21032 RetTyParams.push_back(RetTyElement);
21033 ArrayRef<Type*> ret = ArrayRef<Type*>(RetTyParams);
21034 Type *RetTy = StructType::get(*DAG.getContext(), ret);
21035
21036 RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
21037 SimpleTy);
21038 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21039 SDValue InChain = DAG.getEntryNode();
21041 Subtarget);
21042 bool isSigned = N->getOpcode() == ISD::SREM;
21043
21044 SDValue Callee =
21045 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21046
21047 if (getTM().getTargetTriple().isOSWindows())
21048 InChain = WinDBZCheckDenominator(DAG, N, InChain);
21049
21050 // Lower call
21051 CallLoweringInfo CLI(DAG);
21052 CLI.setChain(InChain)
21053 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21054 Callee, std::move(Args))
21057 .setDebugLoc(SDLoc(N));
21058 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
21059
21060 // Return second (rem) result operand (first contains div)
21061 SDNode *ResNode = CallResult.first.getNode();
21062 assert(ResNode->getNumOperands() == 2 && "divmod should return two operands");
21063 return ResNode->getOperand(1);
21064}
21065
21066SDValue
21067ARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
21068 assert(getTM().getTargetTriple().isOSWindows() &&
21069 "unsupported target platform");
21070 SDLoc DL(Op);
21071
21072 // Get the inputs.
21073 SDValue Chain = Op.getOperand(0);
21074 SDValue Size = Op.getOperand(1);
21075
21077 "no-stack-arg-probe")) {
21078 MaybeAlign Align =
21079 cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
21080 SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21081 Chain = SP.getValue(1);
21082 SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
21083 if (Align)
21084 SP = DAG.getNode(ISD::AND, DL, MVT::i32, SP.getValue(0),
21085 DAG.getSignedConstant(-Align->value(), DL, MVT::i32));
21086 Chain = DAG.getCopyToReg(Chain, DL, ARM::SP, SP);
21087 SDValue Ops[2] = { SP, Chain };
21088 return DAG.getMergeValues(Ops, DL);
21089 }
21090
21091 SDValue Words = DAG.getNode(ISD::SRL, DL, MVT::i32, Size,
21092 DAG.getConstant(2, DL, MVT::i32));
21093
21094 SDValue Glue;
21095 Chain = DAG.getCopyToReg(Chain, DL, ARM::R4, Words, Glue);
21096 Glue = Chain.getValue(1);
21097
21098 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
21099 Chain = DAG.getNode(ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Glue);
21100
21101 SDValue NewSP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21102 Chain = NewSP.getValue(1);
21103
21104 SDValue Ops[2] = { NewSP, Chain };
21105 return DAG.getMergeValues(Ops, DL);
21106}
21107
21108SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
21109 bool IsStrict = Op->isStrictFPOpcode();
21110 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21111 const unsigned DstSz = Op.getValueType().getSizeInBits();
21112 const unsigned SrcSz = SrcVal.getValueType().getSizeInBits();
21113 assert(DstSz > SrcSz && DstSz <= 64 && SrcSz >= 16 &&
21114 "Unexpected type for custom-lowering FP_EXTEND");
21115
21116 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21117 "With both FP DP and 16, any FP conversion is legal!");
21118
21119 assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
21120 "With FP16, 16 to 32 conversion is legal!");
21121
21122 // Converting from 32 -> 64 is valid if we have FP64.
21123 if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
21124 // FIXME: Remove this when we have strict fp instruction selection patterns
21125 if (IsStrict) {
21126 SDLoc Loc(Op);
21128 Loc, Op.getValueType(), SrcVal);
21129 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
21130 }
21131 return Op;
21132 }
21133
21134 // Either we are converting from 16 -> 64, without FP16 and/or
21135 // FP.double-precision or without Armv8-fp. So we must do it in two
21136 // steps.
21137 // Or we are converting from 32 -> 64 without fp.double-precision or 16 -> 32
21138 // without FP16. So we must do a function call.
21139 SDLoc Loc(Op);
21140 RTLIB::Libcall LC;
21141 MakeLibCallOptions CallOptions;
21142 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21143 for (unsigned Sz = SrcSz; Sz <= 32 && Sz < DstSz; Sz *= 2) {
21144 bool Supported = (Sz == 16 ? Subtarget->hasFP16() : Subtarget->hasFP64());
21145 MVT SrcVT = (Sz == 16 ? MVT::f16 : MVT::f32);
21146 MVT DstVT = (Sz == 16 ? MVT::f32 : MVT::f64);
21147 if (Supported) {
21148 if (IsStrict) {
21149 SrcVal = DAG.getNode(ISD::STRICT_FP_EXTEND, Loc,
21150 {DstVT, MVT::Other}, {Chain, SrcVal});
21151 Chain = SrcVal.getValue(1);
21152 } else {
21153 SrcVal = DAG.getNode(ISD::FP_EXTEND, Loc, DstVT, SrcVal);
21154 }
21155 } else {
21156 LC = RTLIB::getFPEXT(SrcVT, DstVT);
21157 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21158 "Unexpected type for custom-lowering FP_EXTEND");
21159 std::tie(SrcVal, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21160 Loc, Chain);
21161 }
21162 }
21163
21164 return IsStrict ? DAG.getMergeValues({SrcVal, Chain}, Loc) : SrcVal;
21165}
21166
21167SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
21168 bool IsStrict = Op->isStrictFPOpcode();
21169
21170 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21171 EVT SrcVT = SrcVal.getValueType();
21172 EVT DstVT = Op.getValueType();
21173
21174 if (DstVT == MVT::bf16) {
21175 if (Subtarget->hasBF16() && SrcVT == MVT::f32)
21176 return Op;
21177 return SDValue();
21178 }
21179
21180 const unsigned DstSz = Op.getValueType().getSizeInBits();
21181 const unsigned SrcSz = SrcVT.getSizeInBits();
21182 (void)DstSz;
21183 assert(DstSz < SrcSz && SrcSz <= 64 && DstSz >= 16 &&
21184 "Unexpected type for custom-lowering FP_ROUND");
21185
21186 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21187 "With both FP DP and 16, any FP conversion is legal!");
21188
21189 SDLoc Loc(Op);
21190
21191 // Instruction from 32 -> 16 if hasFP16 is valid
21192 if (SrcSz == 32 && Subtarget->hasFP16())
21193 return Op;
21194
21195 // Lib call from 32 -> 16 / 64 -> [32, 16]
21196 RTLIB::Libcall LC = RTLIB::getFPROUND(SrcVT, DstVT);
21197 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21198 "Unexpected type for custom-lowering FP_ROUND");
21199 MakeLibCallOptions CallOptions;
21200 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21202 std::tie(Result, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21203 Loc, Chain);
21204 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
21205}
21206
21207bool
21209 // The ARM target isn't yet aware of offsets.
21210 return false;
21211}
21212
21214 if (v == 0xffffffff)
21215 return false;
21216
21217 // there can be 1's on either or both "outsides", all the "inside"
21218 // bits must be 0's
21219 return isShiftedMask_32(~v);
21220}
21221
21222/// isFPImmLegal - Returns true if the target can instruction select the
21223/// specified FP immediate natively. If false, the legalizer will
21224/// materialize the FP immediate as a load from a constant pool.
21226 bool ForCodeSize) const {
21227 if (!Subtarget->hasVFP3Base())
21228 return false;
21229 if (VT == MVT::f16 && Subtarget->hasFullFP16())
21230 return ARM_AM::getFP16Imm(Imm) != -1;
21231 if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
21232 ARM_AM::getFP32FP16Imm(Imm) != -1)
21233 return true;
21234 if (VT == MVT::f32)
21235 return ARM_AM::getFP32Imm(Imm) != -1;
21236 if (VT == MVT::f64 && Subtarget->hasFP64())
21237 return ARM_AM::getFP64Imm(Imm) != -1;
21238 return false;
21239}
21240
21241/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
21242/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
21243/// specified in the intrinsic calls.
21246 MachineFunction &MF, unsigned Intrinsic) const {
21247 IntrinsicInfo Info;
21248 switch (Intrinsic) {
21249 case Intrinsic::arm_neon_vld1:
21250 case Intrinsic::arm_neon_vld2:
21251 case Intrinsic::arm_neon_vld3:
21252 case Intrinsic::arm_neon_vld4:
21253 case Intrinsic::arm_neon_vld2lane:
21254 case Intrinsic::arm_neon_vld3lane:
21255 case Intrinsic::arm_neon_vld4lane:
21256 case Intrinsic::arm_neon_vld2dup:
21257 case Intrinsic::arm_neon_vld3dup:
21258 case Intrinsic::arm_neon_vld4dup: {
21259 Info.opc = ISD::INTRINSIC_W_CHAIN;
21260 // Conservatively set memVT to the entire set of vectors loaded.
21261 auto &DL = I.getDataLayout();
21262 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21263 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21264 Info.ptrVal = I.getArgOperand(0);
21265 Info.offset = 0;
21266 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21267 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21268 // volatile loads with NEON intrinsics not supported
21269 Info.flags = MachineMemOperand::MOLoad;
21270 Infos.push_back(Info);
21271 return;
21272 }
21273 case Intrinsic::arm_neon_vld1x2:
21274 case Intrinsic::arm_neon_vld1x3:
21275 case Intrinsic::arm_neon_vld1x4: {
21276 Info.opc = ISD::INTRINSIC_W_CHAIN;
21277 // Conservatively set memVT to the entire set of vectors loaded.
21278 auto &DL = I.getDataLayout();
21279 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21280 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21281 Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
21282 Info.offset = 0;
21283 Info.align = I.getParamAlign(I.arg_size() - 1).valueOrOne();
21284 // volatile loads with NEON intrinsics not supported
21285 Info.flags = MachineMemOperand::MOLoad;
21286 Infos.push_back(Info);
21287 return;
21288 }
21289 case Intrinsic::arm_neon_vst1:
21290 case Intrinsic::arm_neon_vst2:
21291 case Intrinsic::arm_neon_vst3:
21292 case Intrinsic::arm_neon_vst4:
21293 case Intrinsic::arm_neon_vst2lane:
21294 case Intrinsic::arm_neon_vst3lane:
21295 case Intrinsic::arm_neon_vst4lane: {
21296 Info.opc = ISD::INTRINSIC_VOID;
21297 // Conservatively set memVT to the entire set of vectors stored.
21298 auto &DL = I.getDataLayout();
21299 unsigned NumElts = 0;
21300 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21301 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21302 if (!ArgTy->isVectorTy())
21303 break;
21304 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21305 }
21306 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21307 Info.ptrVal = I.getArgOperand(0);
21308 Info.offset = 0;
21309 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21310 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21311 // volatile stores with NEON intrinsics not supported
21312 Info.flags = MachineMemOperand::MOStore;
21313 Infos.push_back(Info);
21314 return;
21315 }
21316 case Intrinsic::arm_neon_vst1x2:
21317 case Intrinsic::arm_neon_vst1x3:
21318 case Intrinsic::arm_neon_vst1x4: {
21319 Info.opc = ISD::INTRINSIC_VOID;
21320 // Conservatively set memVT to the entire set of vectors stored.
21321 auto &DL = I.getDataLayout();
21322 unsigned NumElts = 0;
21323 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21324 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21325 if (!ArgTy->isVectorTy())
21326 break;
21327 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21328 }
21329 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21330 Info.ptrVal = I.getArgOperand(0);
21331 Info.offset = 0;
21332 Info.align = I.getParamAlign(0).valueOrOne();
21333 // volatile stores with NEON intrinsics not supported
21334 Info.flags = MachineMemOperand::MOStore;
21335 Infos.push_back(Info);
21336 return;
21337 }
21338 case Intrinsic::arm_mve_vld2q:
21339 case Intrinsic::arm_mve_vld4q: {
21340 Info.opc = ISD::INTRINSIC_W_CHAIN;
21341 // Conservatively set memVT to the entire set of vectors loaded.
21342 Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
21343 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
21344 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21345 Info.ptrVal = I.getArgOperand(0);
21346 Info.offset = 0;
21347 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21348 // volatile loads with MVE intrinsics not supported
21349 Info.flags = MachineMemOperand::MOLoad;
21350 Infos.push_back(Info);
21351 return;
21352 }
21353 case Intrinsic::arm_mve_vst2q:
21354 case Intrinsic::arm_mve_vst4q: {
21355 Info.opc = ISD::INTRINSIC_VOID;
21356 // Conservatively set memVT to the entire set of vectors stored.
21357 Type *VecTy = I.getArgOperand(1)->getType();
21358 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vst2q ? 2 : 4;
21359 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21360 Info.ptrVal = I.getArgOperand(0);
21361 Info.offset = 0;
21362 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21363 // volatile stores with MVE intrinsics not supported
21364 Info.flags = MachineMemOperand::MOStore;
21365 Infos.push_back(Info);
21366 return;
21367 }
21368 case Intrinsic::arm_mve_vldr_gather_base:
21369 case Intrinsic::arm_mve_vldr_gather_base_predicated: {
21370 Info.opc = ISD::INTRINSIC_W_CHAIN;
21371 Info.ptrVal = nullptr;
21372 Info.memVT = MVT::getVT(I.getType());
21373 Info.align = Align(1);
21374 Info.flags |= MachineMemOperand::MOLoad;
21375 Infos.push_back(Info);
21376 return;
21377 }
21378 case Intrinsic::arm_mve_vldr_gather_base_wb:
21379 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: {
21380 Info.opc = ISD::INTRINSIC_W_CHAIN;
21381 Info.ptrVal = nullptr;
21382 Info.memVT = MVT::getVT(I.getType()->getContainedType(0));
21383 Info.align = Align(1);
21384 Info.flags |= MachineMemOperand::MOLoad;
21385 Infos.push_back(Info);
21386 return;
21387 }
21388 case Intrinsic::arm_mve_vldr_gather_offset:
21389 case Intrinsic::arm_mve_vldr_gather_offset_predicated: {
21390 Info.opc = ISD::INTRINSIC_W_CHAIN;
21391 Info.ptrVal = nullptr;
21392 MVT DataVT = MVT::getVT(I.getType());
21393 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
21394 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21395 DataVT.getVectorNumElements());
21396 Info.align = Align(1);
21397 Info.flags |= MachineMemOperand::MOLoad;
21398 Infos.push_back(Info);
21399 return;
21400 }
21401 case Intrinsic::arm_mve_vstr_scatter_base:
21402 case Intrinsic::arm_mve_vstr_scatter_base_predicated: {
21403 Info.opc = ISD::INTRINSIC_VOID;
21404 Info.ptrVal = nullptr;
21405 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21406 Info.align = Align(1);
21407 Info.flags |= MachineMemOperand::MOStore;
21408 Infos.push_back(Info);
21409 return;
21410 }
21411 case Intrinsic::arm_mve_vstr_scatter_base_wb:
21412 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated: {
21413 Info.opc = ISD::INTRINSIC_W_CHAIN;
21414 Info.ptrVal = nullptr;
21415 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21416 Info.align = Align(1);
21417 Info.flags |= MachineMemOperand::MOStore;
21418 Infos.push_back(Info);
21419 return;
21420 }
21421 case Intrinsic::arm_mve_vstr_scatter_offset:
21422 case Intrinsic::arm_mve_vstr_scatter_offset_predicated: {
21423 Info.opc = ISD::INTRINSIC_VOID;
21424 Info.ptrVal = nullptr;
21425 MVT DataVT = MVT::getVT(I.getArgOperand(2)->getType());
21426 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
21427 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21428 DataVT.getVectorNumElements());
21429 Info.align = Align(1);
21430 Info.flags |= MachineMemOperand::MOStore;
21431 Infos.push_back(Info);
21432 return;
21433 }
21434 case Intrinsic::arm_ldaex:
21435 case Intrinsic::arm_ldrex: {
21436 auto &DL = I.getDataLayout();
21437 Type *ValTy = I.getParamElementType(0);
21438 Info.opc = ISD::INTRINSIC_W_CHAIN;
21439 Info.memVT = MVT::getVT(ValTy);
21440 Info.ptrVal = I.getArgOperand(0);
21441 Info.offset = 0;
21442 Info.align = DL.getABITypeAlign(ValTy);
21444 Infos.push_back(Info);
21445 return;
21446 }
21447 case Intrinsic::arm_stlex:
21448 case Intrinsic::arm_strex: {
21449 auto &DL = I.getDataLayout();
21450 Type *ValTy = I.getParamElementType(1);
21451 Info.opc = ISD::INTRINSIC_W_CHAIN;
21452 Info.memVT = MVT::getVT(ValTy);
21453 Info.ptrVal = I.getArgOperand(1);
21454 Info.offset = 0;
21455 Info.align = DL.getABITypeAlign(ValTy);
21457 Infos.push_back(Info);
21458 return;
21459 }
21460 case Intrinsic::arm_stlexd:
21461 case Intrinsic::arm_strexd:
21462 Info.opc = ISD::INTRINSIC_W_CHAIN;
21463 Info.memVT = MVT::i64;
21464 Info.ptrVal = I.getArgOperand(2);
21465 Info.offset = 0;
21466 Info.align = Align(8);
21468 Infos.push_back(Info);
21469 return;
21470
21471 case Intrinsic::arm_ldaexd:
21472 case Intrinsic::arm_ldrexd:
21473 Info.opc = ISD::INTRINSIC_W_CHAIN;
21474 Info.memVT = MVT::i64;
21475 Info.ptrVal = I.getArgOperand(0);
21476 Info.offset = 0;
21477 Info.align = Align(8);
21479 Infos.push_back(Info);
21480 return;
21481
21482 default:
21483 break;
21484 }
21485}
21486
21487/// Returns true if it is beneficial to convert a load of a constant
21488/// to just the constant itself.
21490 Type *Ty) const {
21491 assert(Ty->isIntegerTy());
21492
21493 unsigned Bits = Ty->getPrimitiveSizeInBits();
21494 if (Bits == 0 || Bits > 32)
21495 return false;
21496 return true;
21497}
21498
21500 unsigned Index) const {
21502 return false;
21503
21504 return (Index == 0 || Index == ResVT.getVectorNumElements());
21505}
21506
21508 ARM_MB::MemBOpt Domain) const {
21509 // First, if the target has no DMB, see what fallback we can use.
21510 if (!Subtarget->hasDataBarrier()) {
21511 // Some ARMv6 cpus can support data barriers with an mcr instruction.
21512 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
21513 // here.
21514 if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
21515 Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
21516 Builder.getInt32(0), Builder.getInt32(7),
21517 Builder.getInt32(10), Builder.getInt32(5)};
21518 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_mcr, args);
21519 }
21520 // Instead of using barriers, atomic accesses on these subtargets use
21521 // libcalls.
21522 llvm_unreachable("makeDMB on a target so old that it has no barriers");
21523 } else {
21524 // Only a full system barrier exists in the M-class architectures.
21525 Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
21526 Constant *CDomain = Builder.getInt32(Domain);
21527 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_dmb, CDomain);
21528 }
21529}
21530
21531// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
21533 Instruction *Inst,
21534 AtomicOrdering Ord) const {
21535 switch (Ord) {
21538 llvm_unreachable("Invalid fence: unordered/non-atomic");
21541 return nullptr; // Nothing to do
21543 if (!Inst->hasAtomicStore())
21544 return nullptr; // Nothing to do
21545 [[fallthrough]];
21548 if (Subtarget->preferISHSTBarriers())
21549 return makeDMB(Builder, ARM_MB::ISHST);
21550 // FIXME: add a comment with a link to documentation justifying this.
21551 else
21552 return makeDMB(Builder, ARM_MB::ISH);
21553 }
21554 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
21555}
21556
21558 Instruction *Inst,
21559 AtomicOrdering Ord) const {
21560 switch (Ord) {
21563 llvm_unreachable("Invalid fence: unordered/not-atomic");
21566 return nullptr; // Nothing to do
21570 return makeDMB(Builder, ARM_MB::ISH);
21571 }
21572 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
21573}
21574
21575// Loads and stores less than 64-bits are already atomic; ones above that
21576// are doomed anyway, so defer to the default libcall and blame the OS when
21577// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21578// anything for those.
21581 bool has64BitAtomicStore;
21582 if (Subtarget->isMClass())
21583 has64BitAtomicStore = false;
21584 else if (Subtarget->isThumb())
21585 has64BitAtomicStore = Subtarget->hasV7Ops();
21586 else
21587 has64BitAtomicStore = Subtarget->hasV6Ops();
21588
21589 unsigned Size = SI->getValueOperand()->getType()->getPrimitiveSizeInBits();
21590 return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind::Expand
21592}
21593
21594// Loads and stores less than 64-bits are already atomic; ones above that
21595// are doomed anyway, so defer to the default libcall and blame the OS when
21596// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21597// anything for those.
21598// FIXME: ldrd and strd are atomic if the CPU has LPAE (e.g. A15 has that
21599// guarantee, see DDI0406C ARM architecture reference manual,
21600// sections A8.8.72-74 LDRD)
21603 bool has64BitAtomicLoad;
21604 if (Subtarget->isMClass())
21605 has64BitAtomicLoad = false;
21606 else if (Subtarget->isThumb())
21607 has64BitAtomicLoad = Subtarget->hasV7Ops();
21608 else
21609 has64BitAtomicLoad = Subtarget->hasV6Ops();
21610
21611 unsigned Size = LI->getType()->getPrimitiveSizeInBits();
21612 return (Size == 64 && has64BitAtomicLoad) ? AtomicExpansionKind::LLOnly
21614}
21615
21616// For the real atomic operations, we have ldrex/strex up to 32 bits,
21617// and up to 64 bits on the non-M profiles
21620 if (AI->isFloatingPointOperation())
21622
21623 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
21624 bool hasAtomicRMW;
21625 if (Subtarget->isMClass())
21626 hasAtomicRMW = Subtarget->hasV8MBaselineOps();
21627 else if (Subtarget->isThumb())
21628 hasAtomicRMW = Subtarget->hasV7Ops();
21629 else
21630 hasAtomicRMW = Subtarget->hasV6Ops();
21631 if (Size <= (Subtarget->isMClass() ? 32U : 64U) && hasAtomicRMW) {
21632 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21633 // implement atomicrmw without spilling. If the target address is also on
21634 // the stack and close enough to the spill slot, this can lead to a
21635 // situation where the monitor always gets cleared and the atomic operation
21636 // can never succeed. So at -O0 lower this operation to a CAS loop.
21637 if (getTargetMachine().getOptLevel() == CodeGenOptLevel::None)
21640 }
21642}
21643
21644// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
21645// bits, and up to 64 bits on the non-M profiles.
21648 const AtomicCmpXchgInst *AI) const {
21649 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21650 // implement cmpxchg without spilling. If the address being exchanged is also
21651 // on the stack and close enough to the spill slot, this can lead to a
21652 // situation where the monitor always gets cleared and the atomic operation
21653 // can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
21654 unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
21655 bool HasAtomicCmpXchg;
21656 if (Subtarget->isMClass())
21657 HasAtomicCmpXchg = Subtarget->hasV8MBaselineOps();
21658 else if (Subtarget->isThumb())
21659 HasAtomicCmpXchg = Subtarget->hasV7Ops();
21660 else
21661 HasAtomicCmpXchg = Subtarget->hasV6Ops();
21662 if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None &&
21663 HasAtomicCmpXchg && Size <= (Subtarget->isMClass() ? 32U : 64U))
21666}
21667
21669 const Instruction *I) const {
21670 return InsertFencesForAtomic;
21671}
21672
21674 // ROPI/RWPI are not supported currently.
21675 return !Subtarget->isROPI() && !Subtarget->isRWPI();
21676}
21677
21679 Module &M, const LibcallLoweringInfo &Libcalls) const {
21680 // MSVC CRT provides functionalities for stack protection.
21681 RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21682 Libcalls.getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21683
21684 RTLIB::LibcallImpl SecurityCookieVar =
21685 Libcalls.getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
21686 if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
21687 SecurityCookieVar != RTLIB::Unsupported) {
21688 // MSVC CRT has a global variable holding security cookie.
21689 M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
21690 PointerType::getUnqual(M.getContext()));
21691
21692 // MSVC CRT has a function to validate security cookie.
21693 FunctionCallee SecurityCheckCookie =
21694 M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall),
21695 Type::getVoidTy(M.getContext()),
21696 PointerType::getUnqual(M.getContext()));
21697 if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee()))
21698 F->addParamAttr(0, Attribute::AttrKind::InReg);
21699 }
21700
21702}
21703
21705 unsigned &Cost) const {
21706 // If we do not have NEON, vector types are not natively supported.
21707 if (!Subtarget->hasNEON())
21708 return false;
21709
21710 // Floating point values and vector values map to the same register file.
21711 // Therefore, although we could do a store extract of a vector type, this is
21712 // better to leave at float as we have more freedom in the addressing mode for
21713 // those.
21714 if (VectorTy->isFPOrFPVectorTy())
21715 return false;
21716
21717 // If the index is unknown at compile time, this is very expensive to lower
21718 // and it is not possible to combine the store with the extract.
21719 if (!isa<ConstantInt>(Idx))
21720 return false;
21721
21722 assert(VectorTy->isVectorTy() && "VectorTy is not a vector type");
21723 unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
21724 // We can do a store + vector extract on any vector that fits perfectly in a D
21725 // or Q register.
21726 if (BitWidth == 64 || BitWidth == 128) {
21727 Cost = 0;
21728 return true;
21729 }
21730 return false;
21731}
21732
21734 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
21735 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
21736 unsigned Opcode = Op.getOpcode();
21737 switch (Opcode) {
21738 case ARMISD::VORRIMM:
21739 case ARMISD::VBICIMM:
21740 return false;
21741 }
21743 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
21744}
21745
21747 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21748}
21749
21751 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21752}
21753
21755 const Instruction &AndI) const {
21756 if (!Subtarget->hasV7Ops())
21757 return false;
21758
21759 // Sink the `and` instruction only if the mask would fit into a modified
21760 // immediate operand.
21762 if (!Mask || Mask->getValue().getBitWidth() > 32u)
21763 return false;
21764 auto MaskVal = unsigned(Mask->getValue().getZExtValue());
21765 return (Subtarget->isThumb2() ? ARM_AM::getT2SOImmVal(MaskVal)
21766 : ARM_AM::getSOImmVal(MaskVal)) != -1;
21767}
21768
21771 SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const {
21772 if (Subtarget->hasMinSize() && !getTM().getTargetTriple().isOSWindows())
21775 ExpansionFactor);
21776}
21777
21779 Value *Addr,
21780 AtomicOrdering Ord) const {
21781 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21782 bool IsAcquire = isAcquireOrStronger(Ord);
21783
21784 // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd
21785 // intrinsic must return {i32, i32} and we have to recombine them into a
21786 // single i64 here.
21787 if (ValueTy->getPrimitiveSizeInBits() == 64) {
21789 IsAcquire ? Intrinsic::arm_ldaexd : Intrinsic::arm_ldrexd;
21790
21791 Value *LoHi =
21792 Builder.CreateIntrinsic(Int, Addr, /*FMFSource=*/nullptr, "lohi");
21793
21794 Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
21795 Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
21796 if (!Subtarget->isLittle())
21797 std::swap (Lo, Hi);
21798 Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
21799 Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
21800 return Builder.CreateOr(
21801 Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 32)), "val64");
21802 }
21803
21804 Type *Tys[] = { Addr->getType() };
21805 Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex;
21806 CallInst *CI = Builder.CreateIntrinsicWithoutFolding(Int, Tys, Addr);
21807
21808 CI->addParamAttr(
21809 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy));
21810 return Builder.CreateTruncOrBitCast(CI, ValueTy);
21811}
21812
21814 IRBuilderBase &Builder) const {
21815 if (!Subtarget->hasV7Ops())
21816 return;
21817 Builder.CreateIntrinsic(Intrinsic::arm_clrex, {});
21818}
21819
21821 Value *Val, Value *Addr,
21822 AtomicOrdering Ord) const {
21823 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21824 bool IsRelease = isReleaseOrStronger(Ord);
21825
21826 // Since the intrinsics must have legal type, the i64 intrinsics take two
21827 // parameters: "i32, i32". We must marshal Val into the appropriate form
21828 // before the call.
21829 if (Val->getType()->getPrimitiveSizeInBits() == 64) {
21831 IsRelease ? Intrinsic::arm_stlexd : Intrinsic::arm_strexd;
21832 Type *Int32Ty = Type::getInt32Ty(M->getContext());
21833
21834 Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
21835 Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
21836 if (!Subtarget->isLittle())
21837 std::swap(Lo, Hi);
21838 return Builder.CreateIntrinsic(Int, {Lo, Hi, Addr});
21839 }
21840
21841 Intrinsic::ID Int = IsRelease ? Intrinsic::arm_stlex : Intrinsic::arm_strex;
21842 Type *Tys[] = { Addr->getType() };
21844
21845 CallInst *CI = Builder.CreateCall(
21846 Strex, {Builder.CreateZExtOrBitCast(
21847 Val, Strex->getFunctionType()->getParamType(0)),
21848 Addr});
21849 CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType,
21850 Val->getType()));
21851 return CI;
21852}
21853
21854
21856 return Subtarget->isMClass();
21857}
21858
21859/// A helper function for determining the number of interleaved accesses we
21860/// will generate when lowering accesses of the given type.
21861unsigned
21863 const DataLayout &DL) const {
21864 return (DL.getTypeSizeInBits(VecTy) + 127) / 128;
21865}
21866
21868 unsigned Factor, FixedVectorType *VecTy, Align Alignment,
21869 const DataLayout &DL) const {
21870
21871 unsigned VecSize = DL.getTypeSizeInBits(VecTy);
21872 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
21873
21874 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
21875 return false;
21876
21877 // Ensure the vector doesn't have f16 elements. Even though we could do an
21878 // i16 vldN, we can't hold the f16 vectors and will end up converting via
21879 // f32.
21880 if (Subtarget->hasNEON() && VecTy->getElementType()->isHalfTy())
21881 return false;
21882 if (Subtarget->hasMVEIntegerOps() && Factor == 3)
21883 return false;
21884
21885 // Ensure the number of vector elements is greater than 1.
21886 if (VecTy->getNumElements() < 2)
21887 return false;
21888
21889 // Ensure the element type is legal.
21890 if (ElSize != 8 && ElSize != 16 && ElSize != 32)
21891 return false;
21892 // And the alignment if high enough under MVE.
21893 if (Subtarget->hasMVEIntegerOps() && Alignment < ElSize / 8)
21894 return false;
21895
21896 // Ensure the total vector size is 64 or a multiple of 128. Types larger than
21897 // 128 will be split into multiple interleaved accesses.
21898 if (Subtarget->hasNEON() && VecSize == 64)
21899 return true;
21900 return VecSize % 128 == 0;
21901}
21902
21904 if (Subtarget->hasNEON())
21905 return 4;
21906 if (Subtarget->hasMVEIntegerOps())
21909}
21910
21911/// Lower an interleaved load into a vldN intrinsic.
21912///
21913/// E.g. Lower an interleaved load (Factor = 2):
21914/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr, align 4
21915/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
21916/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
21917///
21918/// Into:
21919/// %vld2 = { <4 x i32>, <4 x i32> } call llvm.arm.neon.vld2(%ptr, 4)
21920/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 0
21921/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 1
21924 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
21925 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
21926 "Invalid interleave factor");
21927 assert(!Shuffles.empty() && "Empty shufflevector input");
21928 assert(Shuffles.size() == Indices.size() &&
21929 "Unmatched number of shufflevectors and indices");
21930
21931 auto *LI = dyn_cast<LoadInst>(Load);
21932 if (!LI)
21933 return false;
21934 assert(!Mask && GapMask.popcount() == Factor && "Unexpected mask on a load");
21935
21936 auto *VecTy = cast<FixedVectorType>(Shuffles[0]->getType());
21937 Type *EltTy = VecTy->getElementType();
21938
21939 const DataLayout &DL = LI->getDataLayout();
21940 Align Alignment = LI->getAlign();
21941
21942 // Skip if we do not have NEON and skip illegal vector types. We can
21943 // "legalize" wide vector types into multiple interleaved accesses as long as
21944 // the vector types are divisible by 128.
21945 if (!isLegalInterleavedAccessType(Factor, VecTy, Alignment, DL))
21946 return false;
21947
21948 unsigned NumLoads = getNumInterleavedAccesses(VecTy, DL);
21949
21950 // A pointer vector can not be the return type of the ldN intrinsics. Need to
21951 // load integer vectors first and then convert to pointer vectors.
21952 if (EltTy->isPointerTy())
21953 VecTy = FixedVectorType::get(DL.getIntPtrType(EltTy), VecTy);
21954
21955 IRBuilder<> Builder(LI);
21956
21957 // The base address of the load.
21958 Value *BaseAddr = LI->getPointerOperand();
21959
21960 if (NumLoads > 1) {
21961 // If we're going to generate more than one load, reset the sub-vector type
21962 // to something legal.
21963 VecTy = FixedVectorType::get(VecTy->getElementType(),
21964 VecTy->getNumElements() / NumLoads);
21965 }
21966
21967 assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!");
21968
21969 auto createLoadIntrinsic = [&](Value *BaseAddr) {
21970 if (Subtarget->hasNEON()) {
21971 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21972 Type *Tys[] = {VecTy, PtrTy};
21973 static const Intrinsic::ID LoadInts[3] = {Intrinsic::arm_neon_vld2,
21974 Intrinsic::arm_neon_vld3,
21975 Intrinsic::arm_neon_vld4};
21976
21978 Ops.push_back(BaseAddr);
21979 Ops.push_back(Builder.getInt32(LI->getAlign().value()));
21980
21981 return Builder.CreateIntrinsic(LoadInts[Factor - 2], Tys, Ops,
21982 /*FMFSource=*/nullptr, "vldN");
21983 } else {
21984 assert((Factor == 2 || Factor == 4) &&
21985 "expected interleave factor of 2 or 4 for MVE");
21986 Intrinsic::ID LoadInts =
21987 Factor == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
21988 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21989 Type *Tys[] = {VecTy, PtrTy};
21990
21992 Ops.push_back(BaseAddr);
21993 return Builder.CreateIntrinsic(LoadInts, Tys, Ops, /*FMFSource=*/nullptr,
21994 "vldN");
21995 }
21996 };
21997
21998 // Holds sub-vectors extracted from the load intrinsic return values. The
21999 // sub-vectors are associated with the shufflevector instructions they will
22000 // replace.
22002
22003 for (unsigned LoadCount = 0; LoadCount < NumLoads; ++LoadCount) {
22004 // If we're generating more than one load, compute the base address of
22005 // subsequent loads as an offset from the previous.
22006 if (LoadCount > 0)
22007 BaseAddr = Builder.CreateConstGEP1_32(VecTy->getElementType(), BaseAddr,
22008 VecTy->getNumElements() * Factor);
22009
22010 Value *VldN = createLoadIntrinsic(BaseAddr);
22011
22012 // Replace uses of each shufflevector with the corresponding vector loaded
22013 // by ldN.
22014 for (unsigned i = 0; i < Shuffles.size(); i++) {
22015 ShuffleVectorInst *SV = Shuffles[i];
22016 unsigned Index = Indices[i];
22017
22018 Value *SubVec = Builder.CreateExtractValue(VldN, Index);
22019
22020 // Convert the integer vector to pointer vector if the element is pointer.
22021 if (EltTy->isPointerTy())
22022 SubVec = Builder.CreateIntToPtr(
22023 SubVec,
22025
22026 SubVecs[SV].push_back(SubVec);
22027 }
22028 }
22029
22030 // Replace uses of the shufflevector instructions with the sub-vectors
22031 // returned by the load intrinsic. If a shufflevector instruction is
22032 // associated with more than one sub-vector, those sub-vectors will be
22033 // concatenated into a single wide vector.
22034 for (ShuffleVectorInst *SVI : Shuffles) {
22035 auto &SubVec = SubVecs[SVI];
22036 auto *WideVec =
22037 SubVec.size() > 1 ? concatenateVectors(Builder, SubVec) : SubVec[0];
22038 SVI->replaceAllUsesWith(WideVec);
22039 }
22040
22041 return true;
22042}
22043
22044/// Lower an interleaved store into a vstN intrinsic.
22045///
22046/// E.g. Lower an interleaved store (Factor = 3):
22047/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
22048/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
22049/// store <12 x i32> %i.vec, <12 x i32>* %ptr, align 4
22050///
22051/// Into:
22052/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
22053/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
22054/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
22055/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22056///
22057/// Note that the new shufflevectors will be removed and we'll only generate one
22058/// vst3 instruction in CodeGen.
22059///
22060/// Example for a more general valid mask (Factor 3). Lower:
22061/// %i.vec = shuffle <32 x i32> %v0, <32 x i32> %v1,
22062/// <4, 32, 16, 5, 33, 17, 6, 34, 18, 7, 35, 19>
22063/// store <12 x i32> %i.vec, <12 x i32>* %ptr
22064///
22065/// Into:
22066/// %sub.v0 = shuffle <32 x i32> %v0, <32 x i32> v1, <4, 5, 6, 7>
22067/// %sub.v1 = shuffle <32 x i32> %v0, <32 x i32> v1, <32, 33, 34, 35>
22068/// %sub.v2 = shuffle <32 x i32> %v0, <32 x i32> v1, <16, 17, 18, 19>
22069/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22071 Value *LaneMask,
22072 ShuffleVectorInst *SVI,
22073 unsigned Factor,
22074 const APInt &GapMask) const {
22075 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22076 "Invalid interleave factor");
22077 auto *SI = dyn_cast<StoreInst>(Store);
22078 if (!SI)
22079 return false;
22080 assert(!LaneMask && GapMask.popcount() == Factor &&
22081 "Unexpected mask on store");
22082
22083 auto *VecTy = cast<FixedVectorType>(SVI->getType());
22084 assert(VecTy->getNumElements() % Factor == 0 && "Invalid interleaved store");
22085
22086 unsigned LaneLen = VecTy->getNumElements() / Factor;
22087 Type *EltTy = VecTy->getElementType();
22088 auto *SubVecTy = FixedVectorType::get(EltTy, LaneLen);
22089
22090 const DataLayout &DL = SI->getDataLayout();
22091 Align Alignment = SI->getAlign();
22092
22093 // Skip if we do not have NEON and skip illegal vector types. We can
22094 // "legalize" wide vector types into multiple interleaved accesses as long as
22095 // the vector types are divisible by 128.
22096 if (!isLegalInterleavedAccessType(Factor, SubVecTy, Alignment, DL))
22097 return false;
22098
22099 unsigned NumStores = getNumInterleavedAccesses(SubVecTy, DL);
22100
22101 Value *Op0 = SVI->getOperand(0);
22102 Value *Op1 = SVI->getOperand(1);
22103 IRBuilder<> Builder(SI);
22104
22105 // StN intrinsics don't support pointer vectors as arguments. Convert pointer
22106 // vectors to integer vectors.
22107 if (EltTy->isPointerTy()) {
22108 Type *IntTy = DL.getIntPtrType(EltTy);
22109
22110 // Convert to the corresponding integer vector.
22111 auto *IntVecTy =
22113 Op0 = Builder.CreatePtrToInt(Op0, IntVecTy);
22114 Op1 = Builder.CreatePtrToInt(Op1, IntVecTy);
22115
22116 SubVecTy = FixedVectorType::get(IntTy, LaneLen);
22117 }
22118
22119 // The base address of the store.
22120 Value *BaseAddr = SI->getPointerOperand();
22121
22122 if (NumStores > 1) {
22123 // If we're going to generate more than one store, reset the lane length
22124 // and sub-vector type to something legal.
22125 LaneLen /= NumStores;
22126 SubVecTy = FixedVectorType::get(SubVecTy->getElementType(), LaneLen);
22127 }
22128
22129 assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!");
22130
22131 auto Mask = SVI->getShuffleMask();
22132
22133 auto createStoreIntrinsic = [&](Value *BaseAddr,
22134 SmallVectorImpl<Value *> &Shuffles) {
22135 if (Subtarget->hasNEON()) {
22136 static const Intrinsic::ID StoreInts[3] = {Intrinsic::arm_neon_vst2,
22137 Intrinsic::arm_neon_vst3,
22138 Intrinsic::arm_neon_vst4};
22139 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22140 Type *Tys[] = {PtrTy, SubVecTy};
22141
22143 Ops.push_back(BaseAddr);
22144 append_range(Ops, Shuffles);
22145 Ops.push_back(Builder.getInt32(SI->getAlign().value()));
22146 Builder.CreateIntrinsic(StoreInts[Factor - 2], Tys, Ops);
22147 } else {
22148 assert((Factor == 2 || Factor == 4) &&
22149 "expected interleave factor of 2 or 4 for MVE");
22150 Intrinsic::ID StoreInts =
22151 Factor == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
22152 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22153 Type *Tys[] = {PtrTy, SubVecTy};
22154
22156 Ops.push_back(BaseAddr);
22157 append_range(Ops, Shuffles);
22158 for (unsigned F = 0; F < Factor; F++) {
22159 Ops.push_back(Builder.getInt32(F));
22160 Builder.CreateIntrinsic(StoreInts, Tys, Ops);
22161 Ops.pop_back();
22162 }
22163 }
22164 };
22165
22166 for (unsigned StoreCount = 0; StoreCount < NumStores; ++StoreCount) {
22167 // If we generating more than one store, we compute the base address of
22168 // subsequent stores as an offset from the previous.
22169 if (StoreCount > 0)
22170 BaseAddr = Builder.CreateConstGEP1_32(SubVecTy->getElementType(),
22171 BaseAddr, LaneLen * Factor);
22172
22173 SmallVector<Value *, 4> Shuffles;
22174
22175 // Split the shufflevector operands into sub vectors for the new vstN call.
22176 for (unsigned i = 0; i < Factor; i++) {
22177 unsigned IdxI = StoreCount * LaneLen * Factor + i;
22178 if (Mask[IdxI] >= 0) {
22179 Shuffles.push_back(Builder.CreateShuffleVector(
22180 Op0, Op1, createSequentialMask(Mask[IdxI], LaneLen, 0)));
22181 } else {
22182 unsigned StartMask = 0;
22183 for (unsigned j = 1; j < LaneLen; j++) {
22184 unsigned IdxJ = StoreCount * LaneLen * Factor + j;
22185 if (Mask[IdxJ * Factor + IdxI] >= 0) {
22186 StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
22187 break;
22188 }
22189 }
22190 // Note: If all elements in a chunk are undefs, StartMask=0!
22191 // Note: Filling undef gaps with random elements is ok, since
22192 // those elements were being written anyway (with undefs).
22193 // In the case of all undefs we're defaulting to using elems from 0
22194 // Note: StartMask cannot be negative, it's checked in
22195 // isReInterleaveMask
22196 Shuffles.push_back(Builder.CreateShuffleVector(
22197 Op0, Op1, createSequentialMask(StartMask, LaneLen, 0)));
22198 }
22199 }
22200
22201 createStoreIntrinsic(BaseAddr, Shuffles);
22202 }
22203 return true;
22204}
22205
22213
22215 uint64_t &Members) {
22216 if (auto *ST = dyn_cast<StructType>(Ty)) {
22217 for (unsigned i = 0; i < ST->getNumElements(); ++i) {
22218 uint64_t SubMembers = 0;
22219 if (!isHomogeneousAggregate(ST->getElementType(i), Base, SubMembers))
22220 return false;
22221 Members += SubMembers;
22222 }
22223 } else if (auto *AT = dyn_cast<ArrayType>(Ty)) {
22224 uint64_t SubMembers = 0;
22225 if (!isHomogeneousAggregate(AT->getElementType(), Base, SubMembers))
22226 return false;
22227 Members += SubMembers * AT->getNumElements();
22228 } else if (Ty->isFloatTy()) {
22229 if (Base != HA_UNKNOWN && Base != HA_FLOAT)
22230 return false;
22231 Members = 1;
22232 Base = HA_FLOAT;
22233 } else if (Ty->isDoubleTy()) {
22234 if (Base != HA_UNKNOWN && Base != HA_DOUBLE)
22235 return false;
22236 Members = 1;
22237 Base = HA_DOUBLE;
22238 } else if (auto *VT = dyn_cast<VectorType>(Ty)) {
22239 Members = 1;
22240 switch (Base) {
22241 case HA_FLOAT:
22242 case HA_DOUBLE:
22243 return false;
22244 case HA_VECT64:
22245 return VT->getPrimitiveSizeInBits().getFixedValue() == 64;
22246 case HA_VECT128:
22247 return VT->getPrimitiveSizeInBits().getFixedValue() == 128;
22248 case HA_UNKNOWN:
22249 switch (VT->getPrimitiveSizeInBits().getFixedValue()) {
22250 case 64:
22251 Base = HA_VECT64;
22252 return true;
22253 case 128:
22254 Base = HA_VECT128;
22255 return true;
22256 default:
22257 return false;
22258 }
22259 }
22260 }
22261
22262 return (Members > 0 && Members <= 4);
22263}
22264
22265/// Return the correct alignment for the current calling convention.
22267 Type *ArgTy, const DataLayout &DL) const {
22268 const Align ABITypeAlign = DL.getABITypeAlign(ArgTy);
22269 if (!ArgTy->isVectorTy())
22270 return ABITypeAlign;
22271
22272 // Avoid over-aligning vector parameters. It would require realigning the
22273 // stack and waste space for no real benefit.
22274 MaybeAlign StackAlign = DL.getStackAlignment();
22275 assert(StackAlign && "data layout string is missing stack alignment");
22276 return std::min(ABITypeAlign, *StackAlign);
22277}
22278
22279/// Return true if a type is an AAPCS-VFP homogeneous aggregate or one of
22280/// [N x i32] or [N x i64]. This allows front-ends to skip emitting padding when
22281/// passing according to AAPCS rules.
22283 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
22284 const DataLayout &DL) const {
22285 if (getEffectiveCallingConv(CallConv, isVarArg) !=
22287 return false;
22288
22290 uint64_t Members = 0;
22291 bool IsHA = isHomogeneousAggregate(Ty, Base, Members);
22292 LLVM_DEBUG(dbgs() << "isHA: " << IsHA << " "; Ty->dump());
22293
22294 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
22295 return IsHA || IsIntArray;
22296}
22297
22299 const Constant *PersonalityFn) const {
22300 // Platforms which do not use SjLj EH may return values in these registers
22301 // via the personality function.
22303 return EM == ExceptionHandling::SjLj ? Register() : ARM::R0;
22304}
22305
22307 const Constant *PersonalityFn) const {
22308 // Platforms which do not use SjLj EH may return values in these registers
22309 // via the personality function.
22311 return EM == ExceptionHandling::SjLj ? Register() : ARM::R1;
22312}
22313
22314void ARMTargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
22315 // Update IsSplitCSR in ARMFunctionInfo.
22316 ARMFunctionInfo *AFI = Entry->getParent()->getInfo<ARMFunctionInfo>();
22317 AFI->setIsSplitCSR(true);
22318}
22319
22320void ARMTargetLowering::insertCopiesSplitCSR(
22321 MachineBasicBlock *Entry,
22322 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
22323 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
22324 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
22325 if (!IStart)
22326 return;
22327
22328 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
22329 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
22330 MachineBasicBlock::iterator MBBI = Entry->begin();
22331 for (const MCPhysReg *I = IStart; *I; ++I) {
22332 const TargetRegisterClass *RC = nullptr;
22333 if (ARM::GPRRegClass.contains(*I))
22334 RC = &ARM::GPRRegClass;
22335 else if (ARM::DPRRegClass.contains(*I))
22336 RC = &ARM::DPRRegClass;
22337 else
22338 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
22339
22340 Register NewVR = MRI->createVirtualRegister(RC);
22341 // Create copy from CSR to a virtual register.
22342 // FIXME: this currently does not emit CFI pseudo-instructions, it works
22343 // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
22344 // nounwind. If we want to generalize this later, we may need to emit
22345 // CFI pseudo-instructions.
22346 assert(Entry->getParent()->getFunction().hasFnAttribute(
22347 Attribute::NoUnwind) &&
22348 "Function should be nounwind in insertCopiesSplitCSR!");
22349 Entry->addLiveIn(*I);
22350 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
22351 .addReg(*I);
22352
22353 // Insert the copy-back instructions right before the terminator.
22354 for (auto *Exit : Exits)
22355 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
22356 TII->get(TargetOpcode::COPY), *I)
22357 .addReg(NewVR);
22358 }
22359}
22360
22365
22367 return Subtarget->hasMVEIntegerOps();
22368}
22369
22372 auto *VTy = dyn_cast<FixedVectorType>(Ty);
22373 if (!VTy)
22374 return false;
22375
22376 auto *ScalarTy = VTy->getScalarType();
22377 unsigned NumElements = VTy->getNumElements();
22378
22379 unsigned VTyWidth = VTy->getScalarSizeInBits() * NumElements;
22380 if (VTyWidth < 128 || !llvm::isPowerOf2_32(VTyWidth))
22381 return false;
22382
22383 // Both VCADD and VCMUL/VCMLA support the same types, F16 and F32
22384 if (ScalarTy->isHalfTy() || ScalarTy->isFloatTy())
22385 return Subtarget->hasMVEFloatOps();
22386
22388 return false;
22389
22390 return Subtarget->hasMVEIntegerOps() &&
22391 (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
22392 ScalarTy->isIntegerTy(32));
22393}
22394
22396 static const MCPhysReg RCRegs[] = {ARM::FPSCR_RM};
22397 return RCRegs;
22398}
22399
22402 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
22403 Value *Accumulator) const {
22404
22406
22407 unsigned TyWidth = Ty->getScalarSizeInBits() * Ty->getNumElements();
22408
22409 assert(TyWidth >= 128 && "Width of vector type must be at least 128 bits");
22410
22411 if (TyWidth > 128) {
22412 int Stride = Ty->getNumElements() / 2;
22413 auto SplitSeq = llvm::seq<int>(0, Ty->getNumElements());
22414 auto SplitSeqVec = llvm::to_vector(SplitSeq);
22415 ArrayRef<int> LowerSplitMask(&SplitSeqVec[0], Stride);
22416 ArrayRef<int> UpperSplitMask(&SplitSeqVec[Stride], Stride);
22417
22418 auto *LowerSplitA = B.CreateShuffleVector(InputA, LowerSplitMask);
22419 auto *LowerSplitB = B.CreateShuffleVector(InputB, LowerSplitMask);
22420 auto *UpperSplitA = B.CreateShuffleVector(InputA, UpperSplitMask);
22421 auto *UpperSplitB = B.CreateShuffleVector(InputB, UpperSplitMask);
22422 Value *LowerSplitAcc = nullptr;
22423 Value *UpperSplitAcc = nullptr;
22424
22425 if (Accumulator) {
22426 LowerSplitAcc = B.CreateShuffleVector(Accumulator, LowerSplitMask);
22427 UpperSplitAcc = B.CreateShuffleVector(Accumulator, UpperSplitMask);
22428 }
22429
22430 auto *LowerSplitInt = createComplexDeinterleavingIR(
22431 B, OperationType, Rotation, LowerSplitA, LowerSplitB, LowerSplitAcc);
22432 auto *UpperSplitInt = createComplexDeinterleavingIR(
22433 B, OperationType, Rotation, UpperSplitA, UpperSplitB, UpperSplitAcc);
22434
22435 ArrayRef<int> JoinMask(&SplitSeqVec[0], Ty->getNumElements());
22436 return B.CreateShuffleVector(LowerSplitInt, UpperSplitInt, JoinMask);
22437 }
22438
22439 auto *IntTy = Type::getInt32Ty(B.getContext());
22440
22441 ConstantInt *ConstRotation = nullptr;
22442 if (OperationType == ComplexDeinterleavingOperation::CMulPartial) {
22443 ConstRotation = ConstantInt::get(IntTy, (int)Rotation);
22444
22445 if (Accumulator)
22446 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmlaq, Ty,
22447 {ConstRotation, Accumulator, InputB, InputA});
22448 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmulq, Ty,
22449 {ConstRotation, InputB, InputA});
22450 }
22451
22452 if (OperationType == ComplexDeinterleavingOperation::CAdd) {
22453 // 1 means the value is not halved.
22454 auto *ConstHalving = ConstantInt::get(IntTy, 1);
22455
22457 ConstRotation = ConstantInt::get(IntTy, 0);
22459 ConstRotation = ConstantInt::get(IntTy, 1);
22460
22461 if (!ConstRotation)
22462 return nullptr; // Invalid rotation for arm_mve_vcaddq
22463
22464 return B.CreateIntrinsic(Intrinsic::arm_mve_vcaddq, Ty,
22465 {ConstHalving, ConstRotation, InputA, InputB});
22466 }
22467
22468 return nullptr;
22469}
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void createLoadIntrinsic(IntrinsicInst *II, LoadInst *LI, dxil::ResourceTypeInfo &RTI)
static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI, dxil::ResourceTypeInfo &RTI)
This file defines the DenseMap class.
static bool isSigned(unsigned Opcode)
#define Check(C,...)
#define op(i)
#define im(i)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
std::pair< Value *, Value * > ShuffleOps
We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs.
static Value * LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctpop of V before the specified instruction IP.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LVOptions Options
Definition LVOptions.cpp:25
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
nvptx lower args
uint64_t High
uint64_t IntrinsicInst * II
PowerPC Reduce CR logical Operation
R600 Clause Merge
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Lower i1 Copies
Func MI getDebugLoc()))
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This file describes how to lower LLVM code to machine code.
static X86::CondCode getSwappedCondition(X86::CondCode CC)
Assuming the flags are set by MI(a,b), return the condition code if we modify the instructions such t...
static constexpr int Concat[]
Value * RHS
Value * LHS
BinaryOperator * Mul
static bool isIntrinsic(const CallBase &Call, Intrinsic::ID ID)
The Input class is used to parse a yaml document into in-memory structs and vectors.
static constexpr roundingMode rmTowardZero
Definition APFloat.h:357
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:5871
APInt bitcastToAPInt() const
Definition APFloat.h:1467
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1428
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, ARMCP::ARMCPModifier Modifier=ARMCP::no_modifier, bool AddCurrentAddress=false)
ARMConstantPoolValue - ARM specific constantpool value.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()
void setArgumentStackToRestore(unsigned v)
void setArgRegsSaveSize(unsigned s)
void setReturnRegsCount(unsigned s)
unsigned getArgRegsSaveSize() const
void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV)
Indicate to the backend that GV has had its storage changed to inside a constant pool.
void setArgumentStackSize(unsigned size)
unsigned getArgumentStackSize() const
const Triple & getTargetTriple() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
bool useFPVFMx() const
bool isThumb2() const
bool hasBaseDSP() const
const ARMTargetLowering * getTargetLowering() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
bool hasVFP2Base() const
bool useFPVFMx64() const
bool isLittle() const
bool useFPVFMx16() const
bool isMClass() const
bool useMulOps() const
bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X, SDValue Y) const override
Return true if pulling a binary operation into a select with an identity constant is profitable.
bool isReadOnly(const GlobalValue *GV) const
unsigned getMaxSupportedInterleaveFactor() const override
Get the maximum supported factor for interleaved memory accesses.
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be expanded by the IR-level AtomicExpand pass.
unsigned getNumInterleavedAccesses(VectorType *VecTy, const DataLayout &DL) const
Returns the number of interleaved accesses that will be generated when lowering accesses of the given...
bool shouldInsertFencesForAtomic(const Instruction *I) const override
Whether AtomicExpandPass should automatically insert fences and reduce ordering for this atomic.
Align getABIAlignmentForCallingConv(Type *ArgTy, const DataLayout &DL) const override
Return the correct alignment for the current calling convention.
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
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.
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:688
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:845
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:672
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:727
const GlobalValue * getGlobal() const
bool isDSOLocal() const
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h: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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
LLVM_ABI bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
const APInt & getConstantOperandAPInt(unsigned Num) const
Helper method returns the APInt of a ConstantSDNode operand.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
LLVM_ABI bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void setCFIType(uint32_t Type)
bool isUndef() const
Returns true if the node type is UNDEF or POISON.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
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 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
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)
Set CallSiteInfo to be associated with Node.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base, SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexedMode AM, ISD::LoadExtType, bool IsExpanding=false)
DenormalMode getDenormalMode(EVT VT) const
Return the current function's default denormal handling kind for the given floating point type.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
This instruction constructs a fixed permutation of two input vectors.
VectorType * getType() const
Overload to return most specific vector type.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
static LLVM_ABI bool isSplatMask(ArrayRef< int > Mask)
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
bool empty() const
Definition SmallSet.h:169
bool erase(const T &V)
Definition SmallSet.h:200
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
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:48
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition Triple.h:536
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:775
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.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
TOF
Target Operand Flag enum.
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
static ShiftOpc getShiftOpcForNode(unsigned Opcode)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
uint64_t decodeVMOVModImm(unsigned ModImm, unsigned &EltBits)
decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the element value and the element ...
unsigned getAM2Offset(unsigned AM2Opc)
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned createVMOVModImm(unsigned OpCmode, unsigned Val)
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
int getFP16Imm(const APInt &Imm)
getFP16Imm - Return an 8-bit floating-point version of the 16-bit floating-point value.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
int getFP32FP16Imm(const APInt &Imm)
If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding for it.
AddrOpc getAM2Op(unsigned AM2Opc)
bool isBitFieldInvertedMask(unsigned v)
const unsigned FPStatusBits
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
const unsigned FPReservedBits
const unsigned RoundingBitsPos
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ ARM_APCS
ARM Procedure Calling Standard (obsolete, but still used on some targets).
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ ARM_AAPCS
ARM Architecture Procedure Calling Standard calling convention (aka EABI).
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h: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
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:236
@ SET_FPENV
Sets the current floating-point environment.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition ISDOpcodes.h:168
@ FGETSIGN
INT = FGETSIGN(FP) - Return the sign bit of the specified floating point value as an integer 0/1 valu...
Definition ISDOpcodes.h: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
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:487
@ 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_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:486
@ 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:578
@ Length
Definition DWP.cpp:578
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:256
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
ExceptionHandling
Definition CodeGen.h:54
@ SjLj
setjmp/longjmp based exceptions
Definition CodeGen.h:57
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:244
bool RetCC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI Value * concatenateVectors(IRBuilderBase &Builder, ArrayRef< Value * > Vecs)
Concatenate a list of vectors.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
void shuffle(Iterator first, Iterator last, RNG &&g)
Definition STLExtras.h: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:268
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h: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:332
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool FastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool CC_ARM_Win32_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
CombineLevel
Definition DAGCombine.h:15
@ BeforeLegalizeTypes
Definition DAGCombine.h:16
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
@ Add
Sum of integers.
@ FAdd
Sum of floats.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
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:593
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
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
bool isVREVMask(ArrayRef< int > M, EVT VT, unsigned BlockSize)
isVREVMask - Check if a vector shuffle corresponds to a VREV instruction with the specified blocksize...
unsigned gettBLXrOpcode(const MachineFunction &MF)
bool CC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
bool CC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI llvm::SmallVector< int, 16 > createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs)
Create a sequential shuffle mask.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Load/store instruction that can be merged with a base address update.
SDNode * N
Instruction that updates a pointer.
unsigned ConstInc
Pointer increment value if it is a constant, or 0 otherwise.
SDValue Inc
Pointer increment operand.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition Metadata.h: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...